diff options
author | David S. Miller <davem@davemloft.net> | 2008-06-10 04:54:31 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-06-10 04:54:31 -0400 |
commit | 788c0a53164c05c5ccdb1472474372b72ba74644 (patch) | |
tree | 5f274102e3dc4bcca6cb3a695aa2c8228ad5fc4f /net/mac80211/mlme.c | |
parent | e64bda89b8fe81cce9b4a20885d2c204c2d52532 (diff) | |
parent | 78cf07472f0ede8394bacc4bc02354505080cfe1 (diff) |
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/linville/wireless-next-2.6
Conflicts:
drivers/net/ps3_gelic_wireless.c
drivers/net/wireless/libertas/main.c
Diffstat (limited to 'net/mac80211/mlme.c')
-rw-r--r-- | net/mac80211/mlme.c | 88 |
1 files changed, 69 insertions, 19 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 3f7f92a2f227..adbc1c804dd3 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -578,7 +578,7 @@ void ieee80211_sta_tx(struct net_device *dev, struct sk_buff *skb, | |||
578 | int encrypt) | 578 | int encrypt) |
579 | { | 579 | { |
580 | struct ieee80211_sub_if_data *sdata; | 580 | struct ieee80211_sub_if_data *sdata; |
581 | struct ieee80211_tx_packet_data *pkt_data; | 581 | struct ieee80211_tx_info *info; |
582 | 582 | ||
583 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 583 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
584 | skb->dev = sdata->local->mdev; | 584 | skb->dev = sdata->local->mdev; |
@@ -586,11 +586,11 @@ void ieee80211_sta_tx(struct net_device *dev, struct sk_buff *skb, | |||
586 | skb_set_network_header(skb, 0); | 586 | skb_set_network_header(skb, 0); |
587 | skb_set_transport_header(skb, 0); | 587 | skb_set_transport_header(skb, 0); |
588 | 588 | ||
589 | pkt_data = (struct ieee80211_tx_packet_data *) skb->cb; | 589 | info = IEEE80211_SKB_CB(skb); |
590 | memset(pkt_data, 0, sizeof(struct ieee80211_tx_packet_data)); | 590 | memset(info, 0, sizeof(struct ieee80211_tx_info)); |
591 | pkt_data->ifindex = sdata->dev->ifindex; | 591 | info->control.ifindex = sdata->dev->ifindex; |
592 | if (!encrypt) | 592 | if (!encrypt) |
593 | pkt_data->flags |= IEEE80211_TXPD_DO_NOT_ENCRYPT; | 593 | info->flags |= IEEE80211_TX_CTL_DO_NOT_ENCRYPT; |
594 | 594 | ||
595 | dev_queue_xmit(skb); | 595 | dev_queue_xmit(skb); |
596 | } | 596 | } |
@@ -815,8 +815,29 @@ static void ieee80211_send_assoc(struct net_device *dev, | |||
815 | 815 | ||
816 | /* wmm support is a must to HT */ | 816 | /* wmm support is a must to HT */ |
817 | if (wmm && (ifsta->flags & IEEE80211_STA_WMM_ENABLED) && | 817 | if (wmm && (ifsta->flags & IEEE80211_STA_WMM_ENABLED) && |
818 | sband->ht_info.ht_supported) { | 818 | sband->ht_info.ht_supported && bss->ht_add_ie) { |
819 | __le16 tmp = cpu_to_le16(sband->ht_info.cap); | 819 | struct ieee80211_ht_addt_info *ht_add_info = |
820 | (struct ieee80211_ht_addt_info *)bss->ht_add_ie; | ||
821 | u16 cap = sband->ht_info.cap; | ||
822 | __le16 tmp; | ||
823 | u32 flags = local->hw.conf.channel->flags; | ||
824 | |||
825 | switch (ht_add_info->ht_param & IEEE80211_HT_IE_CHA_SEC_OFFSET) { | ||
826 | case IEEE80211_HT_IE_CHA_SEC_ABOVE: | ||
827 | if (flags & IEEE80211_CHAN_NO_FAT_ABOVE) { | ||
828 | cap &= ~IEEE80211_HT_CAP_SUP_WIDTH; | ||
829 | cap &= ~IEEE80211_HT_CAP_SGI_40; | ||
830 | } | ||
831 | break; | ||
832 | case IEEE80211_HT_IE_CHA_SEC_BELOW: | ||
833 | if (flags & IEEE80211_CHAN_NO_FAT_BELOW) { | ||
834 | cap &= ~IEEE80211_HT_CAP_SUP_WIDTH; | ||
835 | cap &= ~IEEE80211_HT_CAP_SGI_40; | ||
836 | } | ||
837 | break; | ||
838 | } | ||
839 | |||
840 | tmp = cpu_to_le16(cap); | ||
820 | pos = skb_put(skb, sizeof(struct ieee80211_ht_cap)+2); | 841 | pos = skb_put(skb, sizeof(struct ieee80211_ht_cap)+2); |
821 | *pos++ = WLAN_EID_HT_CAPABILITY; | 842 | *pos++ = WLAN_EID_HT_CAPABILITY; |
822 | *pos++ = sizeof(struct ieee80211_ht_cap); | 843 | *pos++ = sizeof(struct ieee80211_ht_cap); |
@@ -2271,6 +2292,7 @@ static void ieee80211_rx_bss_free(struct ieee80211_sta_bss *bss) | |||
2271 | kfree(bss->rsn_ie); | 2292 | kfree(bss->rsn_ie); |
2272 | kfree(bss->wmm_ie); | 2293 | kfree(bss->wmm_ie); |
2273 | kfree(bss->ht_ie); | 2294 | kfree(bss->ht_ie); |
2295 | kfree(bss->ht_add_ie); | ||
2274 | kfree(bss_mesh_id(bss)); | 2296 | kfree(bss_mesh_id(bss)); |
2275 | kfree(bss_mesh_cfg(bss)); | 2297 | kfree(bss_mesh_cfg(bss)); |
2276 | kfree(bss); | 2298 | kfree(bss); |
@@ -2321,7 +2343,7 @@ static int ieee80211_sta_join_ibss(struct net_device *dev, | |||
2321 | int res, rates, i, j; | 2343 | int res, rates, i, j; |
2322 | struct sk_buff *skb; | 2344 | struct sk_buff *skb; |
2323 | struct ieee80211_mgmt *mgmt; | 2345 | struct ieee80211_mgmt *mgmt; |
2324 | struct ieee80211_tx_control control; | 2346 | struct ieee80211_tx_info *control; |
2325 | struct rate_selection ratesel; | 2347 | struct rate_selection ratesel; |
2326 | u8 *pos; | 2348 | u8 *pos; |
2327 | struct ieee80211_sub_if_data *sdata; | 2349 | struct ieee80211_sub_if_data *sdata; |
@@ -2411,21 +2433,22 @@ static int ieee80211_sta_join_ibss(struct net_device *dev, | |||
2411 | memcpy(pos, &bss->supp_rates[8], rates); | 2433 | memcpy(pos, &bss->supp_rates[8], rates); |
2412 | } | 2434 | } |
2413 | 2435 | ||
2414 | memset(&control, 0, sizeof(control)); | 2436 | control = IEEE80211_SKB_CB(skb); |
2437 | |||
2415 | rate_control_get_rate(dev, sband, skb, &ratesel); | 2438 | rate_control_get_rate(dev, sband, skb, &ratesel); |
2416 | if (!ratesel.rate) { | 2439 | if (ratesel.rate_idx < 0) { |
2417 | printk(KERN_DEBUG "%s: Failed to determine TX rate " | 2440 | printk(KERN_DEBUG "%s: Failed to determine TX rate " |
2418 | "for IBSS beacon\n", dev->name); | 2441 | "for IBSS beacon\n", dev->name); |
2419 | break; | 2442 | break; |
2420 | } | 2443 | } |
2421 | control.vif = &sdata->vif; | 2444 | control->control.vif = &sdata->vif; |
2422 | control.tx_rate = ratesel.rate; | 2445 | control->tx_rate_idx = ratesel.rate_idx; |
2423 | if (sdata->bss_conf.use_short_preamble && | 2446 | if (sdata->bss_conf.use_short_preamble && |
2424 | ratesel.rate->flags & IEEE80211_RATE_SHORT_PREAMBLE) | 2447 | sband->bitrates[ratesel.rate_idx].flags & IEEE80211_RATE_SHORT_PREAMBLE) |
2425 | control.flags |= IEEE80211_TXCTL_SHORT_PREAMBLE; | 2448 | control->flags |= IEEE80211_TX_CTL_SHORT_PREAMBLE; |
2426 | control.antenna_sel_tx = local->hw.conf.antenna_sel_tx; | 2449 | control->antenna_sel_tx = local->hw.conf.antenna_sel_tx; |
2427 | control.flags |= IEEE80211_TXCTL_NO_ACK; | 2450 | control->flags |= IEEE80211_TX_CTL_NO_ACK; |
2428 | control.retry_limit = 1; | 2451 | control->control.retry_limit = 1; |
2429 | 2452 | ||
2430 | ifsta->probe_resp = skb_copy(skb, GFP_ATOMIC); | 2453 | ifsta->probe_resp = skb_copy(skb, GFP_ATOMIC); |
2431 | if (ifsta->probe_resp) { | 2454 | if (ifsta->probe_resp) { |
@@ -2440,8 +2463,7 @@ static int ieee80211_sta_join_ibss(struct net_device *dev, | |||
2440 | } | 2463 | } |
2441 | 2464 | ||
2442 | if (local->ops->beacon_update && | 2465 | if (local->ops->beacon_update && |
2443 | local->ops->beacon_update(local_to_hw(local), | 2466 | local->ops->beacon_update(local_to_hw(local), skb) == 0) { |
2444 | skb, &control) == 0) { | ||
2445 | printk(KERN_DEBUG "%s: Configured IBSS beacon " | 2467 | printk(KERN_DEBUG "%s: Configured IBSS beacon " |
2446 | "template\n", dev->name); | 2468 | "template\n", dev->name); |
2447 | skb = NULL; | 2469 | skb = NULL; |
@@ -2647,6 +2669,26 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
2647 | bss->ht_ie_len = 0; | 2669 | bss->ht_ie_len = 0; |
2648 | } | 2670 | } |
2649 | 2671 | ||
2672 | if (elems.ht_info_elem && | ||
2673 | (!bss->ht_add_ie || | ||
2674 | bss->ht_add_ie_len != elems.ht_info_elem_len || | ||
2675 | memcmp(bss->ht_add_ie, elems.ht_info_elem, | ||
2676 | elems.ht_info_elem_len))) { | ||
2677 | kfree(bss->ht_add_ie); | ||
2678 | bss->ht_add_ie = | ||
2679 | kmalloc(elems.ht_info_elem_len + 2, GFP_ATOMIC); | ||
2680 | if (bss->ht_add_ie) { | ||
2681 | memcpy(bss->ht_add_ie, elems.ht_info_elem - 2, | ||
2682 | elems.ht_info_elem_len + 2); | ||
2683 | bss->ht_add_ie_len = elems.ht_info_elem_len + 2; | ||
2684 | } else | ||
2685 | bss->ht_add_ie_len = 0; | ||
2686 | } else if (!elems.ht_info_elem && bss->ht_add_ie) { | ||
2687 | kfree(bss->ht_add_ie); | ||
2688 | bss->ht_add_ie = NULL; | ||
2689 | bss->ht_add_ie_len = 0; | ||
2690 | } | ||
2691 | |||
2650 | bss->beacon_int = le16_to_cpu(mgmt->u.beacon.beacon_int); | 2692 | bss->beacon_int = le16_to_cpu(mgmt->u.beacon.beacon_int); |
2651 | bss->capability = le16_to_cpu(mgmt->u.beacon.capab_info); | 2693 | bss->capability = le16_to_cpu(mgmt->u.beacon.capab_info); |
2652 | 2694 | ||
@@ -4131,6 +4173,14 @@ ieee80211_sta_scan_result(struct net_device *dev, | |||
4131 | bss->rsn_ie); | 4173 | bss->rsn_ie); |
4132 | } | 4174 | } |
4133 | 4175 | ||
4176 | if (bss && bss->ht_ie) { | ||
4177 | memset(&iwe, 0, sizeof(iwe)); | ||
4178 | iwe.cmd = IWEVGENIE; | ||
4179 | iwe.u.data.length = bss->ht_ie_len; | ||
4180 | current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, | ||
4181 | bss->ht_ie); | ||
4182 | } | ||
4183 | |||
4134 | if (bss && bss->supp_rates_len > 0) { | 4184 | if (bss && bss->supp_rates_len > 0) { |
4135 | /* display all supported rates in readable format */ | 4185 | /* display all supported rates in readable format */ |
4136 | char *p = current_ev + IW_EV_LCP_LEN; | 4186 | char *p = current_ev + IW_EV_LCP_LEN; |