1c2d1560aSJohannes Berg /* 2c2d1560aSJohannes Berg * Copyright 2002-2005, Instant802 Networks, Inc. 3c2d1560aSJohannes Berg * Copyright 2005-2006, Devicescape Software, Inc. 4c2d1560aSJohannes Berg * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> 5c2d1560aSJohannes Berg * Copyright 2007 Johannes Berg <johannes@sipsolutions.net> 6c2d1560aSJohannes Berg * 7c2d1560aSJohannes Berg * This program is free software; you can redistribute it and/or modify 8c2d1560aSJohannes Berg * it under the terms of the GNU General Public License version 2 as 9c2d1560aSJohannes Berg * published by the Free Software Foundation. 10c2d1560aSJohannes Berg * 11c2d1560aSJohannes Berg * utilities for mac80211 12c2d1560aSJohannes Berg */ 13c2d1560aSJohannes Berg 14c2d1560aSJohannes Berg #include <net/mac80211.h> 15c2d1560aSJohannes Berg #include <linux/netdevice.h> 16c2d1560aSJohannes Berg #include <linux/types.h> 17c2d1560aSJohannes Berg #include <linux/slab.h> 18c2d1560aSJohannes Berg #include <linux/skbuff.h> 19c2d1560aSJohannes Berg #include <linux/etherdevice.h> 20c2d1560aSJohannes Berg #include <linux/if_arp.h> 21c2d1560aSJohannes Berg #include <linux/wireless.h> 22c2d1560aSJohannes Berg #include <linux/bitmap.h> 23881d966bSEric W. Biederman #include <net/net_namespace.h> 24c2d1560aSJohannes Berg #include <net/cfg80211.h> 25dabeb344SJohannes Berg #include <net/rtnetlink.h> 26c2d1560aSJohannes Berg 27c2d1560aSJohannes Berg #include "ieee80211_i.h" 282c8dccc7SJohannes Berg #include "rate.h" 29ee385855SLuis Carlos Cobo #include "mesh.h" 30c2d1560aSJohannes Berg #include "wme.h" 31c2d1560aSJohannes Berg 32c2d1560aSJohannes Berg /* privid for wiphys to determine whether they belong to us or not */ 33c2d1560aSJohannes Berg void *mac80211_wiphy_privid = &mac80211_wiphy_privid; 34c2d1560aSJohannes Berg 35c2d1560aSJohannes Berg /* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */ 36c2d1560aSJohannes Berg /* Ethernet-II snap header (RFC1042 for most EtherTypes) */ 37c97c23e3SSenthil Balasubramanian const unsigned char rfc1042_header[] __aligned(2) = 38c2d1560aSJohannes Berg { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 }; 39c2d1560aSJohannes Berg 40c2d1560aSJohannes Berg /* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */ 41c97c23e3SSenthil Balasubramanian const unsigned char bridge_tunnel_header[] __aligned(2) = 42c2d1560aSJohannes Berg { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 }; 43c2d1560aSJohannes Berg 44c2d1560aSJohannes Berg 4571364716SRon Rindjunsky u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len, 4671364716SRon Rindjunsky enum ieee80211_if_types type) 47c2d1560aSJohannes Berg { 48a494bb1cSHarvey Harrison __le16 fc = hdr->frame_control; 49c2d1560aSJohannes Berg 5098f0b0a3SRon Rindjunsky /* drop ACK/CTS frames and incorrect hdr len (ctrl) */ 5198f0b0a3SRon Rindjunsky if (len < 16) 52c2d1560aSJohannes Berg return NULL; 53c2d1560aSJohannes Berg 54a494bb1cSHarvey Harrison if (ieee80211_is_data(fc)) { 5598f0b0a3SRon Rindjunsky if (len < 24) /* drop incorrect hdr len (data) */ 5698f0b0a3SRon Rindjunsky return NULL; 57a494bb1cSHarvey Harrison 58a494bb1cSHarvey Harrison if (ieee80211_has_a4(fc)) 59c2d1560aSJohannes Berg return NULL; 60a494bb1cSHarvey Harrison if (ieee80211_has_tods(fc)) 61a494bb1cSHarvey Harrison return hdr->addr1; 62a494bb1cSHarvey Harrison if (ieee80211_has_fromds(fc)) 63c2d1560aSJohannes Berg return hdr->addr2; 64a494bb1cSHarvey Harrison 65c2d1560aSJohannes Berg return hdr->addr3; 66c2d1560aSJohannes Berg } 67a494bb1cSHarvey Harrison 68a494bb1cSHarvey Harrison if (ieee80211_is_mgmt(fc)) { 6998f0b0a3SRon Rindjunsky if (len < 24) /* drop incorrect hdr len (mgmt) */ 7098f0b0a3SRon Rindjunsky return NULL; 71c2d1560aSJohannes Berg return hdr->addr3; 72a494bb1cSHarvey Harrison } 73a494bb1cSHarvey Harrison 74a494bb1cSHarvey Harrison if (ieee80211_is_ctl(fc)) { 75a494bb1cSHarvey Harrison if(ieee80211_is_pspoll(fc)) 76c2d1560aSJohannes Berg return hdr->addr1; 77a494bb1cSHarvey Harrison 78a494bb1cSHarvey Harrison if (ieee80211_is_back_req(fc)) { 7971364716SRon Rindjunsky switch (type) { 8071364716SRon Rindjunsky case IEEE80211_IF_TYPE_STA: 8171364716SRon Rindjunsky return hdr->addr2; 8271364716SRon Rindjunsky case IEEE80211_IF_TYPE_AP: 8371364716SRon Rindjunsky case IEEE80211_IF_TYPE_VLAN: 8471364716SRon Rindjunsky return hdr->addr1; 8571364716SRon Rindjunsky default: 86a494bb1cSHarvey Harrison break; /* fall through to the return */ 8771364716SRon Rindjunsky } 8871364716SRon Rindjunsky } 89c2d1560aSJohannes Berg } 90c2d1560aSJohannes Berg 91c2d1560aSJohannes Berg return NULL; 92c2d1560aSJohannes Berg } 93c2d1560aSJohannes Berg 94c2d1560aSJohannes Berg int ieee80211_get_hdrlen(u16 fc) 95c2d1560aSJohannes Berg { 96c2d1560aSJohannes Berg int hdrlen = 24; 97c2d1560aSJohannes Berg 98c2d1560aSJohannes Berg switch (fc & IEEE80211_FCTL_FTYPE) { 99c2d1560aSJohannes Berg case IEEE80211_FTYPE_DATA: 100c2d1560aSJohannes Berg if ((fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS)) 101c2d1560aSJohannes Berg hdrlen = 30; /* Addr4 */ 102c2d1560aSJohannes Berg /* 103c2d1560aSJohannes Berg * The QoS Control field is two bytes and its presence is 104c2d1560aSJohannes Berg * indicated by the IEEE80211_STYPE_QOS_DATA bit. Add 2 to 105c2d1560aSJohannes Berg * hdrlen if that bit is set. 106c2d1560aSJohannes Berg * This works by masking out the bit and shifting it to 107c2d1560aSJohannes Berg * bit position 1 so the result has the value 0 or 2. 108c2d1560aSJohannes Berg */ 109c2d1560aSJohannes Berg hdrlen += (fc & IEEE80211_STYPE_QOS_DATA) 110c2d1560aSJohannes Berg >> (ilog2(IEEE80211_STYPE_QOS_DATA)-1); 111c2d1560aSJohannes Berg break; 112c2d1560aSJohannes Berg case IEEE80211_FTYPE_CTL: 113c2d1560aSJohannes Berg /* 114c2d1560aSJohannes Berg * ACK and CTS are 10 bytes, all others 16. To see how 115c2d1560aSJohannes Berg * to get this condition consider 116c2d1560aSJohannes Berg * subtype mask: 0b0000000011110000 (0x00F0) 117c2d1560aSJohannes Berg * ACK subtype: 0b0000000011010000 (0x00D0) 118c2d1560aSJohannes Berg * CTS subtype: 0b0000000011000000 (0x00C0) 119c2d1560aSJohannes Berg * bits that matter: ^^^ (0x00E0) 120c2d1560aSJohannes Berg * value of those: 0b0000000011000000 (0x00C0) 121c2d1560aSJohannes Berg */ 122c2d1560aSJohannes Berg if ((fc & 0xE0) == 0xC0) 123c2d1560aSJohannes Berg hdrlen = 10; 124c2d1560aSJohannes Berg else 125c2d1560aSJohannes Berg hdrlen = 16; 126c2d1560aSJohannes Berg break; 127c2d1560aSJohannes Berg } 128c2d1560aSJohannes Berg 129c2d1560aSJohannes Berg return hdrlen; 130c2d1560aSJohannes Berg } 131c2d1560aSJohannes Berg EXPORT_SYMBOL(ieee80211_get_hdrlen); 132c2d1560aSJohannes Berg 1336693be71SHarvey Harrison unsigned int ieee80211_hdrlen(__le16 fc) 1346693be71SHarvey Harrison { 1356693be71SHarvey Harrison unsigned int hdrlen = 24; 1366693be71SHarvey Harrison 1376693be71SHarvey Harrison if (ieee80211_is_data(fc)) { 1386693be71SHarvey Harrison if (ieee80211_has_a4(fc)) 1396693be71SHarvey Harrison hdrlen = 30; 1406693be71SHarvey Harrison if (ieee80211_is_data_qos(fc)) 1416693be71SHarvey Harrison hdrlen += IEEE80211_QOS_CTL_LEN; 1426693be71SHarvey Harrison goto out; 1436693be71SHarvey Harrison } 1446693be71SHarvey Harrison 1456693be71SHarvey Harrison if (ieee80211_is_ctl(fc)) { 1466693be71SHarvey Harrison /* 1476693be71SHarvey Harrison * ACK and CTS are 10 bytes, all others 16. To see how 1486693be71SHarvey Harrison * to get this condition consider 1496693be71SHarvey Harrison * subtype mask: 0b0000000011110000 (0x00F0) 1506693be71SHarvey Harrison * ACK subtype: 0b0000000011010000 (0x00D0) 1516693be71SHarvey Harrison * CTS subtype: 0b0000000011000000 (0x00C0) 1526693be71SHarvey Harrison * bits that matter: ^^^ (0x00E0) 1536693be71SHarvey Harrison * value of those: 0b0000000011000000 (0x00C0) 1546693be71SHarvey Harrison */ 1556693be71SHarvey Harrison if ((fc & cpu_to_le16(0x00E0)) == cpu_to_le16(0x00C0)) 1566693be71SHarvey Harrison hdrlen = 10; 1576693be71SHarvey Harrison else 1586693be71SHarvey Harrison hdrlen = 16; 1596693be71SHarvey Harrison } 1606693be71SHarvey Harrison out: 1616693be71SHarvey Harrison return hdrlen; 1626693be71SHarvey Harrison } 1636693be71SHarvey Harrison EXPORT_SYMBOL(ieee80211_hdrlen); 1646693be71SHarvey Harrison 165c9c6950cSHarvey Harrison unsigned int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb) 166c2d1560aSJohannes Berg { 167c2d1560aSJohannes Berg const struct ieee80211_hdr *hdr = (const struct ieee80211_hdr *)skb->data; 168c9c6950cSHarvey Harrison unsigned int hdrlen; 169c2d1560aSJohannes Berg 170c2d1560aSJohannes Berg if (unlikely(skb->len < 10)) 171c2d1560aSJohannes Berg return 0; 172c9c6950cSHarvey Harrison hdrlen = ieee80211_hdrlen(hdr->frame_control); 173c2d1560aSJohannes Berg if (unlikely(hdrlen > skb->len)) 174c2d1560aSJohannes Berg return 0; 175c2d1560aSJohannes Berg return hdrlen; 176c2d1560aSJohannes Berg } 177c2d1560aSJohannes Berg EXPORT_SYMBOL(ieee80211_get_hdrlen_from_skb); 178c2d1560aSJohannes Berg 179ee385855SLuis Carlos Cobo int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr) 180ee385855SLuis Carlos Cobo { 181ee385855SLuis Carlos Cobo int ae = meshhdr->flags & IEEE80211S_FLAGS_AE; 182ee385855SLuis Carlos Cobo /* 7.1.3.5a.2 */ 183ee385855SLuis Carlos Cobo switch (ae) { 184ee385855SLuis Carlos Cobo case 0: 185ef269254SLuis Carlos Cobo return 6; 186ee385855SLuis Carlos Cobo case 1: 187ef269254SLuis Carlos Cobo return 12; 188ee385855SLuis Carlos Cobo case 2: 189ef269254SLuis Carlos Cobo return 18; 190ee385855SLuis Carlos Cobo case 3: 191ef269254SLuis Carlos Cobo return 24; 192ee385855SLuis Carlos Cobo default: 193ef269254SLuis Carlos Cobo return 6; 194ee385855SLuis Carlos Cobo } 195ee385855SLuis Carlos Cobo } 196ee385855SLuis Carlos Cobo 1975cf121c3SJohannes Berg void ieee80211_tx_set_protected(struct ieee80211_tx_data *tx) 198c2d1560aSJohannes Berg { 199c2d1560aSJohannes Berg struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx->skb->data; 200c2d1560aSJohannes Berg 201c2d1560aSJohannes Berg hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED); 2025cf121c3SJohannes Berg if (tx->extra_frag) { 203c2d1560aSJohannes Berg struct ieee80211_hdr *fhdr; 204c2d1560aSJohannes Berg int i; 2055cf121c3SJohannes Berg for (i = 0; i < tx->num_extra_frag; i++) { 206c2d1560aSJohannes Berg fhdr = (struct ieee80211_hdr *) 2075cf121c3SJohannes Berg tx->extra_frag[i]->data; 208c2d1560aSJohannes Berg fhdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED); 209c2d1560aSJohannes Berg } 210c2d1560aSJohannes Berg } 211c2d1560aSJohannes Berg } 212c2d1560aSJohannes Berg 213c2d1560aSJohannes Berg int ieee80211_frame_duration(struct ieee80211_local *local, size_t len, 214c2d1560aSJohannes Berg int rate, int erp, int short_preamble) 215c2d1560aSJohannes Berg { 216c2d1560aSJohannes Berg int dur; 217c2d1560aSJohannes Berg 218c2d1560aSJohannes Berg /* calculate duration (in microseconds, rounded up to next higher 219c2d1560aSJohannes Berg * integer if it includes a fractional microsecond) to send frame of 220c2d1560aSJohannes Berg * len bytes (does not include FCS) at the given rate. Duration will 221c2d1560aSJohannes Berg * also include SIFS. 222c2d1560aSJohannes Berg * 223c2d1560aSJohannes Berg * rate is in 100 kbps, so divident is multiplied by 10 in the 224c2d1560aSJohannes Berg * DIV_ROUND_UP() operations. 225c2d1560aSJohannes Berg */ 226c2d1560aSJohannes Berg 2278318d78aSJohannes Berg if (local->hw.conf.channel->band == IEEE80211_BAND_5GHZ || erp) { 228c2d1560aSJohannes Berg /* 229c2d1560aSJohannes Berg * OFDM: 230c2d1560aSJohannes Berg * 231c2d1560aSJohannes Berg * N_DBPS = DATARATE x 4 232c2d1560aSJohannes Berg * N_SYM = Ceiling((16+8xLENGTH+6) / N_DBPS) 233c2d1560aSJohannes Berg * (16 = SIGNAL time, 6 = tail bits) 234c2d1560aSJohannes Berg * TXTIME = T_PREAMBLE + T_SIGNAL + T_SYM x N_SYM + Signal Ext 235c2d1560aSJohannes Berg * 236c2d1560aSJohannes Berg * T_SYM = 4 usec 237c2d1560aSJohannes Berg * 802.11a - 17.5.2: aSIFSTime = 16 usec 238c2d1560aSJohannes Berg * 802.11g - 19.8.4: aSIFSTime = 10 usec + 239c2d1560aSJohannes Berg * signal ext = 6 usec 240c2d1560aSJohannes Berg */ 241c2d1560aSJohannes Berg dur = 16; /* SIFS + signal ext */ 242c2d1560aSJohannes Berg dur += 16; /* 17.3.2.3: T_PREAMBLE = 16 usec */ 243c2d1560aSJohannes Berg dur += 4; /* 17.3.2.3: T_SIGNAL = 4 usec */ 244c2d1560aSJohannes Berg dur += 4 * DIV_ROUND_UP((16 + 8 * (len + 4) + 6) * 10, 245c2d1560aSJohannes Berg 4 * rate); /* T_SYM x N_SYM */ 246c2d1560aSJohannes Berg } else { 247c2d1560aSJohannes Berg /* 248c2d1560aSJohannes Berg * 802.11b or 802.11g with 802.11b compatibility: 249c2d1560aSJohannes Berg * 18.3.4: TXTIME = PreambleLength + PLCPHeaderTime + 250c2d1560aSJohannes Berg * Ceiling(((LENGTH+PBCC)x8)/DATARATE). PBCC=0. 251c2d1560aSJohannes Berg * 252c2d1560aSJohannes Berg * 802.11 (DS): 15.3.3, 802.11b: 18.3.4 253c2d1560aSJohannes Berg * aSIFSTime = 10 usec 254c2d1560aSJohannes Berg * aPreambleLength = 144 usec or 72 usec with short preamble 255c2d1560aSJohannes Berg * aPLCPHeaderLength = 48 usec or 24 usec with short preamble 256c2d1560aSJohannes Berg */ 257c2d1560aSJohannes Berg dur = 10; /* aSIFSTime = 10 usec */ 258c2d1560aSJohannes Berg dur += short_preamble ? (72 + 24) : (144 + 48); 259c2d1560aSJohannes Berg 260c2d1560aSJohannes Berg dur += DIV_ROUND_UP(8 * (len + 4) * 10, rate); 261c2d1560aSJohannes Berg } 262c2d1560aSJohannes Berg 263c2d1560aSJohannes Berg return dur; 264c2d1560aSJohannes Berg } 265c2d1560aSJohannes Berg 266c2d1560aSJohannes Berg /* Exported duration function for driver use */ 26732bfd35dSJohannes Berg __le16 ieee80211_generic_frame_duration(struct ieee80211_hw *hw, 26832bfd35dSJohannes Berg struct ieee80211_vif *vif, 2698318d78aSJohannes Berg size_t frame_len, 2708318d78aSJohannes Berg struct ieee80211_rate *rate) 271c2d1560aSJohannes Berg { 272c2d1560aSJohannes Berg struct ieee80211_local *local = hw_to_local(hw); 27332bfd35dSJohannes Berg struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); 274c2d1560aSJohannes Berg u16 dur; 275c2d1560aSJohannes Berg int erp; 276c2d1560aSJohannes Berg 2778318d78aSJohannes Berg erp = 0; 2788318d78aSJohannes Berg if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) 2798318d78aSJohannes Berg erp = rate->flags & IEEE80211_RATE_ERP_G; 2808318d78aSJohannes Berg 2818318d78aSJohannes Berg dur = ieee80211_frame_duration(local, frame_len, rate->bitrate, erp, 282471b3efdSJohannes Berg sdata->bss_conf.use_short_preamble); 283c2d1560aSJohannes Berg 284c2d1560aSJohannes Berg return cpu_to_le16(dur); 285c2d1560aSJohannes Berg } 286c2d1560aSJohannes Berg EXPORT_SYMBOL(ieee80211_generic_frame_duration); 287c2d1560aSJohannes Berg 28832bfd35dSJohannes Berg __le16 ieee80211_rts_duration(struct ieee80211_hw *hw, 28932bfd35dSJohannes Berg struct ieee80211_vif *vif, size_t frame_len, 290e039fa4aSJohannes Berg const struct ieee80211_tx_info *frame_txctl) 291c2d1560aSJohannes Berg { 292c2d1560aSJohannes Berg struct ieee80211_local *local = hw_to_local(hw); 293c2d1560aSJohannes Berg struct ieee80211_rate *rate; 29432bfd35dSJohannes Berg struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); 295471b3efdSJohannes Berg bool short_preamble; 296c2d1560aSJohannes Berg int erp; 297c2d1560aSJohannes Berg u16 dur; 2982e92e6f2SJohannes Berg struct ieee80211_supported_band *sband; 2992e92e6f2SJohannes Berg 3002e92e6f2SJohannes Berg sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; 301c2d1560aSJohannes Berg 302471b3efdSJohannes Berg short_preamble = sdata->bss_conf.use_short_preamble; 3037e9ed188SDaniel Drake 304e039fa4aSJohannes Berg rate = &sband->bitrates[frame_txctl->control.rts_cts_rate_idx]; 3058318d78aSJohannes Berg 3068318d78aSJohannes Berg erp = 0; 3078318d78aSJohannes Berg if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) 3088318d78aSJohannes Berg erp = rate->flags & IEEE80211_RATE_ERP_G; 309c2d1560aSJohannes Berg 310c2d1560aSJohannes Berg /* CTS duration */ 3118318d78aSJohannes Berg dur = ieee80211_frame_duration(local, 10, rate->bitrate, 312c2d1560aSJohannes Berg erp, short_preamble); 313c2d1560aSJohannes Berg /* Data frame duration */ 3148318d78aSJohannes Berg dur += ieee80211_frame_duration(local, frame_len, rate->bitrate, 315c2d1560aSJohannes Berg erp, short_preamble); 316c2d1560aSJohannes Berg /* ACK duration */ 3178318d78aSJohannes Berg dur += ieee80211_frame_duration(local, 10, rate->bitrate, 318c2d1560aSJohannes Berg erp, short_preamble); 319c2d1560aSJohannes Berg 320c2d1560aSJohannes Berg return cpu_to_le16(dur); 321c2d1560aSJohannes Berg } 322c2d1560aSJohannes Berg EXPORT_SYMBOL(ieee80211_rts_duration); 323c2d1560aSJohannes Berg 32432bfd35dSJohannes Berg __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw, 32532bfd35dSJohannes Berg struct ieee80211_vif *vif, 326c2d1560aSJohannes Berg size_t frame_len, 327e039fa4aSJohannes Berg const struct ieee80211_tx_info *frame_txctl) 328c2d1560aSJohannes Berg { 329c2d1560aSJohannes Berg struct ieee80211_local *local = hw_to_local(hw); 330c2d1560aSJohannes Berg struct ieee80211_rate *rate; 33132bfd35dSJohannes Berg struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); 332471b3efdSJohannes Berg bool short_preamble; 333c2d1560aSJohannes Berg int erp; 334c2d1560aSJohannes Berg u16 dur; 3352e92e6f2SJohannes Berg struct ieee80211_supported_band *sband; 3362e92e6f2SJohannes Berg 3372e92e6f2SJohannes Berg sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; 338c2d1560aSJohannes Berg 339471b3efdSJohannes Berg short_preamble = sdata->bss_conf.use_short_preamble; 3407e9ed188SDaniel Drake 341e039fa4aSJohannes Berg rate = &sband->bitrates[frame_txctl->control.rts_cts_rate_idx]; 3428318d78aSJohannes Berg erp = 0; 3438318d78aSJohannes Berg if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) 3448318d78aSJohannes Berg erp = rate->flags & IEEE80211_RATE_ERP_G; 345c2d1560aSJohannes Berg 346c2d1560aSJohannes Berg /* Data frame duration */ 3478318d78aSJohannes Berg dur = ieee80211_frame_duration(local, frame_len, rate->bitrate, 348c2d1560aSJohannes Berg erp, short_preamble); 349e039fa4aSJohannes Berg if (!(frame_txctl->flags & IEEE80211_TX_CTL_NO_ACK)) { 350c2d1560aSJohannes Berg /* ACK duration */ 3518318d78aSJohannes Berg dur += ieee80211_frame_duration(local, 10, rate->bitrate, 352c2d1560aSJohannes Berg erp, short_preamble); 353c2d1560aSJohannes Berg } 354c2d1560aSJohannes Berg 355c2d1560aSJohannes Berg return cpu_to_le16(dur); 356c2d1560aSJohannes Berg } 357c2d1560aSJohannes Berg EXPORT_SYMBOL(ieee80211_ctstoself_duration); 358c2d1560aSJohannes Berg 359c2d1560aSJohannes Berg void ieee80211_wake_queue(struct ieee80211_hw *hw, int queue) 360c2d1560aSJohannes Berg { 361c2d1560aSJohannes Berg struct ieee80211_local *local = hw_to_local(hw); 362c2d1560aSJohannes Berg 363e2530083SJohannes Berg if (test_bit(queue, local->queues_pending)) { 364c2d1560aSJohannes Berg tasklet_schedule(&local->tx_pending_tasklet); 365e2530083SJohannes Berg } else { 366e2530083SJohannes Berg if (ieee80211_is_multiqueue(local)) { 367e2530083SJohannes Berg netif_wake_subqueue(local->mdev, queue); 368e2530083SJohannes Berg } else { 369e2530083SJohannes Berg WARN_ON(queue != 0); 370c2d1560aSJohannes Berg netif_wake_queue(local->mdev); 371e2530083SJohannes Berg } 372c2d1560aSJohannes Berg } 373c2d1560aSJohannes Berg } 374c2d1560aSJohannes Berg EXPORT_SYMBOL(ieee80211_wake_queue); 375c2d1560aSJohannes Berg 376c2d1560aSJohannes Berg void ieee80211_stop_queue(struct ieee80211_hw *hw, int queue) 377c2d1560aSJohannes Berg { 378c2d1560aSJohannes Berg struct ieee80211_local *local = hw_to_local(hw); 379c2d1560aSJohannes Berg 380e2530083SJohannes Berg if (ieee80211_is_multiqueue(local)) { 381e2530083SJohannes Berg netif_stop_subqueue(local->mdev, queue); 382e2530083SJohannes Berg } else { 383e2530083SJohannes Berg WARN_ON(queue != 0); 384c2d1560aSJohannes Berg netif_stop_queue(local->mdev); 385e2530083SJohannes Berg } 386c2d1560aSJohannes Berg } 387c2d1560aSJohannes Berg EXPORT_SYMBOL(ieee80211_stop_queue); 388c2d1560aSJohannes Berg 389c2d1560aSJohannes Berg void ieee80211_stop_queues(struct ieee80211_hw *hw) 390c2d1560aSJohannes Berg { 391c2d1560aSJohannes Berg int i; 392c2d1560aSJohannes Berg 393e2530083SJohannes Berg for (i = 0; i < ieee80211_num_queues(hw); i++) 394c2d1560aSJohannes Berg ieee80211_stop_queue(hw, i); 395c2d1560aSJohannes Berg } 396c2d1560aSJohannes Berg EXPORT_SYMBOL(ieee80211_stop_queues); 397c2d1560aSJohannes Berg 398c2d1560aSJohannes Berg void ieee80211_wake_queues(struct ieee80211_hw *hw) 399c2d1560aSJohannes Berg { 400c2d1560aSJohannes Berg int i; 401c2d1560aSJohannes Berg 402c4680470SJohannes Berg for (i = 0; i < hw->queues + hw->ampdu_queues; i++) 403c2d1560aSJohannes Berg ieee80211_wake_queue(hw, i); 404c2d1560aSJohannes Berg } 405c2d1560aSJohannes Berg EXPORT_SYMBOL(ieee80211_wake_queues); 406dabeb344SJohannes Berg 40732bfd35dSJohannes Berg void ieee80211_iterate_active_interfaces( 40832bfd35dSJohannes Berg struct ieee80211_hw *hw, 409dabeb344SJohannes Berg void (*iterator)(void *data, u8 *mac, 41032bfd35dSJohannes Berg struct ieee80211_vif *vif), 411dabeb344SJohannes Berg void *data) 412dabeb344SJohannes Berg { 413dabeb344SJohannes Berg struct ieee80211_local *local = hw_to_local(hw); 414dabeb344SJohannes Berg struct ieee80211_sub_if_data *sdata; 415dabeb344SJohannes Berg 4162f561febSIvo van Doorn rtnl_lock(); 4172f561febSIvo van Doorn 4182f561febSIvo van Doorn list_for_each_entry(sdata, &local->interfaces, list) { 4192f561febSIvo van Doorn switch (sdata->vif.type) { 4202f561febSIvo van Doorn case IEEE80211_IF_TYPE_INVALID: 4212f561febSIvo van Doorn case IEEE80211_IF_TYPE_MNTR: 4222f561febSIvo van Doorn case IEEE80211_IF_TYPE_VLAN: 4232f561febSIvo van Doorn continue; 4242f561febSIvo van Doorn case IEEE80211_IF_TYPE_AP: 4252f561febSIvo van Doorn case IEEE80211_IF_TYPE_STA: 4262f561febSIvo van Doorn case IEEE80211_IF_TYPE_IBSS: 4272f561febSIvo van Doorn case IEEE80211_IF_TYPE_WDS: 4282f561febSIvo van Doorn case IEEE80211_IF_TYPE_MESH_POINT: 4292f561febSIvo van Doorn break; 4302f561febSIvo van Doorn } 4312f561febSIvo van Doorn if (sdata->dev == local->mdev) 4322f561febSIvo van Doorn continue; 4332f561febSIvo van Doorn if (netif_running(sdata->dev)) 4342f561febSIvo van Doorn iterator(data, sdata->dev->dev_addr, 4352f561febSIvo van Doorn &sdata->vif); 4362f561febSIvo van Doorn } 4372f561febSIvo van Doorn 4382f561febSIvo van Doorn rtnl_unlock(); 4392f561febSIvo van Doorn } 4402f561febSIvo van Doorn EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces); 4412f561febSIvo van Doorn 4422f561febSIvo van Doorn void ieee80211_iterate_active_interfaces_atomic( 4432f561febSIvo van Doorn struct ieee80211_hw *hw, 4442f561febSIvo van Doorn void (*iterator)(void *data, u8 *mac, 4452f561febSIvo van Doorn struct ieee80211_vif *vif), 4462f561febSIvo van Doorn void *data) 4472f561febSIvo van Doorn { 4482f561febSIvo van Doorn struct ieee80211_local *local = hw_to_local(hw); 4492f561febSIvo van Doorn struct ieee80211_sub_if_data *sdata; 4502f561febSIvo van Doorn 451e38bad47SJohannes Berg rcu_read_lock(); 452dabeb344SJohannes Berg 453e38bad47SJohannes Berg list_for_each_entry_rcu(sdata, &local->interfaces, list) { 45451fb61e7SJohannes Berg switch (sdata->vif.type) { 455dabeb344SJohannes Berg case IEEE80211_IF_TYPE_INVALID: 456dabeb344SJohannes Berg case IEEE80211_IF_TYPE_MNTR: 457dabeb344SJohannes Berg case IEEE80211_IF_TYPE_VLAN: 458dabeb344SJohannes Berg continue; 459dabeb344SJohannes Berg case IEEE80211_IF_TYPE_AP: 460dabeb344SJohannes Berg case IEEE80211_IF_TYPE_STA: 461dabeb344SJohannes Berg case IEEE80211_IF_TYPE_IBSS: 462dabeb344SJohannes Berg case IEEE80211_IF_TYPE_WDS: 4636032f934SJohannes Berg case IEEE80211_IF_TYPE_MESH_POINT: 464dabeb344SJohannes Berg break; 465dabeb344SJohannes Berg } 466dabeb344SJohannes Berg if (sdata->dev == local->mdev) 467dabeb344SJohannes Berg continue; 468dabeb344SJohannes Berg if (netif_running(sdata->dev)) 469dabeb344SJohannes Berg iterator(data, sdata->dev->dev_addr, 47032bfd35dSJohannes Berg &sdata->vif); 471dabeb344SJohannes Berg } 472e38bad47SJohannes Berg 473e38bad47SJohannes Berg rcu_read_unlock(); 474dabeb344SJohannes Berg } 4752f561febSIvo van Doorn EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_atomic); 476