diff options
| -rw-r--r-- | drivers/bcma/main.c | 5 | ||||
| -rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/usb.c | 2 | ||||
| -rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 68 | ||||
| -rw-r--r-- | drivers/net/wireless/ipw2x00/ipw2200.c | 2 | ||||
| -rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/devices.c | 39 | ||||
| -rw-r--r-- | include/net/cfg80211.h | 1 | ||||
| -rw-r--r-- | net/bluetooth/smp.c | 6 | ||||
| -rw-r--r-- | net/mac80211/iface.c | 2 | ||||
| -rw-r--r-- | net/mac80211/mlme.c | 35 | ||||
| -rw-r--r-- | net/mac80211/sta_info.c | 4 | ||||
| -rw-r--r-- | net/mac80211/util.c | 4 | ||||
| -rw-r--r-- | net/mac80211/wpa.c | 14 | ||||
| -rw-r--r-- | net/wireless/mlme.c | 12 |
13 files changed, 99 insertions, 95 deletions
diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c index 432aeeedfd5e..d865470bc951 100644 --- a/drivers/bcma/main.c +++ b/drivers/bcma/main.c | |||
| @@ -158,9 +158,10 @@ static int bcma_register_cores(struct bcma_bus *bus) | |||
| 158 | 158 | ||
| 159 | static void bcma_unregister_cores(struct bcma_bus *bus) | 159 | static void bcma_unregister_cores(struct bcma_bus *bus) |
| 160 | { | 160 | { |
| 161 | struct bcma_device *core; | 161 | struct bcma_device *core, *tmp; |
| 162 | 162 | ||
| 163 | list_for_each_entry(core, &bus->cores, list) { | 163 | list_for_each_entry_safe(core, tmp, &bus->cores, list) { |
| 164 | list_del(&core->list); | ||
| 164 | if (core->dev_registered) | 165 | if (core->dev_registered) |
| 165 | device_unregister(&core->dev); | 166 | device_unregister(&core->dev); |
| 166 | } | 167 | } |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c index a2b4b1e71017..7a6dfdc67b6c 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c | |||
| @@ -1339,7 +1339,7 @@ static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo, | |||
| 1339 | } | 1339 | } |
| 1340 | 1340 | ||
| 1341 | ret = brcmf_bus_start(dev); | 1341 | ret = brcmf_bus_start(dev); |
| 1342 | if (ret == -ENOLINK) { | 1342 | if (ret) { |
| 1343 | brcmf_dbg(ERROR, "dongle is not responding\n"); | 1343 | brcmf_dbg(ERROR, "dongle is not responding\n"); |
| 1344 | brcmf_detach(dev); | 1344 | brcmf_detach(dev); |
| 1345 | goto fail; | 1345 | goto fail; |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index c1abaa6db59e..411dfe7c7ff0 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | |||
| @@ -3972,7 +3972,7 @@ brcmf_set_management_ie(struct brcmf_cfg80211_info *cfg, | |||
| 3972 | u8 *iovar_ie_buf; | 3972 | u8 *iovar_ie_buf; |
| 3973 | u8 *curr_ie_buf; | 3973 | u8 *curr_ie_buf; |
| 3974 | u8 *mgmt_ie_buf = NULL; | 3974 | u8 *mgmt_ie_buf = NULL; |
| 3975 | u32 mgmt_ie_buf_len = 0; | 3975 | int mgmt_ie_buf_len; |
| 3976 | u32 *mgmt_ie_len = 0; | 3976 | u32 *mgmt_ie_len = 0; |
| 3977 | u32 del_add_ie_buf_len = 0; | 3977 | u32 del_add_ie_buf_len = 0; |
| 3978 | u32 total_ie_buf_len = 0; | 3978 | u32 total_ie_buf_len = 0; |
| @@ -3982,7 +3982,7 @@ brcmf_set_management_ie(struct brcmf_cfg80211_info *cfg, | |||
| 3982 | struct parsed_vndr_ie_info *vndrie_info; | 3982 | struct parsed_vndr_ie_info *vndrie_info; |
| 3983 | s32 i; | 3983 | s32 i; |
| 3984 | u8 *ptr; | 3984 | u8 *ptr; |
| 3985 | u32 remained_buf_len; | 3985 | int remained_buf_len; |
| 3986 | 3986 | ||
| 3987 | WL_TRACE("bssidx %d, pktflag : 0x%02X\n", bssidx, pktflag); | 3987 | WL_TRACE("bssidx %d, pktflag : 0x%02X\n", bssidx, pktflag); |
| 3988 | iovar_ie_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL); | 3988 | iovar_ie_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL); |
| @@ -4606,12 +4606,13 @@ brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg, | |||
| 4606 | struct brcmf_cfg80211_profile *profile = cfg->profile; | 4606 | struct brcmf_cfg80211_profile *profile = cfg->profile; |
| 4607 | struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg); | 4607 | struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg); |
| 4608 | struct wiphy *wiphy = cfg_to_wiphy(cfg); | 4608 | struct wiphy *wiphy = cfg_to_wiphy(cfg); |
| 4609 | struct brcmf_channel_info_le channel_le; | 4609 | struct ieee80211_channel *notify_channel = NULL; |
| 4610 | struct ieee80211_channel *notify_channel; | ||
| 4611 | struct ieee80211_supported_band *band; | 4610 | struct ieee80211_supported_band *band; |
| 4611 | struct brcmf_bss_info_le *bi; | ||
| 4612 | u32 freq; | 4612 | u32 freq; |
| 4613 | s32 err = 0; | 4613 | s32 err = 0; |
| 4614 | u32 target_channel; | 4614 | u32 target_channel; |
| 4615 | u8 *buf; | ||
| 4615 | 4616 | ||
| 4616 | WL_TRACE("Enter\n"); | 4617 | WL_TRACE("Enter\n"); |
| 4617 | 4618 | ||
| @@ -4619,11 +4620,22 @@ brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg, | |||
| 4619 | memcpy(profile->bssid, e->addr, ETH_ALEN); | 4620 | memcpy(profile->bssid, e->addr, ETH_ALEN); |
| 4620 | brcmf_update_bss_info(cfg); | 4621 | brcmf_update_bss_info(cfg); |
| 4621 | 4622 | ||
| 4622 | brcmf_exec_dcmd(ndev, BRCMF_C_GET_CHANNEL, &channel_le, | 4623 | buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL); |
| 4623 | sizeof(channel_le)); | 4624 | if (buf == NULL) { |
| 4625 | err = -ENOMEM; | ||
| 4626 | goto done; | ||
| 4627 | } | ||
| 4628 | |||
| 4629 | /* data sent to dongle has to be little endian */ | ||
| 4630 | *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX); | ||
| 4631 | err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_BSS_INFO, buf, WL_BSS_INFO_MAX); | ||
| 4632 | |||
| 4633 | if (err) | ||
| 4634 | goto done; | ||
| 4624 | 4635 | ||
| 4625 | target_channel = le32_to_cpu(channel_le.target_channel); | 4636 | bi = (struct brcmf_bss_info_le *)(buf + 4); |
| 4626 | WL_CONN("Roamed to channel %d\n", target_channel); | 4637 | target_channel = bi->ctl_ch ? bi->ctl_ch : |
| 4638 | CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec)); | ||
| 4627 | 4639 | ||
| 4628 | if (target_channel <= CH_MAX_2G_CHANNEL) | 4640 | if (target_channel <= CH_MAX_2G_CHANNEL) |
| 4629 | band = wiphy->bands[IEEE80211_BAND_2GHZ]; | 4641 | band = wiphy->bands[IEEE80211_BAND_2GHZ]; |
| @@ -4633,6 +4645,8 @@ brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg, | |||
| 4633 | freq = ieee80211_channel_to_frequency(target_channel, band->band); | 4645 | freq = ieee80211_channel_to_frequency(target_channel, band->band); |
| 4634 | notify_channel = ieee80211_get_channel(wiphy, freq); | 4646 | notify_channel = ieee80211_get_channel(wiphy, freq); |
| 4635 | 4647 | ||
| 4648 | done: | ||
| 4649 | kfree(buf); | ||
| 4636 | cfg80211_roamed(ndev, notify_channel, (u8 *)profile->bssid, | 4650 | cfg80211_roamed(ndev, notify_channel, (u8 *)profile->bssid, |
| 4637 | conn_info->req_ie, conn_info->req_ie_len, | 4651 | conn_info->req_ie, conn_info->req_ie_len, |
| 4638 | conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL); | 4652 | conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL); |
| @@ -5186,41 +5200,6 @@ brcmf_cfg80211_event(struct net_device *ndev, | |||
| 5186 | schedule_work(&cfg->event_work); | 5200 | schedule_work(&cfg->event_work); |
| 5187 | } | 5201 | } |
| 5188 | 5202 | ||
| 5189 | static s32 brcmf_dongle_mode(struct net_device *ndev, s32 iftype) | ||
| 5190 | { | ||
| 5191 | s32 infra = 0; | ||
| 5192 | s32 err = 0; | ||
| 5193 | |||
| 5194 | switch (iftype) { | ||
| 5195 | case NL80211_IFTYPE_MONITOR: | ||
| 5196 | case NL80211_IFTYPE_WDS: | ||
| 5197 | WL_ERR("type (%d) : currently we do not support this mode\n", | ||
| 5198 | iftype); | ||
| 5199 | err = -EINVAL; | ||
| 5200 | return err; | ||
| 5201 | case NL80211_IFTYPE_ADHOC: | ||
| 5202 | infra = 0; | ||
| 5203 | break; | ||
| 5204 | case NL80211_IFTYPE_STATION: | ||
| 5205 | infra = 1; | ||
| 5206 | break; | ||
| 5207 | case NL80211_IFTYPE_AP: | ||
| 5208 | infra = 1; | ||
| 5209 | break; | ||
| 5210 | default: | ||
| 5211 | err = -EINVAL; | ||
| 5212 | WL_ERR("invalid type (%d)\n", iftype); | ||
| 5213 | return err; | ||
| 5214 | } | ||
| 5215 | err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_INFRA, &infra); | ||
| 5216 | if (err) { | ||
| 5217 | WL_ERR("WLC_SET_INFRA error (%d)\n", err); | ||
| 5218 | return err; | ||
| 5219 | } | ||
| 5220 | |||
| 5221 | return 0; | ||
| 5222 | } | ||
| 5223 | |||
| 5224 | static s32 brcmf_dongle_eventmsg(struct net_device *ndev) | 5203 | static s32 brcmf_dongle_eventmsg(struct net_device *ndev) |
| 5225 | { | 5204 | { |
| 5226 | /* Room for "event_msgs" + '\0' + bitvec */ | 5205 | /* Room for "event_msgs" + '\0' + bitvec */ |
| @@ -5439,7 +5418,8 @@ static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg) | |||
| 5439 | WL_BEACON_TIMEOUT); | 5418 | WL_BEACON_TIMEOUT); |
| 5440 | if (err) | 5419 | if (err) |
| 5441 | goto default_conf_out; | 5420 | goto default_conf_out; |
| 5442 | err = brcmf_dongle_mode(ndev, wdev->iftype); | 5421 | err = brcmf_cfg80211_change_iface(wdev->wiphy, ndev, wdev->iftype, |
| 5422 | NULL, NULL); | ||
| 5443 | if (err && err != -EINPROGRESS) | 5423 | if (err && err != -EINPROGRESS) |
| 5444 | goto default_conf_out; | 5424 | goto default_conf_out; |
| 5445 | err = brcmf_dongle_probecap(cfg); | 5425 | err = brcmf_dongle_probecap(cfg); |
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c index 935120fc8c93..768bf612533e 100644 --- a/drivers/net/wireless/ipw2x00/ipw2200.c +++ b/drivers/net/wireless/ipw2x00/ipw2200.c | |||
| @@ -10472,7 +10472,7 @@ static void ipw_handle_promiscuous_tx(struct ipw_priv *priv, | |||
| 10472 | } else | 10472 | } else |
| 10473 | len = src->len; | 10473 | len = src->len; |
| 10474 | 10474 | ||
| 10475 | dst = alloc_skb(len + sizeof(*rt_hdr), GFP_ATOMIC); | 10475 | dst = alloc_skb(len + sizeof(*rt_hdr) + sizeof(u16)*2, GFP_ATOMIC); |
| 10476 | if (!dst) | 10476 | if (!dst) |
| 10477 | continue; | 10477 | continue; |
| 10478 | 10478 | ||
diff --git a/drivers/net/wireless/iwlwifi/dvm/devices.c b/drivers/net/wireless/iwlwifi/dvm/devices.c index 349c205d5f62..da5862064195 100644 --- a/drivers/net/wireless/iwlwifi/dvm/devices.c +++ b/drivers/net/wireless/iwlwifi/dvm/devices.c | |||
| @@ -518,7 +518,7 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv, | |||
| 518 | * See iwlagn_mac_channel_switch. | 518 | * See iwlagn_mac_channel_switch. |
| 519 | */ | 519 | */ |
| 520 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | 520 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; |
| 521 | struct iwl6000_channel_switch_cmd cmd; | 521 | struct iwl6000_channel_switch_cmd *cmd; |
| 522 | u32 switch_time_in_usec, ucode_switch_time; | 522 | u32 switch_time_in_usec, ucode_switch_time; |
| 523 | u16 ch; | 523 | u16 ch; |
| 524 | u32 tsf_low; | 524 | u32 tsf_low; |
| @@ -527,18 +527,25 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv, | |||
| 527 | struct ieee80211_vif *vif = ctx->vif; | 527 | struct ieee80211_vif *vif = ctx->vif; |
| 528 | struct iwl_host_cmd hcmd = { | 528 | struct iwl_host_cmd hcmd = { |
| 529 | .id = REPLY_CHANNEL_SWITCH, | 529 | .id = REPLY_CHANNEL_SWITCH, |
| 530 | .len = { sizeof(cmd), }, | 530 | .len = { sizeof(*cmd), }, |
| 531 | .flags = CMD_SYNC, | 531 | .flags = CMD_SYNC, |
| 532 | .data = { &cmd, }, | 532 | .dataflags[0] = IWL_HCMD_DFL_NOCOPY, |
| 533 | }; | 533 | }; |
| 534 | int err; | ||
| 534 | 535 | ||
| 535 | cmd.band = priv->band == IEEE80211_BAND_2GHZ; | 536 | cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); |
| 537 | if (!cmd) | ||
| 538 | return -ENOMEM; | ||
| 539 | |||
| 540 | hcmd.data[0] = cmd; | ||
| 541 | |||
| 542 | cmd->band = priv->band == IEEE80211_BAND_2GHZ; | ||
| 536 | ch = ch_switch->channel->hw_value; | 543 | ch = ch_switch->channel->hw_value; |
| 537 | IWL_DEBUG_11H(priv, "channel switch from %u to %u\n", | 544 | IWL_DEBUG_11H(priv, "channel switch from %u to %u\n", |
| 538 | ctx->active.channel, ch); | 545 | ctx->active.channel, ch); |
| 539 | cmd.channel = cpu_to_le16(ch); | 546 | cmd->channel = cpu_to_le16(ch); |
| 540 | cmd.rxon_flags = ctx->staging.flags; | 547 | cmd->rxon_flags = ctx->staging.flags; |
| 541 | cmd.rxon_filter_flags = ctx->staging.filter_flags; | 548 | cmd->rxon_filter_flags = ctx->staging.filter_flags; |
| 542 | switch_count = ch_switch->count; | 549 | switch_count = ch_switch->count; |
| 543 | tsf_low = ch_switch->timestamp & 0x0ffffffff; | 550 | tsf_low = ch_switch->timestamp & 0x0ffffffff; |
| 544 | /* | 551 | /* |
| @@ -554,23 +561,25 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv, | |||
| 554 | switch_count = 0; | 561 | switch_count = 0; |
| 555 | } | 562 | } |
| 556 | if (switch_count <= 1) | 563 | if (switch_count <= 1) |
| 557 | cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time); | 564 | cmd->switch_time = cpu_to_le32(priv->ucode_beacon_time); |
| 558 | else { | 565 | else { |
| 559 | switch_time_in_usec = | 566 | switch_time_in_usec = |
| 560 | vif->bss_conf.beacon_int * switch_count * TIME_UNIT; | 567 | vif->bss_conf.beacon_int * switch_count * TIME_UNIT; |
| 561 | ucode_switch_time = iwl_usecs_to_beacons(priv, | 568 | ucode_switch_time = iwl_usecs_to_beacons(priv, |
| 562 | switch_time_in_usec, | 569 | switch_time_in_usec, |
| 563 | beacon_interval); | 570 | beacon_interval); |
| 564 | cmd.switch_time = iwl_add_beacon_time(priv, | 571 | cmd->switch_time = iwl_add_beacon_time(priv, |
| 565 | priv->ucode_beacon_time, | 572 | priv->ucode_beacon_time, |
| 566 | ucode_switch_time, | 573 | ucode_switch_time, |
| 567 | beacon_interval); | 574 | beacon_interval); |
| 568 | } | 575 | } |
| 569 | IWL_DEBUG_11H(priv, "uCode time for the switch is 0x%x\n", | 576 | IWL_DEBUG_11H(priv, "uCode time for the switch is 0x%x\n", |
| 570 | cmd.switch_time); | 577 | cmd->switch_time); |
| 571 | cmd.expect_beacon = ch_switch->channel->flags & IEEE80211_CHAN_RADAR; | 578 | cmd->expect_beacon = ch_switch->channel->flags & IEEE80211_CHAN_RADAR; |
| 572 | 579 | ||
| 573 | return iwl_dvm_send_cmd(priv, &hcmd); | 580 | err = iwl_dvm_send_cmd(priv, &hcmd); |
| 581 | kfree(cmd); | ||
| 582 | return err; | ||
| 574 | } | 583 | } |
| 575 | 584 | ||
| 576 | struct iwl_lib_ops iwl6000_lib = { | 585 | struct iwl_lib_ops iwl6000_lib = { |
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 1b4989082244..f8cd4cf3fad8 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h | |||
| @@ -1218,6 +1218,7 @@ struct cfg80211_deauth_request { | |||
| 1218 | const u8 *ie; | 1218 | const u8 *ie; |
| 1219 | size_t ie_len; | 1219 | size_t ie_len; |
| 1220 | u16 reason_code; | 1220 | u16 reason_code; |
| 1221 | bool local_state_change; | ||
| 1221 | }; | 1222 | }; |
| 1222 | 1223 | ||
| 1223 | /** | 1224 | /** |
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 8c225ef349cd..2ac8d50861e0 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c | |||
| @@ -32,6 +32,8 @@ | |||
| 32 | 32 | ||
| 33 | #define SMP_TIMEOUT msecs_to_jiffies(30000) | 33 | #define SMP_TIMEOUT msecs_to_jiffies(30000) |
| 34 | 34 | ||
| 35 | #define AUTH_REQ_MASK 0x07 | ||
| 36 | |||
| 35 | static inline void swap128(u8 src[16], u8 dst[16]) | 37 | static inline void swap128(u8 src[16], u8 dst[16]) |
| 36 | { | 38 | { |
| 37 | int i; | 39 | int i; |
| @@ -230,7 +232,7 @@ static void build_pairing_cmd(struct l2cap_conn *conn, | |||
| 230 | req->max_key_size = SMP_MAX_ENC_KEY_SIZE; | 232 | req->max_key_size = SMP_MAX_ENC_KEY_SIZE; |
| 231 | req->init_key_dist = 0; | 233 | req->init_key_dist = 0; |
| 232 | req->resp_key_dist = dist_keys; | 234 | req->resp_key_dist = dist_keys; |
| 233 | req->auth_req = authreq; | 235 | req->auth_req = (authreq & AUTH_REQ_MASK); |
| 234 | return; | 236 | return; |
| 235 | } | 237 | } |
| 236 | 238 | ||
| @@ -239,7 +241,7 @@ static void build_pairing_cmd(struct l2cap_conn *conn, | |||
| 239 | rsp->max_key_size = SMP_MAX_ENC_KEY_SIZE; | 241 | rsp->max_key_size = SMP_MAX_ENC_KEY_SIZE; |
| 240 | rsp->init_key_dist = 0; | 242 | rsp->init_key_dist = 0; |
| 241 | rsp->resp_key_dist = req->resp_key_dist & dist_keys; | 243 | rsp->resp_key_dist = req->resp_key_dist & dist_keys; |
| 242 | rsp->auth_req = authreq; | 244 | rsp->auth_req = (authreq & AUTH_REQ_MASK); |
| 243 | } | 245 | } |
| 244 | 246 | ||
| 245 | static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size) | 247 | static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size) |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 6f8a73c64fb3..7de7717ad67d 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
| @@ -853,7 +853,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, | |||
| 853 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 853 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
| 854 | if (info->control.vif == &sdata->vif) { | 854 | if (info->control.vif == &sdata->vif) { |
| 855 | __skb_unlink(skb, &local->pending[i]); | 855 | __skb_unlink(skb, &local->pending[i]); |
| 856 | dev_kfree_skb_irq(skb); | 856 | ieee80211_free_txskb(&local->hw, skb); |
| 857 | } | 857 | } |
| 858 | } | 858 | } |
| 859 | } | 859 | } |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index e714ed8bb198..1b7eed252fe9 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
| @@ -3099,22 +3099,32 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata, | |||
| 3099 | ht_cfreq, ht_oper->primary_chan, | 3099 | ht_cfreq, ht_oper->primary_chan, |
| 3100 | cbss->channel->band); | 3100 | cbss->channel->band); |
| 3101 | ht_oper = NULL; | 3101 | ht_oper = NULL; |
| 3102 | } else { | ||
| 3103 | channel_type = NL80211_CHAN_HT20; | ||
| 3102 | } | 3104 | } |
| 3103 | } | 3105 | } |
| 3104 | 3106 | ||
| 3105 | if (ht_oper) { | 3107 | if (ht_oper && sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) { |
| 3106 | channel_type = NL80211_CHAN_HT20; | 3108 | /* |
| 3109 | * cfg80211 already verified that the channel itself can | ||
| 3110 | * be used, but it didn't check that we can do the right | ||
| 3111 | * HT type, so do that here as well. If HT40 isn't allowed | ||
| 3112 | * on this channel, disable 40 MHz operation. | ||
| 3113 | */ | ||
| 3107 | 3114 | ||
| 3108 | if (sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) { | 3115 | switch (ht_oper->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) { |
| 3109 | switch (ht_oper->ht_param & | 3116 | case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: |
| 3110 | IEEE80211_HT_PARAM_CHA_SEC_OFFSET) { | 3117 | if (cbss->channel->flags & IEEE80211_CHAN_NO_HT40PLUS) |
| 3111 | case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: | 3118 | ifmgd->flags |= IEEE80211_STA_DISABLE_40MHZ; |
| 3119 | else | ||
| 3112 | channel_type = NL80211_CHAN_HT40PLUS; | 3120 | channel_type = NL80211_CHAN_HT40PLUS; |
| 3113 | break; | 3121 | break; |
| 3114 | case IEEE80211_HT_PARAM_CHA_SEC_BELOW: | 3122 | case IEEE80211_HT_PARAM_CHA_SEC_BELOW: |
| 3123 | if (cbss->channel->flags & IEEE80211_CHAN_NO_HT40MINUS) | ||
| 3124 | ifmgd->flags |= IEEE80211_STA_DISABLE_40MHZ; | ||
| 3125 | else | ||
| 3115 | channel_type = NL80211_CHAN_HT40MINUS; | 3126 | channel_type = NL80211_CHAN_HT40MINUS; |
| 3116 | break; | 3127 | break; |
| 3117 | } | ||
| 3118 | } | 3128 | } |
| 3119 | } | 3129 | } |
| 3120 | 3130 | ||
| @@ -3549,6 +3559,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, | |||
| 3549 | { | 3559 | { |
| 3550 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 3560 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
| 3551 | u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN]; | 3561 | u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN]; |
| 3562 | bool tx = !req->local_state_change; | ||
| 3552 | 3563 | ||
| 3553 | mutex_lock(&ifmgd->mtx); | 3564 | mutex_lock(&ifmgd->mtx); |
| 3554 | 3565 | ||
| @@ -3565,12 +3576,12 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, | |||
| 3565 | if (ifmgd->associated && | 3576 | if (ifmgd->associated && |
| 3566 | ether_addr_equal(ifmgd->associated->bssid, req->bssid)) { | 3577 | ether_addr_equal(ifmgd->associated->bssid, req->bssid)) { |
| 3567 | ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, | 3578 | ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, |
| 3568 | req->reason_code, true, frame_buf); | 3579 | req->reason_code, tx, frame_buf); |
| 3569 | } else { | 3580 | } else { |
| 3570 | drv_mgd_prepare_tx(sdata->local, sdata); | 3581 | drv_mgd_prepare_tx(sdata->local, sdata); |
| 3571 | ieee80211_send_deauth_disassoc(sdata, req->bssid, | 3582 | ieee80211_send_deauth_disassoc(sdata, req->bssid, |
| 3572 | IEEE80211_STYPE_DEAUTH, | 3583 | IEEE80211_STYPE_DEAUTH, |
| 3573 | req->reason_code, true, | 3584 | req->reason_code, tx, |
| 3574 | frame_buf); | 3585 | frame_buf); |
| 3575 | } | 3586 | } |
| 3576 | 3587 | ||
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 797dd36a220d..0a4e4c04db89 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
| @@ -650,7 +650,7 @@ static bool sta_info_cleanup_expire_buffered_ac(struct ieee80211_local *local, | |||
| 650 | */ | 650 | */ |
| 651 | if (!skb) | 651 | if (!skb) |
| 652 | break; | 652 | break; |
| 653 | dev_kfree_skb(skb); | 653 | ieee80211_free_txskb(&local->hw, skb); |
| 654 | } | 654 | } |
| 655 | 655 | ||
| 656 | /* | 656 | /* |
| @@ -679,7 +679,7 @@ static bool sta_info_cleanup_expire_buffered_ac(struct ieee80211_local *local, | |||
| 679 | local->total_ps_buffered--; | 679 | local->total_ps_buffered--; |
| 680 | ps_dbg(sta->sdata, "Buffered frame expired (STA %pM)\n", | 680 | ps_dbg(sta->sdata, "Buffered frame expired (STA %pM)\n", |
| 681 | sta->sta.addr); | 681 | sta->sta.addr); |
| 682 | dev_kfree_skb(skb); | 682 | ieee80211_free_txskb(&local->hw, skb); |
| 683 | } | 683 | } |
| 684 | 684 | ||
| 685 | /* | 685 | /* |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 22ca35054dd0..94e586873979 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
| @@ -406,7 +406,7 @@ void ieee80211_add_pending_skb(struct ieee80211_local *local, | |||
| 406 | int queue = info->hw_queue; | 406 | int queue = info->hw_queue; |
| 407 | 407 | ||
| 408 | if (WARN_ON(!info->control.vif)) { | 408 | if (WARN_ON(!info->control.vif)) { |
| 409 | kfree_skb(skb); | 409 | ieee80211_free_txskb(&local->hw, skb); |
| 410 | return; | 410 | return; |
| 411 | } | 411 | } |
| 412 | 412 | ||
| @@ -431,7 +431,7 @@ void ieee80211_add_pending_skbs_fn(struct ieee80211_local *local, | |||
| 431 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 431 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
| 432 | 432 | ||
| 433 | if (WARN_ON(!info->control.vif)) { | 433 | if (WARN_ON(!info->control.vif)) { |
| 434 | kfree_skb(skb); | 434 | ieee80211_free_txskb(&local->hw, skb); |
| 435 | continue; | 435 | continue; |
| 436 | } | 436 | } |
| 437 | 437 | ||
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c index bdb53aba888e..8bd2f5c6a56e 100644 --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c | |||
| @@ -106,7 +106,8 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) | |||
| 106 | if (status->flag & RX_FLAG_MMIC_ERROR) | 106 | if (status->flag & RX_FLAG_MMIC_ERROR) |
| 107 | goto mic_fail; | 107 | goto mic_fail; |
| 108 | 108 | ||
| 109 | if (!(status->flag & RX_FLAG_IV_STRIPPED) && rx->key) | 109 | if (!(status->flag & RX_FLAG_IV_STRIPPED) && rx->key && |
| 110 | rx->key->conf.cipher == WLAN_CIPHER_SUITE_TKIP) | ||
| 110 | goto update_iv; | 111 | goto update_iv; |
| 111 | 112 | ||
| 112 | return RX_CONTINUE; | 113 | return RX_CONTINUE; |
| @@ -545,14 +546,19 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx) | |||
| 545 | 546 | ||
| 546 | static void bip_aad(struct sk_buff *skb, u8 *aad) | 547 | static void bip_aad(struct sk_buff *skb, u8 *aad) |
| 547 | { | 548 | { |
| 549 | __le16 mask_fc; | ||
| 550 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | ||
| 551 | |||
| 548 | /* BIP AAD: FC(masked) || A1 || A2 || A3 */ | 552 | /* BIP AAD: FC(masked) || A1 || A2 || A3 */ |
| 549 | 553 | ||
| 550 | /* FC type/subtype */ | 554 | /* FC type/subtype */ |
| 551 | aad[0] = skb->data[0]; | ||
| 552 | /* Mask FC Retry, PwrMgt, MoreData flags to zero */ | 555 | /* Mask FC Retry, PwrMgt, MoreData flags to zero */ |
| 553 | aad[1] = skb->data[1] & ~(BIT(4) | BIT(5) | BIT(6)); | 556 | mask_fc = hdr->frame_control; |
| 557 | mask_fc &= ~cpu_to_le16(IEEE80211_FCTL_RETRY | IEEE80211_FCTL_PM | | ||
| 558 | IEEE80211_FCTL_MOREDATA); | ||
| 559 | put_unaligned(mask_fc, (__le16 *) &aad[0]); | ||
| 554 | /* A1 || A2 || A3 */ | 560 | /* A1 || A2 || A3 */ |
| 555 | memcpy(aad + 2, skb->data + 4, 3 * ETH_ALEN); | 561 | memcpy(aad + 2, &hdr->addr1, 3 * ETH_ALEN); |
| 556 | } | 562 | } |
| 557 | 563 | ||
| 558 | 564 | ||
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index 8016fee0752b..904a7f368325 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c | |||
| @@ -457,20 +457,14 @@ int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev, | |||
| 457 | .reason_code = reason, | 457 | .reason_code = reason, |
| 458 | .ie = ie, | 458 | .ie = ie, |
| 459 | .ie_len = ie_len, | 459 | .ie_len = ie_len, |
| 460 | .local_state_change = local_state_change, | ||
| 460 | }; | 461 | }; |
| 461 | 462 | ||
| 462 | ASSERT_WDEV_LOCK(wdev); | 463 | ASSERT_WDEV_LOCK(wdev); |
| 463 | 464 | ||
| 464 | if (local_state_change) { | 465 | if (local_state_change && (!wdev->current_bss || |
| 465 | if (wdev->current_bss && | 466 | !ether_addr_equal(wdev->current_bss->pub.bssid, bssid))) |
| 466 | ether_addr_equal(wdev->current_bss->pub.bssid, bssid)) { | ||
| 467 | cfg80211_unhold_bss(wdev->current_bss); | ||
| 468 | cfg80211_put_bss(&wdev->current_bss->pub); | ||
| 469 | wdev->current_bss = NULL; | ||
| 470 | } | ||
| 471 | |||
| 472 | return 0; | 467 | return 0; |
| 473 | } | ||
| 474 | 468 | ||
| 475 | return rdev->ops->deauth(&rdev->wiphy, dev, &req); | 469 | return rdev->ops->deauth(&rdev->wiphy, dev, &req); |
| 476 | } | 470 | } |
