aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2009-07-24 14:13:05 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-07-27 15:24:21 -0400
commitc2acea8e9b86ba5a5469ff477445676a223af4e2 (patch)
tree3c4705b13dd5c85817a1132a17743757135b7047
parentfbf3a2af3834e8e93e9c2876de62c5b49988e352 (diff)
iwlwifi: fix up command sending
The current command sending in iwlwifi is a bit of a mess: 1) there is a struct, iwl_cmd, that contains both driver and device data in a single packed structure -- this is very confusing 2) the on-stack data and the command metadata share a structure by embedding the latter in the former, which is also rather confusing because it leads to weird unions and similarly odd constructs 3) each txq always has enough space for 256 commands, even if only 32 end up being used This patch fixes these things: 1) rename iwl_cmd to iwl_device_cmd and keep track of command metadata and device command separately, in two arrays in each tx queue 2) remove the 'meta' member from iwl_host_cmd and only put in the required members 3) allocate the cmd/meta arrays separately instead of embedding them into the txq structure Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: Reinette Chatre <reinette.chatre@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-led.c6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c18
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.h9
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-calib.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h69
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-hcmd.c48
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-led.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-scan.c8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.c30
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c96
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c20
14 files changed, 180 insertions, 142 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-led.c b/drivers/net/wireless/iwlwifi/iwl-3945-led.c
index 225e5f889346..b37938217f53 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-led.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-led.c
@@ -80,7 +80,7 @@ static const struct {
80#define IWL_SOLID_BLINK_IDX (ARRAY_SIZE(blink_tbl) - 1) 80#define IWL_SOLID_BLINK_IDX (ARRAY_SIZE(blink_tbl) - 1)
81 81
82static int iwl3945_led_cmd_callback(struct iwl_priv *priv, 82static int iwl3945_led_cmd_callback(struct iwl_priv *priv,
83 struct iwl_cmd *cmd, 83 struct iwl_device_cmd *cmd,
84 struct sk_buff *skb) 84 struct sk_buff *skb)
85{ 85{
86 return 1; 86 return 1;
@@ -99,8 +99,8 @@ static int iwl_send_led_cmd(struct iwl_priv *priv,
99 .id = REPLY_LEDS_CMD, 99 .id = REPLY_LEDS_CMD,
100 .len = sizeof(struct iwl_led_cmd), 100 .len = sizeof(struct iwl_led_cmd),
101 .data = led_cmd, 101 .data = led_cmd,
102 .meta.flags = CMD_ASYNC, 102 .flags = CMD_ASYNC,
103 .meta.u.callback = iwl3945_led_cmd_callback, 103 .callback = iwl3945_led_cmd_callback,
104 }; 104 };
105 105
106 return iwl_send_cmd(priv, &cmd); 106 return iwl_send_cmd(priv, &cmd);
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 8ee403cd9b99..e1b0ef3c56a3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -749,8 +749,8 @@ void iwl3945_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq)
749 /* Unmap tx_cmd */ 749 /* Unmap tx_cmd */
750 if (counter) 750 if (counter)
751 pci_unmap_single(dev, 751 pci_unmap_single(dev,
752 pci_unmap_addr(&txq->cmd[index]->meta, mapping), 752 pci_unmap_addr(&txq->meta[index], mapping),
753 pci_unmap_len(&txq->cmd[index]->meta, len), 753 pci_unmap_len(&txq->meta[index], len),
754 PCI_DMA_TODEVICE); 754 PCI_DMA_TODEVICE);
755 755
756 /* unmap chunks if any */ 756 /* unmap chunks if any */
@@ -774,9 +774,11 @@ void iwl3945_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq)
774 * iwl3945_hw_build_tx_cmd_rate - Add rate portion to TX_CMD: 774 * iwl3945_hw_build_tx_cmd_rate - Add rate portion to TX_CMD:
775 * 775 *
776*/ 776*/
777void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv, struct iwl_cmd *cmd, 777void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv,
778 struct ieee80211_tx_info *info, 778 struct iwl_device_cmd *cmd,
779 struct ieee80211_hdr *hdr, int sta_id, int tx_id) 779 struct ieee80211_tx_info *info,
780 struct ieee80211_hdr *hdr,
781 int sta_id, int tx_id)
780{ 782{
781 u16 hw_value = ieee80211_get_tx_rate(priv->hw, info)->hw_value; 783 u16 hw_value = ieee80211_get_tx_rate(priv->hw, info)->hw_value;
782 u16 rate_index = min(hw_value & 0xffff, IWL_RATE_COUNT - 1); 784 u16 rate_index = min(hw_value & 0xffff, IWL_RATE_COUNT - 1);
@@ -1858,7 +1860,7 @@ static int iwl3945_send_rxon_assoc(struct iwl_priv *priv)
1858 struct iwl_host_cmd cmd = { 1860 struct iwl_host_cmd cmd = {
1859 .id = REPLY_RXON_ASSOC, 1861 .id = REPLY_RXON_ASSOC,
1860 .len = sizeof(rxon_assoc), 1862 .len = sizeof(rxon_assoc),
1861 .meta.flags = CMD_WANT_SKB, 1863 .flags = CMD_WANT_SKB,
1862 .data = &rxon_assoc, 1864 .data = &rxon_assoc,
1863 }; 1865 };
1864 const struct iwl_rxon_cmd *rxon1 = &priv->staging_rxon; 1866 const struct iwl_rxon_cmd *rxon1 = &priv->staging_rxon;
@@ -1882,14 +1884,14 @@ static int iwl3945_send_rxon_assoc(struct iwl_priv *priv)
1882 if (rc) 1884 if (rc)
1883 return rc; 1885 return rc;
1884 1886
1885 res = (struct iwl_rx_packet *)cmd.meta.u.skb->data; 1887 res = (struct iwl_rx_packet *)cmd.reply_skb->data;
1886 if (res->hdr.flags & IWL_CMD_FAILED_MSK) { 1888 if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
1887 IWL_ERR(priv, "Bad return from REPLY_RXON_ASSOC command\n"); 1889 IWL_ERR(priv, "Bad return from REPLY_RXON_ASSOC command\n");
1888 rc = -EIO; 1890 rc = -EIO;
1889 } 1891 }
1890 1892
1891 priv->alloc_rxb_skb--; 1893 priv->alloc_rxb_skb--;
1892 dev_kfree_skb_any(cmd.meta.u.skb); 1894 dev_kfree_skb_any(cmd.reply_skb);
1893 1895
1894 return rc; 1896 return rc;
1895} 1897}
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h
index f2ffc48cbaf8..f24036909916 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.h
@@ -254,10 +254,11 @@ extern int iwl3945_hw_tx_queue_init(struct iwl_priv *priv,
254 struct iwl_tx_queue *txq); 254 struct iwl_tx_queue *txq);
255extern unsigned int iwl3945_hw_get_beacon_cmd(struct iwl_priv *priv, 255extern unsigned int iwl3945_hw_get_beacon_cmd(struct iwl_priv *priv,
256 struct iwl3945_frame *frame, u8 rate); 256 struct iwl3945_frame *frame, u8 rate);
257void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv, struct iwl_cmd *cmd, 257void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv,
258 struct ieee80211_tx_info *info, 258 struct iwl_device_cmd *cmd,
259 struct ieee80211_hdr *hdr, 259 struct ieee80211_tx_info *info,
260 int sta_id, int tx_id); 260 struct ieee80211_hdr *hdr,
261 int sta_id, int tx_id);
261extern int iwl3945_hw_reg_send_txpower(struct iwl_priv *priv); 262extern int iwl3945_hw_reg_send_txpower(struct iwl_priv *priv);
262extern int iwl3945_hw_reg_set_txpower(struct iwl_priv *priv, s8 power); 263extern int iwl3945_hw_reg_set_txpower(struct iwl_priv *priv, s8 power);
263extern void iwl3945_hw_rx_statistics(struct iwl_priv *priv, 264extern void iwl3945_hw_rx_statistics(struct iwl_priv *priv,
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 23ae9914c84b..4cb1a1b73483 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -442,8 +442,8 @@ void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq)
442 /* Unmap tx_cmd */ 442 /* Unmap tx_cmd */
443 if (num_tbs) 443 if (num_tbs)
444 pci_unmap_single(dev, 444 pci_unmap_single(dev,
445 pci_unmap_addr(&txq->cmd[index]->meta, mapping), 445 pci_unmap_addr(&txq->meta[index], mapping),
446 pci_unmap_len(&txq->cmd[index]->meta, len), 446 pci_unmap_len(&txq->meta[index], len),
447 PCI_DMA_BIDIRECTIONAL); 447 PCI_DMA_BIDIRECTIONAL);
448 448
449 /* Unmap chunks, if any. */ 449 /* Unmap chunks, if any. */
diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.c b/drivers/net/wireless/iwlwifi/iwl-calib.c
index f8bf592e939c..13180d6ee2f7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-calib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-calib.c
@@ -86,7 +86,7 @@ int iwl_send_calib_results(struct iwl_priv *priv)
86 86
87 struct iwl_host_cmd hcmd = { 87 struct iwl_host_cmd hcmd = {
88 .id = REPLY_PHY_CALIBRATION_CMD, 88 .id = REPLY_PHY_CALIBRATION_CMD,
89 .meta.flags = CMD_SIZE_HUGE, 89 .flags = CMD_SIZE_HUGE,
90 }; 90 };
91 91
92 for (i = 0; i < IWL_CALIB_MAX; i++) { 92 for (i = 0; i < IWL_CALIB_MAX; i++) {
@@ -419,7 +419,7 @@ static int iwl_sensitivity_write(struct iwl_priv *priv)
419 struct iwl_host_cmd cmd_out = { 419 struct iwl_host_cmd cmd_out = {
420 .id = SENSITIVITY_CMD, 420 .id = SENSITIVITY_CMD,
421 .len = sizeof(struct iwl_sensitivity_cmd), 421 .len = sizeof(struct iwl_sensitivity_cmd),
422 .meta.flags = CMD_ASYNC, 422 .flags = CMD_ASYNC,
423 .data = &cmd, 423 .data = &cmd,
424 }; 424 };
425 425
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index d8aeb24db90a..710dd41c3418 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -2089,7 +2089,7 @@ int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags)
2089 u32 stat_flags = 0; 2089 u32 stat_flags = 0;
2090 struct iwl_host_cmd cmd = { 2090 struct iwl_host_cmd cmd = {
2091 .id = REPLY_STATISTICS_CMD, 2091 .id = REPLY_STATISTICS_CMD,
2092 .meta.flags = flags, 2092 .flags = flags,
2093 .len = sizeof(stat_flags), 2093 .len = sizeof(stat_flags),
2094 .data = (u8 *) &stat_flags, 2094 .data = (u8 *) &stat_flags,
2095 }; 2095 };
@@ -2282,7 +2282,7 @@ int iwl_send_card_state(struct iwl_priv *priv, u32 flags, u8 meta_flag)
2282 .id = REPLY_CARD_STATE_CMD, 2282 .id = REPLY_CARD_STATE_CMD,
2283 .len = sizeof(u32), 2283 .len = sizeof(u32),
2284 .data = &flags, 2284 .data = &flags,
2285 .meta.flags = meta_flag, 2285 .flags = meta_flag,
2286 }; 2286 };
2287 2287
2288 return iwl_send_cmd(priv, &cmd); 2288 return iwl_send_cmd(priv, &cmd);
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 614ec7cc5b31..4156debec39c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -447,7 +447,7 @@ int __must_check iwl_send_cmd_pdu(struct iwl_priv *priv, u8 id,
447int iwl_send_cmd_pdu_async(struct iwl_priv *priv, u8 id, u16 len, 447int iwl_send_cmd_pdu_async(struct iwl_priv *priv, u8 id, u16 len,
448 const void *data, 448 const void *data,
449 int (*callback)(struct iwl_priv *priv, 449 int (*callback)(struct iwl_priv *priv,
450 struct iwl_cmd *cmd, 450 struct iwl_device_cmd *cmd,
451 struct sk_buff *skb)); 451 struct sk_buff *skb));
452 452
453int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd); 453int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd);
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index cddf17350c4b..ce765f79275a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -150,6 +150,31 @@ struct iwl_rx_mem_buffer {
150 struct list_head list; 150 struct list_head list;
151}; 151};
152 152
153/* defined below */
154struct iwl_device_cmd;
155
156struct iwl_cmd_meta {
157 /* only for SYNC commands, iff the reply skb is wanted */
158 struct iwl_host_cmd *source;
159 /*
160 * only for ASYNC commands
161 * (which is somewhat stupid -- look at iwl-sta.c for instance
162 * which duplicates a bunch of code because the callback isn't
163 * invoked for SYNC commands, if it were and its result passed
164 * through it would be simpler...)
165 */
166 int (*callback)(struct iwl_priv *priv,
167 struct iwl_device_cmd *cmd,
168 struct sk_buff *skb);
169
170 /* The CMD_SIZE_HUGE flag bit indicates that the command
171 * structure is stored at the end of the shared queue memory. */
172 u32 flags;
173
174 DECLARE_PCI_UNMAP_ADDR(mapping)
175 DECLARE_PCI_UNMAP_LEN(len)
176};
177
153/* 178/*
154 * Generic queue structure 179 * Generic queue structure
155 * 180 *
@@ -177,7 +202,8 @@ struct iwl_tx_info {
177 * struct iwl_tx_queue - Tx Queue for DMA 202 * struct iwl_tx_queue - Tx Queue for DMA
178 * @q: generic Rx/Tx queue descriptor 203 * @q: generic Rx/Tx queue descriptor
179 * @bd: base of circular buffer of TFDs 204 * @bd: base of circular buffer of TFDs
180 * @cmd: array of command/Tx buffers 205 * @cmd: array of command/TX buffer pointers
206 * @meta: array of meta data for each command/tx buffer
181 * @dma_addr_cmd: physical address of cmd/tx buffer array 207 * @dma_addr_cmd: physical address of cmd/tx buffer array
182 * @txb: array of per-TFD driver data 208 * @txb: array of per-TFD driver data
183 * @need_update: indicates need to update read/write index 209 * @need_update: indicates need to update read/write index
@@ -192,7 +218,8 @@ struct iwl_tx_info {
192struct iwl_tx_queue { 218struct iwl_tx_queue {
193 struct iwl_queue q; 219 struct iwl_queue q;
194 void *tfds; 220 void *tfds;
195 struct iwl_cmd *cmd[TFD_TX_CMD_SLOTS]; 221 struct iwl_device_cmd **cmd;
222 struct iwl_cmd_meta *meta;
196 struct iwl_tx_info *txb; 223 struct iwl_tx_info *txb;
197 u8 need_update; 224 u8 need_update;
198 u8 sched_retry; 225 u8 sched_retry;
@@ -329,35 +356,16 @@ enum {
329 CMD_WANT_SKB = (1 << 2), 356 CMD_WANT_SKB = (1 << 2),
330}; 357};
331 358
332struct iwl_cmd;
333struct iwl_priv;
334
335struct iwl_cmd_meta {
336 struct iwl_cmd_meta *source;
337 union {
338 struct sk_buff *skb;
339 int (*callback)(struct iwl_priv *priv,
340 struct iwl_cmd *cmd, struct sk_buff *skb);
341 } __attribute__ ((packed)) u;
342
343 /* The CMD_SIZE_HUGE flag bit indicates that the command
344 * structure is stored at the end of the shared queue memory. */
345 u32 flags;
346 DECLARE_PCI_UNMAP_ADDR(mapping)
347 DECLARE_PCI_UNMAP_LEN(len)
348} __attribute__ ((packed));
349
350#define IWL_CMD_MAX_PAYLOAD 320 359#define IWL_CMD_MAX_PAYLOAD 320
351 360
352/** 361/**
353 * struct iwl_cmd 362 * struct iwl_device_cmd
354 * 363 *
355 * For allocation of the command and tx queues, this establishes the overall 364 * For allocation of the command and tx queues, this establishes the overall
356 * size of the largest command we send to uCode, except for a scan command 365 * size of the largest command we send to uCode, except for a scan command
357 * (which is relatively huge; space is allocated separately). 366 * (which is relatively huge; space is allocated separately).
358 */ 367 */
359struct iwl_cmd { 368struct iwl_device_cmd {
360 struct iwl_cmd_meta meta; /* driver data */
361 struct iwl_cmd_header hdr; /* uCode API */ 369 struct iwl_cmd_header hdr; /* uCode API */
362 union { 370 union {
363 u32 flags; 371 u32 flags;
@@ -369,17 +377,20 @@ struct iwl_cmd {
369 } __attribute__ ((packed)) cmd; 377 } __attribute__ ((packed)) cmd;
370} __attribute__ ((packed)); 378} __attribute__ ((packed));
371 379
380#define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl_device_cmd))
381
372 382
373struct iwl_host_cmd { 383struct iwl_host_cmd {
374 u8 id;
375 u16 len;
376 struct iwl_cmd_meta meta;
377 const void *data; 384 const void *data;
385 struct sk_buff *reply_skb;
386 int (*callback)(struct iwl_priv *priv,
387 struct iwl_device_cmd *cmd,
388 struct sk_buff *skb);
389 u32 flags;
390 u16 len;
391 u8 id;
378}; 392};
379 393
380#define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl_cmd) - \
381 sizeof(struct iwl_cmd_meta))
382
383/* 394/*
384 * RX related structures and functions 395 * RX related structures and functions
385 */ 396 */
diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c
index 17d61ac8ed61..d8a3eac8ceb7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c
+++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c
@@ -104,7 +104,8 @@ EXPORT_SYMBOL(get_cmd_string);
104#define HOST_COMPLETE_TIMEOUT (HZ / 2) 104#define HOST_COMPLETE_TIMEOUT (HZ / 2)
105 105
106static int iwl_generic_cmd_callback(struct iwl_priv *priv, 106static int iwl_generic_cmd_callback(struct iwl_priv *priv,
107 struct iwl_cmd *cmd, struct sk_buff *skb) 107 struct iwl_device_cmd *cmd,
108 struct sk_buff *skb)
108{ 109{
109 struct iwl_rx_packet *pkt = NULL; 110 struct iwl_rx_packet *pkt = NULL;
110 111
@@ -142,14 +143,14 @@ static int iwl_send_cmd_async(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
142{ 143{
143 int ret; 144 int ret;
144 145
145 BUG_ON(!(cmd->meta.flags & CMD_ASYNC)); 146 BUG_ON(!(cmd->flags & CMD_ASYNC));
146 147
147 /* An asynchronous command can not expect an SKB to be set. */ 148 /* An asynchronous command can not expect an SKB to be set. */
148 BUG_ON(cmd->meta.flags & CMD_WANT_SKB); 149 BUG_ON(cmd->flags & CMD_WANT_SKB);
149 150
150 /* Assign a generic callback if one is not provided */ 151 /* Assign a generic callback if one is not provided */
151 if (!cmd->meta.u.callback) 152 if (!cmd->callback)
152 cmd->meta.u.callback = iwl_generic_cmd_callback; 153 cmd->callback = iwl_generic_cmd_callback;
153 154
154 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 155 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
155 return -EBUSY; 156 return -EBUSY;
@@ -168,10 +169,10 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
168 int cmd_idx; 169 int cmd_idx;
169 int ret; 170 int ret;
170 171
171 BUG_ON(cmd->meta.flags & CMD_ASYNC); 172 BUG_ON(cmd->flags & CMD_ASYNC);
172 173
173 /* A synchronous command can not have a callback set. */ 174 /* A synchronous command can not have a callback set. */
174 BUG_ON(cmd->meta.u.callback != NULL); 175 BUG_ON(cmd->callback);
175 176
176 if (test_and_set_bit(STATUS_HCMD_SYNC_ACTIVE, &priv->status)) { 177 if (test_and_set_bit(STATUS_HCMD_SYNC_ACTIVE, &priv->status)) {
177 IWL_ERR(priv, 178 IWL_ERR(priv,
@@ -183,9 +184,6 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
183 184
184 set_bit(STATUS_HCMD_ACTIVE, &priv->status); 185 set_bit(STATUS_HCMD_ACTIVE, &priv->status);
185 186
186 if (cmd->meta.flags & CMD_WANT_SKB)
187 cmd->meta.source = &cmd->meta;
188
189 cmd_idx = iwl_enqueue_hcmd(priv, cmd); 187 cmd_idx = iwl_enqueue_hcmd(priv, cmd);
190 if (cmd_idx < 0) { 188 if (cmd_idx < 0) {
191 ret = cmd_idx; 189 ret = cmd_idx;
@@ -222,7 +220,7 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
222 ret = -EIO; 220 ret = -EIO;
223 goto fail; 221 goto fail;
224 } 222 }
225 if ((cmd->meta.flags & CMD_WANT_SKB) && !cmd->meta.u.skb) { 223 if ((cmd->flags & CMD_WANT_SKB) && !cmd->reply_skb) {
226 IWL_ERR(priv, "Error: Response NULL in '%s'\n", 224 IWL_ERR(priv, "Error: Response NULL in '%s'\n",
227 get_cmd_string(cmd->id)); 225 get_cmd_string(cmd->id));
228 ret = -EIO; 226 ret = -EIO;
@@ -233,20 +231,20 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
233 goto out; 231 goto out;
234 232
235cancel: 233cancel:
236 if (cmd->meta.flags & CMD_WANT_SKB) { 234 if (cmd->flags & CMD_WANT_SKB) {
237 struct iwl_cmd *qcmd; 235 /*
238 236 * Cancel the CMD_WANT_SKB flag for the cmd in the
239 /* Cancel the CMD_WANT_SKB flag for the cmd in the
240 * TX cmd queue. Otherwise in case the cmd comes 237 * TX cmd queue. Otherwise in case the cmd comes
241 * in later, it will possibly set an invalid 238 * in later, it will possibly set an invalid
242 * address (cmd->meta.source). */ 239 * address (cmd->meta.source).
243 qcmd = priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_idx]; 240 */
244 qcmd->meta.flags &= ~CMD_WANT_SKB; 241 priv->txq[IWL_CMD_QUEUE_NUM].meta[cmd_idx].flags &=
242 ~CMD_WANT_SKB;
245 } 243 }
246fail: 244fail:
247 if (cmd->meta.u.skb) { 245 if (cmd->reply_skb) {
248 dev_kfree_skb_any(cmd->meta.u.skb); 246 dev_kfree_skb_any(cmd->reply_skb);
249 cmd->meta.u.skb = NULL; 247 cmd->reply_skb = NULL;
250 } 248 }
251out: 249out:
252 clear_bit(STATUS_HCMD_SYNC_ACTIVE, &priv->status); 250 clear_bit(STATUS_HCMD_SYNC_ACTIVE, &priv->status);
@@ -256,7 +254,7 @@ EXPORT_SYMBOL(iwl_send_cmd_sync);
256 254
257int iwl_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) 255int iwl_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
258{ 256{
259 if (cmd->meta.flags & CMD_ASYNC) 257 if (cmd->flags & CMD_ASYNC)
260 return iwl_send_cmd_async(priv, cmd); 258 return iwl_send_cmd_async(priv, cmd);
261 259
262 return iwl_send_cmd_sync(priv, cmd); 260 return iwl_send_cmd_sync(priv, cmd);
@@ -278,7 +276,7 @@ EXPORT_SYMBOL(iwl_send_cmd_pdu);
278int iwl_send_cmd_pdu_async(struct iwl_priv *priv, 276int iwl_send_cmd_pdu_async(struct iwl_priv *priv,
279 u8 id, u16 len, const void *data, 277 u8 id, u16 len, const void *data,
280 int (*callback)(struct iwl_priv *priv, 278 int (*callback)(struct iwl_priv *priv,
281 struct iwl_cmd *cmd, 279 struct iwl_device_cmd *cmd,
282 struct sk_buff *skb)) 280 struct sk_buff *skb))
283{ 281{
284 struct iwl_host_cmd cmd = { 282 struct iwl_host_cmd cmd = {
@@ -287,8 +285,8 @@ int iwl_send_cmd_pdu_async(struct iwl_priv *priv,
287 .data = data, 285 .data = data,
288 }; 286 };
289 287
290 cmd.meta.flags |= CMD_ASYNC; 288 cmd.flags |= CMD_ASYNC;
291 cmd.meta.u.callback = callback; 289 cmd.callback = callback;
292 290
293 return iwl_send_cmd_async(priv, &cmd); 291 return iwl_send_cmd_async(priv, &cmd);
294} 292}
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c
index 8c8115293b3c..7cce8f85bcc6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-led.c
+++ b/drivers/net/wireless/iwlwifi/iwl-led.c
@@ -91,8 +91,8 @@ static int iwl_send_led_cmd(struct iwl_priv *priv, struct iwl_led_cmd *led_cmd)
91 .id = REPLY_LEDS_CMD, 91 .id = REPLY_LEDS_CMD,
92 .len = sizeof(struct iwl_led_cmd), 92 .len = sizeof(struct iwl_led_cmd),
93 .data = led_cmd, 93 .data = led_cmd,
94 .meta.flags = CMD_ASYNC, 94 .flags = CMD_ASYNC,
95 .meta.u.callback = NULL, 95 .callback = NULL,
96 }; 96 };
97 u32 reg; 97 u32 reg;
98 98
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index 00398d973a07..c4c916df4a43 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -115,7 +115,7 @@ static int iwl_send_scan_abort(struct iwl_priv *priv)
115 struct iwl_rx_packet *res; 115 struct iwl_rx_packet *res;
116 struct iwl_host_cmd cmd = { 116 struct iwl_host_cmd cmd = {
117 .id = REPLY_SCAN_ABORT_CMD, 117 .id = REPLY_SCAN_ABORT_CMD,
118 .meta.flags = CMD_WANT_SKB, 118 .flags = CMD_WANT_SKB,
119 }; 119 };
120 120
121 /* If there isn't a scan actively going on in the hardware 121 /* If there isn't a scan actively going on in the hardware
@@ -132,7 +132,7 @@ static int iwl_send_scan_abort(struct iwl_priv *priv)
132 return ret; 132 return ret;
133 } 133 }
134 134
135 res = (struct iwl_rx_packet *)cmd.meta.u.skb->data; 135 res = (struct iwl_rx_packet *)cmd.reply_skb->data;
136 if (res->u.status != CAN_ABORT_STATUS) { 136 if (res->u.status != CAN_ABORT_STATUS) {
137 /* The scan abort will return 1 for success or 137 /* The scan abort will return 1 for success or
138 * 2 for "failure". A failure condition can be 138 * 2 for "failure". A failure condition can be
@@ -146,7 +146,7 @@ static int iwl_send_scan_abort(struct iwl_priv *priv)
146 } 146 }
147 147
148 priv->alloc_rxb_skb--; 148 priv->alloc_rxb_skb--;
149 dev_kfree_skb_any(cmd.meta.u.skb); 149 dev_kfree_skb_any(cmd.reply_skb);
150 150
151 return ret; 151 return ret;
152} 152}
@@ -567,7 +567,7 @@ static void iwl_bg_request_scan(struct work_struct *data)
567 struct iwl_host_cmd cmd = { 567 struct iwl_host_cmd cmd = {
568 .id = REPLY_SCAN_CMD, 568 .id = REPLY_SCAN_CMD,
569 .len = sizeof(struct iwl_scan_cmd), 569 .len = sizeof(struct iwl_scan_cmd),
570 .meta.flags = CMD_SIZE_HUGE, 570 .flags = CMD_SIZE_HUGE,
571 }; 571 };
572 struct iwl_scan_cmd *scan; 572 struct iwl_scan_cmd *scan;
573 struct ieee80211_conf *conf = NULL; 573 struct ieee80211_conf *conf = NULL;
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index cbe4e26d053f..1571ace05dde 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -98,7 +98,8 @@ static void iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id)
98} 98}
99 99
100static int iwl_add_sta_callback(struct iwl_priv *priv, 100static int iwl_add_sta_callback(struct iwl_priv *priv,
101 struct iwl_cmd *cmd, struct sk_buff *skb) 101 struct iwl_device_cmd *cmd,
102 struct sk_buff *skb)
102{ 103{
103 struct iwl_rx_packet *res = NULL; 104 struct iwl_rx_packet *res = NULL;
104 struct iwl_addsta_cmd *addsta = 105 struct iwl_addsta_cmd *addsta =
@@ -139,14 +140,14 @@ int iwl_send_add_sta(struct iwl_priv *priv,
139 u8 data[sizeof(*sta)]; 140 u8 data[sizeof(*sta)];
140 struct iwl_host_cmd cmd = { 141 struct iwl_host_cmd cmd = {
141 .id = REPLY_ADD_STA, 142 .id = REPLY_ADD_STA,
142 .meta.flags = flags, 143 .flags = flags,
143 .data = data, 144 .data = data,
144 }; 145 };
145 146
146 if (flags & CMD_ASYNC) 147 if (flags & CMD_ASYNC)
147 cmd.meta.u.callback = iwl_add_sta_callback; 148 cmd.callback = iwl_add_sta_callback;
148 else 149 else
149 cmd.meta.flags |= CMD_WANT_SKB; 150 cmd.flags |= CMD_WANT_SKB;
150 151
151 cmd.len = priv->cfg->ops->utils->build_addsta_hcmd(sta, data); 152 cmd.len = priv->cfg->ops->utils->build_addsta_hcmd(sta, data);
152 ret = iwl_send_cmd(priv, &cmd); 153 ret = iwl_send_cmd(priv, &cmd);
@@ -154,7 +155,7 @@ int iwl_send_add_sta(struct iwl_priv *priv,
154 if (ret || (flags & CMD_ASYNC)) 155 if (ret || (flags & CMD_ASYNC))
155 return ret; 156 return ret;
156 157
157 res = (struct iwl_rx_packet *)cmd.meta.u.skb->data; 158 res = (struct iwl_rx_packet *)cmd.reply_skb->data;
158 if (res->hdr.flags & IWL_CMD_FAILED_MSK) { 159 if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
159 IWL_ERR(priv, "Bad return from REPLY_ADD_STA (0x%08X)\n", 160 IWL_ERR(priv, "Bad return from REPLY_ADD_STA (0x%08X)\n",
160 res->hdr.flags); 161 res->hdr.flags);
@@ -175,7 +176,7 @@ int iwl_send_add_sta(struct iwl_priv *priv,
175 } 176 }
176 177
177 priv->alloc_rxb_skb--; 178 priv->alloc_rxb_skb--;
178 dev_kfree_skb_any(cmd.meta.u.skb); 179 dev_kfree_skb_any(cmd.reply_skb);
179 180
180 return ret; 181 return ret;
181} 182}
@@ -325,7 +326,8 @@ static void iwl_sta_ucode_deactivate(struct iwl_priv *priv, const char *addr)
325} 326}
326 327
327static int iwl_remove_sta_callback(struct iwl_priv *priv, 328static int iwl_remove_sta_callback(struct iwl_priv *priv,
328 struct iwl_cmd *cmd, struct sk_buff *skb) 329 struct iwl_device_cmd *cmd,
330 struct sk_buff *skb)
329{ 331{
330 struct iwl_rx_packet *res = NULL; 332 struct iwl_rx_packet *res = NULL;
331 struct iwl_rem_sta_cmd *rm_sta = 333 struct iwl_rem_sta_cmd *rm_sta =
@@ -368,7 +370,7 @@ static int iwl_send_remove_station(struct iwl_priv *priv, const u8 *addr,
368 struct iwl_host_cmd cmd = { 370 struct iwl_host_cmd cmd = {
369 .id = REPLY_REMOVE_STA, 371 .id = REPLY_REMOVE_STA,
370 .len = sizeof(struct iwl_rem_sta_cmd), 372 .len = sizeof(struct iwl_rem_sta_cmd),
371 .meta.flags = flags, 373 .flags = flags,
372 .data = &rm_sta_cmd, 374 .data = &rm_sta_cmd,
373 }; 375 };
374 376
@@ -377,15 +379,15 @@ static int iwl_send_remove_station(struct iwl_priv *priv, const u8 *addr,
377 memcpy(&rm_sta_cmd.addr, addr , ETH_ALEN); 379 memcpy(&rm_sta_cmd.addr, addr , ETH_ALEN);
378 380
379 if (flags & CMD_ASYNC) 381 if (flags & CMD_ASYNC)
380 cmd.meta.u.callback = iwl_remove_sta_callback; 382 cmd.callback = iwl_remove_sta_callback;
381 else 383 else
382 cmd.meta.flags |= CMD_WANT_SKB; 384 cmd.flags |= CMD_WANT_SKB;
383 ret = iwl_send_cmd(priv, &cmd); 385 ret = iwl_send_cmd(priv, &cmd);
384 386
385 if (ret || (flags & CMD_ASYNC)) 387 if (ret || (flags & CMD_ASYNC))
386 return ret; 388 return ret;
387 389
388 res = (struct iwl_rx_packet *)cmd.meta.u.skb->data; 390 res = (struct iwl_rx_packet *)cmd.reply_skb->data;
389 if (res->hdr.flags & IWL_CMD_FAILED_MSK) { 391 if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
390 IWL_ERR(priv, "Bad return from REPLY_REMOVE_STA (0x%08X)\n", 392 IWL_ERR(priv, "Bad return from REPLY_REMOVE_STA (0x%08X)\n",
391 res->hdr.flags); 393 res->hdr.flags);
@@ -406,7 +408,7 @@ static int iwl_send_remove_station(struct iwl_priv *priv, const u8 *addr,
406 } 408 }
407 409
408 priv->alloc_rxb_skb--; 410 priv->alloc_rxb_skb--;
409 dev_kfree_skb_any(cmd.meta.u.skb); 411 dev_kfree_skb_any(cmd.reply_skb);
410 412
411 return ret; 413 return ret;
412} 414}
@@ -525,7 +527,7 @@ int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty)
525 struct iwl_host_cmd cmd = { 527 struct iwl_host_cmd cmd = {
526 .id = REPLY_WEPKEY, 528 .id = REPLY_WEPKEY,
527 .data = wep_cmd, 529 .data = wep_cmd,
528 .meta.flags = CMD_ASYNC, 530 .flags = CMD_ASYNC,
529 }; 531 };
530 532
531 memset(wep_cmd, 0, cmd_size + 533 memset(wep_cmd, 0, cmd_size +
@@ -930,7 +932,7 @@ int iwl_send_lq_cmd(struct iwl_priv *priv,
930 struct iwl_host_cmd cmd = { 932 struct iwl_host_cmd cmd = {
931 .id = REPLY_TX_LINK_QUALITY_CMD, 933 .id = REPLY_TX_LINK_QUALITY_CMD,
932 .len = sizeof(struct iwl_link_quality_cmd), 934 .len = sizeof(struct iwl_link_quality_cmd),
933 .meta.flags = flags, 935 .flags = flags,
934 .data = lq, 936 .data = lq,
935 }; 937 };
936 938
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index 0912987af603..51ddbab63c23 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -141,7 +141,7 @@ void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id)
141 q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) 141 q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd))
142 priv->cfg->ops->lib->txq_free_tfd(priv, txq); 142 priv->cfg->ops->lib->txq_free_tfd(priv, txq);
143 143
144 len = sizeof(struct iwl_cmd) * q->n_window; 144 len = sizeof(struct iwl_device_cmd) * q->n_window;
145 145
146 /* De-alloc array of command/tx buffers */ 146 /* De-alloc array of command/tx buffers */
147 for (i = 0; i < TFD_TX_CMD_SLOTS; i++) 147 for (i = 0; i < TFD_TX_CMD_SLOTS; i++)
@@ -156,6 +156,12 @@ void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id)
156 kfree(txq->txb); 156 kfree(txq->txb);
157 txq->txb = NULL; 157 txq->txb = NULL;
158 158
159 /* deallocate arrays */
160 kfree(txq->cmd);
161 kfree(txq->meta);
162 txq->cmd = NULL;
163 txq->meta = NULL;
164
159 /* 0-fill queue descriptor structure */ 165 /* 0-fill queue descriptor structure */
160 memset(txq, 0, sizeof(*txq)); 166 memset(txq, 0, sizeof(*txq));
161} 167}
@@ -179,7 +185,7 @@ void iwl_cmd_queue_free(struct iwl_priv *priv)
179 if (q->n_bd == 0) 185 if (q->n_bd == 0)
180 return; 186 return;
181 187
182 len = sizeof(struct iwl_cmd) * q->n_window; 188 len = sizeof(struct iwl_device_cmd) * q->n_window;
183 len += IWL_MAX_SCAN_SIZE; 189 len += IWL_MAX_SCAN_SIZE;
184 190
185 /* De-alloc array of command/tx buffers */ 191 /* De-alloc array of command/tx buffers */
@@ -318,6 +324,7 @@ int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
318{ 324{
319 int i, len; 325 int i, len;
320 int ret; 326 int ret;
327 int actual_slots = slots_num;
321 328
322 /* 329 /*
323 * Alloc buffer array for commands (Tx or other types of commands). 330 * Alloc buffer array for commands (Tx or other types of commands).
@@ -327,14 +334,22 @@ int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
327 * For normal Tx queues (all other queues), no super-size command 334 * For normal Tx queues (all other queues), no super-size command
328 * space is needed. 335 * space is needed.
329 */ 336 */
330 len = sizeof(struct iwl_cmd); 337 if (txq_id == IWL_CMD_QUEUE_NUM)
331 for (i = 0; i <= slots_num; i++) { 338 actual_slots++;
332 if (i == slots_num) { 339
333 if (txq_id == IWL_CMD_QUEUE_NUM) 340 txq->meta = kzalloc(sizeof(struct iwl_cmd_meta) * actual_slots,
334 len += IWL_MAX_SCAN_SIZE; 341 GFP_KERNEL);
335 else 342 txq->cmd = kzalloc(sizeof(struct iwl_device_cmd *) * actual_slots,
336 continue; 343 GFP_KERNEL);
337 } 344
345 if (!txq->meta || !txq->cmd)
346 goto out_free_arrays;
347
348 len = sizeof(struct iwl_device_cmd);
349 for (i = 0; i < actual_slots; i++) {
350 /* only happens for cmd queue */
351 if (i == slots_num)
352 len += IWL_MAX_SCAN_SIZE;
338 353
339 txq->cmd[i] = kmalloc(len, GFP_KERNEL); 354 txq->cmd[i] = kmalloc(len, GFP_KERNEL);
340 if (!txq->cmd[i]) 355 if (!txq->cmd[i])
@@ -364,15 +379,12 @@ int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
364 379
365 return 0; 380 return 0;
366err: 381err:
367 for (i = 0; i < slots_num; i++) { 382 for (i = 0; i < actual_slots; i++)
368 kfree(txq->cmd[i]); 383 kfree(txq->cmd[i]);
369 txq->cmd[i] = NULL; 384out_free_arrays:
370 } 385 kfree(txq->meta);
386 kfree(txq->cmd);
371 387
372 if (txq_id == IWL_CMD_QUEUE_NUM) {
373 kfree(txq->cmd[slots_num]);
374 txq->cmd[slots_num] = NULL;
375 }
376 return -ENOMEM; 388 return -ENOMEM;
377} 389}
378EXPORT_SYMBOL(iwl_tx_queue_init); 390EXPORT_SYMBOL(iwl_tx_queue_init);
@@ -673,7 +685,8 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
673 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 685 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
674 struct iwl_tx_queue *txq; 686 struct iwl_tx_queue *txq;
675 struct iwl_queue *q; 687 struct iwl_queue *q;
676 struct iwl_cmd *out_cmd; 688 struct iwl_device_cmd *out_cmd;
689 struct iwl_cmd_meta *out_meta;
677 struct iwl_tx_cmd *tx_cmd; 690 struct iwl_tx_cmd *tx_cmd;
678 int swq_id, txq_id; 691 int swq_id, txq_id;
679 dma_addr_t phys_addr; 692 dma_addr_t phys_addr;
@@ -766,6 +779,7 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
766 779
767 /* Set up first empty entry in queue's array of Tx/cmd buffers */ 780 /* Set up first empty entry in queue's array of Tx/cmd buffers */
768 out_cmd = txq->cmd[q->write_ptr]; 781 out_cmd = txq->cmd[q->write_ptr];
782 out_meta = &txq->meta[q->write_ptr];
769 tx_cmd = &out_cmd->cmd.tx; 783 tx_cmd = &out_cmd->cmd.tx;
770 memset(&out_cmd->hdr, 0, sizeof(out_cmd->hdr)); 784 memset(&out_cmd->hdr, 0, sizeof(out_cmd->hdr));
771 memset(tx_cmd, 0, sizeof(struct iwl_tx_cmd)); 785 memset(tx_cmd, 0, sizeof(struct iwl_tx_cmd));
@@ -828,8 +842,8 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
828 txcmd_phys = pci_map_single(priv->pci_dev, 842 txcmd_phys = pci_map_single(priv->pci_dev,
829 &out_cmd->hdr, len, 843 &out_cmd->hdr, len,
830 PCI_DMA_BIDIRECTIONAL); 844 PCI_DMA_BIDIRECTIONAL);
831 pci_unmap_addr_set(&out_cmd->meta, mapping, txcmd_phys); 845 pci_unmap_addr_set(out_meta, mapping, txcmd_phys);
832 pci_unmap_len_set(&out_cmd->meta, len, len); 846 pci_unmap_len_set(out_meta, len, len);
833 /* Add buffer containing Tx command and MAC(!) header to TFD's 847 /* Add buffer containing Tx command and MAC(!) header to TFD's
834 * first entry */ 848 * first entry */
835 priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq, 849 priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
@@ -923,7 +937,8 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
923{ 937{
924 struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM]; 938 struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM];
925 struct iwl_queue *q = &txq->q; 939 struct iwl_queue *q = &txq->q;
926 struct iwl_cmd *out_cmd; 940 struct iwl_device_cmd *out_cmd;
941 struct iwl_cmd_meta *out_meta;
927 dma_addr_t phys_addr; 942 dma_addr_t phys_addr;
928 unsigned long flags; 943 unsigned long flags;
929 int len, ret; 944 int len, ret;
@@ -937,25 +952,31 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
937 * the TFD_MAX_PAYLOAD_SIZE, and it sent as a 'small' command then 952 * the TFD_MAX_PAYLOAD_SIZE, and it sent as a 'small' command then
938 * we will need to increase the size of the TFD entries */ 953 * we will need to increase the size of the TFD entries */
939 BUG_ON((fix_size > TFD_MAX_PAYLOAD_SIZE) && 954 BUG_ON((fix_size > TFD_MAX_PAYLOAD_SIZE) &&
940 !(cmd->meta.flags & CMD_SIZE_HUGE)); 955 !(cmd->flags & CMD_SIZE_HUGE));
941 956
942 if (iwl_is_rfkill(priv)) { 957 if (iwl_is_rfkill(priv)) {
943 IWL_DEBUG_INFO(priv, "Not sending command - RF KILL\n"); 958 IWL_DEBUG_INFO(priv, "Not sending command - RF KILL\n");
944 return -EIO; 959 return -EIO;
945 } 960 }
946 961
947 if (iwl_queue_space(q) < ((cmd->meta.flags & CMD_ASYNC) ? 2 : 1)) { 962 if (iwl_queue_space(q) < ((cmd->flags & CMD_ASYNC) ? 2 : 1)) {
948 IWL_ERR(priv, "No space for Tx\n"); 963 IWL_ERR(priv, "No space for Tx\n");
949 return -ENOSPC; 964 return -ENOSPC;
950 } 965 }
951 966
952 spin_lock_irqsave(&priv->hcmd_lock, flags); 967 spin_lock_irqsave(&priv->hcmd_lock, flags);
953 968
954 idx = get_cmd_index(q, q->write_ptr, cmd->meta.flags & CMD_SIZE_HUGE); 969 idx = get_cmd_index(q, q->write_ptr, cmd->flags & CMD_SIZE_HUGE);
955 out_cmd = txq->cmd[idx]; 970 out_cmd = txq->cmd[idx];
971 out_meta = &txq->meta[idx];
972
973 out_meta->flags = cmd->flags;
974 if (cmd->flags & CMD_WANT_SKB)
975 out_meta->source = cmd;
976 if (cmd->flags & CMD_ASYNC)
977 out_meta->callback = cmd->callback;
956 978
957 out_cmd->hdr.cmd = cmd->id; 979 out_cmd->hdr.cmd = cmd->id;
958 memcpy(&out_cmd->meta, &cmd->meta, sizeof(cmd->meta));
959 memcpy(&out_cmd->cmd.payload, cmd->data, cmd->len); 980 memcpy(&out_cmd->cmd.payload, cmd->data, cmd->len);
960 981
961 /* At this point, the out_cmd now has all of the incoming cmd 982 /* At this point, the out_cmd now has all of the incoming cmd
@@ -964,9 +985,9 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
964 out_cmd->hdr.flags = 0; 985 out_cmd->hdr.flags = 0;
965 out_cmd->hdr.sequence = cpu_to_le16(QUEUE_TO_SEQ(IWL_CMD_QUEUE_NUM) | 986 out_cmd->hdr.sequence = cpu_to_le16(QUEUE_TO_SEQ(IWL_CMD_QUEUE_NUM) |
966 INDEX_TO_SEQ(q->write_ptr)); 987 INDEX_TO_SEQ(q->write_ptr));
967 if (out_cmd->meta.flags & CMD_SIZE_HUGE) 988 if (cmd->flags & CMD_SIZE_HUGE)
968 out_cmd->hdr.sequence |= SEQ_HUGE_FRAME; 989 out_cmd->hdr.sequence |= SEQ_HUGE_FRAME;
969 len = sizeof(struct iwl_cmd) - sizeof(struct iwl_cmd_meta); 990 len = sizeof(struct iwl_device_cmd);
970 len += (idx == TFD_CMD_SLOTS) ? IWL_MAX_SCAN_SIZE : 0; 991 len += (idx == TFD_CMD_SLOTS) ? IWL_MAX_SCAN_SIZE : 0;
971 992
972 993
@@ -998,8 +1019,8 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
998 1019
999 phys_addr = pci_map_single(priv->pci_dev, &out_cmd->hdr, 1020 phys_addr = pci_map_single(priv->pci_dev, &out_cmd->hdr,
1000 fix_size, PCI_DMA_BIDIRECTIONAL); 1021 fix_size, PCI_DMA_BIDIRECTIONAL);
1001 pci_unmap_addr_set(&out_cmd->meta, mapping, phys_addr); 1022 pci_unmap_addr_set(out_meta, mapping, phys_addr);
1002 pci_unmap_len_set(&out_cmd->meta, len, fix_size); 1023 pci_unmap_len_set(out_meta, len, fix_size);
1003 1024
1004 priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq, 1025 priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
1005 phys_addr, fix_size, 1, 1026 phys_addr, fix_size, 1,
@@ -1068,8 +1089,8 @@ static void iwl_hcmd_queue_reclaim(struct iwl_priv *priv, int txq_id,
1068 } 1089 }
1069 1090
1070 pci_unmap_single(priv->pci_dev, 1091 pci_unmap_single(priv->pci_dev,
1071 pci_unmap_addr(&txq->cmd[cmd_idx]->meta, mapping), 1092 pci_unmap_addr(&txq->meta[cmd_idx], mapping),
1072 pci_unmap_len(&txq->cmd[cmd_idx]->meta, len), 1093 pci_unmap_len(&txq->meta[cmd_idx], len),
1073 PCI_DMA_BIDIRECTIONAL); 1094 PCI_DMA_BIDIRECTIONAL);
1074 1095
1075 for (idx = iwl_queue_inc_wrap(idx, q->n_bd); q->read_ptr != idx; 1096 for (idx = iwl_queue_inc_wrap(idx, q->n_bd); q->read_ptr != idx;
@@ -1100,7 +1121,8 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
1100 int index = SEQ_TO_INDEX(sequence); 1121 int index = SEQ_TO_INDEX(sequence);
1101 int cmd_index; 1122 int cmd_index;
1102 bool huge = !!(pkt->hdr.sequence & SEQ_HUGE_FRAME); 1123 bool huge = !!(pkt->hdr.sequence & SEQ_HUGE_FRAME);
1103 struct iwl_cmd *cmd; 1124 struct iwl_device_cmd *cmd;
1125 struct iwl_cmd_meta *meta;
1104 1126
1105 /* If a Tx command is being handled and it isn't in the actual 1127 /* If a Tx command is being handled and it isn't in the actual
1106 * command queue then there a command routing bug has been introduced 1128 * command queue then there a command routing bug has been introduced
@@ -1116,18 +1138,18 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
1116 1138
1117 cmd_index = get_cmd_index(&priv->txq[IWL_CMD_QUEUE_NUM].q, index, huge); 1139 cmd_index = get_cmd_index(&priv->txq[IWL_CMD_QUEUE_NUM].q, index, huge);
1118 cmd = priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_index]; 1140 cmd = priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_index];
1141 meta = &priv->txq[IWL_CMD_QUEUE_NUM].meta[cmd_index];
1119 1142
1120 /* Input error checking is done when commands are added to queue. */ 1143 /* Input error checking is done when commands are added to queue. */
1121 if (cmd->meta.flags & CMD_WANT_SKB) { 1144 if (meta->flags & CMD_WANT_SKB) {
1122 cmd->meta.source->u.skb = rxb->skb; 1145 meta->source->reply_skb = rxb->skb;
1123 rxb->skb = NULL; 1146 rxb->skb = NULL;
1124 } else if (cmd->meta.u.callback && 1147 } else if (meta->callback && !meta->callback(priv, cmd, rxb->skb))
1125 !cmd->meta.u.callback(priv, cmd, rxb->skb))
1126 rxb->skb = NULL; 1148 rxb->skb = NULL;
1127 1149
1128 iwl_hcmd_queue_reclaim(priv, txq_id, index, cmd_index); 1150 iwl_hcmd_queue_reclaim(priv, txq_id, index, cmd_index);
1129 1151
1130 if (!(cmd->meta.flags & CMD_ASYNC)) { 1152 if (!(meta->flags & CMD_ASYNC)) {
1131 clear_bit(STATUS_HCMD_ACTIVE, &priv->status); 1153 clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
1132 wake_up_interruptible(&priv->wait_command_queue); 1154 wake_up_interruptible(&priv->wait_command_queue);
1133 } 1155 }
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 2cc7e30d7743..5ded8983b915 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -363,7 +363,7 @@ static void iwl3945_unset_hw_params(struct iwl_priv *priv)
363 363
364static void iwl3945_build_tx_cmd_hwcrypto(struct iwl_priv *priv, 364static void iwl3945_build_tx_cmd_hwcrypto(struct iwl_priv *priv,
365 struct ieee80211_tx_info *info, 365 struct ieee80211_tx_info *info,
366 struct iwl_cmd *cmd, 366 struct iwl_device_cmd *cmd,
367 struct sk_buff *skb_frag, 367 struct sk_buff *skb_frag,
368 int sta_id) 368 int sta_id)
369{ 369{
@@ -403,7 +403,7 @@ static void iwl3945_build_tx_cmd_hwcrypto(struct iwl_priv *priv,
403 * handle build REPLY_TX command notification. 403 * handle build REPLY_TX command notification.
404 */ 404 */
405static void iwl3945_build_tx_cmd_basic(struct iwl_priv *priv, 405static void iwl3945_build_tx_cmd_basic(struct iwl_priv *priv,
406 struct iwl_cmd *cmd, 406 struct iwl_device_cmd *cmd,
407 struct ieee80211_tx_info *info, 407 struct ieee80211_tx_info *info,
408 struct ieee80211_hdr *hdr, u8 std_id) 408 struct ieee80211_hdr *hdr, u8 std_id)
409{ 409{
@@ -476,7 +476,8 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
476 struct iwl3945_tx_cmd *tx; 476 struct iwl3945_tx_cmd *tx;
477 struct iwl_tx_queue *txq = NULL; 477 struct iwl_tx_queue *txq = NULL;
478 struct iwl_queue *q = NULL; 478 struct iwl_queue *q = NULL;
479 struct iwl_cmd *out_cmd = NULL; 479 struct iwl_device_cmd *out_cmd;
480 struct iwl_cmd_meta *out_meta;
480 dma_addr_t phys_addr; 481 dma_addr_t phys_addr;
481 dma_addr_t txcmd_phys; 482 dma_addr_t txcmd_phys;
482 int txq_id = skb_get_queue_mapping(skb); 483 int txq_id = skb_get_queue_mapping(skb);
@@ -565,6 +566,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
565 566
566 /* Init first empty entry in queue's array of Tx/cmd buffers */ 567 /* Init first empty entry in queue's array of Tx/cmd buffers */
567 out_cmd = txq->cmd[idx]; 568 out_cmd = txq->cmd[idx];
569 out_meta = &txq->meta[idx];
568 tx = (struct iwl3945_tx_cmd *)out_cmd->cmd.payload; 570 tx = (struct iwl3945_tx_cmd *)out_cmd->cmd.payload;
569 memset(&out_cmd->hdr, 0, sizeof(out_cmd->hdr)); 571 memset(&out_cmd->hdr, 0, sizeof(out_cmd->hdr));
570 memset(tx, 0, sizeof(*tx)); 572 memset(tx, 0, sizeof(*tx));
@@ -642,8 +644,8 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
642 len, PCI_DMA_TODEVICE); 644 len, PCI_DMA_TODEVICE);
643 /* we do not map meta data ... so we can safely access address to 645 /* we do not map meta data ... so we can safely access address to
644 * provide to unmap command*/ 646 * provide to unmap command*/
645 pci_unmap_addr_set(&out_cmd->meta, mapping, txcmd_phys); 647 pci_unmap_addr_set(out_meta, mapping, txcmd_phys);
646 pci_unmap_len_set(&out_cmd->meta, len, len); 648 pci_unmap_len_set(out_meta, len, len);
647 649
648 /* Add buffer containing Tx command and MAC(!) header to TFD's 650 /* Add buffer containing Tx command and MAC(!) header to TFD's
649 * first entry */ 651 * first entry */
@@ -753,7 +755,7 @@ static int iwl3945_get_measurement(struct iwl_priv *priv,
753 struct iwl_host_cmd cmd = { 755 struct iwl_host_cmd cmd = {
754 .id = REPLY_SPECTRUM_MEASUREMENT_CMD, 756 .id = REPLY_SPECTRUM_MEASUREMENT_CMD,
755 .data = (void *)&spectrum, 757 .data = (void *)&spectrum,
756 .meta.flags = CMD_WANT_SKB, 758 .flags = CMD_WANT_SKB,
757 }; 759 };
758 u32 add_time = le64_to_cpu(params->start_time); 760 u32 add_time = le64_to_cpu(params->start_time);
759 int rc; 761 int rc;
@@ -794,7 +796,7 @@ static int iwl3945_get_measurement(struct iwl_priv *priv,
794 if (rc) 796 if (rc)
795 return rc; 797 return rc;
796 798
797 res = (struct iwl_rx_packet *)cmd.meta.u.skb->data; 799 res = (struct iwl_rx_packet *)cmd.reply_skb->data;
798 if (res->hdr.flags & IWL_CMD_FAILED_MSK) { 800 if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
799 IWL_ERR(priv, "Bad return from REPLY_RX_ON_ASSOC command\n"); 801 IWL_ERR(priv, "Bad return from REPLY_RX_ON_ASSOC command\n");
800 rc = -EIO; 802 rc = -EIO;
@@ -817,7 +819,7 @@ static int iwl3945_get_measurement(struct iwl_priv *priv,
817 break; 819 break;
818 } 820 }
819 821
820 dev_kfree_skb_any(cmd.meta.u.skb); 822 dev_kfree_skb_any(cmd.reply_skb);
821 823
822 return rc; 824 return rc;
823} 825}
@@ -2717,7 +2719,7 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
2717 struct iwl_host_cmd cmd = { 2719 struct iwl_host_cmd cmd = {
2718 .id = REPLY_SCAN_CMD, 2720 .id = REPLY_SCAN_CMD,
2719 .len = sizeof(struct iwl3945_scan_cmd), 2721 .len = sizeof(struct iwl3945_scan_cmd),
2720 .meta.flags = CMD_SIZE_HUGE, 2722 .flags = CMD_SIZE_HUGE,
2721 }; 2723 };
2722 int rc = 0; 2724 int rc = 0;
2723 struct iwl3945_scan_cmd *scan; 2725 struct iwl3945_scan_cmd *scan;