aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>2011-07-07 10:59:02 -0400
committerWey-Yi Guy <wey-yi.w.guy@intel.com>2011-07-16 10:37:06 -0400
commit1ab9f6c11b003d086ae4890ea202cc3c66f5a17a (patch)
tree36296b54edf0e3d8ee2b2c671d730b4de1f215e0
parenta27367d25da06c24e0379ad4489542016ff11dbb (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.c42
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rx.c46
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);
187void iwlagn_rx_replenish_now(struct iwl_priv *priv); 187void iwlagn_rx_replenish_now(struct iwl_priv *priv);
188int iwlagn_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band); 188int iwlagn_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band);
189void iwl_setup_rx_handlers(struct iwl_priv *priv); 189void iwl_setup_rx_handlers(struct iwl_priv *priv);
190void iwl_rx_dispatch(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb);
191
190 192
191/* tx */ 193/* tx */
192void iwlagn_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq, 194void 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
1109void 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}