Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6
This commit is contained in:
commit
dcc51417e5
|
@ -340,9 +340,9 @@ static inline u64 ath5k_extend_tsf(struct ath5k_hw *ah, u32 rstamp)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Interrupt handling */
|
/* Interrupt handling */
|
||||||
static int ath5k_init(struct ath5k_softc *sc);
|
static int ath5k_init(struct ath5k_softc *sc, bool is_resume);
|
||||||
static int ath5k_stop_locked(struct ath5k_softc *sc);
|
static int ath5k_stop_locked(struct ath5k_softc *sc);
|
||||||
static int ath5k_stop_hw(struct ath5k_softc *sc);
|
static int ath5k_stop_hw(struct ath5k_softc *sc, bool is_suspend);
|
||||||
static irqreturn_t ath5k_intr(int irq, void *dev_id);
|
static irqreturn_t ath5k_intr(int irq, void *dev_id);
|
||||||
static void ath5k_tasklet_reset(unsigned long data);
|
static void ath5k_tasklet_reset(unsigned long data);
|
||||||
|
|
||||||
|
@ -646,7 +646,7 @@ ath5k_pci_suspend(struct pci_dev *pdev, pm_message_t state)
|
||||||
|
|
||||||
ath5k_led_off(sc);
|
ath5k_led_off(sc);
|
||||||
|
|
||||||
ath5k_stop_hw(sc);
|
ath5k_stop_hw(sc, true);
|
||||||
|
|
||||||
free_irq(pdev->irq, sc);
|
free_irq(pdev->irq, sc);
|
||||||
pci_save_state(pdev);
|
pci_save_state(pdev);
|
||||||
|
@ -683,7 +683,7 @@ ath5k_pci_resume(struct pci_dev *pdev)
|
||||||
goto err_no_irq;
|
goto err_no_irq;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = ath5k_init(sc);
|
err = ath5k_init(sc, true);
|
||||||
if (err)
|
if (err)
|
||||||
goto err_irq;
|
goto err_irq;
|
||||||
ath5k_led_enable(sc);
|
ath5k_led_enable(sc);
|
||||||
|
@ -2200,12 +2200,17 @@ ath5k_beacon_config(struct ath5k_softc *sc)
|
||||||
\********************/
|
\********************/
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ath5k_init(struct ath5k_softc *sc)
|
ath5k_init(struct ath5k_softc *sc, bool is_resume)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
mutex_lock(&sc->lock);
|
mutex_lock(&sc->lock);
|
||||||
|
|
||||||
|
if (is_resume && !test_bit(ATH_STAT_STARTED, sc->status))
|
||||||
|
goto out_ok;
|
||||||
|
|
||||||
|
__clear_bit(ATH_STAT_STARTED, sc->status);
|
||||||
|
|
||||||
ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "mode %d\n", sc->opmode);
|
ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "mode %d\n", sc->opmode);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2230,12 +2235,15 @@ ath5k_init(struct ath5k_softc *sc)
|
||||||
if (ret)
|
if (ret)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
|
__set_bit(ATH_STAT_STARTED, sc->status);
|
||||||
|
|
||||||
/* Set ack to be sent at low bit-rates */
|
/* Set ack to be sent at low bit-rates */
|
||||||
ath5k_hw_set_ack_bitrate_high(sc->ah, false);
|
ath5k_hw_set_ack_bitrate_high(sc->ah, false);
|
||||||
|
|
||||||
mod_timer(&sc->calib_tim, round_jiffies(jiffies +
|
mod_timer(&sc->calib_tim, round_jiffies(jiffies +
|
||||||
msecs_to_jiffies(ath5k_calinterval * 1000)));
|
msecs_to_jiffies(ath5k_calinterval * 1000)));
|
||||||
|
|
||||||
|
out_ok:
|
||||||
ret = 0;
|
ret = 0;
|
||||||
done:
|
done:
|
||||||
mmiowb();
|
mmiowb();
|
||||||
|
@ -2290,7 +2298,7 @@ ath5k_stop_locked(struct ath5k_softc *sc)
|
||||||
* stop is preempted).
|
* stop is preempted).
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
ath5k_stop_hw(struct ath5k_softc *sc)
|
ath5k_stop_hw(struct ath5k_softc *sc, bool is_suspend)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
@ -2321,6 +2329,9 @@ ath5k_stop_hw(struct ath5k_softc *sc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ath5k_txbuf_free(sc, sc->bbuf);
|
ath5k_txbuf_free(sc, sc->bbuf);
|
||||||
|
if (!is_suspend)
|
||||||
|
__clear_bit(ATH_STAT_STARTED, sc->status);
|
||||||
|
|
||||||
mmiowb();
|
mmiowb();
|
||||||
mutex_unlock(&sc->lock);
|
mutex_unlock(&sc->lock);
|
||||||
|
|
||||||
|
@ -2718,12 +2729,12 @@ ath5k_reset_wake(struct ath5k_softc *sc)
|
||||||
|
|
||||||
static int ath5k_start(struct ieee80211_hw *hw)
|
static int ath5k_start(struct ieee80211_hw *hw)
|
||||||
{
|
{
|
||||||
return ath5k_init(hw->priv);
|
return ath5k_init(hw->priv, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ath5k_stop(struct ieee80211_hw *hw)
|
static void ath5k_stop(struct ieee80211_hw *hw)
|
||||||
{
|
{
|
||||||
ath5k_stop_hw(hw->priv);
|
ath5k_stop_hw(hw->priv, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ath5k_add_interface(struct ieee80211_hw *hw,
|
static int ath5k_add_interface(struct ieee80211_hw *hw,
|
||||||
|
|
|
@ -128,11 +128,12 @@ struct ath5k_softc {
|
||||||
size_t desc_len; /* size of TX/RX descriptors */
|
size_t desc_len; /* size of TX/RX descriptors */
|
||||||
u16 cachelsz; /* cache line size */
|
u16 cachelsz; /* cache line size */
|
||||||
|
|
||||||
DECLARE_BITMAP(status, 4);
|
DECLARE_BITMAP(status, 5);
|
||||||
#define ATH_STAT_INVALID 0 /* disable hardware accesses */
|
#define ATH_STAT_INVALID 0 /* disable hardware accesses */
|
||||||
#define ATH_STAT_MRRETRY 1 /* multi-rate retry support */
|
#define ATH_STAT_MRRETRY 1 /* multi-rate retry support */
|
||||||
#define ATH_STAT_PROMISC 2
|
#define ATH_STAT_PROMISC 2
|
||||||
#define ATH_STAT_LEDSOFT 3 /* enable LED gpio status */
|
#define ATH_STAT_LEDSOFT 3 /* enable LED gpio status */
|
||||||
|
#define ATH_STAT_STARTED 4 /* opened & irqs enabled */
|
||||||
|
|
||||||
unsigned int filter_flags; /* HW flags, AR5K_RX_FILTER_* */
|
unsigned int filter_flags; /* HW flags, AR5K_RX_FILTER_* */
|
||||||
unsigned int curmode; /* current phy mode */
|
unsigned int curmode; /* current phy mode */
|
||||||
|
|
|
@ -433,7 +433,7 @@ struct fw_info {
|
||||||
const static struct fw_info orinoco_fw[] = {
|
const static struct fw_info orinoco_fw[] = {
|
||||||
{ "", "agere_sta_fw.bin", "agere_ap_fw.bin", 0x00390000, 1000 },
|
{ "", "agere_sta_fw.bin", "agere_ap_fw.bin", 0x00390000, 1000 },
|
||||||
{ "", "prism_sta_fw.bin", "prism_ap_fw.bin", 0, 1024 },
|
{ "", "prism_sta_fw.bin", "prism_ap_fw.bin", 0, 1024 },
|
||||||
{ "symbol_sp24t_prim_fw", "symbol_sp24t_sec_fw", "", 0x00003100, 0x100 }
|
{ "symbol_sp24t_prim_fw", "symbol_sp24t_sec_fw", "", 0x00003100, 512 }
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Structure used to access fields in FW
|
/* Structure used to access fields in FW
|
||||||
|
@ -458,7 +458,7 @@ orinoco_dl_firmware(struct orinoco_private *priv,
|
||||||
int ap)
|
int ap)
|
||||||
{
|
{
|
||||||
/* Plug Data Area (PDA) */
|
/* Plug Data Area (PDA) */
|
||||||
__le16 pda[512] = { 0 };
|
__le16 *pda;
|
||||||
|
|
||||||
hermes_t *hw = &priv->hw;
|
hermes_t *hw = &priv->hw;
|
||||||
const struct firmware *fw_entry;
|
const struct firmware *fw_entry;
|
||||||
|
@ -467,7 +467,11 @@ orinoco_dl_firmware(struct orinoco_private *priv,
|
||||||
const unsigned char *end;
|
const unsigned char *end;
|
||||||
const char *firmware;
|
const char *firmware;
|
||||||
struct net_device *dev = priv->ndev;
|
struct net_device *dev = priv->ndev;
|
||||||
int err;
|
int err = 0;
|
||||||
|
|
||||||
|
pda = kzalloc(fw->pda_size, GFP_KERNEL);
|
||||||
|
if (!pda)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
if (ap)
|
if (ap)
|
||||||
firmware = fw->ap_fw;
|
firmware = fw->ap_fw;
|
||||||
|
@ -478,17 +482,17 @@ orinoco_dl_firmware(struct orinoco_private *priv,
|
||||||
dev->name, firmware);
|
dev->name, firmware);
|
||||||
|
|
||||||
/* Read current plug data */
|
/* Read current plug data */
|
||||||
err = hermes_read_pda(hw, pda, fw->pda_addr,
|
err = hermes_read_pda(hw, pda, fw->pda_addr, fw->pda_size, 0);
|
||||||
min_t(u16, fw->pda_size, sizeof(pda)), 0);
|
|
||||||
printk(KERN_DEBUG "%s: Read PDA returned %d\n", dev->name, err);
|
printk(KERN_DEBUG "%s: Read PDA returned %d\n", dev->name, err);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
goto free;
|
||||||
|
|
||||||
err = request_firmware(&fw_entry, firmware, priv->dev);
|
err = request_firmware(&fw_entry, firmware, priv->dev);
|
||||||
if (err) {
|
if (err) {
|
||||||
printk(KERN_ERR "%s: Cannot find firmware %s\n",
|
printk(KERN_ERR "%s: Cannot find firmware %s\n",
|
||||||
dev->name, firmware);
|
dev->name, firmware);
|
||||||
return -ENOENT;
|
err = -ENOENT;
|
||||||
|
goto free;
|
||||||
}
|
}
|
||||||
|
|
||||||
hdr = (const struct orinoco_fw_header *) fw_entry->data;
|
hdr = (const struct orinoco_fw_header *) fw_entry->data;
|
||||||
|
@ -532,6 +536,9 @@ orinoco_dl_firmware(struct orinoco_private *priv,
|
||||||
|
|
||||||
abort:
|
abort:
|
||||||
release_firmware(fw_entry);
|
release_firmware(fw_entry);
|
||||||
|
|
||||||
|
free:
|
||||||
|
kfree(pda);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -549,12 +556,12 @@ symbol_dl_image(struct orinoco_private *priv, const struct fw_info *fw,
|
||||||
int secondary)
|
int secondary)
|
||||||
{
|
{
|
||||||
hermes_t *hw = &priv->hw;
|
hermes_t *hw = &priv->hw;
|
||||||
int ret;
|
int ret = 0;
|
||||||
const unsigned char *ptr;
|
const unsigned char *ptr;
|
||||||
const unsigned char *first_block;
|
const unsigned char *first_block;
|
||||||
|
|
||||||
/* Plug Data Area (PDA) */
|
/* Plug Data Area (PDA) */
|
||||||
__le16 pda[256];
|
__le16 *pda = NULL;
|
||||||
|
|
||||||
/* Binary block begins after the 0x1A marker */
|
/* Binary block begins after the 0x1A marker */
|
||||||
ptr = image;
|
ptr = image;
|
||||||
|
@ -563,28 +570,33 @@ symbol_dl_image(struct orinoco_private *priv, const struct fw_info *fw,
|
||||||
|
|
||||||
/* Read the PDA from EEPROM */
|
/* Read the PDA from EEPROM */
|
||||||
if (secondary) {
|
if (secondary) {
|
||||||
ret = hermes_read_pda(hw, pda, fw->pda_addr, sizeof(pda), 1);
|
pda = kzalloc(fw->pda_size, GFP_KERNEL);
|
||||||
|
if (!pda)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
ret = hermes_read_pda(hw, pda, fw->pda_addr, fw->pda_size, 1);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
goto free;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Stop the firmware, so that it can be safely rewritten */
|
/* Stop the firmware, so that it can be safely rewritten */
|
||||||
if (priv->stop_fw) {
|
if (priv->stop_fw) {
|
||||||
ret = priv->stop_fw(priv, 1);
|
ret = priv->stop_fw(priv, 1);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
goto free;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Program the adapter with new firmware */
|
/* Program the adapter with new firmware */
|
||||||
ret = hermes_program(hw, first_block, end);
|
ret = hermes_program(hw, first_block, end);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
goto free;
|
||||||
|
|
||||||
/* Write the PDA to the adapter */
|
/* Write the PDA to the adapter */
|
||||||
if (secondary) {
|
if (secondary) {
|
||||||
size_t len = hermes_blocks_length(first_block);
|
size_t len = hermes_blocks_length(first_block);
|
||||||
ptr = first_block + len;
|
ptr = first_block + len;
|
||||||
ret = hermes_apply_pda(hw, ptr, pda);
|
ret = hermes_apply_pda(hw, ptr, pda);
|
||||||
|
kfree(pda);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -608,6 +620,10 @@ symbol_dl_image(struct orinoco_private *priv, const struct fw_info *fw,
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
free:
|
||||||
|
kfree(pda);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -306,8 +306,8 @@ static int p54_convert_rev1(struct ieee80211_hw *dev,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *p54_rf_chips[] = { "NULL", "Indigo?", "Duette",
|
static const char *p54_rf_chips[] = { "NULL", "Duette3", "Duette2",
|
||||||
"Frisbee", "Xbow", "Longbow" };
|
"Frisbee", "Xbow", "Longbow", "NULL", "NULL" };
|
||||||
static int p54_init_xbow_synth(struct ieee80211_hw *dev);
|
static int p54_init_xbow_synth(struct ieee80211_hw *dev);
|
||||||
|
|
||||||
static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
|
static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
|
||||||
|
@ -319,6 +319,7 @@ static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
|
||||||
void *tmp;
|
void *tmp;
|
||||||
int err;
|
int err;
|
||||||
u8 *end = (u8 *)eeprom + len;
|
u8 *end = (u8 *)eeprom + len;
|
||||||
|
u16 synth;
|
||||||
DECLARE_MAC_BUF(mac);
|
DECLARE_MAC_BUF(mac);
|
||||||
|
|
||||||
wrap = (struct eeprom_pda_wrap *) eeprom;
|
wrap = (struct eeprom_pda_wrap *) eeprom;
|
||||||
|
@ -400,8 +401,8 @@ static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
|
||||||
tmp = entry->data;
|
tmp = entry->data;
|
||||||
while ((u8 *)tmp < entry->data + data_len) {
|
while ((u8 *)tmp < entry->data + data_len) {
|
||||||
struct bootrec_exp_if *exp_if = tmp;
|
struct bootrec_exp_if *exp_if = tmp;
|
||||||
if (le16_to_cpu(exp_if->if_id) == 0xF)
|
if (le16_to_cpu(exp_if->if_id) == 0xf)
|
||||||
priv->rxhw = le16_to_cpu(exp_if->variant) & 0x07;
|
synth = le16_to_cpu(exp_if->variant);
|
||||||
tmp += sizeof(struct bootrec_exp_if);
|
tmp += sizeof(struct bootrec_exp_if);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -427,22 +428,13 @@ static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (priv->rxhw) {
|
priv->rxhw = synth & 0x07;
|
||||||
case 4: /* XBow */
|
if (priv->rxhw == 4)
|
||||||
p54_init_xbow_synth(dev);
|
p54_init_xbow_synth(dev);
|
||||||
case 1: /* Indigo? */
|
if (!(synth & 0x40))
|
||||||
case 2: /* Duette */
|
|
||||||
dev->wiphy->bands[IEEE80211_BAND_5GHZ] = &band_5GHz;
|
|
||||||
case 3: /* Frisbee */
|
|
||||||
case 5: /* Longbow */
|
|
||||||
dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &band_2GHz;
|
dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &band_2GHz;
|
||||||
break;
|
if (!(synth & 0x80))
|
||||||
default:
|
dev->wiphy->bands[IEEE80211_BAND_5GHZ] = &band_5GHz;
|
||||||
printk(KERN_ERR "%s: unsupported RF-Chip\n",
|
|
||||||
wiphy_name(dev->wiphy));
|
|
||||||
err = -EINVAL;
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!is_valid_ether_addr(dev->wiphy->perm_addr)) {
|
if (!is_valid_ether_addr(dev->wiphy->perm_addr)) {
|
||||||
u8 perm_addr[ETH_ALEN];
|
u8 perm_addr[ETH_ALEN];
|
||||||
|
|
Loading…
Reference in New Issue