diff options
author | Emmanuel Grumbach <emmanuel.grumbach@intel.com> | 2011-07-07 10:59:02 -0400 |
---|---|---|
committer | Wey-Yi Guy <wey-yi.w.guy@intel.com> | 2011-07-16 10:37:06 -0400 |
commit | 1ab9f6c11b003d086ae4890ea202cc3c66f5a17a (patch) | |
tree | 36296b54edf0e3d8ee2b2c671d730b4de1f215e0 | |
parent | a27367d25da06c24e0379ad4489542016ff11dbb (diff) |
iwlagn: move the Rx dispatching to the upper layer
The upper layer receives a pointer to an iwl_rx_mem_buffer. I would prefer the
upper layer to receive a pointer to an iwl_rx_packet, but this is impossible
since the Rx path needs to add the address of the page to the skb.
I may find a solution later.
All the pre_rx_handler and notification code has been moved to the upper layer.
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn.c | 42 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-rx.c | 46 |
3 files changed, 52 insertions, 38 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index c91e0104a7aa..ba4e2a850007 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -513,6 +513,9 @@ static void iwl_rx_handle(struct iwl_priv *priv) | |||
513 | DMA_FROM_DEVICE); | 513 | DMA_FROM_DEVICE); |
514 | pkt = rxb_addr(rxb); | 514 | pkt = rxb_addr(rxb); |
515 | 515 | ||
516 | IWL_DEBUG_RX(priv, "r = %d, i = %d, %s, 0x%02x\n", r, | ||
517 | i, get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd); | ||
518 | |||
516 | len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; | 519 | len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; |
517 | len += sizeof(u32); /* account for status word */ | 520 | len += sizeof(u32); /* account for status word */ |
518 | trace_iwlwifi_dev_rx(priv, pkt, len); | 521 | trace_iwlwifi_dev_rx(priv, pkt, len); |
@@ -531,44 +534,7 @@ static void iwl_rx_handle(struct iwl_priv *priv) | |||
531 | (pkt->hdr.cmd != STATISTICS_NOTIFICATION) && | 534 | (pkt->hdr.cmd != STATISTICS_NOTIFICATION) && |
532 | (pkt->hdr.cmd != REPLY_TX); | 535 | (pkt->hdr.cmd != REPLY_TX); |
533 | 536 | ||
534 | /* | 537 | iwl_rx_dispatch(priv, rxb); |
535 | * Do the notification wait before RX handlers so | ||
536 | * even if the RX handler consumes the RXB we have | ||
537 | * access to it in the notification wait entry. | ||
538 | */ | ||
539 | if (!list_empty(&priv->_agn.notif_waits)) { | ||
540 | struct iwl_notification_wait *w; | ||
541 | |||
542 | spin_lock(&priv->_agn.notif_wait_lock); | ||
543 | list_for_each_entry(w, &priv->_agn.notif_waits, list) { | ||
544 | if (w->cmd == pkt->hdr.cmd) { | ||
545 | w->triggered = true; | ||
546 | if (w->fn) | ||
547 | w->fn(priv, pkt, w->fn_data); | ||
548 | } | ||
549 | } | ||
550 | spin_unlock(&priv->_agn.notif_wait_lock); | ||
551 | |||
552 | wake_up_all(&priv->_agn.notif_waitq); | ||
553 | } | ||
554 | if (priv->pre_rx_handler) | ||
555 | priv->pre_rx_handler(priv, rxb); | ||
556 | |||
557 | /* Based on type of command response or notification, | ||
558 | * handle those that need handling via function in | ||
559 | * rx_handlers table. See iwl_setup_rx_handlers() */ | ||
560 | if (priv->rx_handlers[pkt->hdr.cmd]) { | ||
561 | IWL_DEBUG_RX(priv, "r = %d, i = %d, %s, 0x%02x\n", r, | ||
562 | i, get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd); | ||
563 | priv->isr_stats.rx_handlers[pkt->hdr.cmd]++; | ||
564 | priv->rx_handlers[pkt->hdr.cmd] (priv, rxb); | ||
565 | } else { | ||
566 | /* No handling needed */ | ||
567 | IWL_DEBUG_RX(priv, | ||
568 | "r %d i %d No handler needed for %s, 0x%02x\n", | ||
569 | r, i, get_cmd_string(pkt->hdr.cmd), | ||
570 | pkt->hdr.cmd); | ||
571 | } | ||
572 | 538 | ||
573 | /* | 539 | /* |
574 | * XXX: After here, we should always check rxb->page | 540 | * XXX: After here, we should always check rxb->page |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index fe5451eee82f..666376e3030f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h | |||
@@ -187,6 +187,8 @@ void iwlagn_rx_replenish(struct iwl_priv *priv); | |||
187 | void iwlagn_rx_replenish_now(struct iwl_priv *priv); | 187 | void iwlagn_rx_replenish_now(struct iwl_priv *priv); |
188 | int iwlagn_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band); | 188 | int iwlagn_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band); |
189 | void iwl_setup_rx_handlers(struct iwl_priv *priv); | 189 | void iwl_setup_rx_handlers(struct iwl_priv *priv); |
190 | void iwl_rx_dispatch(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); | ||
191 | |||
190 | 192 | ||
191 | /* tx */ | 193 | /* tx */ |
192 | void iwlagn_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq, | 194 | void iwlagn_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index f3f3efe38ce2..c5eb379246ff 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c | |||
@@ -1105,3 +1105,49 @@ void iwl_setup_rx_handlers(struct iwl_priv *priv) | |||
1105 | /* Set up hardware specific Rx handlers */ | 1105 | /* Set up hardware specific Rx handlers */ |
1106 | priv->cfg->ops->lib->rx_handler_setup(priv); | 1106 | priv->cfg->ops->lib->rx_handler_setup(priv); |
1107 | } | 1107 | } |
1108 | |||
1109 | void iwl_rx_dispatch(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) | ||
1110 | { | ||
1111 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | ||
1112 | |||
1113 | /* | ||
1114 | * Do the notification wait before RX handlers so | ||
1115 | * even if the RX handler consumes the RXB we have | ||
1116 | * access to it in the notification wait entry. | ||
1117 | */ | ||
1118 | if (!list_empty(&priv->_agn.notif_waits)) { | ||
1119 | struct iwl_notification_wait *w; | ||
1120 | |||
1121 | spin_lock(&priv->_agn.notif_wait_lock); | ||
1122 | list_for_each_entry(w, &priv->_agn.notif_waits, list) { | ||
1123 | if (w->cmd != pkt->hdr.cmd) | ||
1124 | continue; | ||
1125 | IWL_DEBUG_RX(priv, | ||
1126 | "Notif: %s, 0x%02x - wake the callers up\n", | ||
1127 | get_cmd_string(pkt->hdr.cmd), | ||
1128 | pkt->hdr.cmd); | ||
1129 | w->triggered = true; | ||
1130 | if (w->fn) | ||
1131 | w->fn(priv, pkt, w->fn_data); | ||
1132 | } | ||
1133 | spin_unlock(&priv->_agn.notif_wait_lock); | ||
1134 | |||
1135 | wake_up_all(&priv->_agn.notif_waitq); | ||
1136 | } | ||
1137 | |||
1138 | if (priv->pre_rx_handler) | ||
1139 | priv->pre_rx_handler(priv, rxb); | ||
1140 | |||
1141 | /* Based on type of command response or notification, | ||
1142 | * handle those that need handling via function in | ||
1143 | * rx_handlers table. See iwl_setup_rx_handlers() */ | ||
1144 | if (priv->rx_handlers[pkt->hdr.cmd]) { | ||
1145 | priv->isr_stats.rx_handlers[pkt->hdr.cmd]++; | ||
1146 | priv->rx_handlers[pkt->hdr.cmd] (priv, rxb); | ||
1147 | } else { | ||
1148 | /* No handling needed */ | ||
1149 | IWL_DEBUG_RX(priv, | ||
1150 | "No handler needed for %s, 0x%02x\n", | ||
1151 | get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd); | ||
1152 | } | ||
1153 | } | ||