aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2012-03-05 14:24:38 -0500
committerJohn W. Linville <linville@tuxdriver.com>2012-03-06 15:16:12 -0500
commit65b94a4abfd55b3304be25ffed9832455d41e1dd (patch)
treee022526ae46b74ebbb9305b43097c7dfebe10bc7 /drivers/net
parent2c6ab7ff8fa9af22a2a616656da6e5a0567da285 (diff)
iwlwifi: pass response packet directly
When CMD_WANT_SKB is set for a (synchronous) command, the response is passed back to the caller which is then responsible for freeing it. Make this more abstract with real API, passing directly the response packet in the new cmd.resp_pkt member and also introduce iwl_free_resp() to free the pages -- this way the upper layers don't have to directly touch the page implementation. NOTE: This breaks IDI -- the new code isn't reflected there yet! Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-sta.c6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-scan.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-shared.h5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-testmode.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c16
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans.h13
6 files changed, 28 insertions, 20 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c
index 7a713ba9bde..9ef8da47ad0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c
@@ -160,7 +160,7 @@ int iwl_send_add_sta(struct iwl_priv *priv,
160 /*else the command was successfully sent in SYNC mode, need to free 160 /*else the command was successfully sent in SYNC mode, need to free
161 * the reply page */ 161 * the reply page */
162 162
163 iwl_free_pages(priv->shrd, cmd.reply_page); 163 iwl_free_resp(&cmd);
164 164
165 if (cmd.handler_status) 165 if (cmd.handler_status)
166 IWL_ERR(priv, "%s - error in the CMD response %d", __func__, 166 IWL_ERR(priv, "%s - error in the CMD response %d", __func__,
@@ -415,7 +415,7 @@ static int iwl_send_remove_station(struct iwl_priv *priv,
415 if (ret) 415 if (ret)
416 return ret; 416 return ret;
417 417
418 pkt = (struct iwl_rx_packet *)cmd.reply_page; 418 pkt = cmd.resp_pkt;
419 if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) { 419 if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) {
420 IWL_ERR(priv, "Bad return from REPLY_REMOVE_STA (0x%08X)\n", 420 IWL_ERR(priv, "Bad return from REPLY_REMOVE_STA (0x%08X)\n",
421 pkt->hdr.flags); 421 pkt->hdr.flags);
@@ -438,7 +438,7 @@ static int iwl_send_remove_station(struct iwl_priv *priv,
438 break; 438 break;
439 } 439 }
440 } 440 }
441 iwl_free_pages(priv->shrd, cmd.reply_page); 441 iwl_free_resp(&cmd);
442 442
443 return ret; 443 return ret;
444} 444}
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index 766572b9ac8..c0fc3687a2f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -76,7 +76,7 @@ static int iwl_send_scan_abort(struct iwl_priv *priv)
76 if (ret) 76 if (ret)
77 return ret; 77 return ret;
78 78
79 pkt = (struct iwl_rx_packet *)cmd.reply_page; 79 pkt = cmd.resp_pkt;
80 if (pkt->u.status != CAN_ABORT_STATUS) { 80 if (pkt->u.status != CAN_ABORT_STATUS) {
81 /* The scan abort will return 1 for success or 81 /* The scan abort will return 1 for success or
82 * 2 for "failure". A failure condition can be 82 * 2 for "failure". A failure condition can be
@@ -88,7 +88,7 @@ static int iwl_send_scan_abort(struct iwl_priv *priv)
88 ret = -EIO; 88 ret = -EIO;
89 } 89 }
90 90
91 iwl_free_pages(priv->shrd, cmd.reply_page); 91 iwl_free_resp(&cmd);
92 return ret; 92 return ret;
93} 93}
94 94
diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h
index a7dbcabafc9..53244d88f1a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-shared.h
+++ b/drivers/net/wireless/iwlwifi/iwl-shared.h
@@ -413,11 +413,6 @@ static inline bool iwl_have_debug_level(u32 level)
413 return iwlagn_mod_params.debug_level & level; 413 return iwlagn_mod_params.debug_level & level;
414} 414}
415 415
416static inline void iwl_free_pages(struct iwl_shared *shrd, unsigned long page)
417{
418 free_pages(page, shrd->hw_params.rx_page_order);
419}
420
421/** 416/**
422 * iwl_queue_inc_wrap - increment queue index, wrap back to beginning 417 * iwl_queue_inc_wrap - increment queue index, wrap back to beginning
423 * @index -- current index 418 * @index -- current index
diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.c b/drivers/net/wireless/iwlwifi/iwl-testmode.c
index 23eea06a74a..cc1f3e990ad 100644
--- a/drivers/net/wireless/iwlwifi/iwl-testmode.c
+++ b/drivers/net/wireless/iwlwifi/iwl-testmode.c
@@ -292,7 +292,7 @@ static int iwl_testmode_ucode(struct ieee80211_hw *hw, struct nlattr **tb)
292 return ret; 292 return ret;
293 293
294 /* Handling return of SKB to the user */ 294 /* Handling return of SKB to the user */
295 pkt = (struct iwl_rx_packet *)cmd.reply_page; 295 pkt = cmd.resp_pkt;
296 if (!pkt) { 296 if (!pkt) {
297 IWL_ERR(priv, "HCMD received a null response packet\n"); 297 IWL_ERR(priv, "HCMD received a null response packet\n");
298 return ret; 298 return ret;
@@ -309,7 +309,7 @@ static int iwl_testmode_ucode(struct ieee80211_hw *hw, struct nlattr **tb)
309 309
310 /* The reply is in a page, that we cannot send to user space. */ 310 /* The reply is in a page, that we cannot send to user space. */
311 memcpy(reply_buf, &(pkt->hdr), reply_len); 311 memcpy(reply_buf, &(pkt->hdr), reply_len);
312 iwl_free_pages(priv->shrd, cmd.reply_page); 312 iwl_free_resp(&cmd);
313 313
314 NLA_PUT_U32(skb, IWL_TM_ATTR_COMMAND, IWL_TM_CMD_DEV2APP_UCODE_RX_PKT); 314 NLA_PUT_U32(skb, IWL_TM_ATTR_COMMAND, IWL_TM_CMD_DEV2APP_UCODE_RX_PKT);
315 NLA_PUT(skb, IWL_TM_ATTR_UCODE_RX_PKT, reply_len, reply_buf); 315 NLA_PUT(skb, IWL_TM_ATTR_UCODE_RX_PKT, reply_len, reply_buf);
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c
index de2a0d91d65..771fae2f9fd 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c
@@ -879,9 +879,13 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_mem_buffer *rxb,
879 879
880 /* Input error checking is done when commands are added to queue. */ 880 /* Input error checking is done when commands are added to queue. */
881 if (meta->flags & CMD_WANT_SKB) { 881 if (meta->flags & CMD_WANT_SKB) {
882 meta->source->reply_page = (unsigned long)rxb_addr(rxb); 882 struct page *p = rxb->page;
883 meta->source->handler_status = handler_status; 883
884 rxb->page = NULL; 884 rxb->page = NULL;
885 meta->source->resp_pkt = pkt;
886 meta->source->_rx_page_addr = (unsigned long)page_address(p);
887 meta->source->_rx_page_order = hw_params(trans).rx_page_order;
888 meta->source->handler_status = handler_status;
885 } 889 }
886 890
887 iwl_hcmd_queue_reclaim(trans, txq_id, index); 891 iwl_hcmd_queue_reclaim(trans, txq_id, index);
@@ -985,7 +989,7 @@ static int iwl_send_cmd_sync(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
985 } 989 }
986 } 990 }
987 991
988 if ((cmd->flags & CMD_WANT_SKB) && !cmd->reply_page) { 992 if ((cmd->flags & CMD_WANT_SKB) && !cmd->resp_pkt) {
989 IWL_ERR(trans, "Error: Response NULL in '%s'\n", 993 IWL_ERR(trans, "Error: Response NULL in '%s'\n",
990 get_cmd_string(cmd->id)); 994 get_cmd_string(cmd->id));
991 ret = -EIO; 995 ret = -EIO;
@@ -1006,9 +1010,9 @@ cancel:
1006 ~CMD_WANT_SKB; 1010 ~CMD_WANT_SKB;
1007 } 1011 }
1008 1012
1009 if (cmd->reply_page) { 1013 if (cmd->resp_pkt) {
1010 iwl_free_pages(trans->shrd, cmd->reply_page); 1014 iwl_free_resp(cmd);
1011 cmd->reply_page = 0; 1015 cmd->resp_pkt = NULL;
1012 } 1016 }
1013 1017
1014 return ret; 1018 return ret;
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h
index 83f04c9d77e..e8ab8d8ca48 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/iwlwifi/iwl-trans.h
@@ -173,7 +173,9 @@ enum iwl_hcmd_dataflag {
173 * struct iwl_host_cmd - Host command to the uCode 173 * struct iwl_host_cmd - Host command to the uCode
174 * 174 *
175 * @data: array of chunks that composes the data of the host command 175 * @data: array of chunks that composes the data of the host command
176 * @reply_page: pointer to the page that holds the response to the host command 176 * @resp_pkt: response packet, if %CMD_WANT_SKB was set
177 * @_rx_page_order: (internally used to free response packet)
178 * @_rx_page_addr: (internally used to free response packet)
177 * @handler_status: return value of the handler of the command 179 * @handler_status: return value of the handler of the command
178 * (put in setup_rx_handlers) - valid for SYNC mode only 180 * (put in setup_rx_handlers) - valid for SYNC mode only
179 * @flags: can be CMD_* 181 * @flags: can be CMD_*
@@ -183,7 +185,9 @@ enum iwl_hcmd_dataflag {
183 */ 185 */
184struct iwl_host_cmd { 186struct iwl_host_cmd {
185 const void *data[IWL_MAX_CMD_TFDS]; 187 const void *data[IWL_MAX_CMD_TFDS];
186 unsigned long reply_page; 188 struct iwl_rx_packet *resp_pkt;
189 unsigned long _rx_page_addr;
190 u32 _rx_page_order;
187 int handler_status; 191 int handler_status;
188 192
189 u32 flags; 193 u32 flags;
@@ -192,6 +196,11 @@ struct iwl_host_cmd {
192 u8 id; 196 u8 id;
193}; 197};
194 198
199static inline void iwl_free_resp(struct iwl_host_cmd *cmd)
200{
201 free_pages(cmd->_rx_page_addr, cmd->_rx_page_order);
202}
203
195/** 204/**
196 * struct iwl_trans_ops - transport specific operations 205 * struct iwl_trans_ops - transport specific operations
197 * 206 *