aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k/main.c
diff options
context:
space:
mode:
authorBenoit Papillault <benoit.papillault@free.fr>2009-11-24 09:49:18 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-11-28 15:04:50 -0500
commit1bc1488067ee2c295b933ef6decd6035230f1a1c (patch)
tree3e378bdeee251367d08fec654056e046b9853c6b /drivers/net/wireless/ath/ath9k/main.c
parente7824a50662f7f79b1a739f705b4d906c31cf221 (diff)
ath9k: Proper padding/unpadding for the TX/RX path.
Software padding is done on the TX path and software unpadding is done on the RX path. This patch corrects the position where the padding occurs. A specific function computes the pad position and this function is used in the TX and RX path. This patch has been tested by generating every possible 802.11 frames with every possible frame_control field and a varying length. This patch is useful for analyzing non standard 802.11 frames going over the air Signed-off-by: Benoit Papillault <benoit.papillault@free.fr> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/main.c')
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c14
1 files changed, 6 insertions, 8 deletions
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 55c669648bd6..cfe710b01d85 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -2364,7 +2364,8 @@ static int ath9k_tx(struct ieee80211_hw *hw,
2364 struct ath_softc *sc = aphy->sc; 2364 struct ath_softc *sc = aphy->sc;
2365 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 2365 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
2366 struct ath_tx_control txctl; 2366 struct ath_tx_control txctl;
2367 int hdrlen, padsize; 2367 int padpos, padsize;
2368 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
2368 2369
2369 if (aphy->state != ATH_WIPHY_ACTIVE && aphy->state != ATH_WIPHY_SCAN) { 2370 if (aphy->state != ATH_WIPHY_ACTIVE && aphy->state != ATH_WIPHY_SCAN) {
2370 ath_print(common, ATH_DBG_XMIT, 2371 ath_print(common, ATH_DBG_XMIT,
@@ -2374,7 +2375,6 @@ static int ath9k_tx(struct ieee80211_hw *hw,
2374 } 2375 }
2375 2376
2376 if (sc->ps_enabled) { 2377 if (sc->ps_enabled) {
2377 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
2378 /* 2378 /*
2379 * mac80211 does not set PM field for normal data frames, so we 2379 * mac80211 does not set PM field for normal data frames, so we
2380 * need to update that based on the current PS mode. 2380 * need to update that based on the current PS mode.
@@ -2394,7 +2394,6 @@ static int ath9k_tx(struct ieee80211_hw *hw,
2394 * power save mode. Need to wake up hardware for the TX to be 2394 * power save mode. Need to wake up hardware for the TX to be
2395 * completed and if needed, also for RX of buffered frames. 2395 * completed and if needed, also for RX of buffered frames.
2396 */ 2396 */
2397 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
2398 ath9k_ps_wakeup(sc); 2397 ath9k_ps_wakeup(sc);
2399 ath9k_hw_setrxabort(sc->sc_ah, 0); 2398 ath9k_hw_setrxabort(sc->sc_ah, 0);
2400 if (ieee80211_is_pspoll(hdr->frame_control)) { 2399 if (ieee80211_is_pspoll(hdr->frame_control)) {
@@ -2422,7 +2421,6 @@ static int ath9k_tx(struct ieee80211_hw *hw,
2422 * BSSes. 2421 * BSSes.
2423 */ 2422 */
2424 if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { 2423 if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
2425 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
2426 if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) 2424 if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
2427 sc->tx.seq_no += 0x10; 2425 sc->tx.seq_no += 0x10;
2428 hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); 2426 hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
@@ -2430,13 +2428,13 @@ static int ath9k_tx(struct ieee80211_hw *hw,
2430 } 2428 }
2431 2429
2432 /* Add the padding after the header if this is not already done */ 2430 /* Add the padding after the header if this is not already done */
2433 hdrlen = ieee80211_get_hdrlen_from_skb(skb); 2431 padpos = ath9k_cmn_padpos(hdr->frame_control);
2434 if (hdrlen & 3) { 2432 padsize = padpos & 3;
2435 padsize = hdrlen % 4; 2433 if (padsize && skb->len>padpos) {
2436 if (skb_headroom(skb) < padsize) 2434 if (skb_headroom(skb) < padsize)
2437 return -1; 2435 return -1;
2438 skb_push(skb, padsize); 2436 skb_push(skb, padsize);
2439 memmove(skb->data, skb->data + padsize, hdrlen); 2437 memmove(skb->data, skb->data + padsize, padpos);
2440 } 2438 }
2441 2439
2442 /* Check if a tx queue is available */ 2440 /* Check if a tx queue is available */