aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorLuis Carlos Cobo <luisca@cozybit.com>2008-02-23 09:17:10 -0500
committerJohn W. Linville <linville@tuxdriver.com>2008-03-06 15:30:41 -0500
commit33b64eb2b1b1759cbdafbe5c59df652f1e7c746e (patch)
tree10b314d244e4a44229a6b0da85c3ac76cce2c895 /net
parent2e3c8736820bf72a8ad10721c7e31d36d4fa7790 (diff)
mac80211: support for mesh interfaces in mac80211 data path
This changes the TX/RX paths in mac80211 to support mesh interfaces. This code will be cleaned up later again before being enabled. Signed-off-by: Luis Carlos Cobo <luisca@cozybit.com> Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/rx.c121
-rw-r--r--net/mac80211/tx.c158
2 files changed, 246 insertions, 33 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index b7eeae0d3956..cc4a896c617f 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -20,6 +20,9 @@
20 20
21#include "ieee80211_i.h" 21#include "ieee80211_i.h"
22#include "ieee80211_led.h" 22#include "ieee80211_led.h"
23#ifdef CONFIG_MAC80211_MESH
24#include "mesh.h"
25#endif
23#include "wep.h" 26#include "wep.h"
24#include "wpa.h" 27#include "wpa.h"
25#include "tkip.h" 28#include "tkip.h"
@@ -390,10 +393,60 @@ ieee80211_rx_h_passive_scan(struct ieee80211_txrx_data *rx)
390 return RX_CONTINUE; 393 return RX_CONTINUE;
391} 394}
392 395
396#ifdef CONFIG_MAC80211_MESH
397#define msh_h_get(h, l) ((struct ieee80211s_hdr *) ((u8 *)h + l))
398static ieee80211_rx_result
399ieee80211_rx_mesh_check(struct ieee80211_txrx_data *rx)
400{
401 int hdrlen = ieee80211_get_hdrlen(rx->fc);
402 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data;
403 if ((rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) {
404 if (!((rx->fc & IEEE80211_FCTL_FROMDS) &&
405 (rx->fc & IEEE80211_FCTL_TODS)))
406 return RX_DROP_MONITOR;
407 if (memcmp(hdr->addr4, rx->dev->dev_addr, ETH_ALEN) == 0)
408 return RX_DROP_MONITOR;
409 }
410
411 /* If there is not an established peer link and this is not a peer link
412 * establisment frame, beacon or probe, drop the frame.
413 */
414
415 if (!rx->sta || rx->sta->plink_state != ESTAB) {
416 struct ieee80211_mgmt *mgmt;
417 if ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT)
418 return RX_DROP_MONITOR;
419
420 switch (rx->fc & IEEE80211_FCTL_STYPE) {
421 case IEEE80211_STYPE_ACTION:
422 mgmt = (struct ieee80211_mgmt *)hdr;
423 if (mgmt->u.action.category != PLINK_CATEGORY)
424 return RX_DROP_MONITOR;
425 /* fall through on else */
426 case IEEE80211_STYPE_PROBE_REQ:
427 case IEEE80211_STYPE_PROBE_RESP:
428 case IEEE80211_STYPE_BEACON:
429 return RX_CONTINUE;
430 break;
431 default:
432 return RX_DROP_MONITOR;
433 }
434
435 } else if ((rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA &&
436 is_broadcast_ether_addr(hdr->addr1) &&
437 mesh_rmc_check(hdr->addr4, msh_h_get(hdr, hdrlen), rx->dev))
438 return RX_DROP_MONITOR;
439 else
440 return RX_CONTINUE;
441}
442#endif
443
444
393static ieee80211_rx_result 445static ieee80211_rx_result
394ieee80211_rx_h_check(struct ieee80211_txrx_data *rx) 446ieee80211_rx_h_check(struct ieee80211_txrx_data *rx)
395{ 447{
396 struct ieee80211_hdr *hdr; 448 struct ieee80211_hdr *hdr;
449
397 hdr = (struct ieee80211_hdr *) rx->skb->data; 450 hdr = (struct ieee80211_hdr *) rx->skb->data;
398 451
399 /* Drop duplicate 802.11 retransmissions (IEEE 802.11 Chap. 9.2.9) */ 452 /* Drop duplicate 802.11 retransmissions (IEEE 802.11 Chap. 9.2.9) */
@@ -423,6 +476,12 @@ ieee80211_rx_h_check(struct ieee80211_txrx_data *rx)
423 * deauth/disassoc frames when needed. In addition, hostapd is 476 * deauth/disassoc frames when needed. In addition, hostapd is
424 * responsible for filtering on both auth and assoc states. 477 * responsible for filtering on both auth and assoc states.
425 */ 478 */
479
480#ifdef CONFIG_MAC80211_MESH
481 if (rx->sdata->vif.type == IEEE80211_IF_TYPE_MESH_POINT)
482 return ieee80211_rx_mesh_check(rx);
483#endif
484
426 if (unlikely(((rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA || 485 if (unlikely(((rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA ||
427 ((rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL && 486 ((rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL &&
428 (rx->fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PSPOLL)) && 487 (rx->fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PSPOLL)) &&
@@ -657,6 +716,8 @@ ieee80211_rx_h_sta_process(struct ieee80211_txrx_data *rx)
657 /* Update last_rx only for unicast frames in order to prevent 716 /* Update last_rx only for unicast frames in order to prevent
658 * the Probe Request frames (the only broadcast frames from a 717 * the Probe Request frames (the only broadcast frames from a
659 * STA in infrastructure mode) from keeping a connection alive. 718 * STA in infrastructure mode) from keeping a connection alive.
719 * Mesh beacons will update last_rx when if they are found to
720 * match the current local configuration when processed.
660 */ 721 */
661 sta->last_rx = jiffies; 722 sta->last_rx = jiffies;
662 } 723 }
@@ -1050,6 +1111,23 @@ ieee80211_data_to_8023(struct ieee80211_txrx_data *rx)
1050 1111
1051 hdrlen = ieee80211_get_hdrlen(fc); 1112 hdrlen = ieee80211_get_hdrlen(fc);
1052 1113
1114#ifdef CONFIG_MAC80211_MESH
1115 if (sdata->vif.type == IEEE80211_IF_TYPE_MESH_POINT) {
1116 int meshhdrlen = ieee80211_get_mesh_hdrlen(
1117 (struct ieee80211s_hdr *) (skb->data + hdrlen));
1118 /* Copy on cb:
1119 * - mesh header: to be used for mesh forwarding
1120 * decision. It will also be used as mesh header template at
1121 * tx.c:ieee80211_subif_start_xmit() if interface
1122 * type is mesh and skb->pkt_type == PACKET_OTHERHOST
1123 * - ta: to be used if a RERR needs to be sent.
1124 */
1125 memcpy(skb->cb, skb->data + hdrlen, meshhdrlen);
1126 memcpy(MESH_PREQ(skb), hdr->addr2, ETH_ALEN);
1127 hdrlen += meshhdrlen;
1128 }
1129#endif
1130
1053 /* convert IEEE 802.11 header + possible LLC headers into Ethernet 1131 /* convert IEEE 802.11 header + possible LLC headers into Ethernet
1054 * header 1132 * header
1055 * IEEE 802.11 address fields: 1133 * IEEE 802.11 address fields:
@@ -1083,9 +1161,10 @@ ieee80211_data_to_8023(struct ieee80211_txrx_data *rx)
1083 memcpy(dst, hdr->addr3, ETH_ALEN); 1161 memcpy(dst, hdr->addr3, ETH_ALEN);
1084 memcpy(src, hdr->addr4, ETH_ALEN); 1162 memcpy(src, hdr->addr4, ETH_ALEN);
1085 1163
1086 if (unlikely(sdata->vif.type != IEEE80211_IF_TYPE_WDS)) { 1164 if (unlikely(sdata->vif.type != IEEE80211_IF_TYPE_WDS &&
1087 if (net_ratelimit()) 1165 sdata->vif.type != IEEE80211_IF_TYPE_MESH_POINT)) {
1088 printk(KERN_DEBUG "%s: dropped FromDS&ToDS " 1166 if (net_ratelimit())
1167 printk(KERN_DEBUG "%s: dropped FromDS&ToDS "
1089 "frame (RA=%s TA=%s DA=%s SA=%s)\n", 1168 "frame (RA=%s TA=%s DA=%s SA=%s)\n",
1090 rx->dev->name, 1169 rx->dev->name,
1091 print_mac(mac, hdr->addr1), 1170 print_mac(mac, hdr->addr1),
@@ -1227,6 +1306,39 @@ ieee80211_deliver_skb(struct ieee80211_txrx_data *rx)
1227 } 1306 }
1228 } 1307 }
1229 1308
1309#ifdef CONFIG_MAC80211_MESH
1310 /* Mesh forwarding */
1311 if (sdata->vif.type == IEEE80211_IF_TYPE_MESH_POINT) {
1312 u8 *mesh_ttl = &((struct ieee80211s_hdr *)skb->cb)->ttl;
1313 (*mesh_ttl)--;
1314
1315 if (is_multicast_ether_addr(skb->data)) {
1316 if (*mesh_ttl > 0) {
1317 xmit_skb = skb_copy(skb, GFP_ATOMIC);
1318 if (!xmit_skb && net_ratelimit())
1319 printk(KERN_DEBUG "%s: failed to clone "
1320 "multicast frame\n", dev->name);
1321 else
1322 xmit_skb->pkt_type = PACKET_OTHERHOST;
1323 } else
1324 sdata->u.sta.mshstats.dropped_frames_ttl++;
1325
1326 } else if (skb->pkt_type != PACKET_OTHERHOST &&
1327 compare_ether_addr(dev->dev_addr, skb->data) != 0) {
1328 if (*mesh_ttl == 0) {
1329 sdata->u.sta.mshstats.dropped_frames_ttl++;
1330 dev_kfree_skb(skb);
1331 skb = NULL;
1332 } else {
1333 xmit_skb = skb;
1334 xmit_skb->pkt_type = PACKET_OTHERHOST;
1335 if (!(dev->flags & IFF_PROMISC))
1336 skb = NULL;
1337 }
1338 }
1339 }
1340#endif
1341
1230 if (skb) { 1342 if (skb) {
1231 /* deliver to local stack */ 1343 /* deliver to local stack */
1232 skb->protocol = eth_type_trans(skb, dev); 1344 skb->protocol = eth_type_trans(skb, dev);
@@ -1444,7 +1556,8 @@ ieee80211_rx_h_mgmt(struct ieee80211_txrx_data *rx)
1444 1556
1445 sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev); 1557 sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev);
1446 if ((sdata->vif.type == IEEE80211_IF_TYPE_STA || 1558 if ((sdata->vif.type == IEEE80211_IF_TYPE_STA ||
1447 sdata->vif.type == IEEE80211_IF_TYPE_IBSS) && 1559 sdata->vif.type == IEEE80211_IF_TYPE_IBSS ||
1560 sdata->vif.type == IEEE80211_IF_TYPE_MESH_POINT) &&
1448 !(sdata->flags & IEEE80211_SDATA_USERSPACE_MLME)) 1561 !(sdata->flags & IEEE80211_SDATA_USERSPACE_MLME))
1449 ieee80211_sta_rx_mgmt(rx->dev, rx->skb, rx->u.rx.status); 1562 ieee80211_sta_rx_mgmt(rx->dev, rx->skb, rx->u.rx.status);
1450 else 1563 else
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 1cd58e01f1ee..fc1ffb55ed5c 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -26,6 +26,9 @@
26 26
27#include "ieee80211_i.h" 27#include "ieee80211_i.h"
28#include "ieee80211_led.h" 28#include "ieee80211_led.h"
29#ifdef CONFIG_MAC80211_MESH
30#include "mesh.h"
31#endif
29#include "wep.h" 32#include "wep.h"
30#include "wpa.h" 33#include "wpa.h"
31#include "wme.h" 34#include "wme.h"
@@ -249,6 +252,9 @@ ieee80211_tx_h_check_assoc(struct ieee80211_txrx_data *tx)
249 (tx->fc & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_PROBE_REQ)) 252 (tx->fc & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_PROBE_REQ))
250 return TX_DROP; 253 return TX_DROP;
251 254
255 if (tx->sdata->vif.type == IEEE80211_IF_TYPE_MESH_POINT)
256 return TX_CONTINUE;
257
252 if (tx->flags & IEEE80211_TXRXD_TXPS_BUFFERED) 258 if (tx->flags & IEEE80211_TXRXD_TXPS_BUFFERED)
253 return TX_CONTINUE; 259 return TX_CONTINUE;
254 260
@@ -1384,8 +1390,9 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
1384 struct ieee80211_tx_packet_data *pkt_data; 1390 struct ieee80211_tx_packet_data *pkt_data;
1385 struct ieee80211_sub_if_data *sdata; 1391 struct ieee80211_sub_if_data *sdata;
1386 int ret = 1, head_need; 1392 int ret = 1, head_need;
1387 u16 ethertype, hdrlen, fc; 1393 u16 ethertype, hdrlen, meshhdrlen = 0, fc;
1388 struct ieee80211_hdr hdr; 1394 struct ieee80211_hdr hdr;
1395 struct ieee80211s_hdr mesh_hdr;
1389 const u8 *encaps_data; 1396 const u8 *encaps_data;
1390 int encaps_len, skip_header_bytes; 1397 int encaps_len, skip_header_bytes;
1391 int nh_pos, h_pos; 1398 int nh_pos, h_pos;
@@ -1427,6 +1434,37 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
1427 memcpy(hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN); 1434 memcpy(hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN);
1428 hdrlen = 30; 1435 hdrlen = 30;
1429 break; 1436 break;
1437#ifdef CONFIG_MAC80211_MESH
1438 case IEEE80211_IF_TYPE_MESH_POINT:
1439 fc |= IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS;
1440 /* RA TA DA SA */
1441 if (is_multicast_ether_addr(skb->data))
1442 memcpy(hdr.addr1, skb->data, ETH_ALEN);
1443 else if (mesh_nexthop_lookup(hdr.addr1, skb, dev))
1444 return 0;
1445 memcpy(hdr.addr2, dev->dev_addr, ETH_ALEN);
1446 memcpy(hdr.addr3, skb->data, ETH_ALEN);
1447 memcpy(hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN);
1448 if (skb->pkt_type == PACKET_OTHERHOST) {
1449 /* Forwarded frame, keep mesh ttl and seqnum */
1450 struct ieee80211s_hdr *prev_meshhdr;
1451 prev_meshhdr = ((struct ieee80211s_hdr *)skb->cb);
1452 meshhdrlen = ieee80211_get_mesh_hdrlen(prev_meshhdr);
1453 memcpy(&mesh_hdr, prev_meshhdr, meshhdrlen);
1454 sdata->u.sta.mshstats.fwded_frames++;
1455 } else {
1456 if (!sdata->u.sta.mshcfg.dot11MeshTTL) {
1457 /* Do not send frames with mesh_ttl == 0 */
1458 sdata->u.sta.mshstats.dropped_frames_ttl++;
1459 ret = 0;
1460 goto fail;
1461 }
1462 meshhdrlen = ieee80211_new_mesh_header(&mesh_hdr,
1463 sdata);
1464 }
1465 hdrlen = 30;
1466 break;
1467#endif
1430 case IEEE80211_IF_TYPE_STA: 1468 case IEEE80211_IF_TYPE_STA:
1431 fc |= IEEE80211_FCTL_TODS; 1469 fc |= IEEE80211_FCTL_TODS;
1432 /* BSSID SA DA */ 1470 /* BSSID SA DA */
@@ -1471,8 +1509,8 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
1471 * EAPOL frames from the local station. 1509 * EAPOL frames from the local station.
1472 */ 1510 */
1473 if (unlikely(!is_multicast_ether_addr(hdr.addr1) && 1511 if (unlikely(!is_multicast_ether_addr(hdr.addr1) &&
1474 !(sta_flags & WLAN_STA_AUTHORIZED) && 1512 !(sta_flags & WLAN_STA_AUTHORIZED) &&
1475 !(ethertype == ETH_P_PAE && 1513 !(ethertype == ETH_P_PAE &&
1476 compare_ether_addr(dev->dev_addr, 1514 compare_ether_addr(dev->dev_addr,
1477 skb->data + ETH_ALEN) == 0))) { 1515 skb->data + ETH_ALEN) == 0))) {
1478#ifdef CONFIG_MAC80211_VERBOSE_DEBUG 1516#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
@@ -1525,7 +1563,7 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
1525 * build in headroom in __dev_alloc_skb() (linux/skbuff.h) and 1563 * build in headroom in __dev_alloc_skb() (linux/skbuff.h) and
1526 * alloc_skb() (net/core/skbuff.c) 1564 * alloc_skb() (net/core/skbuff.c)
1527 */ 1565 */
1528 head_need = hdrlen + encaps_len + local->tx_headroom; 1566 head_need = hdrlen + encaps_len + meshhdrlen + local->tx_headroom;
1529 head_need -= skb_headroom(skb); 1567 head_need -= skb_headroom(skb);
1530 1568
1531 /* We are going to modify skb data, so make a copy of it if happens to 1569 /* We are going to modify skb data, so make a copy of it if happens to
@@ -1559,6 +1597,12 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
1559 h_pos += encaps_len; 1597 h_pos += encaps_len;
1560 } 1598 }
1561 1599
1600 if (meshhdrlen > 0) {
1601 memcpy(skb_push(skb, meshhdrlen), &mesh_hdr, meshhdrlen);
1602 nh_pos += meshhdrlen;
1603 h_pos += meshhdrlen;
1604 }
1605
1562 if (fc & IEEE80211_STYPE_QOS_DATA) { 1606 if (fc & IEEE80211_STYPE_QOS_DATA) {
1563 __le16 *qos_control; 1607 __le16 *qos_control;
1564 1608
@@ -1734,6 +1778,40 @@ static void ieee80211_beacon_add_tim(struct ieee80211_local *local,
1734 read_unlock_bh(&local->sta_lock); 1778 read_unlock_bh(&local->sta_lock);
1735} 1779}
1736 1780
1781#ifdef CONFIG_MAC80211_MESH
1782static struct sk_buff *ieee80211_mesh_beacon_get(struct net_device *dev)
1783{
1784 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1785 struct sk_buff *skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400);
1786 struct ieee80211_mgmt *mgmt;
1787 u8 *pos;
1788
1789 if (!skb)
1790 return NULL;
1791 skb_reserve(skb, local->hw.extra_tx_headroom);
1792 mgmt = (struct ieee80211_mgmt *)
1793 skb_put(skb, 24 + sizeof(mgmt->u.beacon));
1794 memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon));
1795 mgmt->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT,
1796 IEEE80211_STYPE_BEACON);
1797 memset(mgmt->da, 0xff, ETH_ALEN);
1798 memcpy(mgmt->sa, dev->dev_addr, ETH_ALEN);
1799 /* BSSID is left zeroed, wildcard value */
1800 mgmt->u.beacon.beacon_int =
1801 cpu_to_le16(local->hw.conf.beacon_int);
1802 mgmt->u.beacon.capab_info = 0x0; /* 0x0 for MPs */
1803
1804 pos = skb_put(skb, 2);
1805 *pos++ = WLAN_EID_SSID;
1806 *pos++ = 0x0;
1807
1808 mesh_mgmt_ies_add(skb, dev);
1809
1810 return skb;
1811}
1812#endif
1813
1814
1737struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, 1815struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
1738 struct ieee80211_vif *vif, 1816 struct ieee80211_vif *vif,
1739 struct ieee80211_tx_control *control) 1817 struct ieee80211_tx_control *control)
@@ -1746,6 +1824,8 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
1746 struct rate_selection rsel; 1824 struct rate_selection rsel;
1747 struct beacon_data *beacon; 1825 struct beacon_data *beacon;
1748 struct ieee80211_supported_band *sband; 1826 struct ieee80211_supported_band *sband;
1827 int *num_beacons;
1828 int err = 0;
1749 1829
1750 sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; 1830 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
1751 1831
@@ -1753,11 +1833,51 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
1753 1833
1754 sdata = vif_to_sdata(vif); 1834 sdata = vif_to_sdata(vif);
1755 bdev = sdata->dev; 1835 bdev = sdata->dev;
1756 ap = &sdata->u.ap;
1757 1836
1758 beacon = rcu_dereference(ap->beacon); 1837 switch (sdata->vif.type) {
1838 case IEEE80211_IF_TYPE_AP:
1839 ap = &sdata->u.ap;
1840 beacon = rcu_dereference(ap->beacon);
1841 if (!ap || !beacon) {
1842 err = -1;
1843 break;
1844 }
1845
1846 /* headroom, head length, tail length and maximum TIM length */
1847 skb = dev_alloc_skb(local->tx_headroom + beacon->head_len +
1848 beacon->tail_len + 256);
1849 if (!skb)
1850 goto out;
1851
1852 skb_reserve(skb, local->tx_headroom);
1853 memcpy(skb_put(skb, beacon->head_len), beacon->head,
1854 beacon->head_len);
1759 1855
1760 if (!ap || sdata->vif.type != IEEE80211_IF_TYPE_AP || !beacon) { 1856 ieee80211_include_sequence(sdata,
1857 (struct ieee80211_hdr *)skb->data);
1858
1859 ieee80211_beacon_add_tim(local, ap, skb, beacon);
1860
1861 if (beacon->tail)
1862 memcpy(skb_put(skb, beacon->tail_len), beacon->tail,
1863 beacon->tail_len);
1864
1865 num_beacons = &ap->num_beacons;
1866 break;
1867
1868#ifdef CONFIG_MAC80211_MESH
1869 case IEEE80211_IF_TYPE_MESH_POINT:
1870 skb = ieee80211_mesh_beacon_get(bdev);
1871 num_beacons = &sdata->u.sta.num_beacons;
1872 break;
1873#endif
1874
1875 default:
1876 err = -1;
1877 break;
1878 }
1879
1880 if (err) {
1761#ifdef CONFIG_MAC80211_VERBOSE_DEBUG 1881#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
1762 if (net_ratelimit()) 1882 if (net_ratelimit())
1763 printk(KERN_DEBUG "no beacon data avail for %s\n", 1883 printk(KERN_DEBUG "no beacon data avail for %s\n",
@@ -1767,24 +1887,6 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
1767 goto out; 1887 goto out;
1768 } 1888 }
1769 1889
1770 /* headroom, head length, tail length and maximum TIM length */
1771 skb = dev_alloc_skb(local->tx_headroom + beacon->head_len +
1772 beacon->tail_len + 256);
1773 if (!skb)
1774 goto out;
1775
1776 skb_reserve(skb, local->tx_headroom);
1777 memcpy(skb_put(skb, beacon->head_len), beacon->head,
1778 beacon->head_len);
1779
1780 ieee80211_include_sequence(sdata, (struct ieee80211_hdr *)skb->data);
1781
1782 ieee80211_beacon_add_tim(local, ap, skb, beacon);
1783
1784 if (beacon->tail)
1785 memcpy(skb_put(skb, beacon->tail_len), beacon->tail,
1786 beacon->tail_len);
1787
1788 if (control) { 1890 if (control) {
1789 rate_control_get_rate(local->mdev, sband, skb, &rsel); 1891 rate_control_get_rate(local->mdev, sband, skb, &rsel);
1790 if (!rsel.rate) { 1892 if (!rsel.rate) {
@@ -1808,10 +1910,8 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
1808 control->retry_limit = 1; 1910 control->retry_limit = 1;
1809 control->flags |= IEEE80211_TXCTL_CLEAR_PS_FILT; 1911 control->flags |= IEEE80211_TXCTL_CLEAR_PS_FILT;
1810 } 1912 }
1811 1913 (*num_beacons)++;
1812 ap->num_beacons++; 1914out:
1813
1814 out:
1815 rcu_read_unlock(); 1915 rcu_read_unlock();
1816 return skb; 1916 return skb;
1817} 1917}