ath9k_htc: Simplify RX IRQ handler
A bunch of validation and processing in the RX IRQ handler can be moved to the RX tasklet. The IRQ handler is already heavy, with the memory allocation for handling stream mode. Also, a memcpy of 40 bytes for every packet can be avoided in the handler. Signed-off-by: Sujith <Sujith.Manoharan@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
d439260e04
commit
4f824719a2
|
@ -448,10 +448,32 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv,
|
||||||
struct ieee80211_hw *hw = priv->hw;
|
struct ieee80211_hw *hw = priv->hw;
|
||||||
struct sk_buff *skb = rxbuf->skb;
|
struct sk_buff *skb = rxbuf->skb;
|
||||||
struct ath_common *common = ath9k_hw_common(priv->ah);
|
struct ath_common *common = ath9k_hw_common(priv->ah);
|
||||||
|
struct ath_htc_rx_status *rxstatus;
|
||||||
int hdrlen, padpos, padsize;
|
int hdrlen, padpos, padsize;
|
||||||
int last_rssi = ATH_RSSI_DUMMY_MARKER;
|
int last_rssi = ATH_RSSI_DUMMY_MARKER;
|
||||||
__le16 fc;
|
__le16 fc;
|
||||||
|
|
||||||
|
if (skb->len <= HTC_RX_FRAME_HEADER_SIZE) {
|
||||||
|
ath_print(common, ATH_DBG_FATAL,
|
||||||
|
"Corrupted RX frame, dropping\n");
|
||||||
|
goto rx_next;
|
||||||
|
}
|
||||||
|
|
||||||
|
rxstatus = (struct ath_htc_rx_status *)skb->data;
|
||||||
|
|
||||||
|
if (be16_to_cpu(rxstatus->rs_datalen) -
|
||||||
|
(skb->len - HTC_RX_FRAME_HEADER_SIZE) != 0) {
|
||||||
|
ath_print(common, ATH_DBG_FATAL,
|
||||||
|
"Corrupted RX data len, dropping "
|
||||||
|
"(dlen: %d, skblen: %d)\n",
|
||||||
|
rxstatus->rs_datalen, skb->len);
|
||||||
|
goto rx_next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the RX status information */
|
||||||
|
memcpy(&rxbuf->rxstatus, rxstatus, HTC_RX_FRAME_HEADER_SIZE);
|
||||||
|
skb_pull(skb, HTC_RX_FRAME_HEADER_SIZE);
|
||||||
|
|
||||||
hdr = (struct ieee80211_hdr *)skb->data;
|
hdr = (struct ieee80211_hdr *)skb->data;
|
||||||
fc = hdr->frame_control;
|
fc = hdr->frame_control;
|
||||||
hdrlen = ieee80211_get_hdrlen_from_skb(skb);
|
hdrlen = ieee80211_get_hdrlen_from_skb(skb);
|
||||||
|
@ -616,8 +638,6 @@ void ath9k_htc_rxep(void *drv_priv, struct sk_buff *skb,
|
||||||
struct ath_hw *ah = priv->ah;
|
struct ath_hw *ah = priv->ah;
|
||||||
struct ath_common *common = ath9k_hw_common(ah);
|
struct ath_common *common = ath9k_hw_common(ah);
|
||||||
struct ath9k_htc_rxbuf *rxbuf = NULL, *tmp_buf = NULL;
|
struct ath9k_htc_rxbuf *rxbuf = NULL, *tmp_buf = NULL;
|
||||||
struct ath_htc_rx_status *rxstatus;
|
|
||||||
u32 len = 0;
|
|
||||||
|
|
||||||
spin_lock(&priv->rx.rxbuflock);
|
spin_lock(&priv->rx.rxbuflock);
|
||||||
list_for_each_entry(tmp_buf, &priv->rx.rxbuf, list) {
|
list_for_each_entry(tmp_buf, &priv->rx.rxbuf, list) {
|
||||||
|
@ -634,27 +654,7 @@ void ath9k_htc_rxep(void *drv_priv, struct sk_buff *skb,
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
len = skb->len;
|
|
||||||
if (len <= HTC_RX_FRAME_HEADER_SIZE) {
|
|
||||||
ath_print(common, ATH_DBG_FATAL,
|
|
||||||
"Corrupted RX frame, dropping\n");
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
rxstatus = (struct ath_htc_rx_status *)skb->data;
|
|
||||||
|
|
||||||
if (be16_to_cpu(rxstatus->rs_datalen) -
|
|
||||||
(len - HTC_RX_FRAME_HEADER_SIZE) != 0) {
|
|
||||||
ath_print(common, ATH_DBG_FATAL,
|
|
||||||
"Corrupted RX data len, dropping "
|
|
||||||
"(epid: %d, dlen: %d, skblen: %d)\n",
|
|
||||||
ep_id, rxstatus->rs_datalen, len);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
spin_lock(&priv->rx.rxbuflock);
|
spin_lock(&priv->rx.rxbuflock);
|
||||||
memcpy(&rxbuf->rxstatus, rxstatus, HTC_RX_FRAME_HEADER_SIZE);
|
|
||||||
skb_pull(skb, HTC_RX_FRAME_HEADER_SIZE);
|
|
||||||
rxbuf->skb = skb;
|
rxbuf->skb = skb;
|
||||||
rxbuf->in_process = true;
|
rxbuf->in_process = true;
|
||||||
spin_unlock(&priv->rx.rxbuflock);
|
spin_unlock(&priv->rx.rxbuflock);
|
||||||
|
|
Loading…
Reference in New Issue