diff options
author | Samuel Ortiz <samuel.ortiz@intel.com> | 2008-12-21 22:31:16 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-01-29 15:59:24 -0500 |
commit | 188cf6c73a72be1d8c118580a40d70cd76415eec (patch) | |
tree | e684a15fb8011a5666075062315790f3cb6d1600 /drivers | |
parent | 42427b4e436bbbf038742ecbb3bf09815f93ed7a (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.h | 4 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-3945.c | 14 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-3945.h | 8 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-4965-hw.h | 3 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-dev.h | 28 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-fh.h | 11 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl3945-base.c | 125 |
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) | |||
306 | static void iwl3945_tx_queue_reclaim(struct iwl_priv *priv, | 306 | static 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 | */ |
759 | int iwl3945_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl3945_tx_queue *txq) | 759 | int 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 | ||
1257 | void iwl3945_hw_txq_ctx_stop(struct iwl_priv *priv) | 1257 | void 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 | ||
2345 | int iwl3945_hw_tx_queue_init(struct iwl_priv *priv, struct iwl3945_tx_queue *txq) | 2345 | int 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, | |||
219 | extern int iwl3945_calc_db_from_ratio(int sig_ratio); | 219 | extern int iwl3945_calc_db_from_ratio(int sig_ratio); |
220 | extern int iwl3945_calc_sig_qual(int rssi_dbm, int noise_dbm); | 220 | extern int iwl3945_calc_sig_qual(int rssi_dbm, int noise_dbm); |
221 | extern int iwl3945_tx_queue_init(struct iwl_priv *priv, | 221 | extern 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); |
223 | extern void iwl3945_rx_replenish(void *data); | 223 | extern void iwl3945_rx_replenish(void *data); |
224 | extern void iwl3945_tx_queue_free(struct iwl_priv *priv, struct iwl3945_tx_queue *txq); | 224 | extern void iwl3945_tx_queue_free(struct iwl_priv *priv, struct iwl_tx_queue *txq); |
225 | extern int iwl3945_send_cmd_pdu(struct iwl_priv *priv, u8 id, u16 len, | 225 | extern int iwl3945_send_cmd_pdu(struct iwl_priv *priv, u8 id, u16 len, |
226 | const void *data); | 226 | const void *data); |
227 | extern int __must_check iwl3945_send_cmd(struct iwl_priv *priv, | 227 | extern 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); | |||
270 | extern int iwl3945_hw_nic_reset(struct iwl_priv *priv); | 270 | extern int iwl3945_hw_nic_reset(struct iwl_priv *priv); |
271 | extern int iwl3945_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, void *tfd, | 271 | extern 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); |
273 | extern int iwl3945_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl3945_tx_queue *txq); | 273 | extern int iwl3945_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq); |
274 | extern int iwl3945_hw_get_temperature(struct iwl_priv *priv); | 274 | extern int iwl3945_hw_get_temperature(struct iwl_priv *priv); |
275 | extern int iwl3945_hw_tx_queue_init(struct iwl_priv *priv, | 275 | extern int iwl3945_hw_tx_queue_init(struct iwl_priv *priv, |
276 | struct iwl3945_tx_queue *txq); | 276 | struct iwl_tx_queue *txq); |
277 | extern unsigned int iwl3945_hw_get_beacon_cmd(struct iwl_priv *priv, | 277 | extern 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); |
279 | void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv, struct iwl_cmd *cmd, | 279 | void 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 | |||
137 | struct iwl_tx_queue { | 140 | struct 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 | */ | ||
241 | struct 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 | ||
481 | struct iwl3945_tfd_frame_data { | ||
482 | __le32 addr; | ||
483 | __le32 len; | ||
484 | } __attribute__ ((packed)); | ||
485 | |||
486 | struct 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 | ||
59 | static int iwl3945_tx_queue_update_write_ptr(struct iwl_priv *priv, | 59 | static 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 | */ |
164 | static int iwl3945_tx_queue_alloc(struct iwl_priv *priv, | 164 | static 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 | */ |
207 | int iwl3945_tx_queue_init(struct iwl_priv *priv, | 207 | int 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; |
253 | err: | ||
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 | */ |
259 | void iwl3945_tx_queue_free(struct iwl_priv *priv, struct iwl3945_tx_queue *txq) | 274 | void 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 | */ |
445 | static int iwl3945_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | 461 | static 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 | } |
626 | fail: | 649 | fail: |
@@ -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) | |||
3076 | static void iwl3945_cmd_queue_reclaim(struct iwl_priv *priv, | 3105 | static 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 | */ |
3680 | static int iwl3945_tx_queue_update_write_ptr(struct iwl_priv *priv, | 3709 | static 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 | ||