aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/rtl8187.h1
-rw-r--r--drivers/net/wireless/rtl8187_dev.c4
-rw-r--r--include/net/mac80211.h15
-rw-r--r--net/mac80211/ieee80211_i.h7
-rw-r--r--net/mac80211/ieee80211_ioctl.c7
-rw-r--r--net/mac80211/ieee80211_sta.c16
-rw-r--r--net/mac80211/tx.c31
-rw-r--r--net/mac80211/util.c37
8 files changed, 88 insertions, 30 deletions
diff --git a/drivers/net/wireless/rtl8187.h b/drivers/net/wireless/rtl8187.h
index 6124e467b156..7993b3d87203 100644
--- a/drivers/net/wireless/rtl8187.h
+++ b/drivers/net/wireless/rtl8187.h
@@ -67,6 +67,7 @@ struct rtl8187_priv {
67 struct rtl818x_csr *map; 67 struct rtl818x_csr *map;
68 void (*rf_init)(struct ieee80211_hw *); 68 void (*rf_init)(struct ieee80211_hw *);
69 int mode; 69 int mode;
70 int if_id;
70 71
71 /* rtl8187 specific */ 72 /* rtl8187 specific */
72 struct ieee80211_channel channels[14]; 73 struct ieee80211_channel channels[14];
diff --git a/drivers/net/wireless/rtl8187_dev.c b/drivers/net/wireless/rtl8187_dev.c
index e61c6d5ba1a9..73f1ebc7eec7 100644
--- a/drivers/net/wireless/rtl8187_dev.c
+++ b/drivers/net/wireless/rtl8187_dev.c
@@ -96,7 +96,7 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
96 if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS) { 96 if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS) {
97 tmp |= RTL8187_TX_FLAG_RTS; 97 tmp |= RTL8187_TX_FLAG_RTS;
98 hdr->rts_duration = 98 hdr->rts_duration =
99 ieee80211_rts_duration(dev, skb->len, control); 99 ieee80211_rts_duration(dev, priv->if_id, skb->len, control);
100 } 100 }
101 if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) 101 if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT)
102 tmp |= RTL8187_TX_FLAG_CTS; 102 tmp |= RTL8187_TX_FLAG_CTS;
@@ -510,6 +510,8 @@ static int rtl8187_config_interface(struct ieee80211_hw *dev, int if_id,
510 struct rtl8187_priv *priv = dev->priv; 510 struct rtl8187_priv *priv = dev->priv;
511 int i; 511 int i;
512 512
513 priv->if_id = if_id;
514
513 for (i = 0; i < ETH_ALEN; i++) 515 for (i = 0; i < ETH_ALEN; i++)
514 rtl818x_iowrite8(priv, &priv->map->BSSID[i], conf->bssid[i]); 516 rtl818x_iowrite8(priv, &priv->map->BSSID[i], conf->bssid[i]);
515 517
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 91cee0f0aa71..3282038a1510 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -835,6 +835,7 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
835/** 835/**
836 * ieee80211_rts_get - RTS frame generation function 836 * ieee80211_rts_get - RTS frame generation function
837 * @hw: pointer obtained from ieee80211_alloc_hw(). 837 * @hw: pointer obtained from ieee80211_alloc_hw().
838 * @if_id: interface ID from &struct ieee80211_if_init_conf.
838 * @frame: pointer to the frame that is going to be protected by the RTS. 839 * @frame: pointer to the frame that is going to be protected by the RTS.
839 * @frame_len: the frame length (in octets). 840 * @frame_len: the frame length (in octets).
840 * @frame_txctl: &struct ieee80211_tx_control of the frame. 841 * @frame_txctl: &struct ieee80211_tx_control of the frame.
@@ -845,7 +846,7 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
845 * the next RTS frame from the 802.11 code. The low-level is responsible 846 * the next RTS frame from the 802.11 code. The low-level is responsible
846 * for calling this function before and RTS frame is needed. 847 * for calling this function before and RTS frame is needed.
847 */ 848 */
848void ieee80211_rts_get(struct ieee80211_hw *hw, 849void ieee80211_rts_get(struct ieee80211_hw *hw, int if_id,
849 const void *frame, size_t frame_len, 850 const void *frame, size_t frame_len,
850 const struct ieee80211_tx_control *frame_txctl, 851 const struct ieee80211_tx_control *frame_txctl,
851 struct ieee80211_rts *rts); 852 struct ieee80211_rts *rts);
@@ -853,6 +854,7 @@ void ieee80211_rts_get(struct ieee80211_hw *hw,
853/** 854/**
854 * ieee80211_rts_duration - Get the duration field for an RTS frame 855 * ieee80211_rts_duration - Get the duration field for an RTS frame
855 * @hw: pointer obtained from ieee80211_alloc_hw(). 856 * @hw: pointer obtained from ieee80211_alloc_hw().
857 * @if_id: interface ID from &struct ieee80211_if_init_conf.
856 * @frame_len: the length of the frame that is going to be protected by the RTS. 858 * @frame_len: the length of the frame that is going to be protected by the RTS.
857 * @frame_txctl: &struct ieee80211_tx_control of the frame. 859 * @frame_txctl: &struct ieee80211_tx_control of the frame.
858 * 860 *
@@ -860,13 +862,14 @@ void ieee80211_rts_get(struct ieee80211_hw *hw,
860 * the duration field, the low-level driver uses this function to receive 862 * the duration field, the low-level driver uses this function to receive
861 * the duration field value in little-endian byteorder. 863 * the duration field value in little-endian byteorder.
862 */ 864 */
863__le16 ieee80211_rts_duration(struct ieee80211_hw *hw, 865__le16 ieee80211_rts_duration(struct ieee80211_hw *hw, int if_id,
864 size_t frame_len, 866 size_t frame_len,
865 const struct ieee80211_tx_control *frame_txctl); 867 const struct ieee80211_tx_control *frame_txctl);
866 868
867/** 869/**
868 * ieee80211_ctstoself_get - CTS-to-self frame generation function 870 * ieee80211_ctstoself_get - CTS-to-self frame generation function
869 * @hw: pointer obtained from ieee80211_alloc_hw(). 871 * @hw: pointer obtained from ieee80211_alloc_hw().
872 * @if_id: interface ID from &struct ieee80211_if_init_conf.
870 * @frame: pointer to the frame that is going to be protected by the CTS-to-self. 873 * @frame: pointer to the frame that is going to be protected by the CTS-to-self.
871 * @frame_len: the frame length (in octets). 874 * @frame_len: the frame length (in octets).
872 * @frame_txctl: &struct ieee80211_tx_control of the frame. 875 * @frame_txctl: &struct ieee80211_tx_control of the frame.
@@ -877,7 +880,7 @@ __le16 ieee80211_rts_duration(struct ieee80211_hw *hw,
877 * the next CTS-to-self frame from the 802.11 code. The low-level is responsible 880 * the next CTS-to-self frame from the 802.11 code. The low-level is responsible
878 * for calling this function before and CTS-to-self frame is needed. 881 * for calling this function before and CTS-to-self frame is needed.
879 */ 882 */
880void ieee80211_ctstoself_get(struct ieee80211_hw *hw, 883void ieee80211_ctstoself_get(struct ieee80211_hw *hw, int if_id,
881 const void *frame, size_t frame_len, 884 const void *frame, size_t frame_len,
882 const struct ieee80211_tx_control *frame_txctl, 885 const struct ieee80211_tx_control *frame_txctl,
883 struct ieee80211_cts *cts); 886 struct ieee80211_cts *cts);
@@ -885,6 +888,7 @@ void ieee80211_ctstoself_get(struct ieee80211_hw *hw,
885/** 888/**
886 * ieee80211_ctstoself_duration - Get the duration field for a CTS-to-self frame 889 * ieee80211_ctstoself_duration - Get the duration field for a CTS-to-self frame
887 * @hw: pointer obtained from ieee80211_alloc_hw(). 890 * @hw: pointer obtained from ieee80211_alloc_hw().
891 * @if_id: interface ID from &struct ieee80211_if_init_conf.
888 * @frame_len: the length of the frame that is going to be protected by the CTS-to-self. 892 * @frame_len: the length of the frame that is going to be protected by the CTS-to-self.
889 * @frame_txctl: &struct ieee80211_tx_control of the frame. 893 * @frame_txctl: &struct ieee80211_tx_control of the frame.
890 * 894 *
@@ -892,20 +896,21 @@ void ieee80211_ctstoself_get(struct ieee80211_hw *hw,
892 * the duration field, the low-level driver uses this function to receive 896 * the duration field, the low-level driver uses this function to receive
893 * the duration field value in little-endian byteorder. 897 * the duration field value in little-endian byteorder.
894 */ 898 */
895__le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw, 899__le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw, int if_id,
896 size_t frame_len, 900 size_t frame_len,
897 const struct ieee80211_tx_control *frame_txctl); 901 const struct ieee80211_tx_control *frame_txctl);
898 902
899/** 903/**
900 * ieee80211_generic_frame_duration - Calculate the duration field for a frame 904 * ieee80211_generic_frame_duration - Calculate the duration field for a frame
901 * @hw: pointer obtained from ieee80211_alloc_hw(). 905 * @hw: pointer obtained from ieee80211_alloc_hw().
906 * @if_id: interface ID from &struct ieee80211_if_init_conf.
902 * @frame_len: the length of the frame. 907 * @frame_len: the length of the frame.
903 * @rate: the rate (in 100kbps) at which the frame is going to be transmitted. 908 * @rate: the rate (in 100kbps) at which the frame is going to be transmitted.
904 * 909 *
905 * Calculate the duration field of some generic frame, given its 910 * Calculate the duration field of some generic frame, given its
906 * length and transmission rate (in 100kbps). 911 * length and transmission rate (in 100kbps).
907 */ 912 */
908__le16 ieee80211_generic_frame_duration(struct ieee80211_hw *hw, 913__le16 ieee80211_generic_frame_duration(struct ieee80211_hw *hw, int if_id,
909 size_t frame_len, 914 size_t frame_len,
910 int rate); 915 int rate);
911 916
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index e76a58678959..b0af6e9f5319 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -127,7 +127,6 @@ struct ieee80211_txrx_data {
127 struct ieee80211_tx_control *control; 127 struct ieee80211_tx_control *control;
128 unsigned int unicast:1; 128 unsigned int unicast:1;
129 unsigned int ps_buffered:1; 129 unsigned int ps_buffered:1;
130 unsigned int short_preamble:1;
131 unsigned int probe_last_frag:1; 130 unsigned int probe_last_frag:1;
132 struct ieee80211_hw_mode *mode; 131 struct ieee80211_hw_mode *mode;
133 struct ieee80211_rate *rate; 132 struct ieee80211_rate *rate;
@@ -286,6 +285,11 @@ struct ieee80211_sub_if_data {
286 unsigned int promisc:1; 285 unsigned int promisc:1;
287 unsigned int use_protection:1; /* CTS protect ERP frames */ 286 unsigned int use_protection:1; /* CTS protect ERP frames */
288 287
288 /* use short preamble with IEEE 802.11b: this flag is set when the AP
289 * or beacon generator reports that there are no present stations that
290 * cannot support short preambles */
291 unsigned int short_preamble:1;
292
289 struct net_device_stats stats; 293 struct net_device_stats stats;
290 int drop_unencrypted; 294 int drop_unencrypted;
291 int eapol; /* 0 = process EAPOL frames as normal data frames, 295 int eapol; /* 0 = process EAPOL frames as normal data frames,
@@ -447,7 +451,6 @@ struct ieee80211_local {
447 int fragmentation_threshold; 451 int fragmentation_threshold;
448 int short_retry_limit; /* dot11ShortRetryLimit */ 452 int short_retry_limit; /* dot11ShortRetryLimit */
449 int long_retry_limit; /* dot11LongRetryLimit */ 453 int long_retry_limit; /* dot11LongRetryLimit */
450 int short_preamble; /* use short preamble with IEEE 802.11b */
451 454
452 struct crypto_blkcipher *wep_tx_tfm; 455 struct crypto_blkcipher *wep_tx_tfm;
453 struct crypto_blkcipher *wep_rx_tfm; 456 struct crypto_blkcipher *wep_rx_tfm;
diff --git a/net/mac80211/ieee80211_ioctl.c b/net/mac80211/ieee80211_ioctl.c
index e7904db55325..8292431ac48f 100644
--- a/net/mac80211/ieee80211_ioctl.c
+++ b/net/mac80211/ieee80211_ioctl.c
@@ -1061,7 +1061,10 @@ static int ieee80211_ioctl_prism2_param(struct net_device *dev,
1061 break; 1061 break;
1062 1062
1063 case PRISM2_PARAM_PREAMBLE: 1063 case PRISM2_PARAM_PREAMBLE:
1064 local->short_preamble = value; 1064 if (sdata->type != IEEE80211_IF_TYPE_AP)
1065 ret = -ENOENT;
1066 else
1067 sdata->short_preamble = value;
1065 break; 1068 break;
1066 1069
1067 case PRISM2_PARAM_STAT_TIME: 1070 case PRISM2_PARAM_STAT_TIME:
@@ -1184,7 +1187,7 @@ static int ieee80211_ioctl_get_prism2_param(struct net_device *dev,
1184 break; 1187 break;
1185 1188
1186 case PRISM2_PARAM_PREAMBLE: 1189 case PRISM2_PARAM_PREAMBLE:
1187 *param = local->short_preamble; 1190 *param = sdata->short_preamble;
1188 break; 1191 break;
1189 1192
1190 case PRISM2_PARAM_STAT_TIME: 1193 case PRISM2_PARAM_STAT_TIME:
diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c
index 8e6548974a9f..0f5f8131bd71 100644
--- a/net/mac80211/ieee80211_sta.c
+++ b/net/mac80211/ieee80211_sta.c
@@ -318,6 +318,7 @@ static void ieee80211_handle_erp_ie(struct net_device *dev, u8 erp_value)
318 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 318 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
319 struct ieee80211_if_sta *ifsta = &sdata->u.sta; 319 struct ieee80211_if_sta *ifsta = &sdata->u.sta;
320 int use_protection = (erp_value & WLAN_ERP_USE_PROTECTION) != 0; 320 int use_protection = (erp_value & WLAN_ERP_USE_PROTECTION) != 0;
321 int preamble_mode = (erp_value & WLAN_ERP_BARKER_PREAMBLE) != 0;
321 322
322 if (use_protection != sdata->use_protection) { 323 if (use_protection != sdata->use_protection) {
323 if (net_ratelimit()) { 324 if (net_ratelimit()) {
@@ -329,6 +330,18 @@ static void ieee80211_handle_erp_ie(struct net_device *dev, u8 erp_value)
329 } 330 }
330 sdata->use_protection = use_protection; 331 sdata->use_protection = use_protection;
331 } 332 }
333
334 if (!preamble_mode != sdata->short_preamble) {
335 if (net_ratelimit()) {
336 printk(KERN_DEBUG "%s: switched to %s barker preamble"
337 " (BSSID=" MAC_FMT ")\n",
338 dev->name,
339 (preamble_mode == WLAN_ERP_PREAMBLE_SHORT) ?
340 "short" : "long",
341 MAC_ARG(ifsta->bssid));
342 }
343 sdata->short_preamble = !preamble_mode;
344 }
332} 345}
333 346
334 347
@@ -415,6 +428,7 @@ static void ieee80211_set_associated(struct net_device *dev,
415 ieee80211_sta_send_associnfo(dev, ifsta); 428 ieee80211_sta_send_associnfo(dev, ifsta);
416 } else { 429 } else {
417 netif_carrier_off(dev); 430 netif_carrier_off(dev);
431 sdata->short_preamble = 0;
418 sdata->use_protection = 0; 432 sdata->use_protection = 0;
419 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN); 433 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
420 } 434 }
@@ -2281,7 +2295,7 @@ static int ieee80211_sta_join_ibss(struct net_device *dev,
2281 "for IBSS beacon\n", dev->name); 2295 "for IBSS beacon\n", dev->name);
2282 break; 2296 break;
2283 } 2297 }
2284 control.tx_rate = (local->short_preamble && 2298 control.tx_rate = (sdata->short_preamble &&
2285 (rate->flags & IEEE80211_RATE_PREAMBLE2)) ? 2299 (rate->flags & IEEE80211_RATE_PREAMBLE2)) ?
2286 rate->val2 : rate->val; 2300 rate->val2 : rate->val;
2287 control.antenna_sel_tx = local->hw.conf.antenna_sel_tx; 2301 control.antenna_sel_tx = local->hw.conf.antenna_sel_tx;
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 532cf5127b70..36761c7139bc 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -173,7 +173,7 @@ static u16 ieee80211_duration(struct ieee80211_txrx_data *tx, int group_addr,
173 * to closest integer */ 173 * to closest integer */
174 174
175 dur = ieee80211_frame_duration(local, 10, rate, erp, 175 dur = ieee80211_frame_duration(local, 10, rate, erp,
176 local->short_preamble); 176 tx->sdata->short_preamble);
177 177
178 if (next_frag_len) { 178 if (next_frag_len) {
179 /* Frame is fragmented: duration increases with time needed to 179 /* Frame is fragmented: duration increases with time needed to
@@ -182,7 +182,7 @@ static u16 ieee80211_duration(struct ieee80211_txrx_data *tx, int group_addr,
182 /* next fragment */ 182 /* next fragment */
183 dur += ieee80211_frame_duration(local, next_frag_len, 183 dur += ieee80211_frame_duration(local, next_frag_len,
184 txrate->rate, erp, 184 txrate->rate, erp,
185 local->short_preamble); 185 tx->sdata->short_preamble);
186 } 186 }
187 187
188 return dur; 188 return dur;
@@ -627,12 +627,6 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_txrx_data *tx)
627 tx->u.tx.control->rate = tx->u.tx.rate; 627 tx->u.tx.control->rate = tx->u.tx.rate;
628 } 628 }
629 tx->u.tx.control->tx_rate = tx->u.tx.rate->val; 629 tx->u.tx.control->tx_rate = tx->u.tx.rate->val;
630 if ((tx->u.tx.rate->flags & IEEE80211_RATE_PREAMBLE2) &&
631 tx->local->short_preamble &&
632 (!tx->sta || (tx->sta->flags & WLAN_STA_SHORT_PREAMBLE))) {
633 tx->u.tx.short_preamble = 1;
634 tx->u.tx.control->tx_rate = tx->u.tx.rate->val2;
635 }
636 630
637 return TXRX_CONTINUE; 631 return TXRX_CONTINUE;
638} 632}
@@ -641,6 +635,7 @@ static ieee80211_txrx_result
641ieee80211_tx_h_misc(struct ieee80211_txrx_data *tx) 635ieee80211_tx_h_misc(struct ieee80211_txrx_data *tx)
642{ 636{
643 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx->skb->data; 637 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx->skb->data;
638 u16 fc = le16_to_cpu(hdr->frame_control);
644 u16 dur; 639 u16 dur;
645 struct ieee80211_tx_control *control = tx->u.tx.control; 640 struct ieee80211_tx_control *control = tx->u.tx.control;
646 struct ieee80211_hw_mode *mode = tx->u.tx.mode; 641 struct ieee80211_hw_mode *mode = tx->u.tx.mode;
@@ -677,6 +672,16 @@ ieee80211_tx_h_misc(struct ieee80211_txrx_data *tx)
677 !(control->flags & IEEE80211_TXCTL_USE_RTS_CTS)) 672 !(control->flags & IEEE80211_TXCTL_USE_RTS_CTS))
678 control->flags |= IEEE80211_TXCTL_USE_CTS_PROTECT; 673 control->flags |= IEEE80211_TXCTL_USE_CTS_PROTECT;
679 674
675 /* Transmit data frames using short preambles if the driver supports
676 * short preambles at the selected rate and short preambles are
677 * available on the network at the current point in time. */
678 if (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) &&
679 (tx->u.tx.rate->flags & IEEE80211_RATE_PREAMBLE2) &&
680 tx->sdata->short_preamble &&
681 (!tx->sta || (tx->sta->flags & WLAN_STA_SHORT_PREAMBLE))) {
682 tx->u.tx.control->tx_rate = tx->u.tx.rate->val2;
683 }
684
680 /* Setup duration field for the first fragment of the frame. Duration 685 /* Setup duration field for the first fragment of the frame. Duration
681 * for remaining fragments will be updated when they are being sent 686 * for remaining fragments will be updated when they are being sent
682 * to low-level driver in ieee80211_tx(). */ 687 * to low-level driver in ieee80211_tx(). */
@@ -1750,7 +1755,7 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, int if_id,
1750 return NULL; 1755 return NULL;
1751 } 1756 }
1752 1757
1753 control->tx_rate = (local->short_preamble && 1758 control->tx_rate = (sdata->short_preamble &&
1754 (rate->flags & IEEE80211_RATE_PREAMBLE2)) ? 1759 (rate->flags & IEEE80211_RATE_PREAMBLE2)) ?
1755 rate->val2 : rate->val; 1760 rate->val2 : rate->val;
1756 control->antenna_sel_tx = local->hw.conf.antenna_sel_tx; 1761 control->antenna_sel_tx = local->hw.conf.antenna_sel_tx;
@@ -1765,7 +1770,7 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, int if_id,
1765} 1770}
1766EXPORT_SYMBOL(ieee80211_beacon_get); 1771EXPORT_SYMBOL(ieee80211_beacon_get);
1767 1772
1768void ieee80211_rts_get(struct ieee80211_hw *hw, 1773void ieee80211_rts_get(struct ieee80211_hw *hw, int if_id,
1769 const void *frame, size_t frame_len, 1774 const void *frame, size_t frame_len,
1770 const struct ieee80211_tx_control *frame_txctl, 1775 const struct ieee80211_tx_control *frame_txctl,
1771 struct ieee80211_rts *rts) 1776 struct ieee80211_rts *rts)
@@ -1775,13 +1780,13 @@ void ieee80211_rts_get(struct ieee80211_hw *hw,
1775 1780
1776 fctl = IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS; 1781 fctl = IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS;
1777 rts->frame_control = cpu_to_le16(fctl); 1782 rts->frame_control = cpu_to_le16(fctl);
1778 rts->duration = ieee80211_rts_duration(hw, frame_len, frame_txctl); 1783 rts->duration = ieee80211_rts_duration(hw, if_id, frame_len, frame_txctl);
1779 memcpy(rts->ra, hdr->addr1, sizeof(rts->ra)); 1784 memcpy(rts->ra, hdr->addr1, sizeof(rts->ra));
1780 memcpy(rts->ta, hdr->addr2, sizeof(rts->ta)); 1785 memcpy(rts->ta, hdr->addr2, sizeof(rts->ta));
1781} 1786}
1782EXPORT_SYMBOL(ieee80211_rts_get); 1787EXPORT_SYMBOL(ieee80211_rts_get);
1783 1788
1784void ieee80211_ctstoself_get(struct ieee80211_hw *hw, 1789void ieee80211_ctstoself_get(struct ieee80211_hw *hw, int if_id,
1785 const void *frame, size_t frame_len, 1790 const void *frame, size_t frame_len,
1786 const struct ieee80211_tx_control *frame_txctl, 1791 const struct ieee80211_tx_control *frame_txctl,
1787 struct ieee80211_cts *cts) 1792 struct ieee80211_cts *cts)
@@ -1791,7 +1796,7 @@ void ieee80211_ctstoself_get(struct ieee80211_hw *hw,
1791 1796
1792 fctl = IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CTS; 1797 fctl = IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CTS;
1793 cts->frame_control = cpu_to_le16(fctl); 1798 cts->frame_control = cpu_to_le16(fctl);
1794 cts->duration = ieee80211_ctstoself_duration(hw, frame_len, frame_txctl); 1799 cts->duration = ieee80211_ctstoself_duration(hw, if_id, frame_len, frame_txctl);
1795 memcpy(cts->ra, hdr->addr1, sizeof(cts->ra)); 1800 memcpy(cts->ra, hdr->addr1, sizeof(cts->ra));
1796} 1801}
1797EXPORT_SYMBOL(ieee80211_ctstoself_get); 1802EXPORT_SYMBOL(ieee80211_ctstoself_get);
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index c45658309472..091ac0d634a5 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -314,31 +314,46 @@ int ieee80211_frame_duration(struct ieee80211_local *local, size_t len,
314} 314}
315 315
316/* Exported duration function for driver use */ 316/* Exported duration function for driver use */
317__le16 ieee80211_generic_frame_duration(struct ieee80211_hw *hw, 317__le16 ieee80211_generic_frame_duration(struct ieee80211_hw *hw, int if_id,
318 size_t frame_len, int rate) 318 size_t frame_len, int rate)
319{ 319{
320 struct ieee80211_local *local = hw_to_local(hw); 320 struct ieee80211_local *local = hw_to_local(hw);
321 struct net_device *bdev = dev_get_by_index(if_id);
322 struct ieee80211_sub_if_data *sdata;
321 u16 dur; 323 u16 dur;
322 int erp; 324 int erp;
323 325
326 if (unlikely(!bdev))
327 return 0;
328
329 sdata = IEEE80211_DEV_TO_SUB_IF(bdev);
324 erp = ieee80211_is_erp_rate(hw->conf.phymode, rate); 330 erp = ieee80211_is_erp_rate(hw->conf.phymode, rate);
325 dur = ieee80211_frame_duration(local, frame_len, rate, 331 dur = ieee80211_frame_duration(local, frame_len, rate,
326 erp, local->short_preamble); 332 erp, sdata->short_preamble);
327 333
334 dev_put(bdev);
328 return cpu_to_le16(dur); 335 return cpu_to_le16(dur);
329} 336}
330EXPORT_SYMBOL(ieee80211_generic_frame_duration); 337EXPORT_SYMBOL(ieee80211_generic_frame_duration);
331 338
332__le16 ieee80211_rts_duration(struct ieee80211_hw *hw, 339__le16 ieee80211_rts_duration(struct ieee80211_hw *hw, int if_id,
333 size_t frame_len, 340 size_t frame_len,
334 const struct ieee80211_tx_control *frame_txctl) 341 const struct ieee80211_tx_control *frame_txctl)
335{ 342{
336 struct ieee80211_local *local = hw_to_local(hw); 343 struct ieee80211_local *local = hw_to_local(hw);
337 struct ieee80211_rate *rate; 344 struct ieee80211_rate *rate;
338 int short_preamble = local->short_preamble; 345 struct net_device *bdev = dev_get_by_index(if_id);
346 struct ieee80211_sub_if_data *sdata;
347 int short_preamble;
339 int erp; 348 int erp;
340 u16 dur; 349 u16 dur;
341 350
351 if (unlikely(!bdev))
352 return 0;
353
354 sdata = IEEE80211_DEV_TO_SUB_IF(bdev);
355 short_preamble = sdata->short_preamble;
356
342 rate = frame_txctl->rts_rate; 357 rate = frame_txctl->rts_rate;
343 erp = !!(rate->flags & IEEE80211_RATE_ERP); 358 erp = !!(rate->flags & IEEE80211_RATE_ERP);
344 359
@@ -352,20 +367,29 @@ __le16 ieee80211_rts_duration(struct ieee80211_hw *hw,
352 dur += ieee80211_frame_duration(local, 10, rate->rate, 367 dur += ieee80211_frame_duration(local, 10, rate->rate,
353 erp, short_preamble); 368 erp, short_preamble);
354 369
370 dev_put(bdev);
355 return cpu_to_le16(dur); 371 return cpu_to_le16(dur);
356} 372}
357EXPORT_SYMBOL(ieee80211_rts_duration); 373EXPORT_SYMBOL(ieee80211_rts_duration);
358 374
359__le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw, 375__le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw, int if_id,
360 size_t frame_len, 376 size_t frame_len,
361 const struct ieee80211_tx_control *frame_txctl) 377 const struct ieee80211_tx_control *frame_txctl)
362{ 378{
363 struct ieee80211_local *local = hw_to_local(hw); 379 struct ieee80211_local *local = hw_to_local(hw);
364 struct ieee80211_rate *rate; 380 struct ieee80211_rate *rate;
365 int short_preamble = local->short_preamble; 381 struct net_device *bdev = dev_get_by_index(if_id);
382 struct ieee80211_sub_if_data *sdata;
383 int short_preamble;
366 int erp; 384 int erp;
367 u16 dur; 385 u16 dur;
368 386
387 if (unlikely(!bdev))
388 return 0;
389
390 sdata = IEEE80211_DEV_TO_SUB_IF(bdev);
391 short_preamble = sdata->short_preamble;
392
369 rate = frame_txctl->rts_rate; 393 rate = frame_txctl->rts_rate;
370 erp = !!(rate->flags & IEEE80211_RATE_ERP); 394 erp = !!(rate->flags & IEEE80211_RATE_ERP);
371 395
@@ -378,6 +402,7 @@ __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw,
378 erp, short_preamble); 402 erp, short_preamble);
379 } 403 }
380 404
405 dev_put(bdev);
381 return cpu_to_le16(dur); 406 return cpu_to_le16(dur);
382} 407}
383EXPORT_SYMBOL(ieee80211_ctstoself_duration); 408EXPORT_SYMBOL(ieee80211_ctstoself_duration);