aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorSamuel Ortiz <samuel.ortiz@intel.com>2008-12-21 22:31:16 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-01-29 15:59:24 -0500
commit188cf6c73a72be1d8c118580a40d70cd76415eec (patch)
treee684a15fb8011a5666075062315790f3cb6d1600 /drivers
parent42427b4e436bbbf038742ecbb3bf09815f93ed7a (diff)
iwl3945: sync tx queue data structure with iwlagn
We are now using the iwl_tx_queue for iwl3945. To reach that goal, we included the 3945 specific tfd frame structure to iwl_tx_queue. This has no effect on the current iwlagn code. Signed-off-by: Samuel Ortiz <samuel.ortiz@intel.com> Signed-off-by: Abhijeet Kolekar <abhijeet.kolekar@intel.com> Signed-off-by: Zhu Yi <yi.zhu@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-hw.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c14
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.h8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965-hw.h3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h28
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fh.h11
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c125
7 files changed, 103 insertions, 90 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
index 1ba59dfacd1b..c9db98cd0e45 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
@@ -240,7 +240,6 @@ struct iwl3945_eeprom {
240 240
241#define TFD_QUEUE_MIN 0 241#define TFD_QUEUE_MIN 0
242#define TFD_QUEUE_MAX 6 242#define TFD_QUEUE_MAX 6
243#define TFD_QUEUE_SIZE_MAX (256)
244 243
245#define IWL_NUM_SCAN_RATES (2) 244#define IWL_NUM_SCAN_RATES (2)
246 245
@@ -262,9 +261,6 @@ struct iwl3945_eeprom {
262#define TFD_CTL_PAD_SET(n) (n << 28) 261#define TFD_CTL_PAD_SET(n) (n << 28)
263#define TFD_CTL_PAD_GET(ctl) (ctl >> 28) 262#define TFD_CTL_PAD_GET(ctl) (ctl >> 28)
264 263
265#define TFD_TX_CMD_SLOTS 256
266#define TFD_CMD_SLOTS 32
267
268/* 264/*
269 * RX related structures and functions 265 * RX related structures and functions
270 */ 266 */
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index be0974d528e1..54ad07722b0b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -306,7 +306,7 @@ int iwl3945_rs_next_rate(struct iwl_priv *priv, int rate)
306static void iwl3945_tx_queue_reclaim(struct iwl_priv *priv, 306static void iwl3945_tx_queue_reclaim(struct iwl_priv *priv,
307 int txq_id, int index) 307 int txq_id, int index)
308{ 308{
309 struct iwl3945_tx_queue *txq = &priv->txq39[txq_id]; 309 struct iwl_tx_queue *txq = &priv->txq[txq_id];
310 struct iwl_queue *q = &txq->q; 310 struct iwl_queue *q = &txq->q;
311 struct iwl_tx_info *tx_info; 311 struct iwl_tx_info *tx_info;
312 312
@@ -337,7 +337,7 @@ static void iwl3945_rx_reply_tx(struct iwl_priv *priv,
337 u16 sequence = le16_to_cpu(pkt->hdr.sequence); 337 u16 sequence = le16_to_cpu(pkt->hdr.sequence);
338 int txq_id = SEQ_TO_QUEUE(sequence); 338 int txq_id = SEQ_TO_QUEUE(sequence);
339 int index = SEQ_TO_INDEX(sequence); 339 int index = SEQ_TO_INDEX(sequence);
340 struct iwl3945_tx_queue *txq = &priv->txq39[txq_id]; 340 struct iwl_tx_queue *txq = &priv->txq[txq_id];
341 struct ieee80211_tx_info *info; 341 struct ieee80211_tx_info *info;
342 struct iwl3945_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; 342 struct iwl3945_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
343 u32 status = le32_to_cpu(tx_resp->status); 343 u32 status = le32_to_cpu(tx_resp->status);
@@ -756,9 +756,9 @@ int iwl3945_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, void *ptr,
756 * 756 *
757 * Does NOT advance any indexes 757 * Does NOT advance any indexes
758 */ 758 */
759int iwl3945_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl3945_tx_queue *txq) 759int iwl3945_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq)
760{ 760{
761 struct iwl3945_tfd *tfd_tmp = (struct iwl3945_tfd *)&txq->tfds[0]; 761 struct iwl3945_tfd *tfd_tmp = (struct iwl3945_tfd *)&txq->tfds39[0];
762 struct iwl3945_tfd *tfd = &tfd_tmp[txq->q.read_ptr]; 762 struct iwl3945_tfd *tfd = &tfd_tmp[txq->q.read_ptr];
763 struct pci_dev *dev = priv->pci_dev; 763 struct pci_dev *dev = priv->pci_dev;
764 int i; 764 int i;
@@ -1061,7 +1061,7 @@ static int iwl3945_txq_ctx_reset(struct iwl_priv *priv)
1061 for (txq_id = 0; txq_id < TFD_QUEUE_MAX; txq_id++) { 1061 for (txq_id = 0; txq_id < TFD_QUEUE_MAX; txq_id++) {
1062 slots_num = (txq_id == IWL_CMD_QUEUE_NUM) ? 1062 slots_num = (txq_id == IWL_CMD_QUEUE_NUM) ?
1063 TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; 1063 TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
1064 rc = iwl3945_tx_queue_init(priv, &priv->txq39[txq_id], slots_num, 1064 rc = iwl3945_tx_queue_init(priv, &priv->txq[txq_id], slots_num,
1065 txq_id); 1065 txq_id);
1066 if (rc) { 1066 if (rc) {
1067 IWL_ERR(priv, "Tx %d queue init failed\n", txq_id); 1067 IWL_ERR(priv, "Tx %d queue init failed\n", txq_id);
@@ -1251,7 +1251,7 @@ void iwl3945_hw_txq_ctx_free(struct iwl_priv *priv)
1251 1251
1252 /* Tx queues */ 1252 /* Tx queues */
1253 for (txq_id = 0; txq_id < TFD_QUEUE_MAX; txq_id++) 1253 for (txq_id = 0; txq_id < TFD_QUEUE_MAX; txq_id++)
1254 iwl3945_tx_queue_free(priv, &priv->txq39[txq_id]); 1254 iwl3945_tx_queue_free(priv, &priv->txq[txq_id]);
1255} 1255}
1256 1256
1257void iwl3945_hw_txq_ctx_stop(struct iwl_priv *priv) 1257void iwl3945_hw_txq_ctx_stop(struct iwl_priv *priv)
@@ -2342,7 +2342,7 @@ int iwl3945_hw_rxq_stop(struct iwl_priv *priv)
2342 return 0; 2342 return 0;
2343} 2343}
2344 2344
2345int iwl3945_hw_tx_queue_init(struct iwl_priv *priv, struct iwl3945_tx_queue *txq) 2345int iwl3945_hw_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq)
2346{ 2346{
2347 int rc; 2347 int rc;
2348 unsigned long flags; 2348 unsigned long flags;
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h
index 716c4b462335..e584032a1a3d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.h
@@ -219,9 +219,9 @@ extern void iwl3945_rx_queue_reset(struct iwl_priv *priv,
219extern int iwl3945_calc_db_from_ratio(int sig_ratio); 219extern int iwl3945_calc_db_from_ratio(int sig_ratio);
220extern int iwl3945_calc_sig_qual(int rssi_dbm, int noise_dbm); 220extern int iwl3945_calc_sig_qual(int rssi_dbm, int noise_dbm);
221extern int iwl3945_tx_queue_init(struct iwl_priv *priv, 221extern int iwl3945_tx_queue_init(struct iwl_priv *priv,
222 struct iwl3945_tx_queue *txq, int count, u32 id); 222 struct iwl_tx_queue *txq, int count, u32 id);
223extern void iwl3945_rx_replenish(void *data); 223extern void iwl3945_rx_replenish(void *data);
224extern void iwl3945_tx_queue_free(struct iwl_priv *priv, struct iwl3945_tx_queue *txq); 224extern void iwl3945_tx_queue_free(struct iwl_priv *priv, struct iwl_tx_queue *txq);
225extern int iwl3945_send_cmd_pdu(struct iwl_priv *priv, u8 id, u16 len, 225extern int iwl3945_send_cmd_pdu(struct iwl_priv *priv, u8 id, u16 len,
226 const void *data); 226 const void *data);
227extern int __must_check iwl3945_send_cmd(struct iwl_priv *priv, 227extern int __must_check iwl3945_send_cmd(struct iwl_priv *priv,
@@ -270,10 +270,10 @@ extern void iwl3945_hw_txq_ctx_stop(struct iwl_priv *priv);
270extern int iwl3945_hw_nic_reset(struct iwl_priv *priv); 270extern int iwl3945_hw_nic_reset(struct iwl_priv *priv);
271extern int iwl3945_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, void *tfd, 271extern int iwl3945_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, void *tfd,
272 dma_addr_t addr, u16 len); 272 dma_addr_t addr, u16 len);
273extern int iwl3945_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl3945_tx_queue *txq); 273extern int iwl3945_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq);
274extern int iwl3945_hw_get_temperature(struct iwl_priv *priv); 274extern int iwl3945_hw_get_temperature(struct iwl_priv *priv);
275extern int iwl3945_hw_tx_queue_init(struct iwl_priv *priv, 275extern int iwl3945_hw_tx_queue_init(struct iwl_priv *priv,
276 struct iwl3945_tx_queue *txq); 276 struct iwl_tx_queue *txq);
277extern unsigned int iwl3945_hw_get_beacon_cmd(struct iwl_priv *priv, 277extern unsigned int iwl3945_hw_get_beacon_cmd(struct iwl_priv *priv,
278 struct iwl3945_frame *frame, u8 rate); 278 struct iwl3945_frame *frame, u8 rate);
279void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv, struct iwl_cmd *cmd, 279void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv, struct iwl_cmd *cmd,
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
index 9330b5a1aab8..e751c53ae1f8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
@@ -114,9 +114,6 @@
114#define RX_QUEUE_MASK 255 114#define RX_QUEUE_MASK 255
115#define RX_QUEUE_SIZE_LOG 8 115#define RX_QUEUE_SIZE_LOG 8
116 116
117#define TFD_TX_CMD_SLOTS 256
118#define TFD_CMD_SLOTS 32
119
120/* 117/*
121 * RX related structures and functions 118 * RX related structures and functions
122 */ 119 */
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 1ad4d084e357..9b9d7435321b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -134,9 +134,13 @@ struct iwl_tx_info {
134 * A Tx queue consists of circular buffer of BDs (a.k.a. TFDs, transmit frame 134 * A Tx queue consists of circular buffer of BDs (a.k.a. TFDs, transmit frame
135 * descriptors) and required locking structures. 135 * descriptors) and required locking structures.
136 */ 136 */
137#define TFD_TX_CMD_SLOTS 256
138#define TFD_CMD_SLOTS 32
139
137struct iwl_tx_queue { 140struct iwl_tx_queue {
138 struct iwl_queue q; 141 struct iwl_queue q;
139 struct iwl_tfd *tfds; 142 struct iwl_tfd *tfds;
143 struct iwl3945_tfd *tfds39;
140 struct iwl_cmd *cmd[TFD_TX_CMD_SLOTS]; 144 struct iwl_cmd *cmd[TFD_TX_CMD_SLOTS];
141 struct iwl_tx_info *txb; 145 struct iwl_tx_info *txb;
142 u8 need_update; 146 u8 need_update;
@@ -226,28 +230,6 @@ struct iwl_channel_info {
226 struct iwl3945_scan_power_info scan_pwr_info[IWL_NUM_SCAN_RATES]; 230 struct iwl3945_scan_power_info scan_pwr_info[IWL_NUM_SCAN_RATES];
227}; 231};
228 232
229/**
230 * struct iwl3945_tx_queue - Tx Queue for DMA
231 * @q: generic Rx/Tx queue descriptor
232 * @bd: base of circular buffer of TFDs
233 * @cmd: array of command/Tx buffers
234 * @dma_addr_cmd: physical address of cmd/tx buffer array
235 * @txb: array of per-TFD driver data
236 * @need_update: indicates need to update read/write index
237 *
238 * A Tx queue consists of circular buffer of BDs (a.k.a. TFDs, transmit frame
239 * descriptors) and required locking structures.
240 */
241struct iwl3945_tx_queue {
242 struct iwl_queue q;
243 struct iwl3945_tfd *tfds;
244 struct iwl_cmd *cmd;
245 dma_addr_t dma_addr_cmd;
246 struct iwl_tx_info *txb;
247 int need_update;
248 int active;
249};
250
251#define IWL_TX_FIFO_AC0 0 233#define IWL_TX_FIFO_AC0 0
252#define IWL_TX_FIFO_AC1 1 234#define IWL_TX_FIFO_AC1 1
253#define IWL_TX_FIFO_AC2 2 235#define IWL_TX_FIFO_AC2 2
@@ -1099,8 +1081,6 @@ struct iwl_priv {
1099 struct iwl3945_rxon_cmd staging39_rxon; 1081 struct iwl3945_rxon_cmd staging39_rxon;
1100 struct iwl3945_rxon_cmd recovery39_rxon; 1082 struct iwl3945_rxon_cmd recovery39_rxon;
1101 1083
1102 struct iwl3945_tx_queue txq39[IWL39_MAX_NUM_QUEUES];
1103
1104 struct iwl3945_power_mgr power_data_39; 1084 struct iwl3945_power_mgr power_data_39;
1105 struct iwl3945_notif_statistics statistics_39; 1085 struct iwl3945_notif_statistics statistics_39;
1106 1086
diff --git a/drivers/net/wireless/iwlwifi/iwl-fh.h b/drivers/net/wireless/iwlwifi/iwl-fh.h
index 7c19790a3ea7..313b03b5b4cd 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fh.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fh.h
@@ -478,6 +478,17 @@ struct iwl_tfd {
478 __le32 __pad; 478 __le32 __pad;
479} __attribute__ ((packed)); 479} __attribute__ ((packed));
480 480
481struct iwl3945_tfd_frame_data {
482 __le32 addr;
483 __le32 len;
484} __attribute__ ((packed));
485
486struct iwl3945_tfd_frame {
487 __le32 control_flags;
488 struct iwl3945_tfd_frame_data pa[4];
489 u8 reserved[28];
490} __attribute__ ((packed));
491
481 492
482/* Keep Warm Size */ 493/* Keep Warm Size */
483#define IWL_KW_SIZE 0x1000 /* 4k */ 494#define IWL_KW_SIZE 0x1000 /* 4k */
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index c37fa00af6d7..53e274a5f4fe 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -57,7 +57,7 @@
57#include "iwl-dev.h" 57#include "iwl-dev.h"
58 58
59static int iwl3945_tx_queue_update_write_ptr(struct iwl_priv *priv, 59static int iwl3945_tx_queue_update_write_ptr(struct iwl_priv *priv,
60 struct iwl3945_tx_queue *txq); 60 struct iwl_tx_queue *txq);
61 61
62/* 62/*
63 * module name, copyright, version, etc. 63 * module name, copyright, version, etc.
@@ -162,7 +162,7 @@ static int iwl3945_queue_init(struct iwl_priv *priv, struct iwl_queue *q,
162 * iwl3945_tx_queue_alloc - Alloc driver data and TFD CB for one Tx/cmd queue 162 * iwl3945_tx_queue_alloc - Alloc driver data and TFD CB for one Tx/cmd queue
163 */ 163 */
164static int iwl3945_tx_queue_alloc(struct iwl_priv *priv, 164static int iwl3945_tx_queue_alloc(struct iwl_priv *priv,
165 struct iwl3945_tx_queue *txq, u32 id) 165 struct iwl_tx_queue *txq, u32 id)
166{ 166{
167 struct pci_dev *dev = priv->pci_dev; 167 struct pci_dev *dev = priv->pci_dev;
168 168
@@ -181,13 +181,13 @@ static int iwl3945_tx_queue_alloc(struct iwl_priv *priv,
181 181
182 /* Circular buffer of transmit frame descriptors (TFDs), 182 /* Circular buffer of transmit frame descriptors (TFDs),
183 * shared with device */ 183 * shared with device */
184 txq->tfds = pci_alloc_consistent(dev, 184 txq->tfds39 = pci_alloc_consistent(dev,
185 sizeof(txq->tfds[0]) * TFD_QUEUE_SIZE_MAX, 185 sizeof(txq->tfds39[0]) * TFD_QUEUE_SIZE_MAX,
186 &txq->q.dma_addr); 186 &txq->q.dma_addr);
187 187
188 if (!txq->tfds) { 188 if (!txq->tfds39) {
189 IWL_ERR(priv, "pci_alloc_consistent(%zd) failed\n", 189 IWL_ERR(priv, "pci_alloc_consistent(%zd) failed\n",
190 sizeof(txq->tfds[0]) * TFD_QUEUE_SIZE_MAX); 190 sizeof(txq->tfds39[0]) * TFD_QUEUE_SIZE_MAX);
191 goto error; 191 goto error;
192 } 192 }
193 txq->q.id = id; 193 txq->q.id = id;
@@ -205,10 +205,9 @@ static int iwl3945_tx_queue_alloc(struct iwl_priv *priv,
205 * iwl3945_tx_queue_init - Allocate and initialize one tx/cmd queue 205 * iwl3945_tx_queue_init - Allocate and initialize one tx/cmd queue
206 */ 206 */
207int iwl3945_tx_queue_init(struct iwl_priv *priv, 207int iwl3945_tx_queue_init(struct iwl_priv *priv,
208 struct iwl3945_tx_queue *txq, int slots_num, u32 txq_id) 208 struct iwl_tx_queue *txq, int slots_num, u32 txq_id)
209{ 209{
210 struct pci_dev *dev = priv->pci_dev; 210 int len, i;
211 int len;
212 int rc = 0; 211 int rc = 0;
213 212
214 /* 213 /*
@@ -219,20 +218,25 @@ int iwl3945_tx_queue_init(struct iwl_priv *priv,
219 * For data Tx queues (all other queues), no super-size command 218 * For data Tx queues (all other queues), no super-size command
220 * space is needed. 219 * space is needed.
221 */ 220 */
222 len = sizeof(struct iwl_cmd) * slots_num; 221 len = sizeof(struct iwl_cmd);
223 if (txq_id == IWL_CMD_QUEUE_NUM) 222 for (i = 0; i <= slots_num; i++) {
224 len += IWL_MAX_SCAN_SIZE; 223 if (i == slots_num) {
225 txq->cmd = pci_alloc_consistent(dev, len, &txq->dma_addr_cmd); 224 if (txq_id == IWL_CMD_QUEUE_NUM)
226 if (!txq->cmd) 225 len += IWL_MAX_SCAN_SIZE;
227 return -ENOMEM; 226 else
227 continue;
228 }
229
230 txq->cmd[i] = kmalloc(len, GFP_KERNEL);
231 if (!txq->cmd[i])
232 goto err;
233 }
228 234
229 /* Alloc driver data array and TFD circular buffer */ 235 /* Alloc driver data array and TFD circular buffer */
230 rc = iwl3945_tx_queue_alloc(priv, txq, txq_id); 236 rc = iwl3945_tx_queue_alloc(priv, txq, txq_id);
231 if (rc) { 237 if (rc)
232 pci_free_consistent(dev, len, txq->cmd, txq->dma_addr_cmd); 238 goto err;
233 239
234 return -ENOMEM;
235 }
236 txq->need_update = 0; 240 txq->need_update = 0;
237 241
238 /* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise 242 /* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise
@@ -246,6 +250,17 @@ int iwl3945_tx_queue_init(struct iwl_priv *priv,
246 iwl3945_hw_tx_queue_init(priv, txq); 250 iwl3945_hw_tx_queue_init(priv, txq);
247 251
248 return 0; 252 return 0;
253err:
254 for (i = 0; i < slots_num; i++) {
255 kfree(txq->cmd[i]);
256 txq->cmd[i] = NULL;
257 }
258
259 if (txq_id == IWL_CMD_QUEUE_NUM) {
260 kfree(txq->cmd[slots_num]);
261 txq->cmd[slots_num] = NULL;
262 }
263 return -ENOMEM;
249} 264}
250 265
251/** 266/**
@@ -256,11 +271,11 @@ int iwl3945_tx_queue_init(struct iwl_priv *priv,
256 * Free all buffers. 271 * Free all buffers.
257 * 0-fill, but do not free "txq" descriptor structure. 272 * 0-fill, but do not free "txq" descriptor structure.
258 */ 273 */
259void iwl3945_tx_queue_free(struct iwl_priv *priv, struct iwl3945_tx_queue *txq) 274void iwl3945_tx_queue_free(struct iwl_priv *priv, struct iwl_tx_queue *txq)
260{ 275{
261 struct iwl_queue *q = &txq->q; 276 struct iwl_queue *q = &txq->q;
262 struct pci_dev *dev = priv->pci_dev; 277 struct pci_dev *dev = priv->pci_dev;
263 int len; 278 int len, i;
264 279
265 if (q->n_bd == 0) 280 if (q->n_bd == 0)
266 return; 281 return;
@@ -275,12 +290,13 @@ void iwl3945_tx_queue_free(struct iwl_priv *priv, struct iwl3945_tx_queue *txq)
275 len += IWL_MAX_SCAN_SIZE; 290 len += IWL_MAX_SCAN_SIZE;
276 291
277 /* De-alloc array of command/tx buffers */ 292 /* De-alloc array of command/tx buffers */
278 pci_free_consistent(dev, len, txq->cmd, txq->dma_addr_cmd); 293 for (i = 0; i < TFD_TX_CMD_SLOTS; i++)
294 kfree(txq->cmd[i]);
279 295
280 /* De-alloc circular buffer of TFDs */ 296 /* De-alloc circular buffer of TFDs */
281 if (txq->q.n_bd) 297 if (txq->q.n_bd)
282 pci_free_consistent(dev, sizeof(struct iwl3945_tfd) * 298 pci_free_consistent(dev, sizeof(struct iwl3945_tfd) *
283 txq->q.n_bd, txq->tfds, txq->q.dma_addr); 299 txq->q.n_bd, txq->tfds39, txq->q.dma_addr);
284 300
285 /* De-alloc array of per-TFD driver data */ 301 /* De-alloc array of per-TFD driver data */
286 kfree(txq->txb); 302 kfree(txq->txb);
@@ -444,7 +460,7 @@ u8 iwl3945_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap, u8 flag
444 */ 460 */
445static int iwl3945_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) 461static int iwl3945_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
446{ 462{
447 struct iwl3945_tx_queue *txq = &priv->txq39[IWL_CMD_QUEUE_NUM]; 463 struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM];
448 struct iwl_queue *q = &txq->q; 464 struct iwl_queue *q = &txq->q;
449 struct iwl3945_tfd *tfd; 465 struct iwl3945_tfd *tfd;
450 struct iwl_cmd *out_cmd; 466 struct iwl_cmd *out_cmd;
@@ -452,7 +468,7 @@ static int iwl3945_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
452 u16 fix_size = (u16)(cmd->len + sizeof(out_cmd->hdr)); 468 u16 fix_size = (u16)(cmd->len + sizeof(out_cmd->hdr));
453 dma_addr_t phys_addr; 469 dma_addr_t phys_addr;
454 int pad; 470 int pad;
455 int ret; 471 int ret, len;
456 unsigned long flags; 472 unsigned long flags;
457 473
458 /* If any of the command structures end up being larger than 474 /* If any of the command structures end up being larger than
@@ -474,11 +490,11 @@ static int iwl3945_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
474 490
475 spin_lock_irqsave(&priv->hcmd_lock, flags); 491 spin_lock_irqsave(&priv->hcmd_lock, flags);
476 492
477 tfd = &txq->tfds[q->write_ptr]; 493 tfd = &txq->tfds39[q->write_ptr];
478 memset(tfd, 0, sizeof(*tfd)); 494 memset(tfd, 0, sizeof(*tfd));
479 495
480 idx = get_cmd_index(q, q->write_ptr, cmd->meta.flags & CMD_SIZE_HUGE); 496 idx = get_cmd_index(q, q->write_ptr, cmd->meta.flags & CMD_SIZE_HUGE);
481 out_cmd = &txq->cmd[idx]; 497 out_cmd = txq->cmd[idx];
482 498
483 out_cmd->hdr.cmd = cmd->id; 499 out_cmd->hdr.cmd = cmd->id;
484 memcpy(&out_cmd->meta, &cmd->meta, sizeof(cmd->meta)); 500 memcpy(&out_cmd->meta, &cmd->meta, sizeof(cmd->meta));
@@ -493,8 +509,15 @@ static int iwl3945_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
493 if (out_cmd->meta.flags & CMD_SIZE_HUGE) 509 if (out_cmd->meta.flags & CMD_SIZE_HUGE)
494 out_cmd->hdr.sequence |= SEQ_HUGE_FRAME; 510 out_cmd->hdr.sequence |= SEQ_HUGE_FRAME;
495 511
496 phys_addr = txq->dma_addr_cmd + sizeof(txq->cmd[0]) * idx + 512 len = (idx == TFD_CMD_SLOTS) ?
497 offsetof(struct iwl_cmd, hdr); 513 IWL_MAX_SCAN_SIZE : sizeof(struct iwl_cmd);
514
515 phys_addr = pci_map_single(priv->pci_dev, out_cmd,
516 len, PCI_DMA_TODEVICE);
517 pci_unmap_addr_set(&out_cmd->meta, mapping, phys_addr);
518 pci_unmap_len_set(&out_cmd->meta, len, len);
519 phys_addr += offsetof(struct iwl_cmd, hdr);
520
498 iwl3945_hw_txq_attach_buf_to_tfd(priv, tfd, phys_addr, fix_size); 521 iwl3945_hw_txq_attach_buf_to_tfd(priv, tfd, phys_addr, fix_size);
499 522
500 pad = U32_PAD(cmd->len); 523 pad = U32_PAD(cmd->len);
@@ -620,7 +643,7 @@ cancel:
620 * TX cmd queue. Otherwise in case the cmd comes 643 * TX cmd queue. Otherwise in case the cmd comes
621 * in later, it will possibly set an invalid 644 * in later, it will possibly set an invalid
622 * address (cmd->meta.source). */ 645 * address (cmd->meta.source). */
623 qcmd = &priv->txq39[IWL_CMD_QUEUE_NUM].cmd[cmd_idx]; 646 qcmd = priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_idx];
624 qcmd->meta.flags &= ~CMD_WANT_SKB; 647 qcmd->meta.flags &= ~CMD_WANT_SKB;
625 } 648 }
626fail: 649fail:
@@ -2229,7 +2252,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
2229 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 2252 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
2230 struct iwl3945_tfd *tfd; 2253 struct iwl3945_tfd *tfd;
2231 int txq_id = skb_get_queue_mapping(skb); 2254 int txq_id = skb_get_queue_mapping(skb);
2232 struct iwl3945_tx_queue *txq = NULL; 2255 struct iwl_tx_queue *txq = NULL;
2233 struct iwl_queue *q = NULL; 2256 struct iwl_queue *q = NULL;
2234 dma_addr_t phys_addr; 2257 dma_addr_t phys_addr;
2235 dma_addr_t txcmd_phys; 2258 dma_addr_t txcmd_phys;
@@ -2306,13 +2329,13 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
2306 } 2329 }
2307 2330
2308 /* Descriptor for chosen Tx queue */ 2331 /* Descriptor for chosen Tx queue */
2309 txq = &priv->txq39[txq_id]; 2332 txq = &priv->txq[txq_id];
2310 q = &txq->q; 2333 q = &txq->q;
2311 2334
2312 spin_lock_irqsave(&priv->lock, flags); 2335 spin_lock_irqsave(&priv->lock, flags);
2313 2336
2314 /* Set up first empty TFD within this queue's circular TFD buffer */ 2337 /* Set up first empty TFD within this queue's circular TFD buffer */
2315 tfd = &txq->tfds[q->write_ptr]; 2338 tfd = &txq->tfds39[q->write_ptr];
2316 memset(tfd, 0, sizeof(*tfd)); 2339 memset(tfd, 0, sizeof(*tfd));
2317 idx = get_cmd_index(q, q->write_ptr, 0); 2340 idx = get_cmd_index(q, q->write_ptr, 0);
2318 2341
@@ -2321,7 +2344,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
2321 txq->txb[q->write_ptr].skb[0] = skb; 2344 txq->txb[q->write_ptr].skb[0] = skb;
2322 2345
2323 /* Init first empty entry in queue's array of Tx/cmd buffers */ 2346 /* Init first empty entry in queue's array of Tx/cmd buffers */
2324 out_cmd = &txq->cmd[idx]; 2347 out_cmd = txq->cmd[idx];
2325 memset(&out_cmd->hdr, 0, sizeof(out_cmd->hdr)); 2348 memset(&out_cmd->hdr, 0, sizeof(out_cmd->hdr));
2326 memset(&out_cmd->cmd.tx, 0, sizeof(out_cmd->cmd.tx)); 2349 memset(&out_cmd->cmd.tx, 0, sizeof(out_cmd->cmd.tx));
2327 2350
@@ -2360,8 +2383,14 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
2360 2383
2361 /* Physical address of this Tx command's header (not MAC header!), 2384 /* Physical address of this Tx command's header (not MAC header!),
2362 * within command buffer array. */ 2385 * within command buffer array. */
2363 txcmd_phys = txq->dma_addr_cmd + sizeof(struct iwl_cmd) * idx + 2386 txcmd_phys = pci_map_single(priv->pci_dev,
2364 offsetof(struct iwl_cmd, hdr); 2387 out_cmd, sizeof(struct iwl_cmd),
2388 PCI_DMA_TODEVICE);
2389 pci_unmap_addr_set(&out_cmd->meta, mapping, txcmd_phys);
2390 pci_unmap_len_set(&out_cmd->meta, len, sizeof(struct iwl_cmd));
2391 /* Add buffer containing Tx command and MAC(!) header to TFD's
2392 * first entry */
2393 txcmd_phys += offsetof(struct iwl_cmd, hdr);
2365 2394
2366 /* Add buffer containing Tx command and MAC(!) header to TFD's 2395 /* Add buffer containing Tx command and MAC(!) header to TFD's
2367 * first entry */ 2396 * first entry */
@@ -3076,7 +3105,7 @@ static void iwl3945_setup_rx_handlers(struct iwl_priv *priv)
3076static void iwl3945_cmd_queue_reclaim(struct iwl_priv *priv, 3105static void iwl3945_cmd_queue_reclaim(struct iwl_priv *priv,
3077 int txq_id, int index) 3106 int txq_id, int index)
3078{ 3107{
3079 struct iwl3945_tx_queue *txq = &priv->txq39[txq_id]; 3108 struct iwl_tx_queue *txq = &priv->txq[txq_id];
3080 struct iwl_queue *q = &txq->q; 3109 struct iwl_queue *q = &txq->q;
3081 int nfreed = 0; 3110 int nfreed = 0;
3082 3111
@@ -3121,8 +3150,8 @@ static void iwl3945_tx_cmd_complete(struct iwl_priv *priv,
3121 3150
3122 BUG_ON(txq_id != IWL_CMD_QUEUE_NUM); 3151 BUG_ON(txq_id != IWL_CMD_QUEUE_NUM);
3123 3152
3124 cmd_index = get_cmd_index(&priv->txq39[IWL_CMD_QUEUE_NUM].q, index, huge); 3153 cmd_index = get_cmd_index(&priv->txq[IWL_CMD_QUEUE_NUM].q, index, huge);
3125 cmd = &priv->txq39[IWL_CMD_QUEUE_NUM].cmd[cmd_index]; 3154 cmd = priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_index];
3126 3155
3127 /* Input error checking is done when commands are added to queue. */ 3156 /* Input error checking is done when commands are added to queue. */
3128 if (cmd->meta.flags & CMD_WANT_SKB) { 3157 if (cmd->meta.flags & CMD_WANT_SKB) {
@@ -3678,7 +3707,7 @@ static void iwl3945_rx_handle(struct iwl_priv *priv)
3678 * iwl3945_tx_queue_update_write_ptr - Send new write index to hardware 3707 * iwl3945_tx_queue_update_write_ptr - Send new write index to hardware
3679 */ 3708 */
3680static int iwl3945_tx_queue_update_write_ptr(struct iwl_priv *priv, 3709static int iwl3945_tx_queue_update_write_ptr(struct iwl_priv *priv,
3681 struct iwl3945_tx_queue *txq) 3710 struct iwl_tx_queue *txq)
3682{ 3711{
3683 u32 reg = 0; 3712 u32 reg = 0;
3684 int rc = 0; 3713 int rc = 0;
@@ -4088,12 +4117,12 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv)
4088 if (inta & CSR_INT_BIT_WAKEUP) { 4117 if (inta & CSR_INT_BIT_WAKEUP) {
4089 IWL_DEBUG_ISR("Wakeup interrupt\n"); 4118 IWL_DEBUG_ISR("Wakeup interrupt\n");
4090 iwl3945_rx_queue_update_write_ptr(priv, &priv->rxq); 4119 iwl3945_rx_queue_update_write_ptr(priv, &priv->rxq);
4091 iwl3945_tx_queue_update_write_ptr(priv, &priv->txq39[0]); 4120 iwl3945_tx_queue_update_write_ptr(priv, &priv->txq[0]);
4092 iwl3945_tx_queue_update_write_ptr(priv, &priv->txq39[1]); 4121 iwl3945_tx_queue_update_write_ptr(priv, &priv->txq[1]);
4093 iwl3945_tx_queue_update_write_ptr(priv, &priv->txq39[2]); 4122 iwl3945_tx_queue_update_write_ptr(priv, &priv->txq[2]);
4094 iwl3945_tx_queue_update_write_ptr(priv, &priv->txq39[3]); 4123 iwl3945_tx_queue_update_write_ptr(priv, &priv->txq[3]);
4095 iwl3945_tx_queue_update_write_ptr(priv, &priv->txq39[4]); 4124 iwl3945_tx_queue_update_write_ptr(priv, &priv->txq[4]);
4096 iwl3945_tx_queue_update_write_ptr(priv, &priv->txq39[5]); 4125 iwl3945_tx_queue_update_write_ptr(priv, &priv->txq[5]);
4097 4126
4098 handled |= CSR_INT_BIT_WAKEUP; 4127 handled |= CSR_INT_BIT_WAKEUP;
4099 } 4128 }
@@ -6735,7 +6764,7 @@ static int iwl3945_mac_get_tx_stats(struct ieee80211_hw *hw,
6735{ 6764{
6736 struct iwl_priv *priv = hw->priv; 6765 struct iwl_priv *priv = hw->priv;
6737 int i, avail; 6766 int i, avail;
6738 struct iwl3945_tx_queue *txq; 6767 struct iwl_tx_queue *txq;
6739 struct iwl_queue *q; 6768 struct iwl_queue *q;
6740 unsigned long flags; 6769 unsigned long flags;
6741 6770
@@ -6749,7 +6778,7 @@ static int iwl3945_mac_get_tx_stats(struct ieee80211_hw *hw,
6749 spin_lock_irqsave(&priv->lock, flags); 6778 spin_lock_irqsave(&priv->lock, flags);
6750 6779
6751 for (i = 0; i < AC_NUM; i++) { 6780 for (i = 0; i < AC_NUM; i++) {
6752 txq = &priv->txq39[i]; 6781 txq = &priv->txq[i];
6753 q = &txq->q; 6782 q = &txq->q;
6754 avail = iwl_queue_space(q); 6783 avail = iwl_queue_space(q);
6755 6784