aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/wl12xx/tx.c
diff options
context:
space:
mode:
authorShahar Levi <shahar_levi@ti.com>2011-03-06 09:32:14 -0500
committerLuciano Coelho <coelho@ti.com>2011-04-19 09:49:01 -0400
commitae47c45fd02fdf88d57adc370e78e7a01e2bfcbc (patch)
tree3def0959f5332c2fd1279ffe898db0c554c1f819 /drivers/net/wireless/wl12xx/tx.c
parentae77eccf04f8c36769bdba334e1bbcc7bb9d3644 (diff)
wl12xx: 1281/1283 support - Add dummy packet support
Support sending dummy packet to wl128x FW as results of dummy packet event. That is part of dynamic TX mem blocks mechanism. Only send dummy packet when not in AP mode. [Even though the DUMMY_PACKET_EVENT_ID and the STA_REMOVE_COMPLETE_EVENT_ID events are defined to the same value, we need to treat them separately in the code. Keep the check and enable STA_REMOVE_COMPLETE_EVENT_ID for AP mode and DUMMY_PACKET_EVENT_ID for STA. Moved one warning to a cleaner place. Use WL1271_TID_MGMT for dummy packets -- Luca] Signed-off-by: Shahar Levi <shahar_levi@ti.com> Reviewed-by: Luciano Coelho <coelho@ti.com> Signed-off-by: Luciano Coelho <coelho@ti.com>
Diffstat (limited to 'drivers/net/wireless/wl12xx/tx.c')
-rw-r--r--drivers/net/wireless/wl12xx/tx.c75
1 files changed, 55 insertions, 20 deletions
diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c
index afc8505abeb6..75222a681296 100644
--- a/drivers/net/wireless/wl12xx/tx.c
+++ b/drivers/net/wireless/wl12xx/tx.c
@@ -215,13 +215,29 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb,
215 else 215 else
216 desc->life_time = cpu_to_le16(TX_HW_AP_MODE_PKT_LIFETIME_TU); 216 desc->life_time = cpu_to_le16(TX_HW_AP_MODE_PKT_LIFETIME_TU);
217 217
218 /* configure the tx attributes */
219 tx_attr = wl->session_counter << TX_HW_ATTR_OFST_SESSION_COUNTER;
220
221 /* queue (we use same identifiers for tid's and ac's */ 218 /* queue (we use same identifiers for tid's and ac's */
222 ac = wl1271_tx_get_queue(skb_get_queue_mapping(skb)); 219 ac = wl1271_tx_get_queue(skb_get_queue_mapping(skb));
223 desc->tid = ac; 220 desc->tid = ac;
224 221
222 if (skb->pkt_type == TX_PKT_TYPE_DUMMY_REQ) {
223 /*
224 * FW expects the dummy packet to have an invalid session id -
225 * any session id that is different than the one set in the join
226 */
227 tx_attr = ((~wl->session_counter) <<
228 TX_HW_ATTR_OFST_SESSION_COUNTER) &
229 TX_HW_ATTR_SESSION_COUNTER;
230
231 tx_attr |= TX_HW_ATTR_TX_DUMMY_REQ;
232
233 /* Dummy packets require the TID to be management */
234 desc->tid = WL1271_TID_MGMT;
235 } else {
236 /* configure the tx attributes */
237 tx_attr =
238 wl->session_counter << TX_HW_ATTR_OFST_SESSION_COUNTER;
239 }
240
225 if (wl->bss_type != BSS_TYPE_AP_BSS) { 241 if (wl->bss_type != BSS_TYPE_AP_BSS) {
226 desc->aid = hlid; 242 desc->aid = hlid;
227 243
@@ -587,6 +603,12 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl,
587 skb = wl->tx_frames[id]; 603 skb = wl->tx_frames[id];
588 info = IEEE80211_SKB_CB(skb); 604 info = IEEE80211_SKB_CB(skb);
589 605
606 if (skb->pkt_type == TX_PKT_TYPE_DUMMY_REQ) {
607 dev_kfree_skb(skb);
608 wl1271_free_tx_id(wl, id);
609 return;
610 }
611
590 /* update the TX status info */ 612 /* update the TX status info */
591 if (result->status == TX_SUCCESS) { 613 if (result->status == TX_SUCCESS) {
592 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) 614 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
@@ -716,10 +738,15 @@ void wl1271_tx_reset(struct wl1271 *wl)
716 while ((skb = skb_dequeue(&wl->tx_queue[i]))) { 738 while ((skb = skb_dequeue(&wl->tx_queue[i]))) {
717 wl1271_debug(DEBUG_TX, "freeing skb 0x%p", 739 wl1271_debug(DEBUG_TX, "freeing skb 0x%p",
718 skb); 740 skb);
719 info = IEEE80211_SKB_CB(skb); 741
720 info->status.rates[0].idx = -1; 742 if (skb->pkt_type == TX_PKT_TYPE_DUMMY_REQ) {
721 info->status.rates[0].count = 0; 743 dev_kfree_skb(skb);
722 ieee80211_tx_status(wl->hw, skb); 744 } else {
745 info = IEEE80211_SKB_CB(skb);
746 info->status.rates[0].idx = -1;
747 info->status.rates[0].count = 0;
748 ieee80211_tx_status(wl->hw, skb);
749 }
723 } 750 }
724 } 751 }
725 } 752 }
@@ -740,21 +767,29 @@ void wl1271_tx_reset(struct wl1271 *wl)
740 wl1271_free_tx_id(wl, i); 767 wl1271_free_tx_id(wl, i);
741 wl1271_debug(DEBUG_TX, "freeing skb 0x%p", skb); 768 wl1271_debug(DEBUG_TX, "freeing skb 0x%p", skb);
742 769
743 /* Remove private headers before passing the skb to mac80211 */ 770 if (skb->pkt_type == TX_PKT_TYPE_DUMMY_REQ) {
744 info = IEEE80211_SKB_CB(skb); 771 dev_kfree_skb(skb);
745 skb_pull(skb, sizeof(struct wl1271_tx_hw_descr)); 772 } else {
746 if (info->control.hw_key && 773 /*
747 info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) { 774 * Remove private headers before passing the skb to
748 int hdrlen = ieee80211_get_hdrlen_from_skb(skb); 775 * mac80211
749 memmove(skb->data + WL1271_TKIP_IV_SPACE, skb->data, 776 */
750 hdrlen); 777 info = IEEE80211_SKB_CB(skb);
751 skb_pull(skb, WL1271_TKIP_IV_SPACE); 778 skb_pull(skb, sizeof(struct wl1271_tx_hw_descr));
752 } 779 if (info->control.hw_key &&
780 info->control.hw_key->cipher ==
781 WLAN_CIPHER_SUITE_TKIP) {
782 int hdrlen = ieee80211_get_hdrlen_from_skb(skb);
783 memmove(skb->data + WL1271_TKIP_IV_SPACE,
784 skb->data, hdrlen);
785 skb_pull(skb, WL1271_TKIP_IV_SPACE);
786 }
753 787
754 info->status.rates[0].idx = -1; 788 info->status.rates[0].idx = -1;
755 info->status.rates[0].count = 0; 789 info->status.rates[0].count = 0;
756 790
757 ieee80211_tx_status(wl->hw, skb); 791 ieee80211_tx_status(wl->hw, skb);
792 }
758 } 793 }
759} 794}
760 795