diff options
author | Cahill, Ben M <ben.m.cahill@intel.com> | 2007-11-28 22:09:55 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 18:05:23 -0500 |
commit | 6440adb5760a897497c2b1ebdccc32c7944fd57f (patch) | |
tree | f7ab0b2eef45f35b79f6f4e60bccdf67514b5889 /drivers | |
parent | 8b6eaea8ec79b111a18a1c60333deb16ba27e6b3 (diff) |
iwlwifi: add comments to iwl*-base.c
Add comments to iwlXXXX-base.c
Signed-off-by: Cahill, Ben M <ben.m.cahill@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/iwl3945-base.c | 215 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl4965-base.c | 212 |
2 files changed, 356 insertions, 71 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index ba5146ffdf4d..71e9b7c52d57 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c | |||
@@ -63,13 +63,13 @@ static int iwl3945_tx_queue_update_write_ptr(struct iwl3945_priv *priv, | |||
63 | ******************************************************************************/ | 63 | ******************************************************************************/ |
64 | 64 | ||
65 | /* module parameters */ | 65 | /* module parameters */ |
66 | static int iwl3945_param_disable_hw_scan; | 66 | static int iwl3945_param_disable_hw_scan; /* def: 0 = use 3945's h/w scan */ |
67 | static int iwl3945_param_debug; | 67 | static int iwl3945_param_debug; /* def: 0 = minimal debug log messages */ |
68 | static int iwl3945_param_disable; /* def: enable radio */ | 68 | static int iwl3945_param_disable; /* def: 0 = enable radio */ |
69 | static int iwl3945_param_antenna; /* def: 0 = both antennas (use diversity) */ | 69 | static int iwl3945_param_antenna; /* def: 0 = both antennas (use diversity) */ |
70 | int iwl3945_param_hwcrypto; /* def: using software encryption */ | 70 | int iwl3945_param_hwcrypto; /* def: 0 = use software encryption */ |
71 | static int iwl3945_param_qos_enable = 1; | 71 | static int iwl3945_param_qos_enable = 1; /* def: 1 = use quality of service */ |
72 | int iwl3945_param_queues_num = IWL_MAX_NUM_QUEUES; | 72 | int iwl3945_param_queues_num = IWL_MAX_NUM_QUEUES; /* def: 8 Tx queues */ |
73 | 73 | ||
74 | /* | 74 | /* |
75 | * module name, copyright, version, etc. | 75 | * module name, copyright, version, etc. |
@@ -184,17 +184,24 @@ static void iwl3945_print_hex_dump(int level, void *p, u32 len) | |||
184 | * | 184 | * |
185 | * Theory of operation | 185 | * Theory of operation |
186 | * | 186 | * |
187 | * A queue is a circular buffers with 'Read' and 'Write' pointers. | 187 | * A Tx or Rx queue resides in host DRAM, and is comprised of a circular buffer |
188 | * 2 empty entries always kept in the buffer to protect from overflow. | 188 | * of buffer descriptors, each of which points to one or more data buffers for |
189 | * the device to read from or fill. Driver and device exchange status of each | ||
190 | * queue via "read" and "write" pointers. Driver keeps minimum of 2 empty | ||
191 | * entries in each circular buffer, to protect against confusing empty and full | ||
192 | * queue states. | ||
193 | * | ||
194 | * The device reads or writes the data in the queues via the device's several | ||
195 | * DMA/FIFO channels. Each queue is mapped to a single DMA channel. | ||
189 | * | 196 | * |
190 | * For Tx queue, there are low mark and high mark limits. If, after queuing | 197 | * For Tx queue, there are low mark and high mark limits. If, after queuing |
191 | * the packet for Tx, free space become < low mark, Tx queue stopped. When | 198 | * the packet for Tx, free space become < low mark, Tx queue stopped. When |
192 | * reclaiming packets (on 'tx done IRQ), if free space become > high mark, | 199 | * reclaiming packets (on 'tx done IRQ), if free space become > high mark, |
193 | * Tx queue resumed. | 200 | * Tx queue resumed. |
194 | * | 201 | * |
195 | * The IWL operates with six queues, one receive queue in the device's | 202 | * The 3945 operates with six queues: One receive queue, one transmit queue |
196 | * sram, one transmit queue for sending commands to the device firmware, | 203 | * (#4) for sending commands to the device firmware, and four transmit queues |
197 | * and four transmit queues for data. | 204 | * (#0-3) for data tx via EDCA. An additional 2 HCCA queues are unused. |
198 | ***************************************************/ | 205 | ***************************************************/ |
199 | 206 | ||
200 | static int iwl3945_queue_space(const struct iwl3945_queue *q) | 207 | static int iwl3945_queue_space(const struct iwl3945_queue *q) |
@@ -213,13 +220,21 @@ static int iwl3945_queue_space(const struct iwl3945_queue *q) | |||
213 | return s; | 220 | return s; |
214 | } | 221 | } |
215 | 222 | ||
216 | /* XXX: n_bd must be power-of-two size */ | 223 | /** |
224 | * iwl3945_queue_inc_wrap - increment queue index, wrap back to beginning | ||
225 | * @index -- current index | ||
226 | * @n_bd -- total number of entries in queue (must be power of 2) | ||
227 | */ | ||
217 | static inline int iwl3945_queue_inc_wrap(int index, int n_bd) | 228 | static inline int iwl3945_queue_inc_wrap(int index, int n_bd) |
218 | { | 229 | { |
219 | return ++index & (n_bd - 1); | 230 | return ++index & (n_bd - 1); |
220 | } | 231 | } |
221 | 232 | ||
222 | /* XXX: n_bd must be power-of-two size */ | 233 | /** |
234 | * iwl3945_queue_dec_wrap - increment queue index, wrap back to end | ||
235 | * @index -- current index | ||
236 | * @n_bd -- total number of entries in queue (must be power of 2) | ||
237 | */ | ||
223 | static inline int iwl3945_queue_dec_wrap(int index, int n_bd) | 238 | static inline int iwl3945_queue_dec_wrap(int index, int n_bd) |
224 | { | 239 | { |
225 | return --index & (n_bd - 1); | 240 | return --index & (n_bd - 1); |
@@ -234,12 +249,17 @@ static inline int x2_queue_used(const struct iwl3945_queue *q, int i) | |||
234 | 249 | ||
235 | static inline u8 get_cmd_index(struct iwl3945_queue *q, u32 index, int is_huge) | 250 | static inline u8 get_cmd_index(struct iwl3945_queue *q, u32 index, int is_huge) |
236 | { | 251 | { |
252 | /* This is for scan command, the big buffer at end of command array */ | ||
237 | if (is_huge) | 253 | if (is_huge) |
238 | return q->n_window; | 254 | return q->n_window; /* must be power of 2 */ |
239 | 255 | ||
256 | /* Otherwise, use normal size buffers */ | ||
240 | return index & (q->n_window - 1); | 257 | return index & (q->n_window - 1); |
241 | } | 258 | } |
242 | 259 | ||
260 | /** | ||
261 | * iwl3945_queue_init - Initialize queue's high/low-water and read/write indexes | ||
262 | */ | ||
243 | static int iwl3945_queue_init(struct iwl3945_priv *priv, struct iwl3945_queue *q, | 263 | static int iwl3945_queue_init(struct iwl3945_priv *priv, struct iwl3945_queue *q, |
244 | int count, int slots_num, u32 id) | 264 | int count, int slots_num, u32 id) |
245 | { | 265 | { |
@@ -268,11 +288,16 @@ static int iwl3945_queue_init(struct iwl3945_priv *priv, struct iwl3945_queue *q | |||
268 | return 0; | 288 | return 0; |
269 | } | 289 | } |
270 | 290 | ||
291 | /** | ||
292 | * iwl3945_tx_queue_alloc - Alloc driver data and TFD CB for one Tx/cmd queue | ||
293 | */ | ||
271 | static int iwl3945_tx_queue_alloc(struct iwl3945_priv *priv, | 294 | static int iwl3945_tx_queue_alloc(struct iwl3945_priv *priv, |
272 | struct iwl3945_tx_queue *txq, u32 id) | 295 | struct iwl3945_tx_queue *txq, u32 id) |
273 | { | 296 | { |
274 | struct pci_dev *dev = priv->pci_dev; | 297 | struct pci_dev *dev = priv->pci_dev; |
275 | 298 | ||
299 | /* Driver private data, only for Tx (not command) queues, | ||
300 | * not shared with device. */ | ||
276 | if (id != IWL_CMD_QUEUE_NUM) { | 301 | if (id != IWL_CMD_QUEUE_NUM) { |
277 | txq->txb = kmalloc(sizeof(txq->txb[0]) * | 302 | txq->txb = kmalloc(sizeof(txq->txb[0]) * |
278 | TFD_QUEUE_SIZE_MAX, GFP_KERNEL); | 303 | TFD_QUEUE_SIZE_MAX, GFP_KERNEL); |
@@ -284,6 +309,8 @@ static int iwl3945_tx_queue_alloc(struct iwl3945_priv *priv, | |||
284 | } else | 309 | } else |
285 | txq->txb = NULL; | 310 | txq->txb = NULL; |
286 | 311 | ||
312 | /* Circular buffer of transmit frame descriptors (TFDs), | ||
313 | * shared with device */ | ||
287 | txq->bd = pci_alloc_consistent(dev, | 314 | txq->bd = pci_alloc_consistent(dev, |
288 | sizeof(txq->bd[0]) * TFD_QUEUE_SIZE_MAX, | 315 | sizeof(txq->bd[0]) * TFD_QUEUE_SIZE_MAX, |
289 | &txq->q.dma_addr); | 316 | &txq->q.dma_addr); |
@@ -306,6 +333,9 @@ static int iwl3945_tx_queue_alloc(struct iwl3945_priv *priv, | |||
306 | return -ENOMEM; | 333 | return -ENOMEM; |
307 | } | 334 | } |
308 | 335 | ||
336 | /** | ||
337 | * iwl3945_tx_queue_init - Allocate and initialize one tx/cmd queue | ||
338 | */ | ||
309 | int iwl3945_tx_queue_init(struct iwl3945_priv *priv, | 339 | int iwl3945_tx_queue_init(struct iwl3945_priv *priv, |
310 | struct iwl3945_tx_queue *txq, int slots_num, u32 txq_id) | 340 | struct iwl3945_tx_queue *txq, int slots_num, u32 txq_id) |
311 | { | 341 | { |
@@ -313,9 +343,14 @@ int iwl3945_tx_queue_init(struct iwl3945_priv *priv, | |||
313 | int len; | 343 | int len; |
314 | int rc = 0; | 344 | int rc = 0; |
315 | 345 | ||
316 | /* allocate command space + one big command for scan since scan | 346 | /* |
317 | * command is very huge the system will not have two scan at the | 347 | * Alloc buffer array for commands (Tx or other types of commands). |
318 | * same time */ | 348 | * For the command queue (#4), allocate command space + one big |
349 | * command for scan, since scan command is very huge; the system will | ||
350 | * not have two scans at the same time, so only one is needed. | ||
351 | * For data Tx queues (all other queues), no super-size command | ||
352 | * space is needed. | ||
353 | */ | ||
319 | len = sizeof(struct iwl3945_cmd) * slots_num; | 354 | len = sizeof(struct iwl3945_cmd) * slots_num; |
320 | if (txq_id == IWL_CMD_QUEUE_NUM) | 355 | if (txq_id == IWL_CMD_QUEUE_NUM) |
321 | len += IWL_MAX_SCAN_SIZE; | 356 | len += IWL_MAX_SCAN_SIZE; |
@@ -323,6 +358,7 @@ int iwl3945_tx_queue_init(struct iwl3945_priv *priv, | |||
323 | if (!txq->cmd) | 358 | if (!txq->cmd) |
324 | return -ENOMEM; | 359 | return -ENOMEM; |
325 | 360 | ||
361 | /* Alloc driver data array and TFD circular buffer */ | ||
326 | rc = iwl3945_tx_queue_alloc(priv, txq, txq_id); | 362 | rc = iwl3945_tx_queue_alloc(priv, txq, txq_id); |
327 | if (rc) { | 363 | if (rc) { |
328 | pci_free_consistent(dev, len, txq->cmd, txq->dma_addr_cmd); | 364 | pci_free_consistent(dev, len, txq->cmd, txq->dma_addr_cmd); |
@@ -334,8 +370,11 @@ int iwl3945_tx_queue_init(struct iwl3945_priv *priv, | |||
334 | /* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise | 370 | /* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise |
335 | * iwl3945_queue_inc_wrap and iwl3945_queue_dec_wrap are broken. */ | 371 | * iwl3945_queue_inc_wrap and iwl3945_queue_dec_wrap are broken. */ |
336 | BUILD_BUG_ON(TFD_QUEUE_SIZE_MAX & (TFD_QUEUE_SIZE_MAX - 1)); | 372 | BUILD_BUG_ON(TFD_QUEUE_SIZE_MAX & (TFD_QUEUE_SIZE_MAX - 1)); |
373 | |||
374 | /* Initialize queue high/low-water, head/tail indexes */ | ||
337 | iwl3945_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id); | 375 | iwl3945_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id); |
338 | 376 | ||
377 | /* Tell device where to find queue, enable DMA channel. */ | ||
339 | iwl3945_hw_tx_queue_init(priv, txq); | 378 | iwl3945_hw_tx_queue_init(priv, txq); |
340 | 379 | ||
341 | return 0; | 380 | return 0; |
@@ -346,8 +385,8 @@ int iwl3945_tx_queue_init(struct iwl3945_priv *priv, | |||
346 | * @txq: Transmit queue to deallocate. | 385 | * @txq: Transmit queue to deallocate. |
347 | * | 386 | * |
348 | * Empty queue by removing and destroying all BD's. | 387 | * Empty queue by removing and destroying all BD's. |
349 | * Free all buffers. txq itself is not freed. | 388 | * Free all buffers. |
350 | * | 389 | * 0-fill, but do not free "txq" descriptor structure. |
351 | */ | 390 | */ |
352 | void iwl3945_tx_queue_free(struct iwl3945_priv *priv, struct iwl3945_tx_queue *txq) | 391 | void iwl3945_tx_queue_free(struct iwl3945_priv *priv, struct iwl3945_tx_queue *txq) |
353 | { | 392 | { |
@@ -367,19 +406,21 @@ void iwl3945_tx_queue_free(struct iwl3945_priv *priv, struct iwl3945_tx_queue *t | |||
367 | if (q->id == IWL_CMD_QUEUE_NUM) | 406 | if (q->id == IWL_CMD_QUEUE_NUM) |
368 | len += IWL_MAX_SCAN_SIZE; | 407 | len += IWL_MAX_SCAN_SIZE; |
369 | 408 | ||
409 | /* De-alloc array of command/tx buffers */ | ||
370 | pci_free_consistent(dev, len, txq->cmd, txq->dma_addr_cmd); | 410 | pci_free_consistent(dev, len, txq->cmd, txq->dma_addr_cmd); |
371 | 411 | ||
372 | /* free buffers belonging to queue itself */ | 412 | /* De-alloc circular buffer of TFDs */ |
373 | if (txq->q.n_bd) | 413 | if (txq->q.n_bd) |
374 | pci_free_consistent(dev, sizeof(struct iwl3945_tfd_frame) * | 414 | pci_free_consistent(dev, sizeof(struct iwl3945_tfd_frame) * |
375 | txq->q.n_bd, txq->bd, txq->q.dma_addr); | 415 | txq->q.n_bd, txq->bd, txq->q.dma_addr); |
376 | 416 | ||
417 | /* De-alloc array of per-TFD driver data */ | ||
377 | if (txq->txb) { | 418 | if (txq->txb) { |
378 | kfree(txq->txb); | 419 | kfree(txq->txb); |
379 | txq->txb = NULL; | 420 | txq->txb = NULL; |
380 | } | 421 | } |
381 | 422 | ||
382 | /* 0 fill whole structure */ | 423 | /* 0-fill queue descriptor structure */ |
383 | memset(txq, 0, sizeof(*txq)); | 424 | memset(txq, 0, sizeof(*txq)); |
384 | } | 425 | } |
385 | 426 | ||
@@ -392,6 +433,11 @@ const u8 iwl3945_broadcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF | |||
392 | 433 | ||
393 | /**************************************************************/ | 434 | /**************************************************************/ |
394 | #if 0 /* temporary disable till we add real remove station */ | 435 | #if 0 /* temporary disable till we add real remove station */ |
436 | /** | ||
437 | * iwl3945_remove_station - Remove driver's knowledge of station. | ||
438 | * | ||
439 | * NOTE: This does not remove station from device's station table. | ||
440 | */ | ||
395 | static u8 iwl3945_remove_station(struct iwl3945_priv *priv, const u8 *addr, int is_ap) | 441 | static u8 iwl3945_remove_station(struct iwl3945_priv *priv, const u8 *addr, int is_ap) |
396 | { | 442 | { |
397 | int index = IWL_INVALID_STATION; | 443 | int index = IWL_INVALID_STATION; |
@@ -428,6 +474,12 @@ out: | |||
428 | return 0; | 474 | return 0; |
429 | } | 475 | } |
430 | #endif | 476 | #endif |
477 | |||
478 | /** | ||
479 | * iwl3945_clear_stations_table - Clear the driver's station table | ||
480 | * | ||
481 | * NOTE: This does not clear or otherwise alter the device's station table. | ||
482 | */ | ||
431 | static void iwl3945_clear_stations_table(struct iwl3945_priv *priv) | 483 | static void iwl3945_clear_stations_table(struct iwl3945_priv *priv) |
432 | { | 484 | { |
433 | unsigned long flags; | 485 | unsigned long flags; |
@@ -440,7 +492,9 @@ static void iwl3945_clear_stations_table(struct iwl3945_priv *priv) | |||
440 | spin_unlock_irqrestore(&priv->sta_lock, flags); | 492 | spin_unlock_irqrestore(&priv->sta_lock, flags); |
441 | } | 493 | } |
442 | 494 | ||
443 | 495 | /** | |
496 | * iwl3945_add_station - Add station to station tables in driver and device | ||
497 | */ | ||
444 | u8 iwl3945_add_station(struct iwl3945_priv *priv, const u8 *addr, int is_ap, u8 flags) | 498 | u8 iwl3945_add_station(struct iwl3945_priv *priv, const u8 *addr, int is_ap, u8 flags) |
445 | { | 499 | { |
446 | int i; | 500 | int i; |
@@ -486,6 +540,7 @@ u8 iwl3945_add_station(struct iwl3945_priv *priv, const u8 *addr, int is_ap, u8 | |||
486 | station->used = 1; | 540 | station->used = 1; |
487 | priv->num_stations++; | 541 | priv->num_stations++; |
488 | 542 | ||
543 | /* Set up the REPLY_ADD_STA command to send to device */ | ||
489 | memset(&station->sta, 0, sizeof(struct iwl3945_addsta_cmd)); | 544 | memset(&station->sta, 0, sizeof(struct iwl3945_addsta_cmd)); |
490 | memcpy(station->sta.sta.addr, addr, ETH_ALEN); | 545 | memcpy(station->sta.sta.addr, addr, ETH_ALEN); |
491 | station->sta.mode = 0; | 546 | station->sta.mode = 0; |
@@ -504,6 +559,8 @@ u8 iwl3945_add_station(struct iwl3945_priv *priv, const u8 *addr, int is_ap, u8 | |||
504 | le16_to_cpu(station->sta.rate_n_flags); | 559 | le16_to_cpu(station->sta.rate_n_flags); |
505 | 560 | ||
506 | spin_unlock_irqrestore(&priv->sta_lock, flags_spin); | 561 | spin_unlock_irqrestore(&priv->sta_lock, flags_spin); |
562 | |||
563 | /* Add station to device's station table */ | ||
507 | iwl3945_send_add_station(priv, &station->sta, flags); | 564 | iwl3945_send_add_station(priv, &station->sta, flags); |
508 | return index; | 565 | return index; |
509 | 566 | ||
@@ -673,6 +730,8 @@ static int iwl3945_enqueue_hcmd(struct iwl3945_priv *priv, struct iwl3945_host_c | |||
673 | fix_size, q->write_ptr, idx, IWL_CMD_QUEUE_NUM); | 730 | fix_size, q->write_ptr, idx, IWL_CMD_QUEUE_NUM); |
674 | 731 | ||
675 | txq->need_update = 1; | 732 | txq->need_update = 1; |
733 | |||
734 | /* Increment and update queue's write index */ | ||
676 | q->write_ptr = iwl3945_queue_inc_wrap(q->write_ptr, q->n_bd); | 735 | q->write_ptr = iwl3945_queue_inc_wrap(q->write_ptr, q->n_bd); |
677 | ret = iwl3945_tx_queue_update_write_ptr(priv, txq); | 736 | ret = iwl3945_tx_queue_update_write_ptr(priv, txq); |
678 | 737 | ||
@@ -1511,7 +1570,7 @@ static void get_eeprom_mac(struct iwl3945_priv *priv, u8 *mac) | |||
1511 | /** | 1570 | /** |
1512 | * iwl3945_eeprom_init - read EEPROM contents | 1571 | * iwl3945_eeprom_init - read EEPROM contents |
1513 | * | 1572 | * |
1514 | * Load the EEPROM from adapter into priv->eeprom | 1573 | * Load the EEPROM contents from adapter into priv->eeprom |
1515 | * | 1574 | * |
1516 | * NOTE: This routine uses the non-debug IO access functions. | 1575 | * NOTE: This routine uses the non-debug IO access functions. |
1517 | */ | 1576 | */ |
@@ -1536,6 +1595,7 @@ int iwl3945_eeprom_init(struct iwl3945_priv *priv) | |||
1536 | return -ENOENT; | 1595 | return -ENOENT; |
1537 | } | 1596 | } |
1538 | 1597 | ||
1598 | /* Make sure driver (instead of uCode) is allowed to read EEPROM */ | ||
1539 | rc = iwl3945_eeprom_acquire_semaphore(priv); | 1599 | rc = iwl3945_eeprom_acquire_semaphore(priv); |
1540 | if (rc < 0) { | 1600 | if (rc < 0) { |
1541 | IWL_ERROR("Failed to acquire EEPROM semaphore.\n"); | 1601 | IWL_ERROR("Failed to acquire EEPROM semaphore.\n"); |
@@ -2631,21 +2691,23 @@ static void iwl3945_build_tx_cmd_basic(struct iwl3945_priv *priv, | |||
2631 | cmd->cmd.tx.next_frame_len = 0; | 2691 | cmd->cmd.tx.next_frame_len = 0; |
2632 | } | 2692 | } |
2633 | 2693 | ||
2694 | /** | ||
2695 | * iwl3945_get_sta_id - Find station's index within station table | ||
2696 | */ | ||
2634 | static int iwl3945_get_sta_id(struct iwl3945_priv *priv, struct ieee80211_hdr *hdr) | 2697 | static int iwl3945_get_sta_id(struct iwl3945_priv *priv, struct ieee80211_hdr *hdr) |
2635 | { | 2698 | { |
2636 | int sta_id; | 2699 | int sta_id; |
2637 | u16 fc = le16_to_cpu(hdr->frame_control); | 2700 | u16 fc = le16_to_cpu(hdr->frame_control); |
2638 | 2701 | ||
2639 | /* If this frame is broadcast or not data then use the broadcast | 2702 | /* If this frame is broadcast or management, use broadcast station id */ |
2640 | * station id */ | ||
2641 | if (((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA) || | 2703 | if (((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA) || |
2642 | is_multicast_ether_addr(hdr->addr1)) | 2704 | is_multicast_ether_addr(hdr->addr1)) |
2643 | return priv->hw_setting.bcast_sta_id; | 2705 | return priv->hw_setting.bcast_sta_id; |
2644 | 2706 | ||
2645 | switch (priv->iw_mode) { | 2707 | switch (priv->iw_mode) { |
2646 | 2708 | ||
2647 | /* If this frame is part of a BSS network (we're a station), then | 2709 | /* If we are a client station in a BSS network, use the special |
2648 | * we use the AP's station id */ | 2710 | * AP station entry (that's the only station we communicate with) */ |
2649 | case IEEE80211_IF_TYPE_STA: | 2711 | case IEEE80211_IF_TYPE_STA: |
2650 | return IWL_AP_ID; | 2712 | return IWL_AP_ID; |
2651 | 2713 | ||
@@ -2656,11 +2718,12 @@ static int iwl3945_get_sta_id(struct iwl3945_priv *priv, struct ieee80211_hdr *h | |||
2656 | return sta_id; | 2718 | return sta_id; |
2657 | return priv->hw_setting.bcast_sta_id; | 2719 | return priv->hw_setting.bcast_sta_id; |
2658 | 2720 | ||
2659 | /* If this frame is part of a IBSS network, then we use the | 2721 | /* If this frame is going out to an IBSS network, find the station, |
2660 | * target specific station id */ | 2722 | * or create a new station table entry */ |
2661 | case IEEE80211_IF_TYPE_IBSS: { | 2723 | case IEEE80211_IF_TYPE_IBSS: { |
2662 | DECLARE_MAC_BUF(mac); | 2724 | DECLARE_MAC_BUF(mac); |
2663 | 2725 | ||
2726 | /* Create new station table entry */ | ||
2664 | sta_id = iwl3945_hw_find_station(priv, hdr->addr1); | 2727 | sta_id = iwl3945_hw_find_station(priv, hdr->addr1); |
2665 | if (sta_id != IWL_INVALID_STATION) | 2728 | if (sta_id != IWL_INVALID_STATION) |
2666 | return sta_id; | 2729 | return sta_id; |
@@ -2746,6 +2809,8 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, | |||
2746 | spin_unlock_irqrestore(&priv->lock, flags); | 2809 | spin_unlock_irqrestore(&priv->lock, flags); |
2747 | 2810 | ||
2748 | hdr_len = ieee80211_get_hdrlen(fc); | 2811 | hdr_len = ieee80211_get_hdrlen(fc); |
2812 | |||
2813 | /* Find (or create) index into station table for destination station */ | ||
2749 | sta_id = iwl3945_get_sta_id(priv, hdr); | 2814 | sta_id = iwl3945_get_sta_id(priv, hdr); |
2750 | if (sta_id == IWL_INVALID_STATION) { | 2815 | if (sta_id == IWL_INVALID_STATION) { |
2751 | DECLARE_MAC_BUF(mac); | 2816 | DECLARE_MAC_BUF(mac); |
@@ -2767,30 +2832,52 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, | |||
2767 | __constant_cpu_to_le16(IEEE80211_SCTL_FRAG)); | 2832 | __constant_cpu_to_le16(IEEE80211_SCTL_FRAG)); |
2768 | seq_number += 0x10; | 2833 | seq_number += 0x10; |
2769 | } | 2834 | } |
2835 | |||
2836 | /* Descriptor for chosen Tx queue */ | ||
2770 | txq = &priv->txq[txq_id]; | 2837 | txq = &priv->txq[txq_id]; |
2771 | q = &txq->q; | 2838 | q = &txq->q; |
2772 | 2839 | ||
2773 | spin_lock_irqsave(&priv->lock, flags); | 2840 | spin_lock_irqsave(&priv->lock, flags); |
2774 | 2841 | ||
2842 | /* Set up first empty TFD within this queue's circular TFD buffer */ | ||
2775 | tfd = &txq->bd[q->write_ptr]; | 2843 | tfd = &txq->bd[q->write_ptr]; |
2776 | memset(tfd, 0, sizeof(*tfd)); | 2844 | memset(tfd, 0, sizeof(*tfd)); |
2777 | control_flags = (u32 *) tfd; | 2845 | control_flags = (u32 *) tfd; |
2778 | idx = get_cmd_index(q, q->write_ptr, 0); | 2846 | idx = get_cmd_index(q, q->write_ptr, 0); |
2779 | 2847 | ||
2848 | /* Set up driver data for this TFD */ | ||
2780 | memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl3945_tx_info)); | 2849 | memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl3945_tx_info)); |
2781 | txq->txb[q->write_ptr].skb[0] = skb; | 2850 | txq->txb[q->write_ptr].skb[0] = skb; |
2782 | memcpy(&(txq->txb[q->write_ptr].status.control), | 2851 | memcpy(&(txq->txb[q->write_ptr].status.control), |
2783 | ctl, sizeof(struct ieee80211_tx_control)); | 2852 | ctl, sizeof(struct ieee80211_tx_control)); |
2853 | |||
2854 | /* Init first empty entry in queue's array of Tx/cmd buffers */ | ||
2784 | out_cmd = &txq->cmd[idx]; | 2855 | out_cmd = &txq->cmd[idx]; |
2785 | memset(&out_cmd->hdr, 0, sizeof(out_cmd->hdr)); | 2856 | memset(&out_cmd->hdr, 0, sizeof(out_cmd->hdr)); |
2786 | memset(&out_cmd->cmd.tx, 0, sizeof(out_cmd->cmd.tx)); | 2857 | memset(&out_cmd->cmd.tx, 0, sizeof(out_cmd->cmd.tx)); |
2858 | |||
2859 | /* | ||
2860 | * Set up the Tx-command (not MAC!) header. | ||
2861 | * Store the chosen Tx queue and TFD index within the sequence field; | ||
2862 | * after Tx, uCode's Tx response will return this value so driver can | ||
2863 | * locate the frame within the tx queue and do post-tx processing. | ||
2864 | */ | ||
2787 | out_cmd->hdr.cmd = REPLY_TX; | 2865 | out_cmd->hdr.cmd = REPLY_TX; |
2788 | out_cmd->hdr.sequence = cpu_to_le16((u16)(QUEUE_TO_SEQ(txq_id) | | 2866 | out_cmd->hdr.sequence = cpu_to_le16((u16)(QUEUE_TO_SEQ(txq_id) | |
2789 | INDEX_TO_SEQ(q->write_ptr))); | 2867 | INDEX_TO_SEQ(q->write_ptr))); |
2790 | /* copy frags header */ | 2868 | |
2869 | /* Copy MAC header from skb into command buffer */ | ||
2791 | memcpy(out_cmd->cmd.tx.hdr, hdr, hdr_len); | 2870 | memcpy(out_cmd->cmd.tx.hdr, hdr, hdr_len); |
2792 | 2871 | ||
2793 | /* hdr = (struct ieee80211_hdr *)out_cmd->cmd.tx.hdr; */ | 2872 | /* |
2873 | * Use the first empty entry in this queue's command buffer array | ||
2874 | * to contain the Tx command and MAC header concatenated together | ||
2875 | * (payload data will be in another buffer). | ||
2876 | * Size of this varies, due to varying MAC header length. | ||
2877 | * If end is not dword aligned, we'll have 2 extra bytes at the end | ||
2878 | * of the MAC header (device reads on dword boundaries). | ||
2879 | * We'll tell device about this padding later. | ||
2880 | */ | ||
2794 | len = priv->hw_setting.tx_cmd_len + | 2881 | len = priv->hw_setting.tx_cmd_len + |
2795 | sizeof(struct iwl3945_cmd_header) + hdr_len; | 2882 | sizeof(struct iwl3945_cmd_header) + hdr_len; |
2796 | 2883 | ||
@@ -2802,15 +2889,20 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, | |||
2802 | else | 2889 | else |
2803 | len_org = 0; | 2890 | len_org = 0; |
2804 | 2891 | ||
2892 | /* Physical address of this Tx command's header (not MAC header!), | ||
2893 | * within command buffer array. */ | ||
2805 | txcmd_phys = txq->dma_addr_cmd + sizeof(struct iwl3945_cmd) * idx + | 2894 | txcmd_phys = txq->dma_addr_cmd + sizeof(struct iwl3945_cmd) * idx + |
2806 | offsetof(struct iwl3945_cmd, hdr); | 2895 | offsetof(struct iwl3945_cmd, hdr); |
2807 | 2896 | ||
2897 | /* Add buffer containing Tx command and MAC(!) header to TFD's | ||
2898 | * first entry */ | ||
2808 | iwl3945_hw_txq_attach_buf_to_tfd(priv, tfd, txcmd_phys, len); | 2899 | iwl3945_hw_txq_attach_buf_to_tfd(priv, tfd, txcmd_phys, len); |
2809 | 2900 | ||
2810 | if (!(ctl->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT)) | 2901 | if (!(ctl->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT)) |
2811 | iwl3945_build_tx_cmd_hwcrypto(priv, ctl, out_cmd, skb, 0); | 2902 | iwl3945_build_tx_cmd_hwcrypto(priv, ctl, out_cmd, skb, 0); |
2812 | 2903 | ||
2813 | /* 802.11 null functions have no payload... */ | 2904 | /* Set up TFD's 2nd entry to point directly to remainder of skb, |
2905 | * if any (802.11 null frames have no payload). */ | ||
2814 | len = skb->len - hdr_len; | 2906 | len = skb->len - hdr_len; |
2815 | if (len) { | 2907 | if (len) { |
2816 | phys_addr = pci_map_single(priv->pci_dev, skb->data + hdr_len, | 2908 | phys_addr = pci_map_single(priv->pci_dev, skb->data + hdr_len, |
@@ -2818,13 +2910,16 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, | |||
2818 | iwl3945_hw_txq_attach_buf_to_tfd(priv, tfd, phys_addr, len); | 2910 | iwl3945_hw_txq_attach_buf_to_tfd(priv, tfd, phys_addr, len); |
2819 | } | 2911 | } |
2820 | 2912 | ||
2821 | /* If there is no payload, then only one TFD is used */ | ||
2822 | if (!len) | 2913 | if (!len) |
2914 | /* If there is no payload, then we use only one Tx buffer */ | ||
2823 | *control_flags = TFD_CTL_COUNT_SET(1); | 2915 | *control_flags = TFD_CTL_COUNT_SET(1); |
2824 | else | 2916 | else |
2917 | /* Else use 2 buffers. | ||
2918 | * Tell 3945 about any padding after MAC header */ | ||
2825 | *control_flags = TFD_CTL_COUNT_SET(2) | | 2919 | *control_flags = TFD_CTL_COUNT_SET(2) | |
2826 | TFD_CTL_PAD_SET(U32_PAD(len)); | 2920 | TFD_CTL_PAD_SET(U32_PAD(len)); |
2827 | 2921 | ||
2922 | /* Total # bytes to be transmitted */ | ||
2828 | len = (u16)skb->len; | 2923 | len = (u16)skb->len; |
2829 | out_cmd->cmd.tx.len = cpu_to_le16(len); | 2924 | out_cmd->cmd.tx.len = cpu_to_le16(len); |
2830 | 2925 | ||
@@ -2854,6 +2949,7 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, | |||
2854 | iwl3945_print_hex_dump(IWL_DL_TX, (u8 *)out_cmd->cmd.tx.hdr, | 2949 | iwl3945_print_hex_dump(IWL_DL_TX, (u8 *)out_cmd->cmd.tx.hdr, |
2855 | ieee80211_get_hdrlen(fc)); | 2950 | ieee80211_get_hdrlen(fc)); |
2856 | 2951 | ||
2952 | /* Tell device the write index *just past* this latest filled TFD */ | ||
2857 | q->write_ptr = iwl3945_queue_inc_wrap(q->write_ptr, q->n_bd); | 2953 | q->write_ptr = iwl3945_queue_inc_wrap(q->write_ptr, q->n_bd); |
2858 | rc = iwl3945_tx_queue_update_write_ptr(priv, txq); | 2954 | rc = iwl3945_tx_queue_update_write_ptr(priv, txq); |
2859 | spin_unlock_irqrestore(&priv->lock, flags); | 2955 | spin_unlock_irqrestore(&priv->lock, flags); |
@@ -3329,11 +3425,11 @@ static void iwl3945_txstatus_to_ieee(struct iwl3945_priv *priv, | |||
3329 | } | 3425 | } |
3330 | 3426 | ||
3331 | /** | 3427 | /** |
3332 | * iwl3945_tx_queue_reclaim - Reclaim Tx queue entries no more used by NIC. | 3428 | * iwl3945_tx_queue_reclaim - Reclaim Tx queue entries already Tx'd |
3333 | * | 3429 | * |
3334 | * When FW advances 'R' index, all entries between old and | 3430 | * When FW advances 'R' index, all entries between old and new 'R' index |
3335 | * new 'R' index need to be reclaimed. As result, some free space | 3431 | * need to be reclaimed. As result, some free space forms. If there is |
3336 | * forms. If there is enough free space (> low mark), wake Tx queue. | 3432 | * enough free space (> low mark), wake the stack that feeds us. |
3337 | */ | 3433 | */ |
3338 | static int iwl3945_tx_queue_reclaim(struct iwl3945_priv *priv, int txq_id, int index) | 3434 | static int iwl3945_tx_queue_reclaim(struct iwl3945_priv *priv, int txq_id, int index) |
3339 | { | 3435 | { |
@@ -3382,6 +3478,9 @@ static int iwl3945_is_tx_success(u32 status) | |||
3382 | * Generic RX handler implementations | 3478 | * Generic RX handler implementations |
3383 | * | 3479 | * |
3384 | ******************************************************************************/ | 3480 | ******************************************************************************/ |
3481 | /** | ||
3482 | * iwl3945_rx_reply_tx - Handle Tx response | ||
3483 | */ | ||
3385 | static void iwl3945_rx_reply_tx(struct iwl3945_priv *priv, | 3484 | static void iwl3945_rx_reply_tx(struct iwl3945_priv *priv, |
3386 | struct iwl3945_rx_mem_buffer *rxb) | 3485 | struct iwl3945_rx_mem_buffer *rxb) |
3387 | { | 3486 | { |
@@ -3917,6 +4016,7 @@ int iwl3945_rx_queue_update_write_ptr(struct iwl3945_priv *priv, struct iwl3945_ | |||
3917 | if (q->need_update == 0) | 4016 | if (q->need_update == 0) |
3918 | goto exit_unlock; | 4017 | goto exit_unlock; |
3919 | 4018 | ||
4019 | /* If power-saving is in use, make sure device is awake */ | ||
3920 | if (test_bit(STATUS_POWER_PMI, &priv->status)) { | 4020 | if (test_bit(STATUS_POWER_PMI, &priv->status)) { |
3921 | reg = iwl3945_read32(priv, CSR_UCODE_DRV_GP1); | 4021 | reg = iwl3945_read32(priv, CSR_UCODE_DRV_GP1); |
3922 | 4022 | ||
@@ -3930,10 +4030,14 @@ int iwl3945_rx_queue_update_write_ptr(struct iwl3945_priv *priv, struct iwl3945_ | |||
3930 | if (rc) | 4030 | if (rc) |
3931 | goto exit_unlock; | 4031 | goto exit_unlock; |
3932 | 4032 | ||
4033 | /* Device expects a multiple of 8 */ | ||
3933 | iwl3945_write_direct32(priv, FH_RSCSR_CHNL0_WPTR, | 4034 | iwl3945_write_direct32(priv, FH_RSCSR_CHNL0_WPTR, |
3934 | q->write & ~0x7); | 4035 | q->write & ~0x7); |
3935 | iwl3945_release_nic_access(priv); | 4036 | iwl3945_release_nic_access(priv); |
4037 | |||
4038 | /* Else device is assumed to be awake */ | ||
3936 | } else | 4039 | } else |
4040 | /* Device expects a multiple of 8 */ | ||
3937 | iwl3945_write32(priv, FH_RSCSR_CHNL0_WPTR, q->write & ~0x7); | 4041 | iwl3945_write32(priv, FH_RSCSR_CHNL0_WPTR, q->write & ~0x7); |
3938 | 4042 | ||
3939 | 4043 | ||
@@ -3975,9 +4079,12 @@ static int iwl3945_rx_queue_restock(struct iwl3945_priv *priv) | |||
3975 | spin_lock_irqsave(&rxq->lock, flags); | 4079 | spin_lock_irqsave(&rxq->lock, flags); |
3976 | write = rxq->write & ~0x7; | 4080 | write = rxq->write & ~0x7; |
3977 | while ((iwl3945_rx_queue_space(rxq) > 0) && (rxq->free_count)) { | 4081 | while ((iwl3945_rx_queue_space(rxq) > 0) && (rxq->free_count)) { |
4082 | /* Get next free Rx buffer, remove from free list */ | ||
3978 | element = rxq->rx_free.next; | 4083 | element = rxq->rx_free.next; |
3979 | rxb = list_entry(element, struct iwl3945_rx_mem_buffer, list); | 4084 | rxb = list_entry(element, struct iwl3945_rx_mem_buffer, list); |
3980 | list_del(element); | 4085 | list_del(element); |
4086 | |||
4087 | /* Point to Rx buffer via next RBD in circular buffer */ | ||
3981 | rxq->bd[rxq->write] = iwl3945_dma_addr2rbd_ptr(priv, rxb->dma_addr); | 4088 | rxq->bd[rxq->write] = iwl3945_dma_addr2rbd_ptr(priv, rxb->dma_addr); |
3982 | rxq->queue[rxq->write] = rxb; | 4089 | rxq->queue[rxq->write] = rxb; |
3983 | rxq->write = (rxq->write + 1) & RX_QUEUE_MASK; | 4090 | rxq->write = (rxq->write + 1) & RX_QUEUE_MASK; |
@@ -3990,7 +4097,8 @@ static int iwl3945_rx_queue_restock(struct iwl3945_priv *priv) | |||
3990 | queue_work(priv->workqueue, &priv->rx_replenish); | 4097 | queue_work(priv->workqueue, &priv->rx_replenish); |
3991 | 4098 | ||
3992 | 4099 | ||
3993 | /* If we've added more space for the firmware to place data, tell it */ | 4100 | /* If we've added more space for the firmware to place data, tell it. |
4101 | * Increment device's write pointer in multiples of 8. */ | ||
3994 | if ((write != (rxq->write & ~0x7)) | 4102 | if ((write != (rxq->write & ~0x7)) |
3995 | || (abs(rxq->write - rxq->read) > 7)) { | 4103 | || (abs(rxq->write - rxq->read) > 7)) { |
3996 | spin_lock_irqsave(&rxq->lock, flags); | 4104 | spin_lock_irqsave(&rxq->lock, flags); |
@@ -4023,6 +4131,8 @@ void iwl3945_rx_replenish(void *data) | |||
4023 | while (!list_empty(&rxq->rx_used)) { | 4131 | while (!list_empty(&rxq->rx_used)) { |
4024 | element = rxq->rx_used.next; | 4132 | element = rxq->rx_used.next; |
4025 | rxb = list_entry(element, struct iwl3945_rx_mem_buffer, list); | 4133 | rxb = list_entry(element, struct iwl3945_rx_mem_buffer, list); |
4134 | |||
4135 | /* Alloc a new receive buffer */ | ||
4026 | rxb->skb = | 4136 | rxb->skb = |
4027 | alloc_skb(IWL_RX_BUF_SIZE, __GFP_NOWARN | GFP_ATOMIC); | 4137 | alloc_skb(IWL_RX_BUF_SIZE, __GFP_NOWARN | GFP_ATOMIC); |
4028 | if (!rxb->skb) { | 4138 | if (!rxb->skb) { |
@@ -4036,6 +4146,8 @@ void iwl3945_rx_replenish(void *data) | |||
4036 | } | 4146 | } |
4037 | priv->alloc_rxb_skb++; | 4147 | priv->alloc_rxb_skb++; |
4038 | list_del(element); | 4148 | list_del(element); |
4149 | |||
4150 | /* Get physical address of RB/SKB */ | ||
4039 | rxb->dma_addr = | 4151 | rxb->dma_addr = |
4040 | pci_map_single(priv->pci_dev, rxb->skb->data, | 4152 | pci_map_single(priv->pci_dev, rxb->skb->data, |
4041 | IWL_RX_BUF_SIZE, PCI_DMA_FROMDEVICE); | 4153 | IWL_RX_BUF_SIZE, PCI_DMA_FROMDEVICE); |
@@ -4080,12 +4192,16 @@ int iwl3945_rx_queue_alloc(struct iwl3945_priv *priv) | |||
4080 | spin_lock_init(&rxq->lock); | 4192 | spin_lock_init(&rxq->lock); |
4081 | INIT_LIST_HEAD(&rxq->rx_free); | 4193 | INIT_LIST_HEAD(&rxq->rx_free); |
4082 | INIT_LIST_HEAD(&rxq->rx_used); | 4194 | INIT_LIST_HEAD(&rxq->rx_used); |
4195 | |||
4196 | /* Alloc the circular buffer of Read Buffer Descriptors (RBDs) */ | ||
4083 | rxq->bd = pci_alloc_consistent(dev, 4 * RX_QUEUE_SIZE, &rxq->dma_addr); | 4197 | rxq->bd = pci_alloc_consistent(dev, 4 * RX_QUEUE_SIZE, &rxq->dma_addr); |
4084 | if (!rxq->bd) | 4198 | if (!rxq->bd) |
4085 | return -ENOMEM; | 4199 | return -ENOMEM; |
4200 | |||
4086 | /* Fill the rx_used queue with _all_ of the Rx buffers */ | 4201 | /* Fill the rx_used queue with _all_ of the Rx buffers */ |
4087 | for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) | 4202 | for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) |
4088 | list_add_tail(&rxq->pool[i].list, &rxq->rx_used); | 4203 | list_add_tail(&rxq->pool[i].list, &rxq->rx_used); |
4204 | |||
4089 | /* Set us so that we have processed and used all buffers, but have | 4205 | /* Set us so that we have processed and used all buffers, but have |
4090 | * not restocked the Rx queue with fresh buffers */ | 4206 | * not restocked the Rx queue with fresh buffers */ |
4091 | rxq->read = rxq->write = 0; | 4207 | rxq->read = rxq->write = 0; |
@@ -4217,6 +4333,8 @@ static void iwl3945_rx_handle(struct iwl3945_priv *priv) | |||
4217 | int reclaim; | 4333 | int reclaim; |
4218 | unsigned long flags; | 4334 | unsigned long flags; |
4219 | 4335 | ||
4336 | /* uCode's read index (stored in shared DRAM) indicates the last Rx | ||
4337 | * buffer that the driver may process (last buffer filled by ucode). */ | ||
4220 | r = iwl3945_hw_get_rx_read(priv); | 4338 | r = iwl3945_hw_get_rx_read(priv); |
4221 | i = rxq->read; | 4339 | i = rxq->read; |
4222 | 4340 | ||
@@ -4297,6 +4415,9 @@ static void iwl3945_rx_handle(struct iwl3945_priv *priv) | |||
4297 | iwl3945_rx_queue_restock(priv); | 4415 | iwl3945_rx_queue_restock(priv); |
4298 | } | 4416 | } |
4299 | 4417 | ||
4418 | /** | ||
4419 | * iwl3945_tx_queue_update_write_ptr - Send new write index to hardware | ||
4420 | */ | ||
4300 | static int iwl3945_tx_queue_update_write_ptr(struct iwl3945_priv *priv, | 4421 | static int iwl3945_tx_queue_update_write_ptr(struct iwl3945_priv *priv, |
4301 | struct iwl3945_tx_queue *txq) | 4422 | struct iwl3945_tx_queue *txq) |
4302 | { | 4423 | { |
@@ -4926,6 +5047,11 @@ static void iwl3945_init_band_reference(const struct iwl3945_priv *priv, int ban | |||
4926 | } | 5047 | } |
4927 | } | 5048 | } |
4928 | 5049 | ||
5050 | /** | ||
5051 | * iwl3945_get_channel_info - Find driver's private channel info | ||
5052 | * | ||
5053 | * Based on band and channel number. | ||
5054 | */ | ||
4929 | const struct iwl3945_channel_info *iwl3945_get_channel_info(const struct iwl3945_priv *priv, | 5055 | const struct iwl3945_channel_info *iwl3945_get_channel_info(const struct iwl3945_priv *priv, |
4930 | int phymode, u16 channel) | 5056 | int phymode, u16 channel) |
4931 | { | 5057 | { |
@@ -4953,6 +5079,9 @@ const struct iwl3945_channel_info *iwl3945_get_channel_info(const struct iwl3945 | |||
4953 | #define CHECK_AND_PRINT(x) ((eeprom_ch_info[ch].flags & EEPROM_CHANNEL_##x) \ | 5079 | #define CHECK_AND_PRINT(x) ((eeprom_ch_info[ch].flags & EEPROM_CHANNEL_##x) \ |
4954 | ? # x " " : "") | 5080 | ? # x " " : "") |
4955 | 5081 | ||
5082 | /** | ||
5083 | * iwl3945_init_channel_map - Set up driver's info for all possible channels | ||
5084 | */ | ||
4956 | static int iwl3945_init_channel_map(struct iwl3945_priv *priv) | 5085 | static int iwl3945_init_channel_map(struct iwl3945_priv *priv) |
4957 | { | 5086 | { |
4958 | int eeprom_ch_count = 0; | 5087 | int eeprom_ch_count = 0; |
@@ -5062,6 +5191,7 @@ static int iwl3945_init_channel_map(struct iwl3945_priv *priv) | |||
5062 | } | 5191 | } |
5063 | } | 5192 | } |
5064 | 5193 | ||
5194 | /* Set up txpower settings in driver for all channels */ | ||
5065 | if (iwl3945_txpower_set_from_eeprom(priv)) | 5195 | if (iwl3945_txpower_set_from_eeprom(priv)) |
5066 | return -EIO; | 5196 | return -EIO; |
5067 | 5197 | ||
@@ -8289,6 +8419,8 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
8289 | struct ieee80211_hw *hw; | 8419 | struct ieee80211_hw *hw; |
8290 | int i; | 8420 | int i; |
8291 | 8421 | ||
8422 | /* Disabling hardware scan means that mac80211 will perform scans | ||
8423 | * "the hard way", rather than using device's scan. */ | ||
8292 | if (iwl3945_param_disable_hw_scan) { | 8424 | if (iwl3945_param_disable_hw_scan) { |
8293 | IWL_DEBUG_INFO("Disabling hw_scan\n"); | 8425 | IWL_DEBUG_INFO("Disabling hw_scan\n"); |
8294 | iwl3945_hw_ops.hw_scan = NULL; | 8426 | iwl3945_hw_ops.hw_scan = NULL; |
@@ -8319,6 +8451,8 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
8319 | priv->hw = hw; | 8451 | priv->hw = hw; |
8320 | 8452 | ||
8321 | priv->pci_dev = pdev; | 8453 | priv->pci_dev = pdev; |
8454 | |||
8455 | /* Select antenna (may be helpful if only one antenna is connected) */ | ||
8322 | priv->antenna = (enum iwl3945_antenna)iwl3945_param_antenna; | 8456 | priv->antenna = (enum iwl3945_antenna)iwl3945_param_antenna; |
8323 | #ifdef CONFIG_IWL3945_DEBUG | 8457 | #ifdef CONFIG_IWL3945_DEBUG |
8324 | iwl3945_debug_level = iwl3945_param_debug; | 8458 | iwl3945_debug_level = iwl3945_param_debug; |
@@ -8340,6 +8474,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
8340 | /* Tell mac80211 our Tx characteristics */ | 8474 | /* Tell mac80211 our Tx characteristics */ |
8341 | hw->flags = IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE; | 8475 | hw->flags = IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE; |
8342 | 8476 | ||
8477 | /* 4 EDCA QOS priorities */ | ||
8343 | hw->queues = 4; | 8478 | hw->queues = 4; |
8344 | 8479 | ||
8345 | spin_lock_init(&priv->lock); | 8480 | spin_lock_init(&priv->lock); |
@@ -8360,6 +8495,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
8360 | 8495 | ||
8361 | pci_set_master(pdev); | 8496 | pci_set_master(pdev); |
8362 | 8497 | ||
8498 | /* Clear the driver's (not device's) station table */ | ||
8363 | iwl3945_clear_stations_table(priv); | 8499 | iwl3945_clear_stations_table(priv); |
8364 | 8500 | ||
8365 | priv->data_retry_limit = -1; | 8501 | priv->data_retry_limit = -1; |
@@ -8379,9 +8515,11 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
8379 | err = pci_request_regions(pdev, DRV_NAME); | 8515 | err = pci_request_regions(pdev, DRV_NAME); |
8380 | if (err) | 8516 | if (err) |
8381 | goto out_pci_disable_device; | 8517 | goto out_pci_disable_device; |
8518 | |||
8382 | /* We disable the RETRY_TIMEOUT register (0x41) to keep | 8519 | /* We disable the RETRY_TIMEOUT register (0x41) to keep |
8383 | * PCI Tx retries from interfering with C3 CPU state */ | 8520 | * PCI Tx retries from interfering with C3 CPU state */ |
8384 | pci_write_config_byte(pdev, 0x41, 0x00); | 8521 | pci_write_config_byte(pdev, 0x41, 0x00); |
8522 | |||
8385 | priv->hw_base = pci_iomap(pdev, 0, 0); | 8523 | priv->hw_base = pci_iomap(pdev, 0, 0); |
8386 | if (!priv->hw_base) { | 8524 | if (!priv->hw_base) { |
8387 | err = -ENODEV; | 8525 | err = -ENODEV; |
@@ -8394,6 +8532,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
8394 | 8532 | ||
8395 | /* Initialize module parameter values here */ | 8533 | /* Initialize module parameter values here */ |
8396 | 8534 | ||
8535 | /* Disable radio (SW RF KILL) via parameter when loading driver */ | ||
8397 | if (iwl3945_param_disable) { | 8536 | if (iwl3945_param_disable) { |
8398 | set_bit(STATUS_RF_KILL_SW, &priv->status); | 8537 | set_bit(STATUS_RF_KILL_SW, &priv->status); |
8399 | IWL_DEBUG_INFO("Radio disabled.\n"); | 8538 | IWL_DEBUG_INFO("Radio disabled.\n"); |
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index 66aa938e316e..43ce645e4a60 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c | |||
@@ -63,13 +63,13 @@ static int iwl4965_tx_queue_update_write_ptr(struct iwl4965_priv *priv, | |||
63 | ******************************************************************************/ | 63 | ******************************************************************************/ |
64 | 64 | ||
65 | /* module parameters */ | 65 | /* module parameters */ |
66 | static int iwl4965_param_disable_hw_scan; | 66 | static int iwl4965_param_disable_hw_scan; /* def: 0 = use 4965's h/w scan */ |
67 | static int iwl4965_param_debug; | 67 | static int iwl4965_param_debug; /* def: 0 = minimal debug log messages */ |
68 | static int iwl4965_param_disable; /* def: enable radio */ | 68 | static int iwl4965_param_disable; /* def: enable radio */ |
69 | static int iwl4965_param_antenna; /* def: 0 = both antennas (use diversity) */ | 69 | static int iwl4965_param_antenna; /* def: 0 = both antennas (use diversity) */ |
70 | int iwl4965_param_hwcrypto; /* def: using software encryption */ | 70 | int iwl4965_param_hwcrypto; /* def: using software encryption */ |
71 | static int iwl4965_param_qos_enable = 1; | 71 | static int iwl4965_param_qos_enable = 1; /* def: 1 = use quality of service */ |
72 | int iwl4965_param_queues_num = IWL_MAX_NUM_QUEUES; | 72 | int iwl4965_param_queues_num = IWL_MAX_NUM_QUEUES; /* def: 16 Tx queues */ |
73 | 73 | ||
74 | /* | 74 | /* |
75 | * module name, copyright, version, etc. | 75 | * module name, copyright, version, etc. |
@@ -183,17 +183,24 @@ static void iwl4965_print_hex_dump(int level, void *p, u32 len) | |||
183 | * | 183 | * |
184 | * Theory of operation | 184 | * Theory of operation |
185 | * | 185 | * |
186 | * A queue is a circular buffers with 'Read' and 'Write' pointers. | 186 | * A Tx or Rx queue resides in host DRAM, and is comprised of a circular buffer |
187 | * 2 empty entries always kept in the buffer to protect from overflow. | 187 | * of buffer descriptors, each of which points to one or more data buffers for |
188 | * the device to read from or fill. Driver and device exchange status of each | ||
189 | * queue via "read" and "write" pointers. Driver keeps minimum of 2 empty | ||
190 | * entries in each circular buffer, to protect against confusing empty and full | ||
191 | * queue states. | ||
192 | * | ||
193 | * The device reads or writes the data in the queues via the device's several | ||
194 | * DMA/FIFO channels. Each queue is mapped to a single DMA channel. | ||
188 | * | 195 | * |
189 | * For Tx queue, there are low mark and high mark limits. If, after queuing | 196 | * For Tx queue, there are low mark and high mark limits. If, after queuing |
190 | * the packet for Tx, free space become < low mark, Tx queue stopped. When | 197 | * the packet for Tx, free space become < low mark, Tx queue stopped. When |
191 | * reclaiming packets (on 'tx done IRQ), if free space become > high mark, | 198 | * reclaiming packets (on 'tx done IRQ), if free space become > high mark, |
192 | * Tx queue resumed. | 199 | * Tx queue resumed. |
193 | * | 200 | * |
194 | * The IWL operates with six queues, one receive queue in the device's | 201 | * The 4965 operates with up to 17 queues: One receive queue, one transmit |
195 | * sram, one transmit queue for sending commands to the device firmware, | 202 | * queue (#4) for sending commands to the device firmware, and 15 other |
196 | * and four transmit queues for data. | 203 | * Tx queues that may be mapped to prioritized Tx DMA/FIFO channels. |
197 | ***************************************************/ | 204 | ***************************************************/ |
198 | 205 | ||
199 | static int iwl4965_queue_space(const struct iwl4965_queue *q) | 206 | static int iwl4965_queue_space(const struct iwl4965_queue *q) |
@@ -212,13 +219,21 @@ static int iwl4965_queue_space(const struct iwl4965_queue *q) | |||
212 | return s; | 219 | return s; |
213 | } | 220 | } |
214 | 221 | ||
215 | /* XXX: n_bd must be power-of-two size */ | 222 | /** |
223 | * iwl4965_queue_inc_wrap - increment queue index, wrap back to beginning | ||
224 | * @index -- current index | ||
225 | * @n_bd -- total number of entries in queue (must be power of 2) | ||
226 | */ | ||
216 | static inline int iwl4965_queue_inc_wrap(int index, int n_bd) | 227 | static inline int iwl4965_queue_inc_wrap(int index, int n_bd) |
217 | { | 228 | { |
218 | return ++index & (n_bd - 1); | 229 | return ++index & (n_bd - 1); |
219 | } | 230 | } |
220 | 231 | ||
221 | /* XXX: n_bd must be power-of-two size */ | 232 | /** |
233 | * iwl4965_queue_dec_wrap - decrement queue index, wrap back to end | ||
234 | * @index -- current index | ||
235 | * @n_bd -- total number of entries in queue (must be power of 2) | ||
236 | */ | ||
222 | static inline int iwl4965_queue_dec_wrap(int index, int n_bd) | 237 | static inline int iwl4965_queue_dec_wrap(int index, int n_bd) |
223 | { | 238 | { |
224 | return --index & (n_bd - 1); | 239 | return --index & (n_bd - 1); |
@@ -233,12 +248,17 @@ static inline int x2_queue_used(const struct iwl4965_queue *q, int i) | |||
233 | 248 | ||
234 | static inline u8 get_cmd_index(struct iwl4965_queue *q, u32 index, int is_huge) | 249 | static inline u8 get_cmd_index(struct iwl4965_queue *q, u32 index, int is_huge) |
235 | { | 250 | { |
251 | /* This is for scan command, the big buffer at end of command array */ | ||
236 | if (is_huge) | 252 | if (is_huge) |
237 | return q->n_window; | 253 | return q->n_window; /* must be power of 2 */ |
238 | 254 | ||
255 | /* Otherwise, use normal size buffers */ | ||
239 | return index & (q->n_window - 1); | 256 | return index & (q->n_window - 1); |
240 | } | 257 | } |
241 | 258 | ||
259 | /** | ||
260 | * iwl4965_queue_init - Initialize queue's high/low-water and read/write indexes | ||
261 | */ | ||
242 | static int iwl4965_queue_init(struct iwl4965_priv *priv, struct iwl4965_queue *q, | 262 | static int iwl4965_queue_init(struct iwl4965_priv *priv, struct iwl4965_queue *q, |
243 | int count, int slots_num, u32 id) | 263 | int count, int slots_num, u32 id) |
244 | { | 264 | { |
@@ -267,11 +287,16 @@ static int iwl4965_queue_init(struct iwl4965_priv *priv, struct iwl4965_queue *q | |||
267 | return 0; | 287 | return 0; |
268 | } | 288 | } |
269 | 289 | ||
290 | /** | ||
291 | * iwl4965_tx_queue_alloc - Alloc driver data and TFD CB for one Tx/cmd queue | ||
292 | */ | ||
270 | static int iwl4965_tx_queue_alloc(struct iwl4965_priv *priv, | 293 | static int iwl4965_tx_queue_alloc(struct iwl4965_priv *priv, |
271 | struct iwl4965_tx_queue *txq, u32 id) | 294 | struct iwl4965_tx_queue *txq, u32 id) |
272 | { | 295 | { |
273 | struct pci_dev *dev = priv->pci_dev; | 296 | struct pci_dev *dev = priv->pci_dev; |
274 | 297 | ||
298 | /* Driver private data, only for Tx (not command) queues, | ||
299 | * not shared with device. */ | ||
275 | if (id != IWL_CMD_QUEUE_NUM) { | 300 | if (id != IWL_CMD_QUEUE_NUM) { |
276 | txq->txb = kmalloc(sizeof(txq->txb[0]) * | 301 | txq->txb = kmalloc(sizeof(txq->txb[0]) * |
277 | TFD_QUEUE_SIZE_MAX, GFP_KERNEL); | 302 | TFD_QUEUE_SIZE_MAX, GFP_KERNEL); |
@@ -283,6 +308,8 @@ static int iwl4965_tx_queue_alloc(struct iwl4965_priv *priv, | |||
283 | } else | 308 | } else |
284 | txq->txb = NULL; | 309 | txq->txb = NULL; |
285 | 310 | ||
311 | /* Circular buffer of transmit frame descriptors (TFDs), | ||
312 | * shared with device */ | ||
286 | txq->bd = pci_alloc_consistent(dev, | 313 | txq->bd = pci_alloc_consistent(dev, |
287 | sizeof(txq->bd[0]) * TFD_QUEUE_SIZE_MAX, | 314 | sizeof(txq->bd[0]) * TFD_QUEUE_SIZE_MAX, |
288 | &txq->q.dma_addr); | 315 | &txq->q.dma_addr); |
@@ -320,7 +347,7 @@ int iwl4965_tx_queue_init(struct iwl4965_priv *priv, | |||
320 | * For the command queue (#4), allocate command space + one big | 347 | * For the command queue (#4), allocate command space + one big |
321 | * command for scan, since scan command is very huge; the system will | 348 | * command for scan, since scan command is very huge; the system will |
322 | * not have two scans at the same time, so only one is needed. | 349 | * not have two scans at the same time, so only one is needed. |
323 | * For normal Tx queues (all other queues), no super-size command | 350 | * For data Tx queues (all other queues), no super-size command |
324 | * space is needed. | 351 | * space is needed. |
325 | */ | 352 | */ |
326 | len = sizeof(struct iwl4965_cmd) * slots_num; | 353 | len = sizeof(struct iwl4965_cmd) * slots_num; |
@@ -357,8 +384,8 @@ int iwl4965_tx_queue_init(struct iwl4965_priv *priv, | |||
357 | * @txq: Transmit queue to deallocate. | 384 | * @txq: Transmit queue to deallocate. |
358 | * | 385 | * |
359 | * Empty queue by removing and destroying all BD's. | 386 | * Empty queue by removing and destroying all BD's. |
360 | * Free all buffers. txq itself is not freed. | 387 | * Free all buffers. |
361 | * | 388 | * 0-fill, but do not free "txq" descriptor structure. |
362 | */ | 389 | */ |
363 | void iwl4965_tx_queue_free(struct iwl4965_priv *priv, struct iwl4965_tx_queue *txq) | 390 | void iwl4965_tx_queue_free(struct iwl4965_priv *priv, struct iwl4965_tx_queue *txq) |
364 | { | 391 | { |
@@ -378,19 +405,21 @@ void iwl4965_tx_queue_free(struct iwl4965_priv *priv, struct iwl4965_tx_queue *t | |||
378 | if (q->id == IWL_CMD_QUEUE_NUM) | 405 | if (q->id == IWL_CMD_QUEUE_NUM) |
379 | len += IWL_MAX_SCAN_SIZE; | 406 | len += IWL_MAX_SCAN_SIZE; |
380 | 407 | ||
408 | /* De-alloc array of command/tx buffers */ | ||
381 | pci_free_consistent(dev, len, txq->cmd, txq->dma_addr_cmd); | 409 | pci_free_consistent(dev, len, txq->cmd, txq->dma_addr_cmd); |
382 | 410 | ||
383 | /* free buffers belonging to queue itself */ | 411 | /* De-alloc circular buffer of TFDs */ |
384 | if (txq->q.n_bd) | 412 | if (txq->q.n_bd) |
385 | pci_free_consistent(dev, sizeof(struct iwl4965_tfd_frame) * | 413 | pci_free_consistent(dev, sizeof(struct iwl4965_tfd_frame) * |
386 | txq->q.n_bd, txq->bd, txq->q.dma_addr); | 414 | txq->q.n_bd, txq->bd, txq->q.dma_addr); |
387 | 415 | ||
416 | /* De-alloc array of per-TFD driver data */ | ||
388 | if (txq->txb) { | 417 | if (txq->txb) { |
389 | kfree(txq->txb); | 418 | kfree(txq->txb); |
390 | txq->txb = NULL; | 419 | txq->txb = NULL; |
391 | } | 420 | } |
392 | 421 | ||
393 | /* 0 fill whole structure */ | 422 | /* 0-fill queue descriptor structure */ |
394 | memset(txq, 0, sizeof(*txq)); | 423 | memset(txq, 0, sizeof(*txq)); |
395 | } | 424 | } |
396 | 425 | ||
@@ -404,6 +433,11 @@ const u8 iwl4965_broadcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF | |||
404 | /**************************************************************/ | 433 | /**************************************************************/ |
405 | 434 | ||
406 | #if 0 /* temporary disable till we add real remove station */ | 435 | #if 0 /* temporary disable till we add real remove station */ |
436 | /** | ||
437 | * iwl4965_remove_station - Remove driver's knowledge of station. | ||
438 | * | ||
439 | * NOTE: This does not remove station from device's station table. | ||
440 | */ | ||
407 | static u8 iwl4965_remove_station(struct iwl4965_priv *priv, const u8 *addr, int is_ap) | 441 | static u8 iwl4965_remove_station(struct iwl4965_priv *priv, const u8 *addr, int is_ap) |
408 | { | 442 | { |
409 | int index = IWL_INVALID_STATION; | 443 | int index = IWL_INVALID_STATION; |
@@ -441,6 +475,11 @@ out: | |||
441 | } | 475 | } |
442 | #endif | 476 | #endif |
443 | 477 | ||
478 | /** | ||
479 | * iwl4965_clear_stations_table - Clear the driver's station table | ||
480 | * | ||
481 | * NOTE: This does not clear or otherwise alter the device's station table. | ||
482 | */ | ||
444 | static void iwl4965_clear_stations_table(struct iwl4965_priv *priv) | 483 | static void iwl4965_clear_stations_table(struct iwl4965_priv *priv) |
445 | { | 484 | { |
446 | unsigned long flags; | 485 | unsigned long flags; |
@@ -453,6 +492,9 @@ static void iwl4965_clear_stations_table(struct iwl4965_priv *priv) | |||
453 | spin_unlock_irqrestore(&priv->sta_lock, flags); | 492 | spin_unlock_irqrestore(&priv->sta_lock, flags); |
454 | } | 493 | } |
455 | 494 | ||
495 | /** | ||
496 | * iwl4965_add_station_flags - Add station to tables in driver and device | ||
497 | */ | ||
456 | u8 iwl4965_add_station_flags(struct iwl4965_priv *priv, const u8 *addr, int is_ap, u8 flags) | 498 | u8 iwl4965_add_station_flags(struct iwl4965_priv *priv, const u8 *addr, int is_ap, u8 flags) |
457 | { | 499 | { |
458 | int i; | 500 | int i; |
@@ -499,6 +541,7 @@ u8 iwl4965_add_station_flags(struct iwl4965_priv *priv, const u8 *addr, int is_a | |||
499 | station->used = 1; | 541 | station->used = 1; |
500 | priv->num_stations++; | 542 | priv->num_stations++; |
501 | 543 | ||
544 | /* Set up the REPLY_ADD_STA command to send to device */ | ||
502 | memset(&station->sta, 0, sizeof(struct iwl4965_addsta_cmd)); | 545 | memset(&station->sta, 0, sizeof(struct iwl4965_addsta_cmd)); |
503 | memcpy(station->sta.sta.addr, addr, ETH_ALEN); | 546 | memcpy(station->sta.sta.addr, addr, ETH_ALEN); |
504 | station->sta.mode = 0; | 547 | station->sta.mode = 0; |
@@ -513,6 +556,8 @@ u8 iwl4965_add_station_flags(struct iwl4965_priv *priv, const u8 *addr, int is_a | |||
513 | #endif /*CONFIG_IWL4965_HT*/ | 556 | #endif /*CONFIG_IWL4965_HT*/ |
514 | 557 | ||
515 | spin_unlock_irqrestore(&priv->sta_lock, flags_spin); | 558 | spin_unlock_irqrestore(&priv->sta_lock, flags_spin); |
559 | |||
560 | /* Add station to device's station table */ | ||
516 | iwl4965_send_add_station(priv, &station->sta, flags); | 561 | iwl4965_send_add_station(priv, &station->sta, flags); |
517 | return index; | 562 | return index; |
518 | 563 | ||
@@ -682,7 +727,11 @@ static int iwl4965_enqueue_hcmd(struct iwl4965_priv *priv, struct iwl4965_host_c | |||
682 | fix_size, q->write_ptr, idx, IWL_CMD_QUEUE_NUM); | 727 | fix_size, q->write_ptr, idx, IWL_CMD_QUEUE_NUM); |
683 | 728 | ||
684 | txq->need_update = 1; | 729 | txq->need_update = 1; |
730 | |||
731 | /* Set up entry in queue's byte count circular buffer */ | ||
685 | ret = iwl4965_tx_queue_update_wr_ptr(priv, txq, 0); | 732 | ret = iwl4965_tx_queue_update_wr_ptr(priv, txq, 0); |
733 | |||
734 | /* Increment and update queue's write index */ | ||
686 | q->write_ptr = iwl4965_queue_inc_wrap(q->write_ptr, q->n_bd); | 735 | q->write_ptr = iwl4965_queue_inc_wrap(q->write_ptr, q->n_bd); |
687 | iwl4965_tx_queue_update_write_ptr(priv, txq); | 736 | iwl4965_tx_queue_update_write_ptr(priv, txq); |
688 | 737 | ||
@@ -848,7 +897,10 @@ static int iwl4965_rxon_add_station(struct iwl4965_priv *priv, | |||
848 | { | 897 | { |
849 | u8 sta_id; | 898 | u8 sta_id; |
850 | 899 | ||
900 | /* Add station to device's station table */ | ||
851 | sta_id = iwl4965_add_station_flags(priv, addr, is_ap, 0); | 901 | sta_id = iwl4965_add_station_flags(priv, addr, is_ap, 0); |
902 | |||
903 | /* Set up default rate scaling table in device's station table */ | ||
852 | iwl4965_add_station(priv, addr, is_ap); | 904 | iwl4965_add_station(priv, addr, is_ap); |
853 | 905 | ||
854 | return sta_id; | 906 | return sta_id; |
@@ -1574,7 +1626,7 @@ static void get_eeprom_mac(struct iwl4965_priv *priv, u8 *mac) | |||
1574 | /** | 1626 | /** |
1575 | * iwl4965_eeprom_init - read EEPROM contents | 1627 | * iwl4965_eeprom_init - read EEPROM contents |
1576 | * | 1628 | * |
1577 | * Load the EEPROM from adapter into priv->eeprom | 1629 | * Load the EEPROM contents from adapter into priv->eeprom |
1578 | * | 1630 | * |
1579 | * NOTE: This routine uses the non-debug IO access functions. | 1631 | * NOTE: This routine uses the non-debug IO access functions. |
1580 | */ | 1632 | */ |
@@ -1599,6 +1651,7 @@ int iwl4965_eeprom_init(struct iwl4965_priv *priv) | |||
1599 | return -ENOENT; | 1651 | return -ENOENT; |
1600 | } | 1652 | } |
1601 | 1653 | ||
1654 | /* Make sure driver (instead of uCode) is allowed to read EEPROM */ | ||
1602 | rc = iwl4965_eeprom_acquire_semaphore(priv); | 1655 | rc = iwl4965_eeprom_acquire_semaphore(priv); |
1603 | if (rc < 0) { | 1656 | if (rc < 0) { |
1604 | IWL_ERROR("Failed to acquire EEPROM semaphore.\n"); | 1657 | IWL_ERROR("Failed to acquire EEPROM semaphore.\n"); |
@@ -2739,6 +2792,11 @@ static void iwl4965_build_tx_cmd_basic(struct iwl4965_priv *priv, | |||
2739 | cmd->cmd.tx.next_frame_len = 0; | 2792 | cmd->cmd.tx.next_frame_len = 0; |
2740 | } | 2793 | } |
2741 | 2794 | ||
2795 | /** | ||
2796 | * iwl4965_get_sta_id - Find station's index within station table | ||
2797 | * | ||
2798 | * If new IBSS station, create new entry in station table | ||
2799 | */ | ||
2742 | static int iwl4965_get_sta_id(struct iwl4965_priv *priv, | 2800 | static int iwl4965_get_sta_id(struct iwl4965_priv *priv, |
2743 | struct ieee80211_hdr *hdr) | 2801 | struct ieee80211_hdr *hdr) |
2744 | { | 2802 | { |
@@ -2746,16 +2804,15 @@ static int iwl4965_get_sta_id(struct iwl4965_priv *priv, | |||
2746 | u16 fc = le16_to_cpu(hdr->frame_control); | 2804 | u16 fc = le16_to_cpu(hdr->frame_control); |
2747 | DECLARE_MAC_BUF(mac); | 2805 | DECLARE_MAC_BUF(mac); |
2748 | 2806 | ||
2749 | /* If this frame is broadcast or not data then use the broadcast | 2807 | /* If this frame is broadcast or management, use broadcast station id */ |
2750 | * station id */ | ||
2751 | if (((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA) || | 2808 | if (((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA) || |
2752 | is_multicast_ether_addr(hdr->addr1)) | 2809 | is_multicast_ether_addr(hdr->addr1)) |
2753 | return priv->hw_setting.bcast_sta_id; | 2810 | return priv->hw_setting.bcast_sta_id; |
2754 | 2811 | ||
2755 | switch (priv->iw_mode) { | 2812 | switch (priv->iw_mode) { |
2756 | 2813 | ||
2757 | /* If this frame is part of a BSS network (we're a station), then | 2814 | /* If we are a client station in a BSS network, use the special |
2758 | * we use the AP's station id */ | 2815 | * AP station entry (that's the only station we communicate with) */ |
2759 | case IEEE80211_IF_TYPE_STA: | 2816 | case IEEE80211_IF_TYPE_STA: |
2760 | return IWL_AP_ID; | 2817 | return IWL_AP_ID; |
2761 | 2818 | ||
@@ -2766,13 +2823,14 @@ static int iwl4965_get_sta_id(struct iwl4965_priv *priv, | |||
2766 | return sta_id; | 2823 | return sta_id; |
2767 | return priv->hw_setting.bcast_sta_id; | 2824 | return priv->hw_setting.bcast_sta_id; |
2768 | 2825 | ||
2769 | /* If this frame is part of a IBSS network, then we use the | 2826 | /* If this frame is going out to an IBSS network, find the station, |
2770 | * target specific station id */ | 2827 | * or create a new station table entry */ |
2771 | case IEEE80211_IF_TYPE_IBSS: | 2828 | case IEEE80211_IF_TYPE_IBSS: |
2772 | sta_id = iwl4965_hw_find_station(priv, hdr->addr1); | 2829 | sta_id = iwl4965_hw_find_station(priv, hdr->addr1); |
2773 | if (sta_id != IWL_INVALID_STATION) | 2830 | if (sta_id != IWL_INVALID_STATION) |
2774 | return sta_id; | 2831 | return sta_id; |
2775 | 2832 | ||
2833 | /* Create new station table entry */ | ||
2776 | sta_id = iwl4965_add_station_flags(priv, hdr->addr1, 0, CMD_ASYNC); | 2834 | sta_id = iwl4965_add_station_flags(priv, hdr->addr1, 0, CMD_ASYNC); |
2777 | 2835 | ||
2778 | if (sta_id != IWL_INVALID_STATION) | 2836 | if (sta_id != IWL_INVALID_STATION) |
@@ -2854,6 +2912,8 @@ static int iwl4965_tx_skb(struct iwl4965_priv *priv, | |||
2854 | spin_unlock_irqrestore(&priv->lock, flags); | 2912 | spin_unlock_irqrestore(&priv->lock, flags); |
2855 | 2913 | ||
2856 | hdr_len = ieee80211_get_hdrlen(fc); | 2914 | hdr_len = ieee80211_get_hdrlen(fc); |
2915 | |||
2916 | /* Find (or create) index into station table for destination station */ | ||
2857 | sta_id = iwl4965_get_sta_id(priv, hdr); | 2917 | sta_id = iwl4965_get_sta_id(priv, hdr); |
2858 | if (sta_id == IWL_INVALID_STATION) { | 2918 | if (sta_id == IWL_INVALID_STATION) { |
2859 | DECLARE_MAC_BUF(mac); | 2919 | DECLARE_MAC_BUF(mac); |
@@ -2882,30 +2942,52 @@ static int iwl4965_tx_skb(struct iwl4965_priv *priv, | |||
2882 | #endif /* CONFIG_IWL4965_HT_AGG */ | 2942 | #endif /* CONFIG_IWL4965_HT_AGG */ |
2883 | #endif /* CONFIG_IWL4965_HT */ | 2943 | #endif /* CONFIG_IWL4965_HT */ |
2884 | } | 2944 | } |
2945 | |||
2946 | /* Descriptor for chosen Tx queue */ | ||
2885 | txq = &priv->txq[txq_id]; | 2947 | txq = &priv->txq[txq_id]; |
2886 | q = &txq->q; | 2948 | q = &txq->q; |
2887 | 2949 | ||
2888 | spin_lock_irqsave(&priv->lock, flags); | 2950 | spin_lock_irqsave(&priv->lock, flags); |
2889 | 2951 | ||
2952 | /* Set up first empty TFD within this queue's circular TFD buffer */ | ||
2890 | tfd = &txq->bd[q->write_ptr]; | 2953 | tfd = &txq->bd[q->write_ptr]; |
2891 | memset(tfd, 0, sizeof(*tfd)); | 2954 | memset(tfd, 0, sizeof(*tfd)); |
2892 | control_flags = (u32 *) tfd; | 2955 | control_flags = (u32 *) tfd; |
2893 | idx = get_cmd_index(q, q->write_ptr, 0); | 2956 | idx = get_cmd_index(q, q->write_ptr, 0); |
2894 | 2957 | ||
2958 | /* Set up driver data for this TFD */ | ||
2895 | memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl4965_tx_info)); | 2959 | memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl4965_tx_info)); |
2896 | txq->txb[q->write_ptr].skb[0] = skb; | 2960 | txq->txb[q->write_ptr].skb[0] = skb; |
2897 | memcpy(&(txq->txb[q->write_ptr].status.control), | 2961 | memcpy(&(txq->txb[q->write_ptr].status.control), |
2898 | ctl, sizeof(struct ieee80211_tx_control)); | 2962 | ctl, sizeof(struct ieee80211_tx_control)); |
2963 | |||
2964 | /* Set up first empty entry in queue's array of Tx/cmd buffers */ | ||
2899 | out_cmd = &txq->cmd[idx]; | 2965 | out_cmd = &txq->cmd[idx]; |
2900 | memset(&out_cmd->hdr, 0, sizeof(out_cmd->hdr)); | 2966 | memset(&out_cmd->hdr, 0, sizeof(out_cmd->hdr)); |
2901 | memset(&out_cmd->cmd.tx, 0, sizeof(out_cmd->cmd.tx)); | 2967 | memset(&out_cmd->cmd.tx, 0, sizeof(out_cmd->cmd.tx)); |
2968 | |||
2969 | /* | ||
2970 | * Set up the Tx-command (not MAC!) header. | ||
2971 | * Store the chosen Tx queue and TFD index within the sequence field; | ||
2972 | * after Tx, uCode's Tx response will return this value so driver can | ||
2973 | * locate the frame within the tx queue and do post-tx processing. | ||
2974 | */ | ||
2902 | out_cmd->hdr.cmd = REPLY_TX; | 2975 | out_cmd->hdr.cmd = REPLY_TX; |
2903 | out_cmd->hdr.sequence = cpu_to_le16((u16)(QUEUE_TO_SEQ(txq_id) | | 2976 | out_cmd->hdr.sequence = cpu_to_le16((u16)(QUEUE_TO_SEQ(txq_id) | |
2904 | INDEX_TO_SEQ(q->write_ptr))); | 2977 | INDEX_TO_SEQ(q->write_ptr))); |
2905 | /* copy frags header */ | 2978 | |
2979 | /* Copy MAC header from skb into command buffer */ | ||
2906 | memcpy(out_cmd->cmd.tx.hdr, hdr, hdr_len); | 2980 | memcpy(out_cmd->cmd.tx.hdr, hdr, hdr_len); |
2907 | 2981 | ||
2908 | /* hdr = (struct ieee80211_hdr *)out_cmd->cmd.tx.hdr; */ | 2982 | /* |
2983 | * Use the first empty entry in this queue's command buffer array | ||
2984 | * to contain the Tx command and MAC header concatenated together | ||
2985 | * (payload data will be in another buffer). | ||
2986 | * Size of this varies, due to varying MAC header length. | ||
2987 | * If end is not dword aligned, we'll have 2 extra bytes at the end | ||
2988 | * of the MAC header (device reads on dword boundaries). | ||
2989 | * We'll tell device about this padding later. | ||
2990 | */ | ||
2909 | len = priv->hw_setting.tx_cmd_len + | 2991 | len = priv->hw_setting.tx_cmd_len + |
2910 | sizeof(struct iwl4965_cmd_header) + hdr_len; | 2992 | sizeof(struct iwl4965_cmd_header) + hdr_len; |
2911 | 2993 | ||
@@ -2917,15 +2999,20 @@ static int iwl4965_tx_skb(struct iwl4965_priv *priv, | |||
2917 | else | 2999 | else |
2918 | len_org = 0; | 3000 | len_org = 0; |
2919 | 3001 | ||
3002 | /* Physical address of this Tx command's header (not MAC header!), | ||
3003 | * within command buffer array. */ | ||
2920 | txcmd_phys = txq->dma_addr_cmd + sizeof(struct iwl4965_cmd) * idx + | 3004 | txcmd_phys = txq->dma_addr_cmd + sizeof(struct iwl4965_cmd) * idx + |
2921 | offsetof(struct iwl4965_cmd, hdr); | 3005 | offsetof(struct iwl4965_cmd, hdr); |
2922 | 3006 | ||
3007 | /* Add buffer containing Tx command and MAC(!) header to TFD's | ||
3008 | * first entry */ | ||
2923 | iwl4965_hw_txq_attach_buf_to_tfd(priv, tfd, txcmd_phys, len); | 3009 | iwl4965_hw_txq_attach_buf_to_tfd(priv, tfd, txcmd_phys, len); |
2924 | 3010 | ||
2925 | if (!(ctl->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT)) | 3011 | if (!(ctl->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT)) |
2926 | iwl4965_build_tx_cmd_hwcrypto(priv, ctl, out_cmd, skb, 0); | 3012 | iwl4965_build_tx_cmd_hwcrypto(priv, ctl, out_cmd, skb, 0); |
2927 | 3013 | ||
2928 | /* 802.11 null functions have no payload... */ | 3014 | /* Set up TFD's 2nd entry to point directly to remainder of skb, |
3015 | * if any (802.11 null frames have no payload). */ | ||
2929 | len = skb->len - hdr_len; | 3016 | len = skb->len - hdr_len; |
2930 | if (len) { | 3017 | if (len) { |
2931 | phys_addr = pci_map_single(priv->pci_dev, skb->data + hdr_len, | 3018 | phys_addr = pci_map_single(priv->pci_dev, skb->data + hdr_len, |
@@ -2933,9 +3020,11 @@ static int iwl4965_tx_skb(struct iwl4965_priv *priv, | |||
2933 | iwl4965_hw_txq_attach_buf_to_tfd(priv, tfd, phys_addr, len); | 3020 | iwl4965_hw_txq_attach_buf_to_tfd(priv, tfd, phys_addr, len); |
2934 | } | 3021 | } |
2935 | 3022 | ||
3023 | /* Tell 4965 about any 2-byte padding after MAC header */ | ||
2936 | if (len_org) | 3024 | if (len_org) |
2937 | out_cmd->cmd.tx.tx_flags |= TX_CMD_FLG_MH_PAD_MSK; | 3025 | out_cmd->cmd.tx.tx_flags |= TX_CMD_FLG_MH_PAD_MSK; |
2938 | 3026 | ||
3027 | /* Total # bytes to be transmitted */ | ||
2939 | len = (u16)skb->len; | 3028 | len = (u16)skb->len; |
2940 | out_cmd->cmd.tx.len = cpu_to_le16(len); | 3029 | out_cmd->cmd.tx.len = cpu_to_le16(len); |
2941 | 3030 | ||
@@ -2965,8 +3054,10 @@ static int iwl4965_tx_skb(struct iwl4965_priv *priv, | |||
2965 | iwl4965_print_hex_dump(IWL_DL_TX, (u8 *)out_cmd->cmd.tx.hdr, | 3054 | iwl4965_print_hex_dump(IWL_DL_TX, (u8 *)out_cmd->cmd.tx.hdr, |
2966 | ieee80211_get_hdrlen(fc)); | 3055 | ieee80211_get_hdrlen(fc)); |
2967 | 3056 | ||
3057 | /* Set up entry for this TFD in Tx byte-count array */ | ||
2968 | iwl4965_tx_queue_update_wr_ptr(priv, txq, len); | 3058 | iwl4965_tx_queue_update_wr_ptr(priv, txq, len); |
2969 | 3059 | ||
3060 | /* Tell device the write index *just past* this latest filled TFD */ | ||
2970 | q->write_ptr = iwl4965_queue_inc_wrap(q->write_ptr, q->n_bd); | 3061 | q->write_ptr = iwl4965_queue_inc_wrap(q->write_ptr, q->n_bd); |
2971 | rc = iwl4965_tx_queue_update_write_ptr(priv, txq); | 3062 | rc = iwl4965_tx_queue_update_write_ptr(priv, txq); |
2972 | spin_unlock_irqrestore(&priv->lock, flags); | 3063 | spin_unlock_irqrestore(&priv->lock, flags); |
@@ -3443,11 +3534,11 @@ static void iwl4965_txstatus_to_ieee(struct iwl4965_priv *priv, | |||
3443 | } | 3534 | } |
3444 | 3535 | ||
3445 | /** | 3536 | /** |
3446 | * iwl4965_tx_queue_reclaim - Reclaim Tx queue entries no more used by NIC. | 3537 | * iwl4965_tx_queue_reclaim - Reclaim Tx queue entries already Tx'd |
3447 | * | 3538 | * |
3448 | * When FW advances 'R' index, all entries between old and | 3539 | * When FW advances 'R' index, all entries between old and new 'R' index |
3449 | * new 'R' index need to be reclaimed. As result, some free space | 3540 | * need to be reclaimed. As result, some free space forms. If there is |
3450 | * forms. If there is enough free space (> low mark), wake Tx queue. | 3541 | * enough free space (> low mark), wake the stack that feeds us. |
3451 | */ | 3542 | */ |
3452 | int iwl4965_tx_queue_reclaim(struct iwl4965_priv *priv, int txq_id, int index) | 3543 | int iwl4965_tx_queue_reclaim(struct iwl4965_priv *priv, int txq_id, int index) |
3453 | { | 3544 | { |
@@ -3528,6 +3619,10 @@ static inline u32 iwl4965_get_scd_ssn(struct iwl4965_tx_resp *tx_resp) | |||
3528 | return le32_to_cpu(*scd_ssn) & MAX_SN; | 3619 | return le32_to_cpu(*scd_ssn) & MAX_SN; |
3529 | 3620 | ||
3530 | } | 3621 | } |
3622 | |||
3623 | /** | ||
3624 | * iwl4965_tx_status_reply_tx - Handle Tx rspnse for frames in aggregation queue | ||
3625 | */ | ||
3531 | static int iwl4965_tx_status_reply_tx(struct iwl4965_priv *priv, | 3626 | static int iwl4965_tx_status_reply_tx(struct iwl4965_priv *priv, |
3532 | struct iwl4965_ht_agg *agg, | 3627 | struct iwl4965_ht_agg *agg, |
3533 | struct iwl4965_tx_resp *tx_resp, | 3628 | struct iwl4965_tx_resp *tx_resp, |
@@ -3542,14 +3637,16 @@ static int iwl4965_tx_status_reply_tx(struct iwl4965_priv *priv, | |||
3542 | u16 seq; | 3637 | u16 seq; |
3543 | 3638 | ||
3544 | if (agg->wait_for_ba) | 3639 | if (agg->wait_for_ba) |
3545 | IWL_DEBUG_TX_REPLY("got tx repsons w/o back\n"); | 3640 | IWL_DEBUG_TX_REPLY("got tx response w/o block-ack\n"); |
3546 | 3641 | ||
3547 | agg->frame_count = tx_resp->frame_count; | 3642 | agg->frame_count = tx_resp->frame_count; |
3548 | agg->start_idx = start_idx; | 3643 | agg->start_idx = start_idx; |
3549 | agg->rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags); | 3644 | agg->rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags); |
3550 | agg->bitmap0 = agg->bitmap1 = 0; | 3645 | agg->bitmap0 = agg->bitmap1 = 0; |
3551 | 3646 | ||
3647 | /* # frames attempted by Tx command */ | ||
3552 | if (agg->frame_count == 1) { | 3648 | if (agg->frame_count == 1) { |
3649 | /* Only one frame was attempted; no block-ack will arrive */ | ||
3553 | struct iwl4965_tx_queue *txq ; | 3650 | struct iwl4965_tx_queue *txq ; |
3554 | status = le32_to_cpu(frame_status[0]); | 3651 | status = le32_to_cpu(frame_status[0]); |
3555 | 3652 | ||
@@ -3578,9 +3675,11 @@ static int iwl4965_tx_status_reply_tx(struct iwl4965_priv *priv, | |||
3578 | 3675 | ||
3579 | agg->wait_for_ba = 0; | 3676 | agg->wait_for_ba = 0; |
3580 | } else { | 3677 | } else { |
3678 | /* Two or more frames were attempted; expect block-ack */ | ||
3581 | u64 bitmap = 0; | 3679 | u64 bitmap = 0; |
3582 | int start = agg->start_idx; | 3680 | int start = agg->start_idx; |
3583 | 3681 | ||
3682 | /* Construct bit-map of pending frames within Tx window */ | ||
3584 | for (i = 0; i < agg->frame_count; i++) { | 3683 | for (i = 0; i < agg->frame_count; i++) { |
3585 | u16 sc; | 3684 | u16 sc; |
3586 | status = le32_to_cpu(frame_status[i]); | 3685 | status = le32_to_cpu(frame_status[i]); |
@@ -3644,6 +3743,9 @@ static int iwl4965_tx_status_reply_tx(struct iwl4965_priv *priv, | |||
3644 | #endif | 3743 | #endif |
3645 | #endif | 3744 | #endif |
3646 | 3745 | ||
3746 | /** | ||
3747 | * iwl4965_rx_reply_tx - Handle standard (non-aggregation) Tx response | ||
3748 | */ | ||
3647 | static void iwl4965_rx_reply_tx(struct iwl4965_priv *priv, | 3749 | static void iwl4965_rx_reply_tx(struct iwl4965_priv *priv, |
3648 | struct iwl4965_rx_mem_buffer *rxb) | 3750 | struct iwl4965_rx_mem_buffer *rxb) |
3649 | { | 3751 | { |
@@ -4265,6 +4367,7 @@ int iwl4965_rx_queue_update_write_ptr(struct iwl4965_priv *priv, struct iwl4965_ | |||
4265 | if (q->need_update == 0) | 4367 | if (q->need_update == 0) |
4266 | goto exit_unlock; | 4368 | goto exit_unlock; |
4267 | 4369 | ||
4370 | /* If power-saving is in use, make sure device is awake */ | ||
4268 | if (test_bit(STATUS_POWER_PMI, &priv->status)) { | 4371 | if (test_bit(STATUS_POWER_PMI, &priv->status)) { |
4269 | reg = iwl4965_read32(priv, CSR_UCODE_DRV_GP1); | 4372 | reg = iwl4965_read32(priv, CSR_UCODE_DRV_GP1); |
4270 | 4373 | ||
@@ -4278,10 +4381,14 @@ int iwl4965_rx_queue_update_write_ptr(struct iwl4965_priv *priv, struct iwl4965_ | |||
4278 | if (rc) | 4381 | if (rc) |
4279 | goto exit_unlock; | 4382 | goto exit_unlock; |
4280 | 4383 | ||
4384 | /* Device expects a multiple of 8 */ | ||
4281 | iwl4965_write_direct32(priv, FH_RSCSR_CHNL0_WPTR, | 4385 | iwl4965_write_direct32(priv, FH_RSCSR_CHNL0_WPTR, |
4282 | q->write & ~0x7); | 4386 | q->write & ~0x7); |
4283 | iwl4965_release_nic_access(priv); | 4387 | iwl4965_release_nic_access(priv); |
4388 | |||
4389 | /* Else device is assumed to be awake */ | ||
4284 | } else | 4390 | } else |
4391 | /* Device expects a multiple of 8 */ | ||
4285 | iwl4965_write32(priv, FH_RSCSR_CHNL0_WPTR, q->write & ~0x7); | 4392 | iwl4965_write32(priv, FH_RSCSR_CHNL0_WPTR, q->write & ~0x7); |
4286 | 4393 | ||
4287 | 4394 | ||
@@ -4324,9 +4431,12 @@ static int iwl4965_rx_queue_restock(struct iwl4965_priv *priv) | |||
4324 | spin_lock_irqsave(&rxq->lock, flags); | 4431 | spin_lock_irqsave(&rxq->lock, flags); |
4325 | write = rxq->write & ~0x7; | 4432 | write = rxq->write & ~0x7; |
4326 | while ((iwl4965_rx_queue_space(rxq) > 0) && (rxq->free_count)) { | 4433 | while ((iwl4965_rx_queue_space(rxq) > 0) && (rxq->free_count)) { |
4434 | /* Get next free Rx buffer, remove from free list */ | ||
4327 | element = rxq->rx_free.next; | 4435 | element = rxq->rx_free.next; |
4328 | rxb = list_entry(element, struct iwl4965_rx_mem_buffer, list); | 4436 | rxb = list_entry(element, struct iwl4965_rx_mem_buffer, list); |
4329 | list_del(element); | 4437 | list_del(element); |
4438 | |||
4439 | /* Point to Rx buffer via next RBD in circular buffer */ | ||
4330 | rxq->bd[rxq->write] = iwl4965_dma_addr2rbd_ptr(priv, rxb->dma_addr); | 4440 | rxq->bd[rxq->write] = iwl4965_dma_addr2rbd_ptr(priv, rxb->dma_addr); |
4331 | rxq->queue[rxq->write] = rxb; | 4441 | rxq->queue[rxq->write] = rxb; |
4332 | rxq->write = (rxq->write + 1) & RX_QUEUE_MASK; | 4442 | rxq->write = (rxq->write + 1) & RX_QUEUE_MASK; |
@@ -4339,7 +4449,8 @@ static int iwl4965_rx_queue_restock(struct iwl4965_priv *priv) | |||
4339 | queue_work(priv->workqueue, &priv->rx_replenish); | 4449 | queue_work(priv->workqueue, &priv->rx_replenish); |
4340 | 4450 | ||
4341 | 4451 | ||
4342 | /* If we've added more space for the firmware to place data, tell it */ | 4452 | /* If we've added more space for the firmware to place data, tell it. |
4453 | * Increment device's write pointer in multiples of 8. */ | ||
4343 | if ((write != (rxq->write & ~0x7)) | 4454 | if ((write != (rxq->write & ~0x7)) |
4344 | || (abs(rxq->write - rxq->read) > 7)) { | 4455 | || (abs(rxq->write - rxq->read) > 7)) { |
4345 | spin_lock_irqsave(&rxq->lock, flags); | 4456 | spin_lock_irqsave(&rxq->lock, flags); |
@@ -4372,6 +4483,8 @@ void iwl4965_rx_replenish(void *data) | |||
4372 | while (!list_empty(&rxq->rx_used)) { | 4483 | while (!list_empty(&rxq->rx_used)) { |
4373 | element = rxq->rx_used.next; | 4484 | element = rxq->rx_used.next; |
4374 | rxb = list_entry(element, struct iwl4965_rx_mem_buffer, list); | 4485 | rxb = list_entry(element, struct iwl4965_rx_mem_buffer, list); |
4486 | |||
4487 | /* Alloc a new receive buffer */ | ||
4375 | rxb->skb = | 4488 | rxb->skb = |
4376 | alloc_skb(IWL_RX_BUF_SIZE, __GFP_NOWARN | GFP_ATOMIC); | 4489 | alloc_skb(IWL_RX_BUF_SIZE, __GFP_NOWARN | GFP_ATOMIC); |
4377 | if (!rxb->skb) { | 4490 | if (!rxb->skb) { |
@@ -4385,6 +4498,8 @@ void iwl4965_rx_replenish(void *data) | |||
4385 | } | 4498 | } |
4386 | priv->alloc_rxb_skb++; | 4499 | priv->alloc_rxb_skb++; |
4387 | list_del(element); | 4500 | list_del(element); |
4501 | |||
4502 | /* Get physical address of RB/SKB */ | ||
4388 | rxb->dma_addr = | 4503 | rxb->dma_addr = |
4389 | pci_map_single(priv->pci_dev, rxb->skb->data, | 4504 | pci_map_single(priv->pci_dev, rxb->skb->data, |
4390 | IWL_RX_BUF_SIZE, PCI_DMA_FROMDEVICE); | 4505 | IWL_RX_BUF_SIZE, PCI_DMA_FROMDEVICE); |
@@ -4429,12 +4544,16 @@ int iwl4965_rx_queue_alloc(struct iwl4965_priv *priv) | |||
4429 | spin_lock_init(&rxq->lock); | 4544 | spin_lock_init(&rxq->lock); |
4430 | INIT_LIST_HEAD(&rxq->rx_free); | 4545 | INIT_LIST_HEAD(&rxq->rx_free); |
4431 | INIT_LIST_HEAD(&rxq->rx_used); | 4546 | INIT_LIST_HEAD(&rxq->rx_used); |
4547 | |||
4548 | /* Alloc the circular buffer of Read Buffer Descriptors (RBDs) */ | ||
4432 | rxq->bd = pci_alloc_consistent(dev, 4 * RX_QUEUE_SIZE, &rxq->dma_addr); | 4549 | rxq->bd = pci_alloc_consistent(dev, 4 * RX_QUEUE_SIZE, &rxq->dma_addr); |
4433 | if (!rxq->bd) | 4550 | if (!rxq->bd) |
4434 | return -ENOMEM; | 4551 | return -ENOMEM; |
4552 | |||
4435 | /* Fill the rx_used queue with _all_ of the Rx buffers */ | 4553 | /* Fill the rx_used queue with _all_ of the Rx buffers */ |
4436 | for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) | 4554 | for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) |
4437 | list_add_tail(&rxq->pool[i].list, &rxq->rx_used); | 4555 | list_add_tail(&rxq->pool[i].list, &rxq->rx_used); |
4556 | |||
4438 | /* Set us so that we have processed and used all buffers, but have | 4557 | /* Set us so that we have processed and used all buffers, but have |
4439 | * not restocked the Rx queue with fresh buffers */ | 4558 | * not restocked the Rx queue with fresh buffers */ |
4440 | rxq->read = rxq->write = 0; | 4559 | rxq->read = rxq->write = 0; |
@@ -4566,6 +4685,8 @@ static void iwl4965_rx_handle(struct iwl4965_priv *priv) | |||
4566 | int reclaim; | 4685 | int reclaim; |
4567 | unsigned long flags; | 4686 | unsigned long flags; |
4568 | 4687 | ||
4688 | /* uCode's read index (stored in shared DRAM) indicates the last Rx | ||
4689 | * buffer that the driver may process (last buffer filled by ucode). */ | ||
4569 | r = iwl4965_hw_get_rx_read(priv); | 4690 | r = iwl4965_hw_get_rx_read(priv); |
4570 | i = rxq->read; | 4691 | i = rxq->read; |
4571 | 4692 | ||
@@ -4649,6 +4770,9 @@ static void iwl4965_rx_handle(struct iwl4965_priv *priv) | |||
4649 | iwl4965_rx_queue_restock(priv); | 4770 | iwl4965_rx_queue_restock(priv); |
4650 | } | 4771 | } |
4651 | 4772 | ||
4773 | /** | ||
4774 | * iwl4965_tx_queue_update_write_ptr - Send new write index to hardware | ||
4775 | */ | ||
4652 | static int iwl4965_tx_queue_update_write_ptr(struct iwl4965_priv *priv, | 4776 | static int iwl4965_tx_queue_update_write_ptr(struct iwl4965_priv *priv, |
4653 | struct iwl4965_tx_queue *txq) | 4777 | struct iwl4965_tx_queue *txq) |
4654 | { | 4778 | { |
@@ -5282,6 +5406,11 @@ static void iwl4965_init_band_reference(const struct iwl4965_priv *priv, | |||
5282 | } | 5406 | } |
5283 | } | 5407 | } |
5284 | 5408 | ||
5409 | /** | ||
5410 | * iwl4965_get_channel_info - Find driver's private channel info | ||
5411 | * | ||
5412 | * Based on band and channel number. | ||
5413 | */ | ||
5285 | const struct iwl4965_channel_info *iwl4965_get_channel_info(const struct iwl4965_priv *priv, | 5414 | const struct iwl4965_channel_info *iwl4965_get_channel_info(const struct iwl4965_priv *priv, |
5286 | int phymode, u16 channel) | 5415 | int phymode, u16 channel) |
5287 | { | 5416 | { |
@@ -5309,6 +5438,9 @@ const struct iwl4965_channel_info *iwl4965_get_channel_info(const struct iwl4965 | |||
5309 | #define CHECK_AND_PRINT(x) ((eeprom_ch_info[ch].flags & EEPROM_CHANNEL_##x) \ | 5438 | #define CHECK_AND_PRINT(x) ((eeprom_ch_info[ch].flags & EEPROM_CHANNEL_##x) \ |
5310 | ? # x " " : "") | 5439 | ? # x " " : "") |
5311 | 5440 | ||
5441 | /** | ||
5442 | * iwl4965_init_channel_map - Set up driver's info for all possible channels | ||
5443 | */ | ||
5312 | static int iwl4965_init_channel_map(struct iwl4965_priv *priv) | 5444 | static int iwl4965_init_channel_map(struct iwl4965_priv *priv) |
5313 | { | 5445 | { |
5314 | int eeprom_ch_count = 0; | 5446 | int eeprom_ch_count = 0; |
@@ -5418,6 +5550,7 @@ static int iwl4965_init_channel_map(struct iwl4965_priv *priv) | |||
5418 | } | 5550 | } |
5419 | } | 5551 | } |
5420 | 5552 | ||
5553 | /* Two additional EEPROM bands for 2.4 and 5 GHz FAT channels */ | ||
5421 | for (band = 6; band <= 7; band++) { | 5554 | for (band = 6; band <= 7; band++) { |
5422 | int phymode; | 5555 | int phymode; |
5423 | u8 fat_extension_chan; | 5556 | u8 fat_extension_chan; |
@@ -5425,7 +5558,9 @@ static int iwl4965_init_channel_map(struct iwl4965_priv *priv) | |||
5425 | iwl4965_init_band_reference(priv, band, &eeprom_ch_count, | 5558 | iwl4965_init_band_reference(priv, band, &eeprom_ch_count, |
5426 | &eeprom_ch_info, &eeprom_ch_index); | 5559 | &eeprom_ch_info, &eeprom_ch_index); |
5427 | 5560 | ||
5561 | /* EEPROM band 6 is 2.4, band 7 is 5 GHz */ | ||
5428 | phymode = (band == 6) ? MODE_IEEE80211B : MODE_IEEE80211A; | 5562 | phymode = (band == 6) ? MODE_IEEE80211B : MODE_IEEE80211A; |
5563 | |||
5429 | /* Loop through each band adding each of the channels */ | 5564 | /* Loop through each band adding each of the channels */ |
5430 | for (ch = 0; ch < eeprom_ch_count; ch++) { | 5565 | for (ch = 0; ch < eeprom_ch_count; ch++) { |
5431 | 5566 | ||
@@ -5437,11 +5572,13 @@ static int iwl4965_init_channel_map(struct iwl4965_priv *priv) | |||
5437 | else | 5572 | else |
5438 | fat_extension_chan = HT_IE_EXT_CHANNEL_ABOVE; | 5573 | fat_extension_chan = HT_IE_EXT_CHANNEL_ABOVE; |
5439 | 5574 | ||
5575 | /* Set up driver's info for lower half */ | ||
5440 | iwl4965_set_fat_chan_info(priv, phymode, | 5576 | iwl4965_set_fat_chan_info(priv, phymode, |
5441 | eeprom_ch_index[ch], | 5577 | eeprom_ch_index[ch], |
5442 | &(eeprom_ch_info[ch]), | 5578 | &(eeprom_ch_info[ch]), |
5443 | fat_extension_chan); | 5579 | fat_extension_chan); |
5444 | 5580 | ||
5581 | /* Set up driver's info for upper half */ | ||
5445 | iwl4965_set_fat_chan_info(priv, phymode, | 5582 | iwl4965_set_fat_chan_info(priv, phymode, |
5446 | (eeprom_ch_index[ch] + 4), | 5583 | (eeprom_ch_index[ch] + 4), |
5447 | &(eeprom_ch_info[ch]), | 5584 | &(eeprom_ch_info[ch]), |
@@ -8951,6 +9088,8 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
8951 | struct ieee80211_hw *hw; | 9088 | struct ieee80211_hw *hw; |
8952 | int i; | 9089 | int i; |
8953 | 9090 | ||
9091 | /* Disabling hardware scan means that mac80211 will perform scans | ||
9092 | * "the hard way", rather than using device's scan. */ | ||
8954 | if (iwl4965_param_disable_hw_scan) { | 9093 | if (iwl4965_param_disable_hw_scan) { |
8955 | IWL_DEBUG_INFO("Disabling hw_scan\n"); | 9094 | IWL_DEBUG_INFO("Disabling hw_scan\n"); |
8956 | iwl4965_hw_ops.hw_scan = NULL; | 9095 | iwl4965_hw_ops.hw_scan = NULL; |
@@ -9002,9 +9141,11 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
9002 | /* Tell mac80211 our Tx characteristics */ | 9141 | /* Tell mac80211 our Tx characteristics */ |
9003 | hw->flags = IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE; | 9142 | hw->flags = IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE; |
9004 | 9143 | ||
9144 | /* Default value; 4 EDCA QOS priorities */ | ||
9005 | hw->queues = 4; | 9145 | hw->queues = 4; |
9006 | #ifdef CONFIG_IWL4965_HT | 9146 | #ifdef CONFIG_IWL4965_HT |
9007 | #ifdef CONFIG_IWL4965_HT_AGG | 9147 | #ifdef CONFIG_IWL4965_HT_AGG |
9148 | /* Enhanced value; more queues, to support 11n aggregation */ | ||
9008 | hw->queues = 16; | 9149 | hw->queues = 16; |
9009 | #endif /* CONFIG_IWL4965_HT_AGG */ | 9150 | #endif /* CONFIG_IWL4965_HT_AGG */ |
9010 | #endif /* CONFIG_IWL4965_HT */ | 9151 | #endif /* CONFIG_IWL4965_HT */ |
@@ -9028,6 +9169,7 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
9028 | 9169 | ||
9029 | pci_set_master(pdev); | 9170 | pci_set_master(pdev); |
9030 | 9171 | ||
9172 | /* Clear the driver's (not device's) station table */ | ||
9031 | iwl4965_clear_stations_table(priv); | 9173 | iwl4965_clear_stations_table(priv); |
9032 | 9174 | ||
9033 | priv->data_retry_limit = -1; | 9175 | priv->data_retry_limit = -1; |
@@ -9047,9 +9189,11 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
9047 | err = pci_request_regions(pdev, DRV_NAME); | 9189 | err = pci_request_regions(pdev, DRV_NAME); |
9048 | if (err) | 9190 | if (err) |
9049 | goto out_pci_disable_device; | 9191 | goto out_pci_disable_device; |
9192 | |||
9050 | /* We disable the RETRY_TIMEOUT register (0x41) to keep | 9193 | /* We disable the RETRY_TIMEOUT register (0x41) to keep |
9051 | * PCI Tx retries from interfering with C3 CPU state */ | 9194 | * PCI Tx retries from interfering with C3 CPU state */ |
9052 | pci_write_config_byte(pdev, 0x41, 0x00); | 9195 | pci_write_config_byte(pdev, 0x41, 0x00); |
9196 | |||
9053 | priv->hw_base = pci_iomap(pdev, 0, 0); | 9197 | priv->hw_base = pci_iomap(pdev, 0, 0); |
9054 | if (!priv->hw_base) { | 9198 | if (!priv->hw_base) { |
9055 | err = -ENODEV; | 9199 | err = -ENODEV; |
@@ -9062,6 +9206,7 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
9062 | 9206 | ||
9063 | /* Initialize module parameter values here */ | 9207 | /* Initialize module parameter values here */ |
9064 | 9208 | ||
9209 | /* Disable radio (SW RF KILL) via parameter when loading driver */ | ||
9065 | if (iwl4965_param_disable) { | 9210 | if (iwl4965_param_disable) { |
9066 | set_bit(STATUS_RF_KILL_SW, &priv->status); | 9211 | set_bit(STATUS_RF_KILL_SW, &priv->status); |
9067 | IWL_DEBUG_INFO("Radio disabled.\n"); | 9212 | IWL_DEBUG_INFO("Radio disabled.\n"); |
@@ -9076,6 +9221,7 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
9076 | priv->valid_antenna = 0x7; /* assume all 3 connected */ | 9221 | priv->valid_antenna = 0x7; /* assume all 3 connected */ |
9077 | priv->ps_mode = IWL_MIMO_PS_NONE; | 9222 | priv->ps_mode = IWL_MIMO_PS_NONE; |
9078 | 9223 | ||
9224 | /* Choose which receivers/antennas to use */ | ||
9079 | iwl4965_set_rxon_chain(priv); | 9225 | iwl4965_set_rxon_chain(priv); |
9080 | 9226 | ||
9081 | printk(KERN_INFO DRV_NAME | 9227 | printk(KERN_INFO DRV_NAME |