diff options
-rw-r--r-- | drivers/staging/cw1200/debug.c | 4 | ||||
-rw-r--r-- | drivers/staging/cw1200/debug.h | 8 | ||||
-rw-r--r-- | drivers/staging/cw1200/txrx.c | 27 | ||||
-rw-r--r-- | drivers/staging/cw1200/wsm.c | 15 | ||||
-rw-r--r-- | drivers/staging/cw1200/wsm.h | 3 |
5 files changed, 35 insertions, 22 deletions
diff --git a/drivers/staging/cw1200/debug.c b/drivers/staging/cw1200/debug.c index 91c690ad4e6..297b83e1ef5 100644 --- a/drivers/staging/cw1200/debug.c +++ b/drivers/staging/cw1200/debug.c @@ -288,8 +288,8 @@ static int cw1200_status_show(struct seq_file *seq, void *v) d->rx_agg); seq_printf(seq, "TX miss: %d\n", d->tx_cache_miss); - seq_printf(seq, "TX copy: %d\n", - d->tx_copy); + seq_printf(seq, "TX align: %d\n", + d->tx_align); seq_printf(seq, "TX TTL: %d\n", d->tx_ttl); seq_printf(seq, "Scan: %s\n", diff --git a/drivers/staging/cw1200/debug.h b/drivers/staging/cw1200/debug.h index 6f7d8acab00..aab0c061648 100644 --- a/drivers/staging/cw1200/debug.h +++ b/drivers/staging/cw1200/debug.h @@ -14,7 +14,7 @@ struct cw1200_debug_priv { int tx_multi; int tx_multi_frames; int tx_cache_miss; - int tx_copy; + int tx_align; int tx_ttl; }; @@ -53,9 +53,9 @@ static inline void cw1200_debug_tx_cache_miss(struct cw1200_common *priv) ++priv->debug->tx_cache_miss; } -static inline void cw1200_debug_tx_copy(struct cw1200_common *priv) +static inline void cw1200_debug_tx_align(struct cw1200_common *priv) { - ++priv->debug->tx_copy; + ++priv->debug->tx_align; } static inline void cw1200_debug_tx_ttl(struct cw1200_common *priv) @@ -99,7 +99,7 @@ static inline void cw1200_debug_tx_cache_miss(struct cw1200_common *priv) { } -static inline void cw1200_debug_tx_copy(struct cw1200_common *priv) +static inline void cw1200_debug_tx_align(struct cw1200_common *priv) { } diff --git a/drivers/staging/cw1200/txrx.c b/drivers/staging/cw1200/txrx.c index ef5accb19a0..a03a17bb79c 100644 --- a/drivers/staging/cw1200/txrx.c +++ b/drivers/staging/cw1200/txrx.c @@ -508,14 +508,22 @@ cw1200_tx_h_crypt(struct cw1200_common *priv, static int cw1200_tx_h_align(struct cw1200_common *priv, - struct cw1200_txinfo *t) + struct cw1200_txinfo *t, + u8 *flags) { size_t offset = (size_t)t->skb->data & 3; - u8 *p; if (!offset) return 0; + if (offset & 1) { + wiphy_err(priv->hw->wiphy, + "Bug: attempt to transmit a frame " + "with wrong alignment: %d\n", + offset); + return -EINVAL; + } + if (skb_headroom(t->skb) < offset) { wiphy_err(priv->hw->wiphy, "Bug: no space allocated " @@ -524,10 +532,11 @@ cw1200_tx_h_align(struct cw1200_common *priv, skb_headroom(t->skb)); return -ENOMEM; } - p = skb_push(t->skb, offset); - memmove(p, &p[offset], t->skb->len - offset); - skb_trim(t->skb, t->skb->len - offset); - cw1200_debug_tx_copy(priv); + skb_push(t->skb, offset); + t->hdrlen += offset; + t->txpriv.offset += offset; + *flags |= WSM_TX_2BYTES_SHIFT; + cw1200_debug_tx_align(priv); return 0; } @@ -645,7 +654,7 @@ cw1200_tx_h_rate_policy(struct cw1200_common *priv, t->txpriv.rate_id = tx_policy_get(priv, t->tx_info->control.rates, IEEE80211_TX_MAX_RATES, &tx_policy_renew); - wsm->flags = t->txpriv.rate_id << 4; + wsm->flags |= t->txpriv.rate_id << 4; if (tx_policy_renew) { tx_policy_printk(KERN_DEBUG "[TX] TX policy renew.\n"); @@ -696,6 +705,7 @@ void cw1200_tx(struct ieee80211_hw *dev, struct sk_buff *skb) }; struct wsm_tx *wsm; bool tid_update = 0; + u8 flags = 0; int ret; t.rate = cw1200_get_tx_rate(priv, @@ -722,7 +732,7 @@ void cw1200_tx(struct ieee80211_hw *dev, struct sk_buff *skb) ret = cw1200_tx_h_crypt(priv, &t); if (ret) goto drop; - ret = cw1200_tx_h_align(priv, &t); + ret = cw1200_tx_h_align(priv, &t, &flags); if (ret) goto drop; ret = cw1200_tx_h_action(priv, &t); @@ -733,6 +743,7 @@ void cw1200_tx(struct ieee80211_hw *dev, struct sk_buff *skb) ret = -ENOMEM; goto drop; } + wsm->flags |= flags; cw1200_tx_h_bt(priv, &t, wsm); cw1200_tx_h_rate_policy(priv, &t, wsm); diff --git a/drivers/staging/cw1200/wsm.c b/drivers/staging/cw1200/wsm.c index 10303fae3c8..295b13f5676 100644 --- a/drivers/staging/cw1200/wsm.c +++ b/drivers/staging/cw1200/wsm.c @@ -1313,12 +1313,12 @@ out: static bool wsm_handle_tx_data(struct cw1200_common *priv, const struct wsm_tx *wsm, const struct ieee80211_tx_info *tx_info, - struct cw1200_queue *queue, - int link_id) + const struct cw1200_txpriv *txpriv, + struct cw1200_queue *queue) { bool handled = false; const struct ieee80211_hdr *frame = - (struct ieee80211_hdr *)&wsm[1]; + (struct ieee80211_hdr *) &((u8 *)wsm)[txpriv->offset]; __le16 fctl = frame->frame_control; enum { doProbe, @@ -1349,7 +1349,7 @@ static bool wsm_handle_tx_data(struct cw1200_common *priv, case NL80211_IFTYPE_AP: if (unlikely(!priv->join_status)) action = doDrop; - else if (unlikely(!(BIT(link_id) & + else if (unlikely(!(BIT(txpriv->raw_link_id) & (BIT(0) | priv->link_id_map)))) { wiphy_warn(priv->hw->wiphy, "A frame with expired link id " @@ -1396,7 +1396,6 @@ static bool wsm_handle_tx_data(struct cw1200_common *priv, switch (action) { case doProbe: { - const struct cw1200_txpriv *txpriv; /* An interesting FW "feature". Device filters * probe responses. * The easiest way to get it back is to convert @@ -1619,8 +1618,7 @@ int wsm_get_tx(struct cw1200_common *priv, u8 **data, continue; if (wsm_handle_tx_data(priv, wsm, - tx_info, queue, - txpriv->raw_link_id)) + tx_info, txpriv, queue)) continue; /* Handled by WSM */ wsm->hdr.id &= __cpu_to_le16( @@ -1635,7 +1633,8 @@ int wsm_get_tx(struct cw1200_common *priv, u8 **data, if (more) { struct ieee80211_hdr *hdr = - (struct ieee80211_hdr *) &wsm[1]; + (struct ieee80211_hdr *) + &((u8 *)wsm)[txpriv->offset]; /* more buffered multicast/broadcast frames * ==> set MoreData flag in IEEE 802.11 header * to inform PS STAs */ diff --git a/drivers/staging/cw1200/wsm.h b/drivers/staging/cw1200/wsm.h index f0b07dc08a2..6698d771396 100644 --- a/drivers/staging/cw1200/wsm.h +++ b/drivers/staging/cw1200/wsm.h @@ -284,6 +284,9 @@ struct cw1200_common; /* Macro to fetch encryption key index. */ #define WSM_RX_STATUS_KEY_IDX(status) (((status >> 20)) & 0x0F) +/* Frame Control field starts at Frame offset + 2 */ +#define WSM_TX_2BYTES_SHIFT (BIT(7)) + /* Join mode */ /* IBSS */ #define WSM_JOIN_MODE_IBSS (0) |