aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/mlme.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-06-10 04:54:31 -0400
committerDavid S. Miller <davem@davemloft.net>2008-06-10 04:54:31 -0400
commit788c0a53164c05c5ccdb1472474372b72ba74644 (patch)
tree5f274102e3dc4bcca6cb3a695aa2c8228ad5fc4f /net/mac80211/mlme.c
parente64bda89b8fe81cce9b4a20885d2c204c2d52532 (diff)
parent78cf07472f0ede8394bacc4bc02354505080cfe1 (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.c88
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;