diff options
author | Paul Mundt <lethal@linux-sh.org> | 2009-08-13 11:48:01 +0900 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2009-08-13 11:48:01 +0900 |
commit | e290861f99131fc42d98012a9ea2dc185f08f8f9 (patch) | |
tree | 5c8b92d095d74d03b281711c81bac54bd59989cd /drivers/net/wireless | |
parent | b4a757367d36cebddcd332a4024d92f1e87af370 (diff) | |
parent | dbefd606a3b3634799b625f4900336e61c89e868 (diff) |
Merge branch 'sh/stable-updates'
Diffstat (limited to 'drivers/net/wireless')
25 files changed, 117 insertions, 58 deletions
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index c70604f0329..8ce5e4cee16 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c @@ -5918,20 +5918,19 @@ static int airo_set_essid(struct net_device *dev, readSsidRid(local, &SSID_rid); /* Check if we asked for `any' */ - if(dwrq->flags == 0) { + if (dwrq->flags == 0) { /* Just send an empty SSID list */ memset(&SSID_rid, 0, sizeof(SSID_rid)); } else { - int index = (dwrq->flags & IW_ENCODE_INDEX) - 1; + unsigned index = (dwrq->flags & IW_ENCODE_INDEX) - 1; /* Check the size of the string */ - if(dwrq->length > IW_ESSID_MAX_SIZE) { + if (dwrq->length > IW_ESSID_MAX_SIZE) return -E2BIG ; - } + /* Check if index is valid */ - if((index < 0) || (index >= 4)) { + if (index >= ARRAY_SIZE(SSID_rid.ssids)) return -EINVAL; - } /* Set the SSID */ memset(SSID_rid.ssids[index].ssid, 0, @@ -6819,7 +6818,7 @@ static int airo_set_txpow(struct net_device *dev, return -EINVAL; } clear_bit (FLAG_RADIO_OFF, &local->flags); - for (i = 0; cap_rid.txPowerLevels[i] && (i < 8); i++) + for (i = 0; i < 8 && cap_rid.txPowerLevels[i]; i++) if (v == cap_rid.txPowerLevels[i]) { readConfigRid(local, 1); local->config.txPower = v; diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index ea045151f95..029c1bc7468 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -2970,6 +2970,9 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, if (modparam_nohwcrypt) return -EOPNOTSUPP; + if (sc->opmode == NL80211_IFTYPE_AP) + return -EOPNOTSUPP; + switch (key->alg) { case ALG_WEP: case ALG_TKIP: diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c index 1aeafb511dd..aad259b4c19 100644 --- a/drivers/net/wireless/ath/ath9k/ani.c +++ b/drivers/net/wireless/ath/ath9k/ani.c @@ -478,6 +478,18 @@ void ath9k_ani_reset(struct ath_hw *ah) "Reset ANI state opmode %u\n", ah->opmode); ah->stats.ast_ani_reset++; + if (ah->opmode == NL80211_IFTYPE_AP) { + /* + * ath9k_hw_ani_control() will only process items set on + * ah->ani_function + */ + if (IS_CHAN_2GHZ(chan)) + ah->ani_function = (ATH9K_ANI_SPUR_IMMUNITY_LEVEL | + ATH9K_ANI_FIRSTEP_LEVEL); + else + ah->ani_function = 0; + } + ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, 0); ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL, 0); ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, 0); diff --git a/drivers/net/wireless/ath/ath9k/eeprom.c b/drivers/net/wireless/ath/ath9k/eeprom.c index a2fda702b62..ce0e86c36a8 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.c +++ b/drivers/net/wireless/ath/ath9k/eeprom.c @@ -460,7 +460,7 @@ static int ath9k_hw_4k_check_eeprom(struct ath_hw *ah) integer = swab32(eep->modalHeader.antCtrlCommon); eep->modalHeader.antCtrlCommon = integer; - for (i = 0; i < AR5416_MAX_CHAINS; i++) { + for (i = 0; i < AR5416_EEP4K_MAX_CHAINS; i++) { integer = swab32(eep->modalHeader.antCtrlChain[i]); eep->modalHeader.antCtrlChain[i] = integer; } @@ -914,7 +914,7 @@ static void ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah, ctlMode, numCtlModes, isHt40CtlMode, (pCtlMode[ctlMode] & EXT_ADDITIVE)); - for (i = 0; (i < AR5416_NUM_CTLS) && + for (i = 0; (i < AR5416_EEP4K_NUM_CTLS) && pEepData->ctlIndex[i]; i++) { DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, " LOOP-Ctlidx %d: cfgCtl 0x%2.2x " diff --git a/drivers/net/wireless/ath/regd.c b/drivers/net/wireless/ath/regd.c index eef370bd121..bf3d25ba7be 100644 --- a/drivers/net/wireless/ath/regd.c +++ b/drivers/net/wireless/ath/regd.c @@ -474,6 +474,21 @@ ath_regd_init_wiphy(struct ath_regulatory *reg, return 0; } +/* + * Some users have reported their EEPROM programmed with + * 0x8000 set, this is not a supported regulatory domain + * but since we have more than one user with it we need + * a solution for them. We default to 0x64, which is the + * default Atheros world regulatory domain. + */ +static void ath_regd_sanitize(struct ath_regulatory *reg) +{ + if (reg->current_rd != COUNTRY_ERD_FLAG) + return; + printk(KERN_DEBUG "ath: EEPROM regdomain sanitized\n"); + reg->current_rd = 0x64; +} + int ath_regd_init(struct ath_regulatory *reg, struct wiphy *wiphy, @@ -486,6 +501,8 @@ ath_regd_init(struct ath_regulatory *reg, if (!reg) return -EINVAL; + ath_regd_sanitize(reg); + printk(KERN_DEBUG "ath: EEPROM regdomain: 0x%0x\n", reg->current_rd); if (!ath_regd_is_eeprom_valid(reg)) { diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h index fbb3a573463..2de6471d4be 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945.h @@ -112,7 +112,7 @@ enum iwl3945_antenna { #define IWL_TX_FIFO_NONE 7 /* Minimum number of queues. MAX_NUM is defined in hw specific files */ -#define IWL_MIN_NUM_QUEUES 4 +#define IWL39_MIN_NUM_QUEUES 4 #define IEEE80211_DATA_LEN 2304 #define IEEE80211_4ADDR_LEN 30 diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 6d1519e1f01..355f50ea7fe 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2675,12 +2675,10 @@ static ssize_t show_power_level(struct device *d, struct device_attribute *attr, char *buf) { struct iwl_priv *priv = dev_get_drvdata(d); - int mode = priv->power_data.user_power_setting; int level = priv->power_data.power_mode; char *p = buf; - p += sprintf(p, "INDEX:%d\t", level); - p += sprintf(p, "USER:%d\n", mode); + p += sprintf(p, "%d\n", level); return p - buf + 1; } diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 6ab07165ea2..18b135f510e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1332,6 +1332,9 @@ int iwl_setup_mac(struct iwl_priv *priv) hw->wiphy->custom_regulatory = true; + /* Firmware does not support this */ + hw->wiphy->disable_beacon_hints = true; + hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX; /* we create the 802.11 header and a zero-length SSID element */ hw->wiphy->max_scan_ie_len = IWL_MAX_PROBE_REQUEST - 24 - 2; diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 11e08c06891..ca00cc8ad4c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -308,18 +308,18 @@ static ssize_t iwl_dbgfs_nvm_read(struct file *file, return -ENODATA; } + ptr = priv->eeprom; + if (!ptr) { + IWL_ERR(priv, "Invalid EEPROM/OTP memory\n"); + return -ENOMEM; + } + /* 4 characters for byte 0xYY */ buf = kzalloc(buf_size, GFP_KERNEL); if (!buf) { IWL_ERR(priv, "Can not allocate Buffer\n"); return -ENOMEM; } - - ptr = priv->eeprom; - if (!ptr) { - IWL_ERR(priv, "Invalid EEPROM/OTP memory\n"); - return -ENOMEM; - } pos += scnprintf(buf + pos, buf_size - pos, "NVM Type: %s\n", (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP) ? "OTP" : "EEPROM"); diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index e2d620f0b6e..650e20af20f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -258,8 +258,10 @@ struct iwl_channel_info { #define IWL_TX_FIFO_HCCA_2 6 #define IWL_TX_FIFO_NONE 7 -/* Minimum number of queues. MAX_NUM is defined in hw specific files */ -#define IWL_MIN_NUM_QUEUES 4 +/* Minimum number of queues. MAX_NUM is defined in hw specific files. + * Set the minimum to accommodate the 4 standard TX queues, 1 command + * queue, 2 (unused) HCCA queues, and 4 HT queues (one for each AC) */ +#define IWL_MIN_NUM_QUEUES 10 /* Power management (not Tx power) structures */ diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index 2addf735b19..ffd5c61a755 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c @@ -566,6 +566,8 @@ int iwl_remove_default_wep_key(struct iwl_priv *priv, unsigned long flags; spin_lock_irqsave(&priv->sta_lock, flags); + IWL_DEBUG_WEP(priv, "Removing default WEP key: idx=%d\n", + keyconf->keyidx); if (!test_and_clear_bit(keyconf->keyidx, &priv->ucode_key_table)) IWL_ERR(priv, "index %d not used in uCode key table.\n", @@ -573,6 +575,11 @@ int iwl_remove_default_wep_key(struct iwl_priv *priv, priv->default_wep_key--; memset(&priv->wep_keys[keyconf->keyidx], 0, sizeof(priv->wep_keys[0])); + if (iwl_is_rfkill(priv)) { + IWL_DEBUG_WEP(priv, "Not sending REPLY_WEPKEY command due to RFKILL.\n"); + spin_unlock_irqrestore(&priv->sta_lock, flags); + return 0; + } ret = iwl_send_static_wepkey_cmd(priv, 1); IWL_DEBUG_WEP(priv, "Remove default WEP key: idx=%d ret=%d\n", keyconf->keyidx, ret); @@ -853,6 +860,11 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv, priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; + if (iwl_is_rfkill(priv)) { + IWL_DEBUG_WEP(priv, "Not sending REPLY_ADD_STA command because RFKILL enabled. \n"); + spin_unlock_irqrestore(&priv->sta_lock, flags); + return 0; + } ret = iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); spin_unlock_irqrestore(&priv->sta_lock, flags); return ret; diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index 85ae7a62109..2e89040e63b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -720,8 +720,6 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) goto drop_unlock; } - spin_unlock_irqrestore(&priv->lock, flags); - hdr_len = ieee80211_hdrlen(fc); /* Find (or create) index into station table for destination station */ @@ -729,7 +727,7 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) if (sta_id == IWL_INVALID_STATION) { IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n", hdr->addr1); - goto drop; + goto drop_unlock; } IWL_DEBUG_TX(priv, "station Id %d\n", sta_id); @@ -750,14 +748,17 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) txq_id = priv->stations[sta_id].tid[tid].agg.txq_id; swq_id = iwl_virtual_agg_queue_num(swq_id, txq_id); } - priv->stations[sta_id].tid[tid].tfds_in_queue++; } txq = &priv->txq[txq_id]; q = &txq->q; txq->swq_id = swq_id; - spin_lock_irqsave(&priv->lock, flags); + if (unlikely(iwl_queue_space(q) < q->high_mark)) + goto drop_unlock; + + if (ieee80211_is_data_qos(fc)) + priv->stations[sta_id].tid[tid].tfds_in_queue++; /* Set up driver data for this TFD */ memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl_tx_info)); @@ -872,7 +873,8 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx_cmd->hdr, hdr_len); /* Set up entry for this TFD in Tx byte-count array */ - priv->cfg->ops->lib->txq_update_byte_cnt_tbl(priv, txq, + if (info->flags & IEEE80211_TX_CTL_AMPDU) + priv->cfg->ops->lib->txq_update_byte_cnt_tbl(priv, txq, le16_to_cpu(tx_cmd->len)); pci_dma_sync_single_for_device(priv->pci_dev, txcmd_phys, @@ -901,7 +903,6 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) drop_unlock: spin_unlock_irqrestore(&priv->lock, flags); -drop: return -1; } EXPORT_SYMBOL(iwl_tx_skb); @@ -1170,6 +1171,8 @@ int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn) IWL_ERR(priv, "Start AGG on invalid station\n"); return -ENXIO; } + if (unlikely(tid >= MAX_TID_COUNT)) + return -EINVAL; if (priv->stations[sta_id].tid[tid].agg.state != IWL_AGG_OFF) { IWL_ERR(priv, "Start AGG when state is not IWL_AGG_OFF !\n"); diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index cb9bd4c8f25..523843369ca 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -3643,12 +3643,10 @@ static ssize_t show_power_level(struct device *d, struct device_attribute *attr, char *buf) { struct iwl_priv *priv = dev_get_drvdata(d); - int mode = priv->power_data.user_power_setting; int level = priv->power_data.power_mode; char *p = buf; - p += sprintf(p, "INDEX:%d\t", level); - p += sprintf(p, "USER:%d\n", mode); + p += sprintf(p, "%d\n", level); return p - buf + 1; } @@ -3970,6 +3968,9 @@ static int iwl3945_setup_mac(struct iwl_priv *priv) hw->wiphy->custom_regulatory = true; + /* Firmware does not support this */ + hw->wiphy->disable_beacon_hints = true; + hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX_3945; /* we create the 802.11 header and a zero-length SSID element */ hw->wiphy->max_scan_ie_len = IWL_MAX_PROBE_REQUEST - 24 - 2; @@ -4020,10 +4021,10 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e SET_IEEE80211_DEV(hw, &pdev->dev); if ((iwl3945_mod_params.num_of_queues > IWL39_MAX_NUM_QUEUES) || - (iwl3945_mod_params.num_of_queues < IWL_MIN_NUM_QUEUES)) { + (iwl3945_mod_params.num_of_queues < IWL39_MIN_NUM_QUEUES)) { IWL_ERR(priv, "invalid queues_num, should be between %d and %d\n", - IWL_MIN_NUM_QUEUES, IWL39_MAX_NUM_QUEUES); + IWL39_MIN_NUM_QUEUES, IWL39_MAX_NUM_QUEUES); err = -EINVAL; goto out_ieee80211_free_hw; } diff --git a/drivers/net/wireless/iwmc3200wifi/commands.c b/drivers/net/wireless/iwmc3200wifi/commands.c index 834a7f544e5..e2334d12359 100644 --- a/drivers/net/wireless/iwmc3200wifi/commands.c +++ b/drivers/net/wireless/iwmc3200wifi/commands.c @@ -220,6 +220,7 @@ int iwm_store_rxiq_calib_result(struct iwm_priv *iwm) eeprom_rxiq = iwm_eeprom_access(iwm, IWM_EEPROM_CALIB_RXIQ); if (IS_ERR(eeprom_rxiq)) { IWM_ERR(iwm, "Couldn't access EEPROM RX IQ entry\n"); + kfree(rxiq); return PTR_ERR(eeprom_rxiq); } diff --git a/drivers/net/wireless/iwmc3200wifi/netdev.c b/drivers/net/wireless/iwmc3200wifi/netdev.c index aaa20c6885c..bf294e41753 100644 --- a/drivers/net/wireless/iwmc3200wifi/netdev.c +++ b/drivers/net/wireless/iwmc3200wifi/netdev.c @@ -106,10 +106,8 @@ void *iwm_if_alloc(int sizeof_bus, struct device *dev, int ret = 0; wdev = iwm_wdev_alloc(sizeof_bus, dev); - if (!wdev) { - dev_err(dev, "no memory for wireless device instance\n"); - return ERR_PTR(-ENOMEM); - } + if (IS_ERR(wdev)) + return wdev; iwm = wdev_to_iwm(wdev); iwm->bus_ops = if_ops; @@ -151,8 +149,8 @@ void iwm_if_free(struct iwm_priv *iwm) return; free_netdev(iwm_to_ndev(iwm)); - iwm_wdev_free(iwm); iwm_priv_deinit(iwm); + iwm_wdev_free(iwm); } int iwm_if_add(struct iwm_priv *iwm) diff --git a/drivers/net/wireless/libertas/11d.c b/drivers/net/wireless/libertas/11d.c index 9a5408e7d94..5c6968101f0 100644 --- a/drivers/net/wireless/libertas/11d.c +++ b/drivers/net/wireless/libertas/11d.c @@ -47,7 +47,7 @@ static u8 lbs_region_2_code(u8 *region) { u8 i; - for (i = 0; region[i] && i < COUNTRY_CODE_LEN; i++) + for (i = 0; i < COUNTRY_CODE_LEN && region[i]; i++) region[i] = toupper(region[i]); for (i = 0; i < ARRAY_SIZE(region_code_mapping); i++) { diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c index b9b37411903..d6997371c27 100644 --- a/drivers/net/wireless/libertas/assoc.c +++ b/drivers/net/wireless/libertas/assoc.c @@ -1,6 +1,7 @@ /* Copyright (C) 2006, Red Hat, Inc. */ #include <linux/types.h> +#include <linux/kernel.h> #include <linux/etherdevice.h> #include <linux/ieee80211.h> #include <linux/if_arp.h> @@ -43,21 +44,21 @@ static int get_common_rates(struct lbs_private *priv, u16 *rates_size) { u8 *card_rates = lbs_bg_rates; - size_t num_card_rates = sizeof(lbs_bg_rates); int ret = 0, i, j; - u8 tmp[30]; + u8 tmp[(ARRAY_SIZE(lbs_bg_rates) - 1) * (*rates_size - 1)]; size_t tmp_size = 0; /* For each rate in card_rates that exists in rate1, copy to tmp */ - for (i = 0; card_rates[i] && (i < num_card_rates); i++) { - for (j = 0; rates[j] && (j < *rates_size); j++) { + for (i = 0; i < ARRAY_SIZE(lbs_bg_rates) && card_rates[i]; i++) { + for (j = 0; j < *rates_size && rates[j]; j++) { if (rates[j] == card_rates[i]) tmp[tmp_size++] = card_rates[i]; } } lbs_deb_hex(LBS_DEB_JOIN, "AP rates ", rates, *rates_size); - lbs_deb_hex(LBS_DEB_JOIN, "card rates ", card_rates, num_card_rates); + lbs_deb_hex(LBS_DEB_JOIN, "card rates ", card_rates, + ARRAY_SIZE(lbs_bg_rates)); lbs_deb_hex(LBS_DEB_JOIN, "common rates", tmp, tmp_size); lbs_deb_join("TX data rate 0x%02x\n", priv->cur_rate); @@ -69,10 +70,7 @@ static int get_common_rates(struct lbs_private *priv, lbs_pr_alert("Previously set fixed data rate %#x isn't " "compatible with the network.\n", priv->cur_rate); ret = -1; - goto done; } - ret = 0; - done: memset(rates, 0, *rates_size); *rates_size = min_t(int, tmp_size, *rates_size); @@ -322,7 +320,7 @@ static int lbs_associate(struct lbs_private *priv, rates = (struct mrvl_ie_rates_param_set *) pos; rates->header.type = cpu_to_le16(TLV_TYPE_RATES); memcpy(&rates->rates, &bss->rates, MAX_RATES); - tmplen = MAX_RATES; + tmplen = min_t(u16, ARRAY_SIZE(rates->rates), MAX_RATES); if (get_common_rates(priv, rates->rates, &tmplen)) { ret = -1; goto done; @@ -598,7 +596,7 @@ static int lbs_adhoc_join(struct lbs_private *priv, /* Copy Data rates from the rates recorded in scan response */ memset(cmd.bss.rates, 0, sizeof(cmd.bss.rates)); - ratesize = min_t(u16, sizeof(cmd.bss.rates), MAX_RATES); + ratesize = min_t(u16, ARRAY_SIZE(cmd.bss.rates), MAX_RATES); memcpy(cmd.bss.rates, bss->rates, ratesize); if (get_common_rates(priv, cmd.bss.rates, &ratesize)) { lbs_deb_join("ADHOC_JOIN: get_common_rates returned error.\n"); diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c index 01db705a38e..685098148e1 100644 --- a/drivers/net/wireless/libertas/cmd.c +++ b/drivers/net/wireless/libertas/cmd.c @@ -135,8 +135,14 @@ int lbs_update_hw_spec(struct lbs_private *priv) /* Clamp region code to 8-bit since FW spec indicates that it should * only ever be 8-bit, even though the field size is 16-bit. Some firmware * returns non-zero high 8 bits here. + * + * Firmware version 4.0.102 used in CF8381 has region code shifted. We + * need to check for this problem and handle it properly. */ - priv->regioncode = le16_to_cpu(cmd.regioncode) & 0xFF; + if (MRVL_FW_MAJOR_REV(priv->fwrelease) == MRVL_FW_V4) + priv->regioncode = (le16_to_cpu(cmd.regioncode) >> 8) & 0xFF; + else + priv->regioncode = le16_to_cpu(cmd.regioncode) & 0xFF; for (i = 0; i < MRVDRV_MAX_REGION_CODE; i++) { /* use the region code to search for the index */ diff --git a/drivers/net/wireless/libertas/defs.h b/drivers/net/wireless/libertas/defs.h index 48da157d6cd..72f3479a4d7 100644 --- a/drivers/net/wireless/libertas/defs.h +++ b/drivers/net/wireless/libertas/defs.h @@ -234,6 +234,8 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in /** Mesh enable bit in FW capability */ #define MESH_CAPINFO_ENABLE_MASK (1<<16) +/** FW definition from Marvell v4 */ +#define MRVL_FW_V4 (0x04) /** FW definition from Marvell v5 */ #define MRVL_FW_V5 (0x05) /** FW definition from Marvell v10 */ diff --git a/drivers/net/wireless/libertas/scan.c b/drivers/net/wireless/libertas/scan.c index 601b5424967..6c95af3023c 100644 --- a/drivers/net/wireless/libertas/scan.c +++ b/drivers/net/wireless/libertas/scan.c @@ -5,6 +5,7 @@ * for sending scan commands to the firmware. */ #include <linux/types.h> +#include <linux/kernel.h> #include <linux/etherdevice.h> #include <linux/if_arp.h> #include <asm/unaligned.h> @@ -876,7 +877,7 @@ static inline char *lbs_translate_scan(struct lbs_private *priv, iwe.u.bitrate.disabled = 0; iwe.u.bitrate.value = 0; - for (j = 0; bss->rates[j] && (j < sizeof(bss->rates)); j++) { + for (j = 0; j < ARRAY_SIZE(bss->rates) && bss->rates[j]; j++) { /* Bit rate given in 500 kb/s units */ iwe.u.bitrate.value = bss->rates[j] * 500000; current_val = iwe_stream_add_value(info, start, current_val, diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index a111bda392e..7916ca3f84c 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -709,7 +709,7 @@ static const struct ieee80211_ops mac80211_hwsim_ops = static void mac80211_hwsim_free(void) { struct list_head tmplist, *i, *tmp; - struct mac80211_hwsim_data *data; + struct mac80211_hwsim_data *data, *tmpdata; INIT_LIST_HEAD(&tmplist); @@ -718,7 +718,7 @@ static void mac80211_hwsim_free(void) list_move(i, &tmplist); spin_unlock_bh(&hwsim_radio_lock); - list_for_each_entry(data, &tmplist, list) { + list_for_each_entry_safe(data, tmpdata, &tmplist, list) { debugfs_remove(data->debugfs_group); debugfs_remove(data->debugfs_ps); debugfs_remove(data->debugfs); @@ -1167,8 +1167,8 @@ static void __exit exit_mac80211_hwsim(void) { printk(KERN_DEBUG "mac80211_hwsim: unregister radios\n"); - unregister_netdev(hwsim_mon); mac80211_hwsim_free(); + unregister_netdev(hwsim_mon); } diff --git a/drivers/net/wireless/p54/p54spi.c b/drivers/net/wireless/p54/p54spi.c index 83116baeb11..72c7dbd39d0 100644 --- a/drivers/net/wireless/p54/p54spi.c +++ b/drivers/net/wireless/p54/p54spi.c @@ -635,7 +635,7 @@ static int __devinit p54spi_probe(struct spi_device *spi) hw = p54_init_common(sizeof(*priv)); if (!hw) { - dev_err(&priv->spi->dev, "could not alloc ieee80211_hw"); + dev_err(&spi->dev, "could not alloc ieee80211_hw"); return -ENOMEM; } diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 66daf68ff0e..ce75426764a 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c @@ -1550,7 +1550,9 @@ static int rt2500usb_init_eeprom(struct rt2x00_dev *rt2x00dev) rt2500usb_register_read(rt2x00dev, MAC_CSR0, ®); rt2x00_set_chip(rt2x00dev, RT2570, value, reg); - if (!rt2x00_check_rev(&rt2x00dev->chip, 0x000ffff0, 0)) { + if (!rt2x00_check_rev(&rt2x00dev->chip, 0x000ffff0, 0) || + rt2x00_check_rev(&rt2x00dev->chip, 0x0000000f, 0)) { + ERROR(rt2x00dev, "Invalid RT chipset detected.\n"); return -ENODEV; } diff --git a/drivers/net/wireless/rtl818x/rtl8187_leds.c b/drivers/net/wireless/rtl818x/rtl8187_leds.c index b4425359224..cf9f899fe0e 100644 --- a/drivers/net/wireless/rtl818x/rtl8187_leds.c +++ b/drivers/net/wireless/rtl818x/rtl8187_leds.c @@ -208,11 +208,12 @@ void rtl8187_leds_exit(struct ieee80211_hw *dev) { struct rtl8187_priv *priv = dev->priv; - rtl8187_unregister_led(&priv->led_tx); /* turn the LED off before exiting */ queue_delayed_work(dev->workqueue, &priv->led_off, 0); cancel_delayed_work_sync(&priv->led_off); + cancel_delayed_work_sync(&priv->led_on); rtl8187_unregister_led(&priv->led_rx); + rtl8187_unregister_led(&priv->led_tx); } #endif /* def CONFIG_RTL8187_LED */ diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 40b07b98822..3bd3c779fff 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c @@ -698,7 +698,7 @@ int zd_mac_rx(struct ieee80211_hw *hw, const u8 *buffer, unsigned int length) && !mac->pass_ctrl) return 0; - fc = *(__le16 *)buffer; + fc = get_unaligned((__le16*)buffer); need_padding = ieee80211_is_data_qos(fc) ^ ieee80211_has_a4(fc); skb = dev_alloc_skb(length + (need_padding ? 2 : 0)); |