aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/ath/ath9k/common.c24
-rw-r--r--drivers/net/wireless/ath/ath9k/common.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c14
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c9
4 files changed, 31 insertions, 18 deletions
diff --git a/drivers/net/wireless/ath/ath9k/common.c b/drivers/net/wireless/ath/ath9k/common.c
index d96751ccee96..4d775ae141db 100644
--- a/drivers/net/wireless/ath/ath9k/common.c
+++ b/drivers/net/wireless/ath/ath9k/common.c
@@ -236,16 +236,8 @@ void ath9k_cmn_rx_skb_postprocess(struct ath_common *common,
236 /* see if any padding is done by the hw and remove it */ 236 /* see if any padding is done by the hw and remove it */
237 hdr = (struct ieee80211_hdr *) skb->data; 237 hdr = (struct ieee80211_hdr *) skb->data;
238 hdrlen = ieee80211_get_hdrlen_from_skb(skb); 238 hdrlen = ieee80211_get_hdrlen_from_skb(skb);
239 padpos = 24;
240 fc = hdr->frame_control; 239 fc = hdr->frame_control;
241 if ((fc & cpu_to_le16(IEEE80211_FCTL_FROMDS|IEEE80211_FCTL_TODS)) == 240 padpos = ath9k_cmn_padpos(hdr->frame_control);
242 cpu_to_le16(IEEE80211_FCTL_FROMDS|IEEE80211_FCTL_TODS)) {
243 padpos += 6; /* ETH_ALEN */
244 }
245 if ((fc & cpu_to_le16(IEEE80211_STYPE_QOS_DATA|IEEE80211_FCTL_FTYPE)) ==
246 cpu_to_le16(IEEE80211_STYPE_QOS_DATA|IEEE80211_FTYPE_DATA)) {
247 padpos += 2;
248 }
249 241
250 /* The MAC header is padded to have 32-bit boundary if the 242 /* The MAC header is padded to have 32-bit boundary if the
251 * packet payload is non-zero. The general calculation for 243 * packet payload is non-zero. The general calculation for
@@ -280,6 +272,20 @@ void ath9k_cmn_rx_skb_postprocess(struct ath_common *common,
280} 272}
281EXPORT_SYMBOL(ath9k_cmn_rx_skb_postprocess); 273EXPORT_SYMBOL(ath9k_cmn_rx_skb_postprocess);
282 274
275int ath9k_cmn_padpos(__le16 frame_control)
276{
277 int padpos = 24;
278 if (ieee80211_has_a4(frame_control)) {
279 padpos += ETH_ALEN;
280 }
281 if (ieee80211_is_data_qos(frame_control)) {
282 padpos += IEEE80211_QOS_CTL_LEN;
283 }
284
285 return padpos;
286}
287EXPORT_SYMBOL(ath9k_cmn_padpos);
288
283static int __init ath9k_cmn_init(void) 289static int __init ath9k_cmn_init(void)
284{ 290{
285 return 0; 291 return 0;
diff --git a/drivers/net/wireless/ath/ath9k/common.h b/drivers/net/wireless/ath/ath9k/common.h
index b230bb15279e..042999c2fe9c 100644
--- a/drivers/net/wireless/ath/ath9k/common.h
+++ b/drivers/net/wireless/ath/ath9k/common.h
@@ -123,3 +123,5 @@ void ath9k_cmn_rx_skb_postprocess(struct ath_common *common,
123 struct ath_rx_status *rx_stats, 123 struct ath_rx_status *rx_stats,
124 struct ieee80211_rx_status *rxs, 124 struct ieee80211_rx_status *rxs,
125 bool decrypt_error); 125 bool decrypt_error);
126
127int ath9k_cmn_padpos(__le16 frame_control);
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 */
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 6f91a8ae616f..564c6cb1c2b4 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -1596,6 +1596,7 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf,
1596 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 1596 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
1597 int hdrlen; 1597 int hdrlen;
1598 __le16 fc; 1598 __le16 fc;
1599 int padpos, padsize;
1599 1600
1600 tx_info->pad[0] = 0; 1601 tx_info->pad[0] = 0;
1601 switch (txctl->frame_type) { 1602 switch (txctl->frame_type) {
@@ -1614,7 +1615,13 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf,
1614 ATH_TXBUF_RESET(bf); 1615 ATH_TXBUF_RESET(bf);
1615 1616
1616 bf->aphy = aphy; 1617 bf->aphy = aphy;
1617 bf->bf_frmlen = skb->len + FCS_LEN - (hdrlen & 3); 1618 bf->bf_frmlen = skb->len + FCS_LEN;
1619 /* Remove the padding size from bf_frmlen, if any */
1620 padpos = ath9k_cmn_padpos(hdr->frame_control);
1621 padsize = padpos & 3;
1622 if (padsize && skb->len>padpos+padsize) {
1623 bf->bf_frmlen -= padsize;
1624 }
1618 1625
1619 if (conf_is_ht(&hw->conf) && !is_pae(skb)) 1626 if (conf_is_ht(&hw->conf) && !is_pae(skb))
1620 bf->bf_state.bf_type |= BUF_HT; 1627 bf->bf_state.bf_type |= BUF_HT;