diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-4965.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-4965.c | 661 |
1 files changed, 186 insertions, 475 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 5d675e39bab8..17847f981e11 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c | |||
@@ -50,11 +50,10 @@ static struct iwl_mod_params iwl4965_mod_params = { | |||
50 | .num_of_queues = IWL49_NUM_QUEUES, | 50 | .num_of_queues = IWL49_NUM_QUEUES, |
51 | .enable_qos = 1, | 51 | .enable_qos = 1, |
52 | .amsdu_size_8K = 1, | 52 | .amsdu_size_8K = 1, |
53 | .restart_fw = 1, | ||
53 | /* the rest are 0 by default */ | 54 | /* the rest are 0 by default */ |
54 | }; | 55 | }; |
55 | 56 | ||
56 | static void iwl4965_hw_card_show_info(struct iwl_priv *priv); | ||
57 | |||
58 | #ifdef CONFIG_IWL4965_HT | 57 | #ifdef CONFIG_IWL4965_HT |
59 | 58 | ||
60 | static const u16 default_tid_to_tx_fifo[] = { | 59 | static const u16 default_tid_to_tx_fifo[] = { |
@@ -224,6 +223,102 @@ static int iwl4965_load_bsm(struct iwl_priv *priv) | |||
224 | return 0; | 223 | return 0; |
225 | } | 224 | } |
226 | 225 | ||
226 | /** | ||
227 | * iwl4965_set_ucode_ptrs - Set uCode address location | ||
228 | * | ||
229 | * Tell initialization uCode where to find runtime uCode. | ||
230 | * | ||
231 | * BSM registers initially contain pointers to initialization uCode. | ||
232 | * We need to replace them to load runtime uCode inst and data, | ||
233 | * and to save runtime data when powering down. | ||
234 | */ | ||
235 | static int iwl4965_set_ucode_ptrs(struct iwl_priv *priv) | ||
236 | { | ||
237 | dma_addr_t pinst; | ||
238 | dma_addr_t pdata; | ||
239 | unsigned long flags; | ||
240 | int ret = 0; | ||
241 | |||
242 | /* bits 35:4 for 4965 */ | ||
243 | pinst = priv->ucode_code.p_addr >> 4; | ||
244 | pdata = priv->ucode_data_backup.p_addr >> 4; | ||
245 | |||
246 | spin_lock_irqsave(&priv->lock, flags); | ||
247 | ret = iwl_grab_nic_access(priv); | ||
248 | if (ret) { | ||
249 | spin_unlock_irqrestore(&priv->lock, flags); | ||
250 | return ret; | ||
251 | } | ||
252 | |||
253 | /* Tell bootstrap uCode where to find image to load */ | ||
254 | iwl_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst); | ||
255 | iwl_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata); | ||
256 | iwl_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG, | ||
257 | priv->ucode_data.len); | ||
258 | |||
259 | /* Inst bytecount must be last to set up, bit 31 signals uCode | ||
260 | * that all new ptr/size info is in place */ | ||
261 | iwl_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG, | ||
262 | priv->ucode_code.len | BSM_DRAM_INST_LOAD); | ||
263 | iwl_release_nic_access(priv); | ||
264 | |||
265 | spin_unlock_irqrestore(&priv->lock, flags); | ||
266 | |||
267 | IWL_DEBUG_INFO("Runtime uCode pointers are set.\n"); | ||
268 | |||
269 | return ret; | ||
270 | } | ||
271 | |||
272 | /** | ||
273 | * iwl4965_init_alive_start - Called after REPLY_ALIVE notification received | ||
274 | * | ||
275 | * Called after REPLY_ALIVE notification received from "initialize" uCode. | ||
276 | * | ||
277 | * The 4965 "initialize" ALIVE reply contains calibration data for: | ||
278 | * Voltage, temperature, and MIMO tx gain correction, now stored in priv | ||
279 | * (3945 does not contain this data). | ||
280 | * | ||
281 | * Tell "initialize" uCode to go ahead and load the runtime uCode. | ||
282 | */ | ||
283 | static void iwl4965_init_alive_start(struct iwl_priv *priv) | ||
284 | { | ||
285 | /* Check alive response for "valid" sign from uCode */ | ||
286 | if (priv->card_alive_init.is_valid != UCODE_VALID_OK) { | ||
287 | /* We had an error bringing up the hardware, so take it | ||
288 | * all the way back down so we can try again */ | ||
289 | IWL_DEBUG_INFO("Initialize Alive failed.\n"); | ||
290 | goto restart; | ||
291 | } | ||
292 | |||
293 | /* Bootstrap uCode has loaded initialize uCode ... verify inst image. | ||
294 | * This is a paranoid check, because we would not have gotten the | ||
295 | * "initialize" alive if code weren't properly loaded. */ | ||
296 | if (iwl_verify_ucode(priv)) { | ||
297 | /* Runtime instruction load was bad; | ||
298 | * take it all the way back down so we can try again */ | ||
299 | IWL_DEBUG_INFO("Bad \"initialize\" uCode load.\n"); | ||
300 | goto restart; | ||
301 | } | ||
302 | |||
303 | /* Calculate temperature */ | ||
304 | priv->temperature = iwl4965_get_temperature(priv); | ||
305 | |||
306 | /* Send pointers to protocol/runtime uCode image ... init code will | ||
307 | * load and launch runtime uCode, which will send us another "Alive" | ||
308 | * notification. */ | ||
309 | IWL_DEBUG_INFO("Initialization Alive received.\n"); | ||
310 | if (iwl4965_set_ucode_ptrs(priv)) { | ||
311 | /* Runtime instruction load won't happen; | ||
312 | * take it all the way back down so we can try again */ | ||
313 | IWL_DEBUG_INFO("Couldn't set up uCode pointers.\n"); | ||
314 | goto restart; | ||
315 | } | ||
316 | return; | ||
317 | |||
318 | restart: | ||
319 | queue_work(priv->workqueue, &priv->restart); | ||
320 | } | ||
321 | |||
227 | static int is_fat_channel(__le32 rxon_flags) | 322 | static int is_fat_channel(__le32 rxon_flags) |
228 | { | 323 | { |
229 | return (rxon_flags & RXON_FLG_CHANNEL_MODE_PURE_40_MSK) || | 324 | return (rxon_flags & RXON_FLG_CHANNEL_MODE_PURE_40_MSK) || |
@@ -372,178 +467,31 @@ int iwl4965_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src) | |||
372 | return ret; | 467 | return ret; |
373 | } | 468 | } |
374 | 469 | ||
375 | static int iwl4965_rx_init(struct iwl_priv *priv, struct iwl4965_rx_queue *rxq) | 470 | static int iwl4965_disable_tx_fifo(struct iwl_priv *priv) |
376 | { | 471 | { |
377 | int ret; | ||
378 | unsigned long flags; | 472 | unsigned long flags; |
379 | unsigned int rb_size; | 473 | int ret; |
380 | 474 | ||
381 | spin_lock_irqsave(&priv->lock, flags); | 475 | spin_lock_irqsave(&priv->lock, flags); |
476 | |||
382 | ret = iwl_grab_nic_access(priv); | 477 | ret = iwl_grab_nic_access(priv); |
383 | if (ret) { | 478 | if (unlikely(ret)) { |
479 | IWL_ERROR("Tx fifo reset failed"); | ||
384 | spin_unlock_irqrestore(&priv->lock, flags); | 480 | spin_unlock_irqrestore(&priv->lock, flags); |
385 | return ret; | 481 | return ret; |
386 | } | 482 | } |
387 | 483 | ||
388 | if (priv->cfg->mod_params->amsdu_size_8K) | 484 | iwl_write_prph(priv, IWL49_SCD_TXFACT, 0); |
389 | rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_8K; | ||
390 | else | ||
391 | rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K; | ||
392 | |||
393 | /* Stop Rx DMA */ | ||
394 | iwl_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0); | ||
395 | |||
396 | /* Reset driver's Rx queue write index */ | ||
397 | iwl_write_direct32(priv, FH_RSCSR_CHNL0_RBDCB_WPTR_REG, 0); | ||
398 | |||
399 | /* Tell device where to find RBD circular buffer in DRAM */ | ||
400 | iwl_write_direct32(priv, FH_RSCSR_CHNL0_RBDCB_BASE_REG, | ||
401 | rxq->dma_addr >> 8); | ||
402 | |||
403 | /* Tell device where in DRAM to update its Rx status */ | ||
404 | iwl_write_direct32(priv, FH_RSCSR_CHNL0_STTS_WPTR_REG, | ||
405 | (priv->shared_phys + | ||
406 | offsetof(struct iwl4965_shared, rb_closed)) >> 4); | ||
407 | |||
408 | /* Enable Rx DMA, enable host interrupt, Rx buffer size 4k, 256 RBDs */ | ||
409 | iwl_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG, | ||
410 | FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL | | ||
411 | FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL | | ||
412 | rb_size | | ||
413 | /* 0x10 << 4 | */ | ||
414 | (RX_QUEUE_SIZE_LOG << | ||
415 | FH_RCSR_RX_CONFIG_RBDCB_SIZE_BITSHIFT)); | ||
416 | |||
417 | /* | ||
418 | * iwl_write32(priv,CSR_INT_COAL_REG,0); | ||
419 | */ | ||
420 | |||
421 | iwl_release_nic_access(priv); | ||
422 | spin_unlock_irqrestore(&priv->lock, flags); | ||
423 | |||
424 | return 0; | ||
425 | } | ||
426 | |||
427 | /* Tell 4965 where to find the "keep warm" buffer */ | ||
428 | static int iwl4965_kw_init(struct iwl_priv *priv) | ||
429 | { | ||
430 | unsigned long flags; | ||
431 | int rc; | ||
432 | |||
433 | spin_lock_irqsave(&priv->lock, flags); | ||
434 | rc = iwl_grab_nic_access(priv); | ||
435 | if (rc) | ||
436 | goto out; | ||
437 | |||
438 | iwl_write_direct32(priv, FH_KW_MEM_ADDR_REG, | ||
439 | priv->kw.dma_addr >> 4); | ||
440 | iwl_release_nic_access(priv); | 485 | iwl_release_nic_access(priv); |
441 | out: | ||
442 | spin_unlock_irqrestore(&priv->lock, flags); | 486 | spin_unlock_irqrestore(&priv->lock, flags); |
443 | return rc; | ||
444 | } | ||
445 | |||
446 | static int iwl4965_kw_alloc(struct iwl_priv *priv) | ||
447 | { | ||
448 | struct pci_dev *dev = priv->pci_dev; | ||
449 | struct iwl4965_kw *kw = &priv->kw; | ||
450 | |||
451 | kw->size = IWL4965_KW_SIZE; /* TBW need set somewhere else */ | ||
452 | kw->v_addr = pci_alloc_consistent(dev, kw->size, &kw->dma_addr); | ||
453 | if (!kw->v_addr) | ||
454 | return -ENOMEM; | ||
455 | 487 | ||
456 | return 0; | 488 | return 0; |
457 | } | 489 | } |
458 | 490 | ||
459 | /** | ||
460 | * iwl4965_kw_free - Free the "keep warm" buffer | ||
461 | */ | ||
462 | static void iwl4965_kw_free(struct iwl_priv *priv) | ||
463 | { | ||
464 | struct pci_dev *dev = priv->pci_dev; | ||
465 | struct iwl4965_kw *kw = &priv->kw; | ||
466 | |||
467 | if (kw->v_addr) { | ||
468 | pci_free_consistent(dev, kw->size, kw->v_addr, kw->dma_addr); | ||
469 | memset(kw, 0, sizeof(*kw)); | ||
470 | } | ||
471 | } | ||
472 | |||
473 | /** | ||
474 | * iwl4965_txq_ctx_reset - Reset TX queue context | ||
475 | * Destroys all DMA structures and initialise them again | ||
476 | * | ||
477 | * @param priv | ||
478 | * @return error code | ||
479 | */ | ||
480 | static int iwl4965_txq_ctx_reset(struct iwl_priv *priv) | ||
481 | { | ||
482 | int rc = 0; | ||
483 | int txq_id, slots_num; | ||
484 | unsigned long flags; | ||
485 | |||
486 | iwl4965_kw_free(priv); | ||
487 | |||
488 | /* Free all tx/cmd queues and keep-warm buffer */ | ||
489 | iwl4965_hw_txq_ctx_free(priv); | ||
490 | |||
491 | /* Alloc keep-warm buffer */ | ||
492 | rc = iwl4965_kw_alloc(priv); | ||
493 | if (rc) { | ||
494 | IWL_ERROR("Keep Warm allocation failed"); | ||
495 | goto error_kw; | ||
496 | } | ||
497 | |||
498 | spin_lock_irqsave(&priv->lock, flags); | ||
499 | |||
500 | rc = iwl_grab_nic_access(priv); | ||
501 | if (unlikely(rc)) { | ||
502 | IWL_ERROR("TX reset failed"); | ||
503 | spin_unlock_irqrestore(&priv->lock, flags); | ||
504 | goto error_reset; | ||
505 | } | ||
506 | |||
507 | /* Turn off all Tx DMA channels */ | ||
508 | iwl_write_prph(priv, IWL49_SCD_TXFACT, 0); | ||
509 | iwl_release_nic_access(priv); | ||
510 | spin_unlock_irqrestore(&priv->lock, flags); | ||
511 | |||
512 | /* Tell 4965 where to find the keep-warm buffer */ | ||
513 | rc = iwl4965_kw_init(priv); | ||
514 | if (rc) { | ||
515 | IWL_ERROR("kw_init failed\n"); | ||
516 | goto error_reset; | ||
517 | } | ||
518 | |||
519 | /* Alloc and init all (default 16) Tx queues, | ||
520 | * including the command queue (#4) */ | ||
521 | for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) { | ||
522 | slots_num = (txq_id == IWL_CMD_QUEUE_NUM) ? | ||
523 | TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; | ||
524 | rc = iwl4965_tx_queue_init(priv, &priv->txq[txq_id], slots_num, | ||
525 | txq_id); | ||
526 | if (rc) { | ||
527 | IWL_ERROR("Tx %d queue init failed\n", txq_id); | ||
528 | goto error; | ||
529 | } | ||
530 | } | ||
531 | |||
532 | return rc; | ||
533 | |||
534 | error: | ||
535 | iwl4965_hw_txq_ctx_free(priv); | ||
536 | error_reset: | ||
537 | iwl4965_kw_free(priv); | ||
538 | error_kw: | ||
539 | return rc; | ||
540 | } | ||
541 | static int iwl4965_apm_init(struct iwl_priv *priv) | 491 | static int iwl4965_apm_init(struct iwl_priv *priv) |
542 | { | 492 | { |
543 | unsigned long flags; | ||
544 | int ret = 0; | 493 | int ret = 0; |
545 | 494 | ||
546 | spin_lock_irqsave(&priv->lock, flags); | ||
547 | iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS, | 495 | iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS, |
548 | CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER); | 496 | CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER); |
549 | 497 | ||
@@ -575,7 +523,6 @@ static int iwl4965_apm_init(struct iwl_priv *priv) | |||
575 | 523 | ||
576 | iwl_release_nic_access(priv); | 524 | iwl_release_nic_access(priv); |
577 | out: | 525 | out: |
578 | spin_unlock_irqrestore(&priv->lock, flags); | ||
579 | return ret; | 526 | return ret; |
580 | } | 527 | } |
581 | 528 | ||
@@ -621,59 +568,6 @@ static void iwl4965_nic_config(struct iwl_priv *priv) | |||
621 | spin_unlock_irqrestore(&priv->lock, flags); | 568 | spin_unlock_irqrestore(&priv->lock, flags); |
622 | } | 569 | } |
623 | 570 | ||
624 | |||
625 | int iwl4965_hw_nic_init(struct iwl_priv *priv) | ||
626 | { | ||
627 | unsigned long flags; | ||
628 | struct iwl4965_rx_queue *rxq = &priv->rxq; | ||
629 | int ret; | ||
630 | |||
631 | /* nic_init */ | ||
632 | priv->cfg->ops->lib->apm_ops.init(priv); | ||
633 | |||
634 | spin_lock_irqsave(&priv->lock, flags); | ||
635 | iwl_write32(priv, CSR_INT_COALESCING, 512 / 32); | ||
636 | spin_unlock_irqrestore(&priv->lock, flags); | ||
637 | |||
638 | ret = priv->cfg->ops->lib->apm_ops.set_pwr_src(priv, IWL_PWR_SRC_VMAIN); | ||
639 | |||
640 | priv->cfg->ops->lib->apm_ops.config(priv); | ||
641 | |||
642 | iwl4965_hw_card_show_info(priv); | ||
643 | |||
644 | /* end nic_init */ | ||
645 | |||
646 | /* Allocate the RX queue, or reset if it is already allocated */ | ||
647 | if (!rxq->bd) { | ||
648 | ret = iwl4965_rx_queue_alloc(priv); | ||
649 | if (ret) { | ||
650 | IWL_ERROR("Unable to initialize Rx queue\n"); | ||
651 | return -ENOMEM; | ||
652 | } | ||
653 | } else | ||
654 | iwl4965_rx_queue_reset(priv, rxq); | ||
655 | |||
656 | iwl4965_rx_replenish(priv); | ||
657 | |||
658 | iwl4965_rx_init(priv, rxq); | ||
659 | |||
660 | spin_lock_irqsave(&priv->lock, flags); | ||
661 | |||
662 | rxq->need_update = 1; | ||
663 | iwl4965_rx_queue_update_write_ptr(priv, rxq); | ||
664 | |||
665 | spin_unlock_irqrestore(&priv->lock, flags); | ||
666 | |||
667 | /* Allocate and init all Tx and Command queues */ | ||
668 | ret = iwl4965_txq_ctx_reset(priv); | ||
669 | if (ret) | ||
670 | return ret; | ||
671 | |||
672 | set_bit(STATUS_INIT, &priv->status); | ||
673 | |||
674 | return 0; | ||
675 | } | ||
676 | |||
677 | int iwl4965_hw_nic_stop_master(struct iwl_priv *priv) | 571 | int iwl4965_hw_nic_stop_master(struct iwl_priv *priv) |
678 | { | 572 | { |
679 | int rc = 0; | 573 | int rc = 0; |
@@ -734,7 +628,7 @@ void iwl4965_hw_txq_ctx_stop(struct iwl_priv *priv) | |||
734 | } | 628 | } |
735 | 629 | ||
736 | /* Deallocate memory for all Tx queues */ | 630 | /* Deallocate memory for all Tx queues */ |
737 | iwl4965_hw_txq_ctx_free(priv); | 631 | iwl_hw_txq_ctx_free(priv); |
738 | } | 632 | } |
739 | 633 | ||
740 | int iwl4965_hw_nic_reset(struct iwl_priv *priv) | 634 | int iwl4965_hw_nic_reset(struct iwl_priv *priv) |
@@ -984,7 +878,7 @@ static void iwl4965_set_wr_ptrs(struct iwl_priv *priv, int txq_id, u32 index) | |||
984 | * NOTE: Acquire priv->lock before calling this function ! | 878 | * NOTE: Acquire priv->lock before calling this function ! |
985 | */ | 879 | */ |
986 | static void iwl4965_tx_queue_set_status(struct iwl_priv *priv, | 880 | static void iwl4965_tx_queue_set_status(struct iwl_priv *priv, |
987 | struct iwl4965_tx_queue *txq, | 881 | struct iwl_tx_queue *txq, |
988 | int tx_fifo_id, int scd_retry) | 882 | int tx_fifo_id, int scd_retry) |
989 | { | 883 | { |
990 | int txq_id = txq->q.id; | 884 | int txq_id = txq->q.id; |
@@ -1188,82 +1082,6 @@ int iwl4965_hw_set_hw_params(struct iwl_priv *priv) | |||
1188 | return 0; | 1082 | return 0; |
1189 | } | 1083 | } |
1190 | 1084 | ||
1191 | /** | ||
1192 | * iwl4965_hw_txq_ctx_free - Free TXQ Context | ||
1193 | * | ||
1194 | * Destroy all TX DMA queues and structures | ||
1195 | */ | ||
1196 | void iwl4965_hw_txq_ctx_free(struct iwl_priv *priv) | ||
1197 | { | ||
1198 | int txq_id; | ||
1199 | |||
1200 | /* Tx queues */ | ||
1201 | for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) | ||
1202 | iwl4965_tx_queue_free(priv, &priv->txq[txq_id]); | ||
1203 | |||
1204 | /* Keep-warm buffer */ | ||
1205 | iwl4965_kw_free(priv); | ||
1206 | } | ||
1207 | |||
1208 | /** | ||
1209 | * iwl4965_hw_txq_free_tfd - Free all chunks referenced by TFD [txq->q.read_ptr] | ||
1210 | * | ||
1211 | * Does NOT advance any TFD circular buffer read/write indexes | ||
1212 | * Does NOT free the TFD itself (which is within circular buffer) | ||
1213 | */ | ||
1214 | int iwl4965_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl4965_tx_queue *txq) | ||
1215 | { | ||
1216 | struct iwl4965_tfd_frame *bd_tmp = (struct iwl4965_tfd_frame *)&txq->bd[0]; | ||
1217 | struct iwl4965_tfd_frame *bd = &bd_tmp[txq->q.read_ptr]; | ||
1218 | struct pci_dev *dev = priv->pci_dev; | ||
1219 | int i; | ||
1220 | int counter = 0; | ||
1221 | int index, is_odd; | ||
1222 | |||
1223 | /* Host command buffers stay mapped in memory, nothing to clean */ | ||
1224 | if (txq->q.id == IWL_CMD_QUEUE_NUM) | ||
1225 | return 0; | ||
1226 | |||
1227 | /* Sanity check on number of chunks */ | ||
1228 | counter = IWL_GET_BITS(*bd, num_tbs); | ||
1229 | if (counter > MAX_NUM_OF_TBS) { | ||
1230 | IWL_ERROR("Too many chunks: %i\n", counter); | ||
1231 | /* @todo issue fatal error, it is quite serious situation */ | ||
1232 | return 0; | ||
1233 | } | ||
1234 | |||
1235 | /* Unmap chunks, if any. | ||
1236 | * TFD info for odd chunks is different format than for even chunks. */ | ||
1237 | for (i = 0; i < counter; i++) { | ||
1238 | index = i / 2; | ||
1239 | is_odd = i & 0x1; | ||
1240 | |||
1241 | if (is_odd) | ||
1242 | pci_unmap_single( | ||
1243 | dev, | ||
1244 | IWL_GET_BITS(bd->pa[index], tb2_addr_lo16) | | ||
1245 | (IWL_GET_BITS(bd->pa[index], | ||
1246 | tb2_addr_hi20) << 16), | ||
1247 | IWL_GET_BITS(bd->pa[index], tb2_len), | ||
1248 | PCI_DMA_TODEVICE); | ||
1249 | |||
1250 | else if (i > 0) | ||
1251 | pci_unmap_single(dev, | ||
1252 | le32_to_cpu(bd->pa[index].tb1_addr), | ||
1253 | IWL_GET_BITS(bd->pa[index], tb1_len), | ||
1254 | PCI_DMA_TODEVICE); | ||
1255 | |||
1256 | /* Free SKB, if any, for this chunk */ | ||
1257 | if (txq->txb[txq->q.read_ptr].skb[i]) { | ||
1258 | struct sk_buff *skb = txq->txb[txq->q.read_ptr].skb[i]; | ||
1259 | |||
1260 | dev_kfree_skb(skb); | ||
1261 | txq->txb[txq->q.read_ptr].skb[i] = NULL; | ||
1262 | } | ||
1263 | } | ||
1264 | return 0; | ||
1265 | } | ||
1266 | |||
1267 | /* set card power command */ | 1085 | /* set card power command */ |
1268 | static int iwl4965_set_power(struct iwl_priv *priv, | 1086 | static int iwl4965_set_power(struct iwl_priv *priv, |
1269 | void *cmd) | 1087 | void *cmd) |
@@ -2186,7 +2004,7 @@ void iwl4965_hw_build_tx_cmd_rate(struct iwl_priv *priv, | |||
2186 | tx->rate_n_flags = iwl4965_hw_set_rate_n_flags(rate_plcp, rate_flags); | 2004 | tx->rate_n_flags = iwl4965_hw_set_rate_n_flags(rate_plcp, rate_flags); |
2187 | } | 2005 | } |
2188 | 2006 | ||
2189 | int iwl4965_hw_get_rx_read(struct iwl_priv *priv) | 2007 | static int iwl4965_shared_mem_rx_idx(struct iwl_priv *priv) |
2190 | { | 2008 | { |
2191 | struct iwl4965_shared *s = priv->shared_virt; | 2009 | struct iwl4965_shared *s = priv->shared_virt; |
2192 | return le32_to_cpu(s->rb_closed) & 0xFFF; | 2010 | return le32_to_cpu(s->rb_closed) & 0xFFF; |
@@ -2229,46 +2047,11 @@ unsigned int iwl4965_hw_get_beacon_cmd(struct iwl_priv *priv, | |||
2229 | return (sizeof(*tx_beacon_cmd) + frame_size); | 2047 | return (sizeof(*tx_beacon_cmd) + frame_size); |
2230 | } | 2048 | } |
2231 | 2049 | ||
2232 | /* | ||
2233 | * Tell 4965 where to find circular buffer of Tx Frame Descriptors for | ||
2234 | * given Tx queue, and enable the DMA channel used for that queue. | ||
2235 | * | ||
2236 | * 4965 supports up to 16 Tx queues in DRAM, mapped to up to 8 Tx DMA | ||
2237 | * channels supported in hardware. | ||
2238 | */ | ||
2239 | int iwl4965_hw_tx_queue_init(struct iwl_priv *priv, struct iwl4965_tx_queue *txq) | ||
2240 | { | ||
2241 | int rc; | ||
2242 | unsigned long flags; | ||
2243 | int txq_id = txq->q.id; | ||
2244 | |||
2245 | spin_lock_irqsave(&priv->lock, flags); | ||
2246 | rc = iwl_grab_nic_access(priv); | ||
2247 | if (rc) { | ||
2248 | spin_unlock_irqrestore(&priv->lock, flags); | ||
2249 | return rc; | ||
2250 | } | ||
2251 | |||
2252 | /* Circular buffer (TFD queue in DRAM) physical base address */ | ||
2253 | iwl_write_direct32(priv, FH_MEM_CBBC_QUEUE(txq_id), | ||
2254 | txq->q.dma_addr >> 8); | ||
2255 | |||
2256 | /* Enable DMA channel, using same id as for TFD queue */ | ||
2257 | iwl_write_direct32( | ||
2258 | priv, FH_TCSR_CHNL_TX_CONFIG_REG(txq_id), | ||
2259 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE | | ||
2260 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL); | ||
2261 | iwl_release_nic_access(priv); | ||
2262 | spin_unlock_irqrestore(&priv->lock, flags); | ||
2263 | |||
2264 | return 0; | ||
2265 | } | ||
2266 | |||
2267 | int iwl4965_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, void *ptr, | 2050 | int iwl4965_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, void *ptr, |
2268 | dma_addr_t addr, u16 len) | 2051 | dma_addr_t addr, u16 len) |
2269 | { | 2052 | { |
2270 | int index, is_odd; | 2053 | int index, is_odd; |
2271 | struct iwl4965_tfd_frame *tfd = ptr; | 2054 | struct iwl_tfd_frame *tfd = ptr; |
2272 | u32 num_tbs = IWL_GET_BITS(*tfd, num_tbs); | 2055 | u32 num_tbs = IWL_GET_BITS(*tfd, num_tbs); |
2273 | 2056 | ||
2274 | /* Each TFD can point to a maximum 20 Tx buffers */ | 2057 | /* Each TFD can point to a maximum 20 Tx buffers */ |
@@ -2298,18 +2081,6 @@ int iwl4965_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, void *ptr, | |||
2298 | return 0; | 2081 | return 0; |
2299 | } | 2082 | } |
2300 | 2083 | ||
2301 | static void iwl4965_hw_card_show_info(struct iwl_priv *priv) | ||
2302 | { | ||
2303 | u16 hw_version = iwl_eeprom_query16(priv, EEPROM_4965_BOARD_REVISION); | ||
2304 | |||
2305 | IWL_DEBUG_INFO("4965ABGN HW Version %u.%u.%u\n", | ||
2306 | ((hw_version >> 8) & 0x0F), | ||
2307 | ((hw_version >> 8) >> 4), (hw_version & 0x00FF)); | ||
2308 | |||
2309 | IWL_DEBUG_INFO("4965ABGN PBA Number %.16s\n", | ||
2310 | &priv->eeprom[EEPROM_4965_BOARD_PBA]); | ||
2311 | } | ||
2312 | |||
2313 | static int iwl4965_alloc_shared_mem(struct iwl_priv *priv) | 2084 | static int iwl4965_alloc_shared_mem(struct iwl_priv *priv) |
2314 | { | 2085 | { |
2315 | priv->shared_virt = pci_alloc_consistent(priv->pci_dev, | 2086 | priv->shared_virt = pci_alloc_consistent(priv->pci_dev, |
@@ -2320,6 +2091,8 @@ static int iwl4965_alloc_shared_mem(struct iwl_priv *priv) | |||
2320 | 2091 | ||
2321 | memset(priv->shared_virt, 0, sizeof(struct iwl4965_shared)); | 2092 | memset(priv->shared_virt, 0, sizeof(struct iwl4965_shared)); |
2322 | 2093 | ||
2094 | priv->rb_closed_offset = offsetof(struct iwl4965_shared, rb_closed); | ||
2095 | |||
2323 | return 0; | 2096 | return 0; |
2324 | } | 2097 | } |
2325 | 2098 | ||
@@ -2336,7 +2109,7 @@ static void iwl4965_free_shared_mem(struct iwl_priv *priv) | |||
2336 | * iwl4965_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array | 2109 | * iwl4965_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array |
2337 | */ | 2110 | */ |
2338 | static void iwl4965_txq_update_byte_cnt_tbl(struct iwl_priv *priv, | 2111 | static void iwl4965_txq_update_byte_cnt_tbl(struct iwl_priv *priv, |
2339 | struct iwl4965_tx_queue *txq, | 2112 | struct iwl_tx_queue *txq, |
2340 | u16 byte_cnt) | 2113 | u16 byte_cnt) |
2341 | { | 2114 | { |
2342 | int len; | 2115 | int len; |
@@ -2516,9 +2289,10 @@ static void iwl4965_rx_calc_noise(struct iwl_priv *priv) | |||
2516 | priv->last_rx_noise); | 2289 | priv->last_rx_noise); |
2517 | } | 2290 | } |
2518 | 2291 | ||
2519 | void iwl4965_hw_rx_statistics(struct iwl_priv *priv, struct iwl4965_rx_mem_buffer *rxb) | 2292 | void iwl4965_hw_rx_statistics(struct iwl_priv *priv, |
2293 | struct iwl_rx_mem_buffer *rxb) | ||
2520 | { | 2294 | { |
2521 | struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; | 2295 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; |
2522 | int change; | 2296 | int change; |
2523 | s32 temp; | 2297 | s32 temp; |
2524 | 2298 | ||
@@ -2588,7 +2362,7 @@ static void iwl4965_add_radiotap(struct iwl_priv *priv, | |||
2588 | struct ieee80211_rx_status *stats, | 2362 | struct ieee80211_rx_status *stats, |
2589 | u32 ampdu_status) | 2363 | u32 ampdu_status) |
2590 | { | 2364 | { |
2591 | s8 signal = stats->ssi; | 2365 | s8 signal = stats->signal; |
2592 | s8 noise = 0; | 2366 | s8 noise = 0; |
2593 | int rate = stats->rate_idx; | 2367 | int rate = stats->rate_idx; |
2594 | u64 tsf = stats->mactime; | 2368 | u64 tsf = stats->mactime; |
@@ -2742,7 +2516,7 @@ static int iwl4965_set_decrypted_flag(struct iwl_priv *priv, | |||
2742 | return 0; | 2516 | return 0; |
2743 | } | 2517 | } |
2744 | 2518 | ||
2745 | static u32 iwl4965_translate_rx_status(u32 decrypt_in) | 2519 | static u32 iwl4965_translate_rx_status(struct iwl_priv *priv, u32 decrypt_in) |
2746 | { | 2520 | { |
2747 | u32 decrypt_out = 0; | 2521 | u32 decrypt_out = 0; |
2748 | 2522 | ||
@@ -2803,10 +2577,10 @@ static u32 iwl4965_translate_rx_status(u32 decrypt_in) | |||
2803 | 2577 | ||
2804 | static void iwl4965_handle_data_packet(struct iwl_priv *priv, int is_data, | 2578 | static void iwl4965_handle_data_packet(struct iwl_priv *priv, int is_data, |
2805 | int include_phy, | 2579 | int include_phy, |
2806 | struct iwl4965_rx_mem_buffer *rxb, | 2580 | struct iwl_rx_mem_buffer *rxb, |
2807 | struct ieee80211_rx_status *stats) | 2581 | struct ieee80211_rx_status *stats) |
2808 | { | 2582 | { |
2809 | struct iwl4965_rx_packet *pkt = (struct iwl4965_rx_packet *)rxb->skb->data; | 2583 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; |
2810 | struct iwl4965_rx_phy_res *rx_start = (include_phy) ? | 2584 | struct iwl4965_rx_phy_res *rx_start = (include_phy) ? |
2811 | (struct iwl4965_rx_phy_res *)&(pkt->u.raw[0]) : NULL; | 2585 | (struct iwl4965_rx_phy_res *)&(pkt->u.raw[0]) : NULL; |
2812 | struct ieee80211_hdr *hdr; | 2586 | struct ieee80211_hdr *hdr; |
@@ -2843,7 +2617,9 @@ static void iwl4965_handle_data_packet(struct iwl_priv *priv, int is_data, | |||
2843 | rx_start->byte_count = amsdu->byte_count; | 2617 | rx_start->byte_count = amsdu->byte_count; |
2844 | rx_end = (__le32 *) (((u8 *) hdr) + len); | 2618 | rx_end = (__le32 *) (((u8 *) hdr) + len); |
2845 | } | 2619 | } |
2846 | if (len > priv->hw_params.max_pkt_size || len < 16) { | 2620 | /* In monitor mode allow 802.11 ACk frames (10 bytes) */ |
2621 | if (len > priv->hw_params.max_pkt_size || | ||
2622 | len < ((priv->iw_mode == IEEE80211_IF_TYPE_MNTR) ? 10 : 16)) { | ||
2847 | IWL_WARNING("byte count out of range [16,4K] : %d\n", len); | 2623 | IWL_WARNING("byte count out of range [16,4K] : %d\n", len); |
2848 | return; | 2624 | return; |
2849 | } | 2625 | } |
@@ -2854,7 +2630,7 @@ static void iwl4965_handle_data_packet(struct iwl_priv *priv, int is_data, | |||
2854 | if (!include_phy) { | 2630 | if (!include_phy) { |
2855 | /* New status scheme, need to translate */ | 2631 | /* New status scheme, need to translate */ |
2856 | ampdu_status_legacy = ampdu_status; | 2632 | ampdu_status_legacy = ampdu_status; |
2857 | ampdu_status = iwl4965_translate_rx_status(ampdu_status); | 2633 | ampdu_status = iwl4965_translate_rx_status(priv, ampdu_status); |
2858 | } | 2634 | } |
2859 | 2635 | ||
2860 | /* start from MAC */ | 2636 | /* start from MAC */ |
@@ -2886,7 +2662,8 @@ static void iwl4965_handle_data_packet(struct iwl_priv *priv, int is_data, | |||
2886 | } | 2662 | } |
2887 | 2663 | ||
2888 | /* Calc max signal level (dBm) among 3 possible receivers */ | 2664 | /* Calc max signal level (dBm) among 3 possible receivers */ |
2889 | static int iwl4965_calc_rssi(struct iwl4965_rx_phy_res *rx_resp) | 2665 | static int iwl4965_calc_rssi(struct iwl_priv *priv, |
2666 | struct iwl4965_rx_phy_res *rx_resp) | ||
2890 | { | 2667 | { |
2891 | /* data from PHY/DSP regarding signal strength, etc., | 2668 | /* data from PHY/DSP regarding signal strength, etc., |
2892 | * contents are always there, not configurable by host. */ | 2669 | * contents are always there, not configurable by host. */ |
@@ -2930,7 +2707,7 @@ static void iwl4965_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id) | |||
2930 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; | 2707 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; |
2931 | spin_unlock_irqrestore(&priv->sta_lock, flags); | 2708 | spin_unlock_irqrestore(&priv->sta_lock, flags); |
2932 | 2709 | ||
2933 | iwl4965_send_add_station(priv, &priv->stations[sta_id].sta, CMD_ASYNC); | 2710 | iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); |
2934 | } | 2711 | } |
2935 | 2712 | ||
2936 | static void iwl4965_update_ps_mode(struct iwl_priv *priv, u16 ps_bit, u8 *addr) | 2713 | static void iwl4965_update_ps_mode(struct iwl_priv *priv, u16 ps_bit, u8 *addr) |
@@ -2963,7 +2740,7 @@ static void iwl4965_update_ps_mode(struct iwl_priv *priv, u16 ps_bit, u8 *addr) | |||
2963 | * proper operation with 4965. | 2740 | * proper operation with 4965. |
2964 | */ | 2741 | */ |
2965 | static void iwl4965_dbg_report_frame(struct iwl_priv *priv, | 2742 | static void iwl4965_dbg_report_frame(struct iwl_priv *priv, |
2966 | struct iwl4965_rx_packet *pkt, | 2743 | struct iwl_rx_packet *pkt, |
2967 | struct ieee80211_hdr *header, int group100) | 2744 | struct ieee80211_hdr *header, int group100) |
2968 | { | 2745 | { |
2969 | u32 to_us; | 2746 | u32 to_us; |
@@ -2990,7 +2767,7 @@ static void iwl4965_dbg_report_frame(struct iwl_priv *priv, | |||
2990 | struct iwl4965_rx_frame_end *rx_end = IWL_RX_END(pkt); | 2767 | struct iwl4965_rx_frame_end *rx_end = IWL_RX_END(pkt); |
2991 | u8 *data = IWL_RX_DATA(pkt); | 2768 | u8 *data = IWL_RX_DATA(pkt); |
2992 | 2769 | ||
2993 | if (likely(!(iwl_debug_level & IWL_DL_RX))) | 2770 | if (likely(!(priv->debug_level & IWL_DL_RX))) |
2994 | return; | 2771 | return; |
2995 | 2772 | ||
2996 | /* MAC header */ | 2773 | /* MAC header */ |
@@ -3093,11 +2870,11 @@ static void iwl4965_dbg_report_frame(struct iwl_priv *priv, | |||
3093 | } | 2870 | } |
3094 | } | 2871 | } |
3095 | if (print_dump) | 2872 | if (print_dump) |
3096 | iwl_print_hex_dump(IWL_DL_RX, data, length); | 2873 | iwl_print_hex_dump(priv, IWL_DL_RX, data, length); |
3097 | } | 2874 | } |
3098 | #else | 2875 | #else |
3099 | static inline void iwl4965_dbg_report_frame(struct iwl_priv *priv, | 2876 | static inline void iwl4965_dbg_report_frame(struct iwl_priv *priv, |
3100 | struct iwl4965_rx_packet *pkt, | 2877 | struct iwl_rx_packet *pkt, |
3101 | struct ieee80211_hdr *header, | 2878 | struct ieee80211_hdr *header, |
3102 | int group100) | 2879 | int group100) |
3103 | { | 2880 | { |
@@ -3109,11 +2886,11 @@ static inline void iwl4965_dbg_report_frame(struct iwl_priv *priv, | |||
3109 | /* Called for REPLY_RX (legacy ABG frames), or | 2886 | /* Called for REPLY_RX (legacy ABG frames), or |
3110 | * REPLY_RX_MPDU_CMD (HT high-throughput N frames). */ | 2887 | * REPLY_RX_MPDU_CMD (HT high-throughput N frames). */ |
3111 | static void iwl4965_rx_reply_rx(struct iwl_priv *priv, | 2888 | static void iwl4965_rx_reply_rx(struct iwl_priv *priv, |
3112 | struct iwl4965_rx_mem_buffer *rxb) | 2889 | struct iwl_rx_mem_buffer *rxb) |
3113 | { | 2890 | { |
3114 | struct ieee80211_hdr *header; | 2891 | struct ieee80211_hdr *header; |
3115 | struct ieee80211_rx_status rx_status; | 2892 | struct ieee80211_rx_status rx_status; |
3116 | struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; | 2893 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; |
3117 | /* Use phy data (Rx signal strength, etc.) contained within | 2894 | /* Use phy data (Rx signal strength, etc.) contained within |
3118 | * this rx packet for legacy frames, | 2895 | * this rx packet for legacy frames, |
3119 | * or phy data cached from REPLY_RX_PHY_CMD for HT frames. */ | 2896 | * or phy data cached from REPLY_RX_PHY_CMD for HT frames. */ |
@@ -3186,7 +2963,7 @@ static void iwl4965_rx_reply_rx(struct iwl_priv *priv, | |||
3186 | priv->ucode_beacon_time = le32_to_cpu(rx_start->beacon_time_stamp); | 2963 | priv->ucode_beacon_time = le32_to_cpu(rx_start->beacon_time_stamp); |
3187 | 2964 | ||
3188 | /* Find max signal strength (dBm) among 3 antenna/receiver chains */ | 2965 | /* Find max signal strength (dBm) among 3 antenna/receiver chains */ |
3189 | rx_status.ssi = iwl4965_calc_rssi(rx_start); | 2966 | rx_status.signal = iwl4965_calc_rssi(priv, rx_start); |
3190 | 2967 | ||
3191 | /* Meaningful noise values are available only from beacon statistics, | 2968 | /* Meaningful noise values are available only from beacon statistics, |
3192 | * which are gathered only when associated, and indicate noise | 2969 | * which are gathered only when associated, and indicate noise |
@@ -3195,11 +2972,11 @@ static void iwl4965_rx_reply_rx(struct iwl_priv *priv, | |||
3195 | if (iwl_is_associated(priv) && | 2972 | if (iwl_is_associated(priv) && |
3196 | !test_bit(STATUS_SCANNING, &priv->status)) { | 2973 | !test_bit(STATUS_SCANNING, &priv->status)) { |
3197 | rx_status.noise = priv->last_rx_noise; | 2974 | rx_status.noise = priv->last_rx_noise; |
3198 | rx_status.signal = iwl4965_calc_sig_qual(rx_status.ssi, | 2975 | rx_status.qual = iwl4965_calc_sig_qual(rx_status.signal, |
3199 | rx_status.noise); | 2976 | rx_status.noise); |
3200 | } else { | 2977 | } else { |
3201 | rx_status.noise = IWL_NOISE_MEAS_NOT_AVAILABLE; | 2978 | rx_status.noise = IWL_NOISE_MEAS_NOT_AVAILABLE; |
3202 | rx_status.signal = iwl4965_calc_sig_qual(rx_status.ssi, 0); | 2979 | rx_status.qual = iwl4965_calc_sig_qual(rx_status.signal, 0); |
3203 | } | 2980 | } |
3204 | 2981 | ||
3205 | /* Reset beacon noise level if not associated. */ | 2982 | /* Reset beacon noise level if not associated. */ |
@@ -3211,12 +2988,19 @@ static void iwl4965_rx_reply_rx(struct iwl_priv *priv, | |||
3211 | iwl4965_dbg_report_frame(priv, pkt, header, 1); | 2988 | iwl4965_dbg_report_frame(priv, pkt, header, 1); |
3212 | 2989 | ||
3213 | IWL_DEBUG_STATS_LIMIT("Rssi %d, noise %d, qual %d, TSF %llu\n", | 2990 | IWL_DEBUG_STATS_LIMIT("Rssi %d, noise %d, qual %d, TSF %llu\n", |
3214 | rx_status.ssi, rx_status.noise, rx_status.signal, | 2991 | rx_status.signal, rx_status.noise, rx_status.signal, |
3215 | (unsigned long long)rx_status.mactime); | 2992 | (unsigned long long)rx_status.mactime); |
3216 | 2993 | ||
2994 | |||
2995 | if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) { | ||
2996 | iwl4965_handle_data_packet(priv, 1, include_phy, | ||
2997 | rxb, &rx_status); | ||
2998 | return; | ||
2999 | } | ||
3000 | |||
3217 | network_packet = iwl4965_is_network_packet(priv, header); | 3001 | network_packet = iwl4965_is_network_packet(priv, header); |
3218 | if (network_packet) { | 3002 | if (network_packet) { |
3219 | priv->last_rx_rssi = rx_status.ssi; | 3003 | priv->last_rx_rssi = rx_status.signal; |
3220 | priv->last_beacon_time = priv->ucode_beacon_time; | 3004 | priv->last_beacon_time = priv->ucode_beacon_time; |
3221 | priv->last_tsf = le64_to_cpu(rx_start->timestamp); | 3005 | priv->last_tsf = le64_to_cpu(rx_start->timestamp); |
3222 | } | 3006 | } |
@@ -3278,19 +3062,19 @@ static void iwl4965_rx_reply_rx(struct iwl_priv *priv, | |||
3278 | /* Cache phy data (Rx signal strength, etc) for HT frame (REPLY_RX_PHY_CMD). | 3062 | /* Cache phy data (Rx signal strength, etc) for HT frame (REPLY_RX_PHY_CMD). |
3279 | * This will be used later in iwl4965_rx_reply_rx() for REPLY_RX_MPDU_CMD. */ | 3063 | * This will be used later in iwl4965_rx_reply_rx() for REPLY_RX_MPDU_CMD. */ |
3280 | static void iwl4965_rx_reply_rx_phy(struct iwl_priv *priv, | 3064 | static void iwl4965_rx_reply_rx_phy(struct iwl_priv *priv, |
3281 | struct iwl4965_rx_mem_buffer *rxb) | 3065 | struct iwl_rx_mem_buffer *rxb) |
3282 | { | 3066 | { |
3283 | struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; | 3067 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; |
3284 | priv->last_phy_res[0] = 1; | 3068 | priv->last_phy_res[0] = 1; |
3285 | memcpy(&priv->last_phy_res[1], &(pkt->u.raw[0]), | 3069 | memcpy(&priv->last_phy_res[1], &(pkt->u.raw[0]), |
3286 | sizeof(struct iwl4965_rx_phy_res)); | 3070 | sizeof(struct iwl4965_rx_phy_res)); |
3287 | } | 3071 | } |
3288 | static void iwl4965_rx_missed_beacon_notif(struct iwl_priv *priv, | 3072 | static void iwl4965_rx_missed_beacon_notif(struct iwl_priv *priv, |
3289 | struct iwl4965_rx_mem_buffer *rxb) | 3073 | struct iwl_rx_mem_buffer *rxb) |
3290 | 3074 | ||
3291 | { | 3075 | { |
3292 | #ifdef CONFIG_IWL4965_RUN_TIME_CALIB | 3076 | #ifdef CONFIG_IWL4965_RUN_TIME_CALIB |
3293 | struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; | 3077 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; |
3294 | struct iwl4965_missed_beacon_notif *missed_beacon; | 3078 | struct iwl4965_missed_beacon_notif *missed_beacon; |
3295 | 3079 | ||
3296 | missed_beacon = &pkt->u.missed_beacon; | 3080 | missed_beacon = &pkt->u.missed_beacon; |
@@ -3322,7 +3106,7 @@ static void iwl4965_sta_modify_enable_tid_tx(struct iwl_priv *priv, | |||
3322 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; | 3106 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; |
3323 | spin_unlock_irqrestore(&priv->sta_lock, flags); | 3107 | spin_unlock_irqrestore(&priv->sta_lock, flags); |
3324 | 3108 | ||
3325 | iwl4965_send_add_station(priv, &priv->stations[sta_id].sta, CMD_ASYNC); | 3109 | iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); |
3326 | } | 3110 | } |
3327 | 3111 | ||
3328 | /** | 3112 | /** |
@@ -3332,7 +3116,7 @@ static void iwl4965_sta_modify_enable_tid_tx(struct iwl_priv *priv, | |||
3332 | * ACK vs. not. This gets sent to mac80211, then to rate scaling algo. | 3116 | * ACK vs. not. This gets sent to mac80211, then to rate scaling algo. |
3333 | */ | 3117 | */ |
3334 | static int iwl4965_tx_status_reply_compressed_ba(struct iwl_priv *priv, | 3118 | static int iwl4965_tx_status_reply_compressed_ba(struct iwl_priv *priv, |
3335 | struct iwl4965_ht_agg *agg, | 3119 | struct iwl_ht_agg *agg, |
3336 | struct iwl4965_compressed_ba_resp* | 3120 | struct iwl4965_compressed_ba_resp* |
3337 | ba_resp) | 3121 | ba_resp) |
3338 | 3122 | ||
@@ -3449,7 +3233,7 @@ int iwl4965_check_empty_hw_queue(struct iwl_priv *priv, int sta_id, | |||
3449 | { | 3233 | { |
3450 | struct iwl4965_queue *q = &priv->txq[txq_id].q; | 3234 | struct iwl4965_queue *q = &priv->txq[txq_id].q; |
3451 | u8 *addr = priv->stations[sta_id].sta.sta.addr; | 3235 | u8 *addr = priv->stations[sta_id].sta.sta.addr; |
3452 | struct iwl4965_tid_data *tid_data = &priv->stations[sta_id].tid[tid]; | 3236 | struct iwl_tid_data *tid_data = &priv->stations[sta_id].tid[tid]; |
3453 | 3237 | ||
3454 | switch (priv->stations[sta_id].tid[tid].agg.state) { | 3238 | switch (priv->stations[sta_id].tid[tid].agg.state) { |
3455 | case IWL_EMPTYING_HW_QUEUE_DELBA: | 3239 | case IWL_EMPTYING_HW_QUEUE_DELBA: |
@@ -3495,13 +3279,13 @@ static inline int iwl4965_queue_dec_wrap(int index, int n_bd) | |||
3495 | * of frames sent via aggregation. | 3279 | * of frames sent via aggregation. |
3496 | */ | 3280 | */ |
3497 | static void iwl4965_rx_reply_compressed_ba(struct iwl_priv *priv, | 3281 | static void iwl4965_rx_reply_compressed_ba(struct iwl_priv *priv, |
3498 | struct iwl4965_rx_mem_buffer *rxb) | 3282 | struct iwl_rx_mem_buffer *rxb) |
3499 | { | 3283 | { |
3500 | struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; | 3284 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; |
3501 | struct iwl4965_compressed_ba_resp *ba_resp = &pkt->u.compressed_ba; | 3285 | struct iwl4965_compressed_ba_resp *ba_resp = &pkt->u.compressed_ba; |
3502 | int index; | 3286 | int index; |
3503 | struct iwl4965_tx_queue *txq = NULL; | 3287 | struct iwl_tx_queue *txq = NULL; |
3504 | struct iwl4965_ht_agg *agg; | 3288 | struct iwl_ht_agg *agg; |
3505 | DECLARE_MAC_BUF(mac); | 3289 | DECLARE_MAC_BUF(mac); |
3506 | 3290 | ||
3507 | /* "flow" corresponds to Tx queue */ | 3291 | /* "flow" corresponds to Tx queue */ |
@@ -3547,13 +3331,16 @@ static void iwl4965_rx_reply_compressed_ba(struct iwl_priv *priv, | |||
3547 | * block-ack window (we assume that they've been successfully | 3331 | * block-ack window (we assume that they've been successfully |
3548 | * transmitted ... if not, it's too late anyway). */ | 3332 | * transmitted ... if not, it's too late anyway). */ |
3549 | if (txq->q.read_ptr != (ba_resp_scd_ssn & 0xff)) { | 3333 | if (txq->q.read_ptr != (ba_resp_scd_ssn & 0xff)) { |
3334 | /* calculate mac80211 ampdu sw queue to wake */ | ||
3335 | int ampdu_q = | ||
3336 | scd_flow - IWL_BACK_QUEUE_FIRST_ID + priv->hw->queues; | ||
3550 | int freed = iwl4965_tx_queue_reclaim(priv, scd_flow, index); | 3337 | int freed = iwl4965_tx_queue_reclaim(priv, scd_flow, index); |
3551 | priv->stations[ba_resp->sta_id]. | 3338 | priv->stations[ba_resp->sta_id]. |
3552 | tid[ba_resp->tid].tfds_in_queue -= freed; | 3339 | tid[ba_resp->tid].tfds_in_queue -= freed; |
3553 | if (iwl4965_queue_space(&txq->q) > txq->q.low_mark && | 3340 | if (iwl4965_queue_space(&txq->q) > txq->q.low_mark && |
3554 | priv->mac80211_registered && | 3341 | priv->mac80211_registered && |
3555 | agg->state != IWL_EMPTYING_HW_QUEUE_DELBA) | 3342 | agg->state != IWL_EMPTYING_HW_QUEUE_DELBA) |
3556 | ieee80211_wake_queue(priv->hw, scd_flow); | 3343 | ieee80211_wake_queue(priv->hw, ampdu_q); |
3557 | iwl4965_check_empty_hw_queue(priv, ba_resp->sta_id, | 3344 | iwl4965_check_empty_hw_queue(priv, ba_resp->sta_id, |
3558 | ba_resp->tid, scd_flow); | 3345 | ba_resp->tid, scd_flow); |
3559 | } | 3346 | } |
@@ -3714,103 +3501,6 @@ void iwl4965_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap) | |||
3714 | 3501 | ||
3715 | #ifdef CONFIG_IWL4965_HT | 3502 | #ifdef CONFIG_IWL4965_HT |
3716 | 3503 | ||
3717 | static u8 iwl4965_is_channel_extension(struct iwl_priv *priv, | ||
3718 | enum ieee80211_band band, | ||
3719 | u16 channel, u8 extension_chan_offset) | ||
3720 | { | ||
3721 | const struct iwl_channel_info *ch_info; | ||
3722 | |||
3723 | ch_info = iwl_get_channel_info(priv, band, channel); | ||
3724 | if (!is_channel_valid(ch_info)) | ||
3725 | return 0; | ||
3726 | |||
3727 | if (extension_chan_offset == IWL_EXT_CHANNEL_OFFSET_NONE) | ||
3728 | return 0; | ||
3729 | |||
3730 | if ((ch_info->fat_extension_channel == extension_chan_offset) || | ||
3731 | (ch_info->fat_extension_channel == HT_IE_EXT_CHANNEL_MAX)) | ||
3732 | return 1; | ||
3733 | |||
3734 | return 0; | ||
3735 | } | ||
3736 | |||
3737 | static u8 iwl4965_is_fat_tx_allowed(struct iwl_priv *priv, | ||
3738 | struct ieee80211_ht_info *sta_ht_inf) | ||
3739 | { | ||
3740 | struct iwl_ht_info *iwl_ht_conf = &priv->current_ht_config; | ||
3741 | |||
3742 | if ((!iwl_ht_conf->is_ht) || | ||
3743 | (iwl_ht_conf->supported_chan_width != IWL_CHANNEL_WIDTH_40MHZ) || | ||
3744 | (iwl_ht_conf->extension_chan_offset == IWL_EXT_CHANNEL_OFFSET_NONE)) | ||
3745 | return 0; | ||
3746 | |||
3747 | if (sta_ht_inf) { | ||
3748 | if ((!sta_ht_inf->ht_supported) || | ||
3749 | (!(sta_ht_inf->cap & IEEE80211_HT_CAP_SUP_WIDTH))) | ||
3750 | return 0; | ||
3751 | } | ||
3752 | |||
3753 | return (iwl4965_is_channel_extension(priv, priv->band, | ||
3754 | iwl_ht_conf->control_channel, | ||
3755 | iwl_ht_conf->extension_chan_offset)); | ||
3756 | } | ||
3757 | |||
3758 | void iwl4965_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info) | ||
3759 | { | ||
3760 | struct iwl4965_rxon_cmd *rxon = &priv->staging_rxon; | ||
3761 | u32 val; | ||
3762 | |||
3763 | if (!ht_info->is_ht) | ||
3764 | return; | ||
3765 | |||
3766 | /* Set up channel bandwidth: 20 MHz only, or 20/40 mixed if fat ok */ | ||
3767 | if (iwl4965_is_fat_tx_allowed(priv, NULL)) | ||
3768 | rxon->flags |= RXON_FLG_CHANNEL_MODE_MIXED_MSK; | ||
3769 | else | ||
3770 | rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MIXED_MSK | | ||
3771 | RXON_FLG_CHANNEL_MODE_PURE_40_MSK); | ||
3772 | |||
3773 | if (le16_to_cpu(rxon->channel) != ht_info->control_channel) { | ||
3774 | IWL_DEBUG_ASSOC("control diff than current %d %d\n", | ||
3775 | le16_to_cpu(rxon->channel), | ||
3776 | ht_info->control_channel); | ||
3777 | rxon->channel = cpu_to_le16(ht_info->control_channel); | ||
3778 | return; | ||
3779 | } | ||
3780 | |||
3781 | /* Note: control channel is opposite of extension channel */ | ||
3782 | switch (ht_info->extension_chan_offset) { | ||
3783 | case IWL_EXT_CHANNEL_OFFSET_ABOVE: | ||
3784 | rxon->flags &= ~(RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK); | ||
3785 | break; | ||
3786 | case IWL_EXT_CHANNEL_OFFSET_BELOW: | ||
3787 | rxon->flags |= RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK; | ||
3788 | break; | ||
3789 | case IWL_EXT_CHANNEL_OFFSET_NONE: | ||
3790 | default: | ||
3791 | rxon->flags &= ~RXON_FLG_CHANNEL_MODE_MIXED_MSK; | ||
3792 | break; | ||
3793 | } | ||
3794 | |||
3795 | val = ht_info->ht_protection; | ||
3796 | |||
3797 | rxon->flags |= cpu_to_le32(val << RXON_FLG_HT_OPERATING_MODE_POS); | ||
3798 | |||
3799 | iwl_set_rxon_chain(priv); | ||
3800 | |||
3801 | IWL_DEBUG_ASSOC("supported HT rate 0x%X 0x%X 0x%X " | ||
3802 | "rxon flags 0x%X operation mode :0x%X " | ||
3803 | "extension channel offset 0x%x " | ||
3804 | "control chan %d\n", | ||
3805 | ht_info->supp_mcs_set[0], | ||
3806 | ht_info->supp_mcs_set[1], | ||
3807 | ht_info->supp_mcs_set[2], | ||
3808 | le32_to_cpu(rxon->flags), ht_info->ht_protection, | ||
3809 | ht_info->extension_chan_offset, | ||
3810 | ht_info->control_channel); | ||
3811 | return; | ||
3812 | } | ||
3813 | |||
3814 | void iwl4965_set_ht_add_station(struct iwl_priv *priv, u8 index, | 3504 | void iwl4965_set_ht_add_station(struct iwl_priv *priv, u8 index, |
3815 | struct ieee80211_ht_info *sta_ht_inf) | 3505 | struct ieee80211_ht_info *sta_ht_inf) |
3816 | { | 3506 | { |
@@ -3846,7 +3536,7 @@ void iwl4965_set_ht_add_station(struct iwl_priv *priv, u8 index, | |||
3846 | sta_flags |= cpu_to_le32( | 3536 | sta_flags |= cpu_to_le32( |
3847 | (u32)sta_ht_inf->ampdu_density << STA_FLG_AGG_MPDU_DENSITY_POS); | 3537 | (u32)sta_ht_inf->ampdu_density << STA_FLG_AGG_MPDU_DENSITY_POS); |
3848 | 3538 | ||
3849 | if (iwl4965_is_fat_tx_allowed(priv, sta_ht_inf)) | 3539 | if (iwl_is_fat_tx_allowed(priv, sta_ht_inf)) |
3850 | sta_flags |= STA_FLG_FAT_EN_MSK; | 3540 | sta_flags |= STA_FLG_FAT_EN_MSK; |
3851 | else | 3541 | else |
3852 | sta_flags &= ~STA_FLG_FAT_EN_MSK; | 3542 | sta_flags &= ~STA_FLG_FAT_EN_MSK; |
@@ -3874,7 +3564,7 @@ static int iwl4965_rx_agg_start(struct iwl_priv *priv, | |||
3874 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; | 3564 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; |
3875 | spin_unlock_irqrestore(&priv->sta_lock, flags); | 3565 | spin_unlock_irqrestore(&priv->sta_lock, flags); |
3876 | 3566 | ||
3877 | return iwl4965_send_add_station(priv, &priv->stations[sta_id].sta, | 3567 | return iwl_send_add_sta(priv, &priv->stations[sta_id].sta, |
3878 | CMD_ASYNC); | 3568 | CMD_ASYNC); |
3879 | } | 3569 | } |
3880 | 3570 | ||
@@ -3895,7 +3585,7 @@ static int iwl4965_rx_agg_stop(struct iwl_priv *priv, | |||
3895 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; | 3585 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; |
3896 | spin_unlock_irqrestore(&priv->sta_lock, flags); | 3586 | spin_unlock_irqrestore(&priv->sta_lock, flags); |
3897 | 3587 | ||
3898 | return iwl4965_send_add_station(priv, &priv->stations[sta_id].sta, | 3588 | return iwl_send_add_sta(priv, &priv->stations[sta_id].sta, |
3899 | CMD_ASYNC); | 3589 | CMD_ASYNC); |
3900 | } | 3590 | } |
3901 | 3591 | ||
@@ -3925,7 +3615,7 @@ static int iwl4965_tx_agg_start(struct ieee80211_hw *hw, const u8 *ra, | |||
3925 | int ssn = -1; | 3615 | int ssn = -1; |
3926 | int ret = 0; | 3616 | int ret = 0; |
3927 | unsigned long flags; | 3617 | unsigned long flags; |
3928 | struct iwl4965_tid_data *tid_data; | 3618 | struct iwl_tid_data *tid_data; |
3929 | DECLARE_MAC_BUF(mac); | 3619 | DECLARE_MAC_BUF(mac); |
3930 | 3620 | ||
3931 | if (likely(tid < ARRAY_SIZE(default_tid_to_tx_fifo))) | 3621 | if (likely(tid < ARRAY_SIZE(default_tid_to_tx_fifo))) |
@@ -3978,7 +3668,7 @@ static int iwl4965_tx_agg_stop(struct ieee80211_hw *hw, const u8 *ra, u16 tid) | |||
3978 | { | 3668 | { |
3979 | struct iwl_priv *priv = hw->priv; | 3669 | struct iwl_priv *priv = hw->priv; |
3980 | int tx_fifo_id, txq_id, sta_id, ssn = -1; | 3670 | int tx_fifo_id, txq_id, sta_id, ssn = -1; |
3981 | struct iwl4965_tid_data *tid_data; | 3671 | struct iwl_tid_data *tid_data; |
3982 | int ret, write_ptr, read_ptr; | 3672 | int ret, write_ptr, read_ptr; |
3983 | unsigned long flags; | 3673 | unsigned long flags; |
3984 | DECLARE_MAC_BUF(mac); | 3674 | DECLARE_MAC_BUF(mac); |
@@ -4060,9 +3750,26 @@ int iwl4965_mac_ampdu_action(struct ieee80211_hw *hw, | |||
4060 | } | 3750 | } |
4061 | return 0; | 3751 | return 0; |
4062 | } | 3752 | } |
4063 | |||
4064 | #endif /* CONFIG_IWL4965_HT */ | 3753 | #endif /* CONFIG_IWL4965_HT */ |
4065 | 3754 | ||
3755 | |||
3756 | static u16 iwl4965_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data) | ||
3757 | { | ||
3758 | struct iwl4965_addsta_cmd *addsta = (struct iwl4965_addsta_cmd *)data; | ||
3759 | addsta->mode = cmd->mode; | ||
3760 | memcpy(&addsta->sta, &cmd->sta, sizeof(struct sta_id_modify)); | ||
3761 | memcpy(&addsta->key, &cmd->key, sizeof(struct iwl4965_keyinfo)); | ||
3762 | addsta->station_flags = cmd->station_flags; | ||
3763 | addsta->station_flags_msk = cmd->station_flags_msk; | ||
3764 | addsta->tid_disable_tx = cmd->tid_disable_tx; | ||
3765 | addsta->add_immediate_ba_tid = cmd->add_immediate_ba_tid; | ||
3766 | addsta->remove_immediate_ba_tid = cmd->remove_immediate_ba_tid; | ||
3767 | addsta->add_immediate_ba_ssn = cmd->add_immediate_ba_ssn; | ||
3768 | addsta->reserved1 = __constant_cpu_to_le16(0); | ||
3769 | addsta->reserved2 = __constant_cpu_to_le32(0); | ||
3770 | |||
3771 | return (u16)sizeof(struct iwl4965_addsta_cmd); | ||
3772 | } | ||
4066 | /* Set up 4965-specific Rx frame reply handlers */ | 3773 | /* Set up 4965-specific Rx frame reply handlers */ |
4067 | static void iwl4965_rx_handler_setup(struct iwl_priv *priv) | 3774 | static void iwl4965_rx_handler_setup(struct iwl_priv *priv) |
4068 | { | 3775 | { |
@@ -4106,6 +3813,7 @@ static struct iwl_hcmd_ops iwl4965_hcmd = { | |||
4106 | 3813 | ||
4107 | static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = { | 3814 | static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = { |
4108 | .enqueue_hcmd = iwl4965_enqueue_hcmd, | 3815 | .enqueue_hcmd = iwl4965_enqueue_hcmd, |
3816 | .build_addsta_hcmd = iwl4965_build_addsta_hcmd, | ||
4109 | #ifdef CONFIG_IWL4965_RUN_TIME_CALIB | 3817 | #ifdef CONFIG_IWL4965_RUN_TIME_CALIB |
4110 | .chain_noise_reset = iwl4965_chain_noise_reset, | 3818 | .chain_noise_reset = iwl4965_chain_noise_reset, |
4111 | .gain_computation = iwl4965_gain_computation, | 3819 | .gain_computation = iwl4965_gain_computation, |
@@ -4116,11 +3824,13 @@ static struct iwl_lib_ops iwl4965_lib = { | |||
4116 | .set_hw_params = iwl4965_hw_set_hw_params, | 3824 | .set_hw_params = iwl4965_hw_set_hw_params, |
4117 | .alloc_shared_mem = iwl4965_alloc_shared_mem, | 3825 | .alloc_shared_mem = iwl4965_alloc_shared_mem, |
4118 | .free_shared_mem = iwl4965_free_shared_mem, | 3826 | .free_shared_mem = iwl4965_free_shared_mem, |
3827 | .shared_mem_rx_idx = iwl4965_shared_mem_rx_idx, | ||
4119 | .txq_update_byte_cnt_tbl = iwl4965_txq_update_byte_cnt_tbl, | 3828 | .txq_update_byte_cnt_tbl = iwl4965_txq_update_byte_cnt_tbl, |
4120 | .hw_nic_init = iwl4965_hw_nic_init, | 3829 | .disable_tx_fifo = iwl4965_disable_tx_fifo, |
4121 | .rx_handler_setup = iwl4965_rx_handler_setup, | 3830 | .rx_handler_setup = iwl4965_rx_handler_setup, |
4122 | .is_valid_rtc_data_addr = iwl4965_hw_valid_rtc_data_addr, | 3831 | .is_valid_rtc_data_addr = iwl4965_hw_valid_rtc_data_addr, |
4123 | .alive_notify = iwl4965_alive_notify, | 3832 | .alive_notify = iwl4965_alive_notify, |
3833 | .init_alive_start = iwl4965_init_alive_start, | ||
4124 | .load_ucode = iwl4965_load_bsm, | 3834 | .load_ucode = iwl4965_load_bsm, |
4125 | .apm_ops = { | 3835 | .apm_ops = { |
4126 | .init = iwl4965_apm_init, | 3836 | .init = iwl4965_apm_init, |
@@ -4183,4 +3893,5 @@ module_param_named(qos_enable, iwl4965_mod_params.enable_qos, int, 0444); | |||
4183 | MODULE_PARM_DESC(qos_enable, "enable all QoS functionality"); | 3893 | MODULE_PARM_DESC(qos_enable, "enable all QoS functionality"); |
4184 | module_param_named(amsdu_size_8K, iwl4965_mod_params.amsdu_size_8K, int, 0444); | 3894 | module_param_named(amsdu_size_8K, iwl4965_mod_params.amsdu_size_8K, int, 0444); |
4185 | MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size"); | 3895 | MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size"); |
4186 | 3896 | module_param_named(fw_restart4965, iwl4965_mod_params.restart_fw, int, 0444); | |
3897 | MODULE_PARM_DESC(fw_restart4965, "restart firmware in case of error"); | ||