diff options
Diffstat (limited to 'drivers/net/wireless/ath/wil6210/txrx_edma.c')
-rw-r--r-- | drivers/net/wireless/ath/wil6210/txrx_edma.c | 42 |
1 files changed, 27 insertions, 15 deletions
diff --git a/drivers/net/wireless/ath/wil6210/txrx_edma.c b/drivers/net/wireless/ath/wil6210/txrx_edma.c index dc040cd4ab06..04d576deae72 100644 --- a/drivers/net/wireless/ath/wil6210/txrx_edma.c +++ b/drivers/net/wireless/ath/wil6210/txrx_edma.c @@ -221,10 +221,17 @@ static int wil_ring_alloc_skb_edma(struct wil6210_priv *wil, } static inline -void wil_get_next_rx_status_msg(struct wil_status_ring *sring, void *msg) +void wil_get_next_rx_status_msg(struct wil_status_ring *sring, u8 *dr_bit, + void *msg) { - memcpy(msg, (void *)(sring->va + (sring->elem_size * sring->swhead)), - sring->elem_size); + struct wil_rx_status_compressed *_msg; + + _msg = (struct wil_rx_status_compressed *) + (sring->va + (sring->elem_size * sring->swhead)); + *dr_bit = WIL_GET_BITS(_msg->d0, 31, 31); + /* make sure dr_bit is read before the rest of status msg */ + rmb(); + memcpy(msg, (void *)_msg, sring->elem_size); } static inline void wil_sring_advance_swhead(struct wil_status_ring *sring) @@ -587,8 +594,7 @@ static bool wil_is_rx_idle_edma(struct wil6210_priv *wil) if (!sring->va) continue; - wil_get_next_rx_status_msg(sring, msg); - dr_bit = wil_rx_status_get_desc_rdy_bit(msg); + wil_get_next_rx_status_msg(sring, &dr_bit, msg); /* Check if there are unhandled RX status messages */ if (dr_bit == sring->desc_rdy_pol) @@ -878,8 +884,7 @@ static struct sk_buff *wil_sring_reap_rx_edma(struct wil6210_priv *wil, BUILD_BUG_ON(sizeof(struct wil_rx_status_extended) > sizeof(skb->cb)); again: - wil_get_next_rx_status_msg(sring, msg); - dr_bit = wil_rx_status_get_desc_rdy_bit(msg); + wil_get_next_rx_status_msg(sring, &dr_bit, msg); /* Completed handling all the ready status messages */ if (dr_bit != sring->desc_rdy_pol) @@ -959,8 +964,8 @@ again: } stats = &wil->sta[cid].stats; - if (unlikely(skb->len < ETH_HLEN)) { - wil_dbg_txrx(wil, "Short frame, len = %d\n", skb->len); + if (unlikely(dmalen < ETH_HLEN)) { + wil_dbg_txrx(wil, "Short frame, len = %d\n", dmalen); stats->rx_short_frame++; rxdata->skipping = true; goto skipping; @@ -1023,6 +1028,8 @@ skipping: stats->last_mcs_rx = wil_rx_status_get_mcs(msg); if (stats->last_mcs_rx < ARRAY_SIZE(stats->rx_per_mcs)) stats->rx_per_mcs[stats->last_mcs_rx]++; + + stats->last_cb_mode_rx = wil_rx_status_get_cb_mode(msg); } if (!wil->use_rx_hw_reordering && !wil->use_compressed_rx_status && @@ -1133,12 +1140,15 @@ static int wil_tx_desc_map_edma(union wil_tx_desc *desc, } static inline void -wil_get_next_tx_status_msg(struct wil_status_ring *sring, +wil_get_next_tx_status_msg(struct wil_status_ring *sring, u8 *dr_bit, struct wil_ring_tx_status *msg) { struct wil_ring_tx_status *_msg = (struct wil_ring_tx_status *) (sring->va + (sring->elem_size * sring->swhead)); + *dr_bit = _msg->desc_ready >> TX_STATUS_DESC_READY_POS; + /* make sure dr_bit is read before the rest of status msg */ + rmb(); *msg = *_msg; } @@ -1167,8 +1177,7 @@ int wil_tx_sring_handler(struct wil6210_priv *wil, int used_before_complete; int used_new; - wil_get_next_tx_status_msg(sring, &msg); - dr_bit = msg.desc_ready >> TX_STATUS_DESC_READY_POS; + wil_get_next_tx_status_msg(sring, &dr_bit, &msg); /* Process completion messages while DR bit has the expected polarity */ while (dr_bit == sring->desc_rdy_pol) { @@ -1255,6 +1264,10 @@ int wil_tx_sring_handler(struct wil6210_priv *wil, if (stats) stats->tx_errors++; } + + if (skb->protocol == cpu_to_be16(ETH_P_PAE)) + wil_tx_complete_handle_eapol(vif, skb); + wil_consume_skb(skb, msg.status == 0); } memset(ctx, 0, sizeof(*ctx)); @@ -1287,8 +1300,7 @@ again: wil_sring_advance_swhead(sring); - wil_get_next_tx_status_msg(sring, &msg); - dr_bit = msg.desc_ready >> TX_STATUS_DESC_READY_POS; + wil_get_next_tx_status_msg(sring, &dr_bit, &msg); } /* shall we wake net queues? */ @@ -1471,7 +1483,7 @@ static int __wil_tx_ring_tso_edma(struct wil6210_priv *wil, /* Rest of the descriptors are from the SKB fragments */ for (f = 0; f < nr_frags; f++) { skb_frag_t *frag = &skb_shinfo(skb)->frags[f]; - int len = frag->size; + int len = skb_frag_size(frag); wil_dbg_txrx(wil, "TSO: frag[%d]: len %u, descs_used %d\n", f, len, descs_used); |