diff options
-rw-r--r-- | drivers/net/wireless/rtl8187.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/rtl8187_dev.c | 4 | ||||
-rw-r--r-- | include/net/mac80211.h | 15 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 7 | ||||
-rw-r--r-- | net/mac80211/ieee80211_ioctl.c | 7 | ||||
-rw-r--r-- | net/mac80211/ieee80211_sta.c | 16 | ||||
-rw-r--r-- | net/mac80211/tx.c | 31 | ||||
-rw-r--r-- | net/mac80211/util.c | 37 |
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 | */ |
848 | void ieee80211_rts_get(struct ieee80211_hw *hw, | 849 | void 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 | */ |
880 | void ieee80211_ctstoself_get(struct ieee80211_hw *hw, | 883 | void 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 | |||
641 | ieee80211_tx_h_misc(struct ieee80211_txrx_data *tx) | 635 | ieee80211_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 | } |
1766 | EXPORT_SYMBOL(ieee80211_beacon_get); | 1771 | EXPORT_SYMBOL(ieee80211_beacon_get); |
1767 | 1772 | ||
1768 | void ieee80211_rts_get(struct ieee80211_hw *hw, | 1773 | void 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 | } |
1782 | EXPORT_SYMBOL(ieee80211_rts_get); | 1787 | EXPORT_SYMBOL(ieee80211_rts_get); |
1783 | 1788 | ||
1784 | void ieee80211_ctstoself_get(struct ieee80211_hw *hw, | 1789 | void 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 | } |
1797 | EXPORT_SYMBOL(ieee80211_ctstoself_get); | 1802 | EXPORT_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 | } |
330 | EXPORT_SYMBOL(ieee80211_generic_frame_duration); | 337 | EXPORT_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 | } |
357 | EXPORT_SYMBOL(ieee80211_rts_duration); | 373 | EXPORT_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 | } |
383 | EXPORT_SYMBOL(ieee80211_ctstoself_duration); | 408 | EXPORT_SYMBOL(ieee80211_ctstoself_duration); |