Commit d14a7679 authored by David S. Miller's avatar David S. Miller
parents de72e5de 15483996
...@@ -2970,6 +2970,9 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, ...@@ -2970,6 +2970,9 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
if (modparam_nohwcrypt) if (modparam_nohwcrypt)
return -EOPNOTSUPP; return -EOPNOTSUPP;
if (sc->opmode == NL80211_IFTYPE_AP)
return -EOPNOTSUPP;
switch (key->alg) { switch (key->alg) {
case ALG_WEP: case ALG_WEP:
case ALG_TKIP: case ALG_TKIP:
......
...@@ -478,6 +478,18 @@ void ath9k_ani_reset(struct ath_hw *ah) ...@@ -478,6 +478,18 @@ void ath9k_ani_reset(struct ath_hw *ah)
"Reset ANI state opmode %u\n", ah->opmode); "Reset ANI state opmode %u\n", ah->opmode);
ah->stats.ast_ani_reset++; 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_NOISE_IMMUNITY_LEVEL, 0);
ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL, 0); ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL, 0);
ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, 0); ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, 0);
......
...@@ -474,6 +474,21 @@ ath_regd_init_wiphy(struct ath_regulatory *reg, ...@@ -474,6 +474,21 @@ ath_regd_init_wiphy(struct ath_regulatory *reg,
return 0; 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 int
ath_regd_init(struct ath_regulatory *reg, ath_regd_init(struct ath_regulatory *reg,
struct wiphy *wiphy, struct wiphy *wiphy,
...@@ -486,6 +501,8 @@ ath_regd_init(struct ath_regulatory *reg, ...@@ -486,6 +501,8 @@ ath_regd_init(struct ath_regulatory *reg,
if (!reg) if (!reg)
return -EINVAL; return -EINVAL;
ath_regd_sanitize(reg);
printk(KERN_DEBUG "ath: EEPROM regdomain: 0x%0x\n", reg->current_rd); printk(KERN_DEBUG "ath: EEPROM regdomain: 0x%0x\n", reg->current_rd);
if (!ath_regd_is_eeprom_valid(reg)) { if (!ath_regd_is_eeprom_valid(reg)) {
......
...@@ -2675,12 +2675,10 @@ static ssize_t show_power_level(struct device *d, ...@@ -2675,12 +2675,10 @@ static ssize_t show_power_level(struct device *d,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
struct iwl_priv *priv = dev_get_drvdata(d); struct iwl_priv *priv = dev_get_drvdata(d);
int mode = priv->power_data.user_power_setting;
int level = priv->power_data.power_mode; int level = priv->power_data.power_mode;
char *p = buf; char *p = buf;
p += sprintf(p, "INDEX:%d\t", level); p += sprintf(p, "%d\n", level);
p += sprintf(p, "USER:%d\n", mode);
return p - buf + 1; return p - buf + 1;
} }
......
...@@ -872,7 +872,8 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) ...@@ -872,7 +872,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); 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 */ /* 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)); le16_to_cpu(tx_cmd->len));
pci_dma_sync_single_for_device(priv->pci_dev, txcmd_phys, pci_dma_sync_single_for_device(priv->pci_dev, txcmd_phys,
......
...@@ -3643,12 +3643,10 @@ static ssize_t show_power_level(struct device *d, ...@@ -3643,12 +3643,10 @@ static ssize_t show_power_level(struct device *d,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
struct iwl_priv *priv = dev_get_drvdata(d); struct iwl_priv *priv = dev_get_drvdata(d);
int mode = priv->power_data.user_power_setting;
int level = priv->power_data.power_mode; int level = priv->power_data.power_mode;
char *p = buf; char *p = buf;
p += sprintf(p, "INDEX:%d\t", level); p += sprintf(p, "%d\n", level);
p += sprintf(p, "USER:%d\n", mode);
return p - buf + 1; return p - buf + 1;
} }
......
...@@ -151,8 +151,8 @@ void iwm_if_free(struct iwm_priv *iwm) ...@@ -151,8 +151,8 @@ void iwm_if_free(struct iwm_priv *iwm)
return; return;
free_netdev(iwm_to_ndev(iwm)); free_netdev(iwm_to_ndev(iwm));
iwm_wdev_free(iwm);
iwm_priv_deinit(iwm); iwm_priv_deinit(iwm);
iwm_wdev_free(iwm);
} }
int iwm_if_add(struct iwm_priv *iwm) int iwm_if_add(struct iwm_priv *iwm)
......
...@@ -135,8 +135,14 @@ int lbs_update_hw_spec(struct lbs_private *priv) ...@@ -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 /* 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 * only ever be 8-bit, even though the field size is 16-bit. Some firmware
* returns non-zero high 8 bits here. * 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++) { for (i = 0; i < MRVDRV_MAX_REGION_CODE; i++) {
/* use the region code to search for the index */ /* use the region code to search for the index */
......
...@@ -234,6 +234,8 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in ...@@ -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 */ /** Mesh enable bit in FW capability */
#define MESH_CAPINFO_ENABLE_MASK (1<<16) #define MESH_CAPINFO_ENABLE_MASK (1<<16)
/** FW definition from Marvell v4 */
#define MRVL_FW_V4 (0x04)
/** FW definition from Marvell v5 */ /** FW definition from Marvell v5 */
#define MRVL_FW_V5 (0x05) #define MRVL_FW_V5 (0x05)
/** FW definition from Marvell v10 */ /** FW definition from Marvell v10 */
......
...@@ -709,7 +709,7 @@ static const struct ieee80211_ops mac80211_hwsim_ops = ...@@ -709,7 +709,7 @@ static const struct ieee80211_ops mac80211_hwsim_ops =
static void mac80211_hwsim_free(void) static void mac80211_hwsim_free(void)
{ {
struct list_head tmplist, *i, *tmp; struct list_head tmplist, *i, *tmp;
struct mac80211_hwsim_data *data; struct mac80211_hwsim_data *data, *tmpdata;
INIT_LIST_HEAD(&tmplist); INIT_LIST_HEAD(&tmplist);
...@@ -718,7 +718,7 @@ static void mac80211_hwsim_free(void) ...@@ -718,7 +718,7 @@ static void mac80211_hwsim_free(void)
list_move(i, &tmplist); list_move(i, &tmplist);
spin_unlock_bh(&hwsim_radio_lock); 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_group);
debugfs_remove(data->debugfs_ps); debugfs_remove(data->debugfs_ps);
debugfs_remove(data->debugfs); debugfs_remove(data->debugfs);
...@@ -1167,8 +1167,8 @@ static void __exit exit_mac80211_hwsim(void) ...@@ -1167,8 +1167,8 @@ static void __exit exit_mac80211_hwsim(void)
{ {
printk(KERN_DEBUG "mac80211_hwsim: unregister radios\n"); printk(KERN_DEBUG "mac80211_hwsim: unregister radios\n");
unregister_netdev(hwsim_mon);
mac80211_hwsim_free(); mac80211_hwsim_free();
unregister_netdev(hwsim_mon);
} }
......
...@@ -635,7 +635,7 @@ static int __devinit p54spi_probe(struct spi_device *spi) ...@@ -635,7 +635,7 @@ static int __devinit p54spi_probe(struct spi_device *spi)
hw = p54_init_common(sizeof(*priv)); hw = p54_init_common(sizeof(*priv));
if (!hw) { if (!hw) {
dev_err(&priv->spi->dev, "could not alloc ieee80211_hw"); dev_err(&spi->dev, "could not alloc ieee80211_hw");
return -ENOMEM; return -ENOMEM;
} }
......
...@@ -1550,7 +1550,9 @@ static int rt2500usb_init_eeprom(struct rt2x00_dev *rt2x00dev) ...@@ -1550,7 +1550,9 @@ static int rt2500usb_init_eeprom(struct rt2x00_dev *rt2x00dev)
rt2500usb_register_read(rt2x00dev, MAC_CSR0, &reg); rt2500usb_register_read(rt2x00dev, MAC_CSR0, &reg);
rt2x00_set_chip(rt2x00dev, RT2570, value, reg); 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"); ERROR(rt2x00dev, "Invalid RT chipset detected.\n");
return -ENODEV; return -ENODEV;
} }
......
...@@ -208,11 +208,12 @@ void rtl8187_leds_exit(struct ieee80211_hw *dev) ...@@ -208,11 +208,12 @@ void rtl8187_leds_exit(struct ieee80211_hw *dev)
{ {
struct rtl8187_priv *priv = dev->priv; struct rtl8187_priv *priv = dev->priv;
rtl8187_unregister_led(&priv->led_tx);
/* turn the LED off before exiting */ /* turn the LED off before exiting */
queue_delayed_work(dev->workqueue, &priv->led_off, 0); queue_delayed_work(dev->workqueue, &priv->led_off, 0);
cancel_delayed_work_sync(&priv->led_off); 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_rx);
rtl8187_unregister_led(&priv->led_tx);
} }
#endif /* def CONFIG_RTL8187_LED */ #endif /* def CONFIG_RTL8187_LED */
...@@ -973,7 +973,7 @@ static int acer_rfkill_set(void *data, bool blocked) ...@@ -973,7 +973,7 @@ static int acer_rfkill_set(void *data, bool blocked)
{ {
acpi_status status; acpi_status status;
u32 cap = (unsigned long)data; u32 cap = (unsigned long)data;
status = set_u32(!!blocked, cap); status = set_u32(!blocked, cap);
if (ACPI_FAILURE(status)) if (ACPI_FAILURE(status))
return -ENODEV; return -ENODEV;
return 0; return 0;
......
...@@ -224,7 +224,7 @@ void rfkill_destroy(struct rfkill *rfkill); ...@@ -224,7 +224,7 @@ void rfkill_destroy(struct rfkill *rfkill);
* should be blocked) so that drivers need not keep track of the soft * should be blocked) so that drivers need not keep track of the soft
* block state -- which they might not be able to. * block state -- which they might not be able to.
*/ */
bool __must_check rfkill_set_hw_state(struct rfkill *rfkill, bool blocked); bool rfkill_set_hw_state(struct rfkill *rfkill, bool blocked);
/** /**
* rfkill_set_sw_state - Set the internal rfkill software block state * rfkill_set_sw_state - Set the internal rfkill software block state
......
...@@ -83,6 +83,7 @@ endmenu ...@@ -83,6 +83,7 @@ endmenu
config MAC80211_MESH config MAC80211_MESH
bool "Enable mac80211 mesh networking (pre-802.11s) support" bool "Enable mac80211 mesh networking (pre-802.11s) support"
depends on MAC80211 && EXPERIMENTAL depends on MAC80211 && EXPERIMENTAL
depends on BROKEN
---help--- ---help---
This options enables support of Draft 802.11s mesh networking. This options enables support of Draft 802.11s mesh networking.
The implementation is based on Draft 1.08 of the Mesh Networking The implementation is based on Draft 1.08 of the Mesh Networking
......
...@@ -175,6 +175,8 @@ int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata) ...@@ -175,6 +175,8 @@ int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata)
int err = 0; int err = 0;
u32 hash_idx; u32 hash_idx;
might_sleep();
if (memcmp(dst, sdata->dev->dev_addr, ETH_ALEN) == 0) if (memcmp(dst, sdata->dev->dev_addr, ETH_ALEN) == 0)
/* never add ourselves as neighbours */ /* never add ourselves as neighbours */
return -ENOTSUPP; return -ENOTSUPP;
...@@ -265,6 +267,7 @@ int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata) ...@@ -265,6 +267,7 @@ int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata)
int err = 0; int err = 0;
u32 hash_idx; u32 hash_idx;
might_sleep();
if (memcmp(dst, sdata->dev->dev_addr, ETH_ALEN) == 0) if (memcmp(dst, sdata->dev->dev_addr, ETH_ALEN) == 0)
/* never add ourselves as neighbours */ /* never add ourselves as neighbours */
...@@ -491,8 +494,10 @@ void mesh_path_tx_pending(struct mesh_path *mpath) ...@@ -491,8 +494,10 @@ void mesh_path_tx_pending(struct mesh_path *mpath)
* @skb: frame to discard * @skb: frame to discard
* @sdata: network subif the frame was to be sent through * @sdata: network subif the frame was to be sent through
* *
* If the frame was beign forwarded from another MP, a PERR frame will be sent * If the frame was being forwarded from another MP, a PERR frame will be sent
* to the precursor. * to the precursor. The precursor's address (i.e. the previous hop) was saved
* in addr1 of the frame-to-be-forwarded, and would only be overwritten once
* the destination is successfully resolved.
* *
* Locking: the function must me called within a rcu_read_lock region * Locking: the function must me called within a rcu_read_lock region
*/ */
...@@ -507,7 +512,7 @@ void mesh_path_discard_frame(struct sk_buff *skb, ...@@ -507,7 +512,7 @@ void mesh_path_discard_frame(struct sk_buff *skb,
u8 *ra, *da; u8 *ra, *da;
da = hdr->addr3; da = hdr->addr3;
ra = hdr->addr2; ra = hdr->addr1;
mpath = mesh_path_lookup(da, sdata); mpath = mesh_path_lookup(da, sdata);
if (mpath) if (mpath)
dsn = ++mpath->dsn; dsn = ++mpath->dsn;
......
...@@ -1455,7 +1455,7 @@ int ieee80211_master_start_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -1455,7 +1455,7 @@ int ieee80211_master_start_xmit(struct sk_buff *skb, struct net_device *dev)
monitor_iface = UNKNOWN_ADDRESS; monitor_iface = UNKNOWN_ADDRESS;
len_rthdr = ieee80211_get_radiotap_len(skb->data); len_rthdr = ieee80211_get_radiotap_len(skb->data);
hdr = (struct ieee80211_hdr *)skb->data + len_rthdr; hdr = (struct ieee80211_hdr *)(skb->data + len_rthdr);
hdrlen = ieee80211_hdrlen(hdr->frame_control); hdrlen = ieee80211_hdrlen(hdr->frame_control);
/* check the header is complete in the frame */ /* check the header is complete in the frame */
......
...@@ -549,6 +549,10 @@ void rfkill_set_states(struct rfkill *rfkill, bool sw, bool hw) ...@@ -549,6 +549,10 @@ void rfkill_set_states(struct rfkill *rfkill, bool sw, bool hw)
swprev = !!(rfkill->state & RFKILL_BLOCK_SW); swprev = !!(rfkill->state & RFKILL_BLOCK_SW);
hwprev = !!(rfkill->state & RFKILL_BLOCK_HW); hwprev = !!(rfkill->state & RFKILL_BLOCK_HW);
__rfkill_set_sw_state(rfkill, sw); __rfkill_set_sw_state(rfkill, sw);
if (hw)
rfkill->state |= RFKILL_BLOCK_HW;
else
rfkill->state &= ~RFKILL_BLOCK_HW;
spin_unlock_irqrestore(&rfkill->lock, flags); spin_unlock_irqrestore(&rfkill->lock, flags);
...@@ -648,15 +652,26 @@ static ssize_t rfkill_state_store(struct device *dev, ...@@ -648,15 +652,26 @@ static ssize_t rfkill_state_store(struct device *dev,
struct device_attribute *attr, struct device_attribute *attr,
const char *buf, size_t count) const char *buf, size_t count)
{ {
/* struct rfkill *rfkill = to_rfkill(dev);
* The intention was that userspace can only take control over unsigned long state;
* a given device when/if rfkill-input doesn't control it due int err;
* to user_claim. Since user_claim is currently unsupported,
* we never support changing the state from userspace -- this if (!capable(CAP_NET_ADMIN))
* can be implemented again later. return -EPERM;
*/
err = strict_strtoul(buf, 0, &state);
if (err)
return err;
if (state != RFKILL_USER_STATE_SOFT_BLOCKED &&
state != RFKILL_USER_STATE_UNBLOCKED)
return -EINVAL;
mutex_lock(&rfkill_global_mutex);
rfkill_set_block(rfkill, state == RFKILL_USER_STATE_SOFT_BLOCKED);
mutex_unlock(&rfkill_global_mutex);
return -EPERM; return err ?: count;
} }
static ssize_t rfkill_claim_show(struct device *dev, static ssize_t rfkill_claim_show(struct device *dev,
......
...@@ -997,7 +997,7 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info) ...@@ -997,7 +997,7 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
if (IS_ERR(hdr)) { if (IS_ERR(hdr)) {
err = PTR_ERR(hdr); err = PTR_ERR(hdr);
goto out; goto free_msg;
} }
cookie.msg = msg; cookie.msg = msg;
...@@ -1011,7 +1011,7 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info) ...@@ -1011,7 +1011,7 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
&cookie, get_key_callback); &cookie, get_key_callback);
if (err) if (err)
goto out; goto free_msg;
if (cookie.error) if (cookie.error)
goto nla_put_failure; goto nla_put_failure;
...@@ -1022,6 +1022,7 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info) ...@@ -1022,6 +1022,7 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
nla_put_failure: nla_put_failure:
err = -ENOBUFS; err = -ENOBUFS;
free_msg:
nlmsg_free(msg); nlmsg_free(msg);
out: out:
cfg80211_put_dev(drv); cfg80211_put_dev(drv);
......
...@@ -35,8 +35,6 @@ void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted) ...@@ -35,8 +35,6 @@ void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted)
else else
nl80211_send_scan_done(wiphy_to_dev(request->wiphy), dev); nl80211_send_scan_done(wiphy_to_dev(request->wiphy), dev);
wiphy_to_dev(request->wiphy)->scan_req = NULL;
#ifdef CONFIG_WIRELESS_EXT #ifdef CONFIG_WIRELESS_EXT
if (!aborted) { if (!aborted) {
memset(&wrqu, 0, sizeof(wrqu)); memset(&wrqu, 0, sizeof(wrqu));
...@@ -48,6 +46,7 @@ void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted) ...@@ -48,6 +46,7 @@ void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted)
dev_put(dev); dev_put(dev);
out: out:
wiphy_to_dev(request->wiphy)->scan_req = NULL;
kfree(request); kfree(request);
} }
EXPORT_SYMBOL(cfg80211_scan_done); EXPORT_SYMBOL(cfg80211_scan_done);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment