aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/wl12xx/tx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/wl12xx/tx.c')
-rw-r--r--drivers/net/wireless/wl12xx/tx.c75
1 files changed, 34 insertions, 41 deletions
diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c
index 4508ccd78328..6446e4d3e8f9 100644
--- a/drivers/net/wireless/wl12xx/tx.c
+++ b/drivers/net/wireless/wl12xx/tx.c
@@ -77,35 +77,6 @@ static void wl1271_free_tx_id(struct wl1271 *wl, int id)
77 } 77 }
78} 78}
79 79
80static int wl1271_tx_update_filters(struct wl1271 *wl,
81 struct wl12xx_vif *wlvif,
82 struct sk_buff *skb)
83{
84 struct ieee80211_hdr *hdr;
85 int ret;
86
87 hdr = (struct ieee80211_hdr *)skb->data;
88
89 /*
90 * stop bssid-based filtering before transmitting authentication
91 * requests. this way the hw will never drop authentication
92 * responses coming from BSSIDs it isn't familiar with (e.g. on
93 * roaming)
94 */
95 if (!ieee80211_is_auth(hdr->frame_control))
96 return 0;
97
98 if (wlvif->dev_hlid != WL12XX_INVALID_LINK_ID)
99 goto out;
100
101 wl1271_debug(DEBUG_CMD, "starting device role for roaming");
102 ret = wl12xx_start_dev(wl, wlvif);
103 if (ret < 0)
104 goto out;
105out:
106 return 0;
107}
108
109static void wl1271_tx_ap_update_inconnection_sta(struct wl1271 *wl, 80static void wl1271_tx_ap_update_inconnection_sta(struct wl1271 *wl,
110 struct sk_buff *skb) 81 struct sk_buff *skb)
111{ 82{
@@ -187,8 +158,6 @@ u8 wl12xx_tx_get_hlid(struct wl1271 *wl, struct wl12xx_vif *wlvif,
187 if (wlvif->bss_type == BSS_TYPE_AP_BSS) 158 if (wlvif->bss_type == BSS_TYPE_AP_BSS)
188 return wl12xx_tx_get_hlid_ap(wl, wlvif, skb); 159 return wl12xx_tx_get_hlid_ap(wl, wlvif, skb);
189 160
190 wl1271_tx_update_filters(wl, wlvif, skb);
191
192 if ((test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags) || 161 if ((test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags) ||
193 test_bit(WLVIF_FLAG_IBSS_JOINED, &wlvif->flags)) && 162 test_bit(WLVIF_FLAG_IBSS_JOINED, &wlvif->flags)) &&
194 !ieee80211_is_auth(hdr->frame_control) && 163 !ieee80211_is_auth(hdr->frame_control) &&
@@ -286,16 +255,20 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct wl12xx_vif *wlvif,
286 int aligned_len, ac, rate_idx; 255 int aligned_len, ac, rate_idx;
287 s64 hosttime; 256 s64 hosttime;
288 u16 tx_attr = 0; 257 u16 tx_attr = 0;
258 __le16 frame_control;
259 struct ieee80211_hdr *hdr;
260 u8 *frame_start;
289 bool is_dummy; 261 bool is_dummy;
290 262
291 desc = (struct wl1271_tx_hw_descr *) skb->data; 263 desc = (struct wl1271_tx_hw_descr *) skb->data;
264 frame_start = (u8 *)(desc + 1);
265 hdr = (struct ieee80211_hdr *)(frame_start + extra);
266 frame_control = hdr->frame_control;
292 267
293 /* relocate space for security header */ 268 /* relocate space for security header */
294 if (extra) { 269 if (extra) {
295 void *framestart = skb->data + sizeof(*desc); 270 int hdrlen = ieee80211_hdrlen(frame_control);
296 u16 fc = *(u16 *)(framestart + extra); 271 memmove(frame_start, hdr, hdrlen);
297 int hdrlen = ieee80211_hdrlen(cpu_to_le16(fc));
298 memmove(framestart, framestart + extra, hdrlen);
299 } 272 }
300 273
301 /* configure packet life time */ 274 /* configure packet life time */
@@ -384,6 +357,11 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct wl12xx_vif *wlvif,
384 desc->wl127x_mem.total_mem_blocks); 357 desc->wl127x_mem.total_mem_blocks);
385 } 358 }
386 359
360 /* for WEP shared auth - no fw encryption is needed */
361 if (ieee80211_is_auth(frame_control) &&
362 ieee80211_has_protected(frame_control))
363 tx_attr |= TX_HW_ATTR_HOST_ENCRYPT;
364
387 desc->tx_attr = cpu_to_le16(tx_attr); 365 desc->tx_attr = cpu_to_le16(tx_attr);
388} 366}
389 367
@@ -408,7 +386,7 @@ static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct wl12xx_vif *wlvif,
408 386
409 if (info->control.hw_key && 387 if (info->control.hw_key &&
410 info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) 388 info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP)
411 extra = WL1271_TKIP_IV_SPACE; 389 extra = WL1271_EXTRA_SPACE_TKIP;
412 390
413 if (info->control.hw_key) { 391 if (info->control.hw_key) {
414 bool is_wep; 392 bool is_wep;
@@ -795,6 +773,18 @@ out:
795 mutex_unlock(&wl->mutex); 773 mutex_unlock(&wl->mutex);
796} 774}
797 775
776static u8 wl1271_tx_get_rate_flags(u8 rate_class_index)
777{
778 u8 flags = 0;
779
780 if (rate_class_index >= CONF_HW_RXTX_RATE_MCS_MIN &&
781 rate_class_index <= CONF_HW_RXTX_RATE_MCS_MAX)
782 flags |= IEEE80211_TX_RC_MCS;
783 if (rate_class_index == CONF_HW_RXTX_RATE_MCS7_SGI)
784 flags |= IEEE80211_TX_RC_SHORT_GI;
785 return flags;
786}
787
798static void wl1271_tx_complete_packet(struct wl1271 *wl, 788static void wl1271_tx_complete_packet(struct wl1271 *wl,
799 struct wl1271_tx_hw_res_descr *result) 789 struct wl1271_tx_hw_res_descr *result)
800{ 790{
@@ -804,6 +794,7 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl,
804 struct sk_buff *skb; 794 struct sk_buff *skb;
805 int id = result->id; 795 int id = result->id;
806 int rate = -1; 796 int rate = -1;
797 u8 rate_flags = 0;
807 u8 retries = 0; 798 u8 retries = 0;
808 799
809 /* check for id legality */ 800 /* check for id legality */
@@ -830,6 +821,7 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl,
830 info->flags |= IEEE80211_TX_STAT_ACK; 821 info->flags |= IEEE80211_TX_STAT_ACK;
831 rate = wl1271_rate_to_idx(result->rate_class_index, 822 rate = wl1271_rate_to_idx(result->rate_class_index,
832 wlvif->band); 823 wlvif->band);
824 rate_flags = wl1271_tx_get_rate_flags(result->rate_class_index);
833 retries = result->ack_failures; 825 retries = result->ack_failures;
834 } else if (result->status == TX_RETRY_EXCEEDED) { 826 } else if (result->status == TX_RETRY_EXCEEDED) {
835 wl->stats.excessive_retries++; 827 wl->stats.excessive_retries++;
@@ -838,7 +830,7 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl,
838 830
839 info->status.rates[0].idx = rate; 831 info->status.rates[0].idx = rate;
840 info->status.rates[0].count = retries; 832 info->status.rates[0].count = retries;
841 info->status.rates[0].flags = 0; 833 info->status.rates[0].flags = rate_flags;
842 info->status.ack_signal = -1; 834 info->status.ack_signal = -1;
843 835
844 wl->stats.retry_count += result->ack_failures; 836 wl->stats.retry_count += result->ack_failures;
@@ -869,8 +861,9 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl,
869 if (info->control.hw_key && 861 if (info->control.hw_key &&
870 info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) { 862 info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) {
871 int hdrlen = ieee80211_get_hdrlen_from_skb(skb); 863 int hdrlen = ieee80211_get_hdrlen_from_skb(skb);
872 memmove(skb->data + WL1271_TKIP_IV_SPACE, skb->data, hdrlen); 864 memmove(skb->data + WL1271_EXTRA_SPACE_TKIP, skb->data,
873 skb_pull(skb, WL1271_TKIP_IV_SPACE); 865 hdrlen);
866 skb_pull(skb, WL1271_EXTRA_SPACE_TKIP);
874 } 867 }
875 868
876 wl1271_debug(DEBUG_TX, "tx status id %u skb 0x%p failures %u rate 0x%x" 869 wl1271_debug(DEBUG_TX, "tx status id %u skb 0x%p failures %u rate 0x%x"
@@ -1012,9 +1005,9 @@ void wl12xx_tx_reset(struct wl1271 *wl, bool reset_tx_queues)
1012 info->control.hw_key->cipher == 1005 info->control.hw_key->cipher ==
1013 WLAN_CIPHER_SUITE_TKIP) { 1006 WLAN_CIPHER_SUITE_TKIP) {
1014 int hdrlen = ieee80211_get_hdrlen_from_skb(skb); 1007 int hdrlen = ieee80211_get_hdrlen_from_skb(skb);
1015 memmove(skb->data + WL1271_TKIP_IV_SPACE, 1008 memmove(skb->data + WL1271_EXTRA_SPACE_TKIP,
1016 skb->data, hdrlen); 1009 skb->data, hdrlen);
1017 skb_pull(skb, WL1271_TKIP_IV_SPACE); 1010 skb_pull(skb, WL1271_EXTRA_SPACE_TKIP);
1018 } 1011 }
1019 1012
1020 info->status.rates[0].idx = -1; 1013 info->status.rates[0].idx = -1;