diff options
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-3945.c | 67 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-4965.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-5000.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn.c | 42 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-commands.h | 10 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-core.c | 13 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-core.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-dev.h | 27 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-hcmd.c | 21 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-rx.c | 122 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-scan.c | 20 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-spectrum.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-sta.c | 62 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-tx.c | 10 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl3945-base.c | 120 |
15 files changed, 284 insertions, 240 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 8012381d3717..b188a026637a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c | |||
@@ -293,7 +293,7 @@ static void iwl3945_tx_queue_reclaim(struct iwl_priv *priv, | |||
293 | static void iwl3945_rx_reply_tx(struct iwl_priv *priv, | 293 | static void iwl3945_rx_reply_tx(struct iwl_priv *priv, |
294 | struct iwl_rx_mem_buffer *rxb) | 294 | struct iwl_rx_mem_buffer *rxb) |
295 | { | 295 | { |
296 | struct iwl_rx_packet *pkt = (void *)rxb->skb->data; | 296 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
297 | u16 sequence = le16_to_cpu(pkt->hdr.sequence); | 297 | u16 sequence = le16_to_cpu(pkt->hdr.sequence); |
298 | int txq_id = SEQ_TO_QUEUE(sequence); | 298 | int txq_id = SEQ_TO_QUEUE(sequence); |
299 | int index = SEQ_TO_INDEX(sequence); | 299 | int index = SEQ_TO_INDEX(sequence); |
@@ -353,7 +353,7 @@ static void iwl3945_rx_reply_tx(struct iwl_priv *priv, | |||
353 | void iwl3945_hw_rx_statistics(struct iwl_priv *priv, | 353 | void iwl3945_hw_rx_statistics(struct iwl_priv *priv, |
354 | struct iwl_rx_mem_buffer *rxb) | 354 | struct iwl_rx_mem_buffer *rxb) |
355 | { | 355 | { |
356 | struct iwl_rx_packet *pkt = (void *)rxb->skb->data; | 356 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
357 | IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n", | 357 | IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n", |
358 | (int)sizeof(struct iwl3945_notif_statistics), | 358 | (int)sizeof(struct iwl3945_notif_statistics), |
359 | le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK); | 359 | le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK); |
@@ -543,14 +543,17 @@ static void iwl3945_pass_packet_to_mac80211(struct iwl_priv *priv, | |||
543 | struct iwl_rx_mem_buffer *rxb, | 543 | struct iwl_rx_mem_buffer *rxb, |
544 | struct ieee80211_rx_status *stats) | 544 | struct ieee80211_rx_status *stats) |
545 | { | 545 | { |
546 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | 546 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
547 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)IWL_RX_DATA(pkt); | 547 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)IWL_RX_DATA(pkt); |
548 | struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt); | 548 | struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt); |
549 | struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt); | 549 | struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt); |
550 | short len = le16_to_cpu(rx_hdr->len); | 550 | u16 len = le16_to_cpu(rx_hdr->len); |
551 | struct sk_buff *skb; | ||
552 | int ret; | ||
551 | 553 | ||
552 | /* We received data from the HW, so stop the watchdog */ | 554 | /* We received data from the HW, so stop the watchdog */ |
553 | if (unlikely((len + IWL39_RX_FRAME_SIZE) > skb_tailroom(rxb->skb))) { | 555 | if (unlikely(len + IWL39_RX_FRAME_SIZE > |
556 | PAGE_SIZE << priv->hw_params.rx_page_order)) { | ||
554 | IWL_DEBUG_DROP(priv, "Corruption detected!\n"); | 557 | IWL_DEBUG_DROP(priv, "Corruption detected!\n"); |
555 | return; | 558 | return; |
556 | } | 559 | } |
@@ -562,20 +565,45 @@ static void iwl3945_pass_packet_to_mac80211(struct iwl_priv *priv, | |||
562 | return; | 565 | return; |
563 | } | 566 | } |
564 | 567 | ||
565 | skb_reserve(rxb->skb, (void *)rx_hdr->payload - (void *)pkt); | 568 | skb = alloc_skb(IWL_LINK_HDR_MAX, GFP_ATOMIC); |
566 | /* Set the size of the skb to the size of the frame */ | 569 | if (!skb) { |
567 | skb_put(rxb->skb, le16_to_cpu(rx_hdr->len)); | 570 | IWL_ERR(priv, "alloc_skb failed\n"); |
571 | return; | ||
572 | } | ||
568 | 573 | ||
569 | if (!iwl3945_mod_params.sw_crypto) | 574 | if (!iwl3945_mod_params.sw_crypto) |
570 | iwl_set_decrypted_flag(priv, | 575 | iwl_set_decrypted_flag(priv, |
571 | (struct ieee80211_hdr *)rxb->skb->data, | 576 | (struct ieee80211_hdr *)rxb_addr(rxb), |
572 | le32_to_cpu(rx_end->status), stats); | 577 | le32_to_cpu(rx_end->status), stats); |
573 | 578 | ||
579 | skb_add_rx_frag(skb, 0, rxb->page, | ||
580 | (void *)rx_hdr->payload - (void *)pkt, len); | ||
581 | |||
582 | /* mac80211 currently doesn't support paged SKB. Convert it to | ||
583 | * linear SKB for management frame and data frame requires | ||
584 | * software decryption or software defragementation. */ | ||
585 | if (ieee80211_is_mgmt(hdr->frame_control) || | ||
586 | ieee80211_has_protected(hdr->frame_control) || | ||
587 | ieee80211_has_morefrags(hdr->frame_control) || | ||
588 | le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG) | ||
589 | ret = skb_linearize(skb); | ||
590 | else | ||
591 | ret = __pskb_pull_tail(skb, min_t(u16, IWL_LINK_HDR_MAX, len)) ? | ||
592 | 0 : -ENOMEM; | ||
593 | |||
594 | if (ret) { | ||
595 | kfree_skb(skb); | ||
596 | goto out; | ||
597 | } | ||
598 | |||
574 | iwl_update_stats(priv, false, hdr->frame_control, len); | 599 | iwl_update_stats(priv, false, hdr->frame_control, len); |
575 | 600 | ||
576 | memcpy(IEEE80211_SKB_RXCB(rxb->skb), stats, sizeof(*stats)); | 601 | memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats)); |
577 | ieee80211_rx_irqsafe(priv->hw, rxb->skb); | 602 | ieee80211_rx(priv->hw, skb); |
578 | rxb->skb = NULL; | 603 | |
604 | out: | ||
605 | priv->alloc_rxb_page--; | ||
606 | rxb->page = NULL; | ||
579 | } | 607 | } |
580 | 608 | ||
581 | #define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6) | 609 | #define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6) |
@@ -585,7 +613,7 @@ static void iwl3945_rx_reply_rx(struct iwl_priv *priv, | |||
585 | { | 613 | { |
586 | struct ieee80211_hdr *header; | 614 | struct ieee80211_hdr *header; |
587 | struct ieee80211_rx_status rx_status; | 615 | struct ieee80211_rx_status rx_status; |
588 | struct iwl_rx_packet *pkt = (void *)rxb->skb->data; | 616 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
589 | struct iwl3945_rx_frame_stats *rx_stats = IWL_RX_STATS(pkt); | 617 | struct iwl3945_rx_frame_stats *rx_stats = IWL_RX_STATS(pkt); |
590 | struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt); | 618 | struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt); |
591 | struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt); | 619 | struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt); |
@@ -1811,7 +1839,7 @@ int iwl3945_hw_reg_set_txpower(struct iwl_priv *priv, s8 power) | |||
1811 | static int iwl3945_send_rxon_assoc(struct iwl_priv *priv) | 1839 | static int iwl3945_send_rxon_assoc(struct iwl_priv *priv) |
1812 | { | 1840 | { |
1813 | int rc = 0; | 1841 | int rc = 0; |
1814 | struct iwl_rx_packet *res = NULL; | 1842 | struct iwl_rx_packet *pkt; |
1815 | struct iwl3945_rxon_assoc_cmd rxon_assoc; | 1843 | struct iwl3945_rxon_assoc_cmd rxon_assoc; |
1816 | struct iwl_host_cmd cmd = { | 1844 | struct iwl_host_cmd cmd = { |
1817 | .id = REPLY_RXON_ASSOC, | 1845 | .id = REPLY_RXON_ASSOC, |
@@ -1840,14 +1868,14 @@ static int iwl3945_send_rxon_assoc(struct iwl_priv *priv) | |||
1840 | if (rc) | 1868 | if (rc) |
1841 | return rc; | 1869 | return rc; |
1842 | 1870 | ||
1843 | res = (struct iwl_rx_packet *)cmd.reply_skb->data; | 1871 | pkt = (struct iwl_rx_packet *)cmd.reply_page; |
1844 | if (res->hdr.flags & IWL_CMD_FAILED_MSK) { | 1872 | if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) { |
1845 | IWL_ERR(priv, "Bad return from REPLY_RXON_ASSOC command\n"); | 1873 | IWL_ERR(priv, "Bad return from REPLY_RXON_ASSOC command\n"); |
1846 | rc = -EIO; | 1874 | rc = -EIO; |
1847 | } | 1875 | } |
1848 | 1876 | ||
1849 | priv->alloc_rxb_skb--; | 1877 | priv->alloc_rxb_page--; |
1850 | dev_kfree_skb_any(cmd.reply_skb); | 1878 | free_pages(cmd.reply_page, priv->hw_params.rx_page_order); |
1851 | 1879 | ||
1852 | return rc; | 1880 | return rc; |
1853 | } | 1881 | } |
@@ -2513,8 +2541,7 @@ int iwl3945_hw_set_hw_params(struct iwl_priv *priv) | |||
2513 | priv->hw_params.max_txq_num = priv->cfg->num_of_queues; | 2541 | priv->hw_params.max_txq_num = priv->cfg->num_of_queues; |
2514 | 2542 | ||
2515 | priv->hw_params.tfd_size = sizeof(struct iwl3945_tfd); | 2543 | priv->hw_params.tfd_size = sizeof(struct iwl3945_tfd); |
2516 | priv->hw_params.rx_buf_size = IWL_RX_BUF_SIZE_3K; | 2544 | priv->hw_params.rx_page_order = get_order(IWL_RX_BUF_SIZE_3K); |
2517 | priv->hw_params.max_pkt_size = 2342; | ||
2518 | priv->hw_params.max_rxq_size = RX_QUEUE_SIZE; | 2545 | priv->hw_params.max_rxq_size = RX_QUEUE_SIZE; |
2519 | priv->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG; | 2546 | priv->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG; |
2520 | priv->hw_params.max_stations = IWL3945_STATION_COUNT; | 2547 | priv->hw_params.max_stations = IWL3945_STATION_COUNT; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 6d77039b4ed2..1a622aa5a160 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c | |||
@@ -1999,7 +1999,7 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv, | |||
1999 | static void iwl4965_rx_reply_tx(struct iwl_priv *priv, | 1999 | static void iwl4965_rx_reply_tx(struct iwl_priv *priv, |
2000 | struct iwl_rx_mem_buffer *rxb) | 2000 | struct iwl_rx_mem_buffer *rxb) |
2001 | { | 2001 | { |
2002 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | 2002 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
2003 | u16 sequence = le16_to_cpu(pkt->hdr.sequence); | 2003 | u16 sequence = le16_to_cpu(pkt->hdr.sequence); |
2004 | int txq_id = SEQ_TO_QUEUE(sequence); | 2004 | int txq_id = SEQ_TO_QUEUE(sequence); |
2005 | int index = SEQ_TO_INDEX(sequence); | 2005 | int index = SEQ_TO_INDEX(sequence); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index ab5b9d8d66be..17555c7c1d67 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c | |||
@@ -423,7 +423,7 @@ static int iwl5000_send_calib_cfg(struct iwl_priv *priv) | |||
423 | static void iwl5000_rx_calib_result(struct iwl_priv *priv, | 423 | static void iwl5000_rx_calib_result(struct iwl_priv *priv, |
424 | struct iwl_rx_mem_buffer *rxb) | 424 | struct iwl_rx_mem_buffer *rxb) |
425 | { | 425 | { |
426 | struct iwl_rx_packet *pkt = (void *)rxb->skb->data; | 426 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
427 | struct iwl_calib_hdr *hdr = (struct iwl_calib_hdr *)pkt->u.raw; | 427 | struct iwl_calib_hdr *hdr = (struct iwl_calib_hdr *)pkt->u.raw; |
428 | int len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; | 428 | int len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; |
429 | int index; | 429 | int index; |
@@ -1143,7 +1143,7 @@ static int iwl5000_tx_status_reply_tx(struct iwl_priv *priv, | |||
1143 | static void iwl5000_rx_reply_tx(struct iwl_priv *priv, | 1143 | static void iwl5000_rx_reply_tx(struct iwl_priv *priv, |
1144 | struct iwl_rx_mem_buffer *rxb) | 1144 | struct iwl_rx_mem_buffer *rxb) |
1145 | { | 1145 | { |
1146 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | 1146 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
1147 | u16 sequence = le16_to_cpu(pkt->hdr.sequence); | 1147 | u16 sequence = le16_to_cpu(pkt->hdr.sequence); |
1148 | int txq_id = SEQ_TO_QUEUE(sequence); | 1148 | int txq_id = SEQ_TO_QUEUE(sequence); |
1149 | int index = SEQ_TO_INDEX(sequence); | 1149 | int index = SEQ_TO_INDEX(sequence); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 0878b34ee586..fc7a51144f0c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -524,7 +524,7 @@ int iwl_hw_tx_queue_init(struct iwl_priv *priv, | |||
524 | static void iwl_rx_reply_alive(struct iwl_priv *priv, | 524 | static void iwl_rx_reply_alive(struct iwl_priv *priv, |
525 | struct iwl_rx_mem_buffer *rxb) | 525 | struct iwl_rx_mem_buffer *rxb) |
526 | { | 526 | { |
527 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | 527 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
528 | struct iwl_alive_resp *palive; | 528 | struct iwl_alive_resp *palive; |
529 | struct delayed_work *pwork; | 529 | struct delayed_work *pwork; |
530 | 530 | ||
@@ -610,7 +610,7 @@ static void iwl_rx_beacon_notif(struct iwl_priv *priv, | |||
610 | struct iwl_rx_mem_buffer *rxb) | 610 | struct iwl_rx_mem_buffer *rxb) |
611 | { | 611 | { |
612 | #ifdef CONFIG_IWLWIFI_DEBUG | 612 | #ifdef CONFIG_IWLWIFI_DEBUG |
613 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | 613 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
614 | struct iwl4965_beacon_notif *beacon = | 614 | struct iwl4965_beacon_notif *beacon = |
615 | (struct iwl4965_beacon_notif *)pkt->u.raw; | 615 | (struct iwl4965_beacon_notif *)pkt->u.raw; |
616 | u8 rate = iwl_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags); | 616 | u8 rate = iwl_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags); |
@@ -634,7 +634,7 @@ static void iwl_rx_beacon_notif(struct iwl_priv *priv, | |||
634 | static void iwl_rx_card_state_notif(struct iwl_priv *priv, | 634 | static void iwl_rx_card_state_notif(struct iwl_priv *priv, |
635 | struct iwl_rx_mem_buffer *rxb) | 635 | struct iwl_rx_mem_buffer *rxb) |
636 | { | 636 | { |
637 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | 637 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
638 | u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags); | 638 | u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags); |
639 | unsigned long status = priv->status; | 639 | unsigned long status = priv->status; |
640 | 640 | ||
@@ -786,10 +786,10 @@ void iwl_rx_handle(struct iwl_priv *priv) | |||
786 | 786 | ||
787 | rxq->queue[i] = NULL; | 787 | rxq->queue[i] = NULL; |
788 | 788 | ||
789 | pci_unmap_single(priv->pci_dev, rxb->real_dma_addr, | 789 | pci_unmap_page(priv->pci_dev, rxb->page_dma, |
790 | priv->hw_params.rx_buf_size + 256, | 790 | PAGE_SIZE << priv->hw_params.rx_page_order, |
791 | PCI_DMA_FROMDEVICE); | 791 | PCI_DMA_FROMDEVICE); |
792 | pkt = (struct iwl_rx_packet *)rxb->skb->data; | 792 | pkt = rxb_addr(rxb); |
793 | 793 | ||
794 | trace_iwlwifi_dev_rx(priv, pkt, | 794 | trace_iwlwifi_dev_rx(priv, pkt, |
795 | le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK); | 795 | le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK); |
@@ -825,10 +825,10 @@ void iwl_rx_handle(struct iwl_priv *priv) | |||
825 | } | 825 | } |
826 | 826 | ||
827 | if (reclaim) { | 827 | if (reclaim) { |
828 | /* Invoke any callbacks, transfer the skb to caller, and | 828 | /* Invoke any callbacks, transfer the buffer to caller, |
829 | * fire off the (possibly) blocking iwl_send_cmd() | 829 | * and fire off the (possibly) blocking iwl_send_cmd() |
830 | * as we reclaim the driver command queue */ | 830 | * as we reclaim the driver command queue */ |
831 | if (rxb && rxb->skb) | 831 | if (rxb && rxb->page) |
832 | iwl_tx_cmd_complete(priv, rxb); | 832 | iwl_tx_cmd_complete(priv, rxb); |
833 | else | 833 | else |
834 | IWL_WARN(priv, "Claim null rxb?\n"); | 834 | IWL_WARN(priv, "Claim null rxb?\n"); |
@@ -837,10 +837,10 @@ void iwl_rx_handle(struct iwl_priv *priv) | |||
837 | /* For now we just don't re-use anything. We can tweak this | 837 | /* For now we just don't re-use anything. We can tweak this |
838 | * later to try and re-use notification packets and SKBs that | 838 | * later to try and re-use notification packets and SKBs that |
839 | * fail to Rx correctly */ | 839 | * fail to Rx correctly */ |
840 | if (rxb->skb != NULL) { | 840 | if (rxb->page != NULL) { |
841 | priv->alloc_rxb_skb--; | 841 | priv->alloc_rxb_page--; |
842 | dev_kfree_skb_any(rxb->skb); | 842 | __free_pages(rxb->page, priv->hw_params.rx_page_order); |
843 | rxb->skb = NULL; | 843 | rxb->page = NULL; |
844 | } | 844 | } |
845 | 845 | ||
846 | spin_lock_irqsave(&rxq->lock, flags); | 846 | spin_lock_irqsave(&rxq->lock, flags); |
@@ -907,6 +907,8 @@ static void iwl_irq_tasklet_legacy(struct iwl_priv *priv) | |||
907 | } | 907 | } |
908 | #endif | 908 | #endif |
909 | 909 | ||
910 | spin_unlock_irqrestore(&priv->lock, flags); | ||
911 | |||
910 | /* Since CSR_INT and CSR_FH_INT_STATUS reads and clears are not | 912 | /* Since CSR_INT and CSR_FH_INT_STATUS reads and clears are not |
911 | * atomic, make sure that inta covers all the interrupts that | 913 | * atomic, make sure that inta covers all the interrupts that |
912 | * we've discovered, even if FH interrupt came in just after | 914 | * we've discovered, even if FH interrupt came in just after |
@@ -928,8 +930,6 @@ static void iwl_irq_tasklet_legacy(struct iwl_priv *priv) | |||
928 | 930 | ||
929 | handled |= CSR_INT_BIT_HW_ERR; | 931 | handled |= CSR_INT_BIT_HW_ERR; |
930 | 932 | ||
931 | spin_unlock_irqrestore(&priv->lock, flags); | ||
932 | |||
933 | return; | 933 | return; |
934 | } | 934 | } |
935 | 935 | ||
@@ -1056,7 +1056,6 @@ static void iwl_irq_tasklet_legacy(struct iwl_priv *priv) | |||
1056 | "flags 0x%08lx\n", inta, inta_mask, inta_fh, flags); | 1056 | "flags 0x%08lx\n", inta, inta_mask, inta_fh, flags); |
1057 | } | 1057 | } |
1058 | #endif | 1058 | #endif |
1059 | spin_unlock_irqrestore(&priv->lock, flags); | ||
1060 | } | 1059 | } |
1061 | 1060 | ||
1062 | /* tasklet for iwlagn interrupt */ | 1061 | /* tasklet for iwlagn interrupt */ |
@@ -1086,6 +1085,9 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) | |||
1086 | inta, inta_mask); | 1085 | inta, inta_mask); |
1087 | } | 1086 | } |
1088 | #endif | 1087 | #endif |
1088 | |||
1089 | spin_unlock_irqrestore(&priv->lock, flags); | ||
1090 | |||
1089 | /* saved interrupt in inta variable now we can reset priv->inta */ | 1091 | /* saved interrupt in inta variable now we can reset priv->inta */ |
1090 | priv->inta = 0; | 1092 | priv->inta = 0; |
1091 | 1093 | ||
@@ -1101,8 +1103,6 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) | |||
1101 | 1103 | ||
1102 | handled |= CSR_INT_BIT_HW_ERR; | 1104 | handled |= CSR_INT_BIT_HW_ERR; |
1103 | 1105 | ||
1104 | spin_unlock_irqrestore(&priv->lock, flags); | ||
1105 | |||
1106 | return; | 1106 | return; |
1107 | } | 1107 | } |
1108 | 1108 | ||
@@ -1242,14 +1242,10 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) | |||
1242 | inta & ~priv->inta_mask); | 1242 | inta & ~priv->inta_mask); |
1243 | } | 1243 | } |
1244 | 1244 | ||
1245 | |||
1246 | /* Re-enable all interrupts */ | 1245 | /* Re-enable all interrupts */ |
1247 | /* only Re-enable if diabled by irq */ | 1246 | /* only Re-enable if diabled by irq */ |
1248 | if (test_bit(STATUS_INT_ENABLED, &priv->status)) | 1247 | if (test_bit(STATUS_INT_ENABLED, &priv->status)) |
1249 | iwl_enable_interrupts(priv); | 1248 | iwl_enable_interrupts(priv); |
1250 | |||
1251 | spin_unlock_irqrestore(&priv->lock, flags); | ||
1252 | |||
1253 | } | 1249 | } |
1254 | 1250 | ||
1255 | 1251 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index cc4e9122709e..7d4f131708f3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h | |||
@@ -3544,6 +3544,16 @@ struct iwl_wimax_coex_cmd { | |||
3544 | *****************************************************************************/ | 3544 | *****************************************************************************/ |
3545 | 3545 | ||
3546 | struct iwl_rx_packet { | 3546 | struct iwl_rx_packet { |
3547 | /* | ||
3548 | * The first 4 bytes of the RX frame header contain both the RX frame | ||
3549 | * size and some flags. | ||
3550 | * Bit fields: | ||
3551 | * 31: flag flush RB request | ||
3552 | * 30: flag ignore TC (terminal counter) request | ||
3553 | * 29: flag fast IRQ request | ||
3554 | * 28-14: Reserved | ||
3555 | * 13-00: RX frame size | ||
3556 | */ | ||
3547 | __le32 len_n_flags; | 3557 | __le32 len_n_flags; |
3548 | struct iwl_cmd_header hdr; | 3558 | struct iwl_cmd_header hdr; |
3549 | union { | 3559 | union { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 2ae168af0f2c..3e6ce5ce36aa 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -1281,7 +1281,7 @@ static void iwl_set_rate(struct iwl_priv *priv) | |||
1281 | 1281 | ||
1282 | void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) | 1282 | void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) |
1283 | { | 1283 | { |
1284 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | 1284 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
1285 | struct iwl_rxon_cmd *rxon = (void *)&priv->active_rxon; | 1285 | struct iwl_rxon_cmd *rxon = (void *)&priv->active_rxon; |
1286 | struct iwl_csa_notification *csa = &(pkt->u.csa_notif); | 1286 | struct iwl_csa_notification *csa = &(pkt->u.csa_notif); |
1287 | IWL_DEBUG_11H(priv, "CSA notif: channel %d, status %d\n", | 1287 | IWL_DEBUG_11H(priv, "CSA notif: channel %d, status %d\n", |
@@ -1492,10 +1492,9 @@ int iwl_set_hw_params(struct iwl_priv *priv) | |||
1492 | priv->hw_params.max_rxq_size = RX_QUEUE_SIZE; | 1492 | priv->hw_params.max_rxq_size = RX_QUEUE_SIZE; |
1493 | priv->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG; | 1493 | priv->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG; |
1494 | if (priv->cfg->mod_params->amsdu_size_8K) | 1494 | if (priv->cfg->mod_params->amsdu_size_8K) |
1495 | priv->hw_params.rx_buf_size = IWL_RX_BUF_SIZE_8K; | 1495 | priv->hw_params.rx_page_order = get_order(IWL_RX_BUF_SIZE_8K); |
1496 | else | 1496 | else |
1497 | priv->hw_params.rx_buf_size = IWL_RX_BUF_SIZE_4K; | 1497 | priv->hw_params.rx_page_order = get_order(IWL_RX_BUF_SIZE_4K); |
1498 | priv->hw_params.max_pkt_size = priv->hw_params.rx_buf_size - 256; | ||
1499 | 1498 | ||
1500 | priv->hw_params.max_beacon_itrvl = IWL_MAX_UCODE_BEACON_INTERVAL; | 1499 | priv->hw_params.max_beacon_itrvl = IWL_MAX_UCODE_BEACON_INTERVAL; |
1501 | 1500 | ||
@@ -2176,7 +2175,7 @@ void iwl_rx_pm_sleep_notif(struct iwl_priv *priv, | |||
2176 | struct iwl_rx_mem_buffer *rxb) | 2175 | struct iwl_rx_mem_buffer *rxb) |
2177 | { | 2176 | { |
2178 | #ifdef CONFIG_IWLWIFI_DEBUG | 2177 | #ifdef CONFIG_IWLWIFI_DEBUG |
2179 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | 2178 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
2180 | struct iwl_sleep_notification *sleep = &(pkt->u.sleep_notif); | 2179 | struct iwl_sleep_notification *sleep = &(pkt->u.sleep_notif); |
2181 | IWL_DEBUG_RX(priv, "sleep mode: %d, src: %d\n", | 2180 | IWL_DEBUG_RX(priv, "sleep mode: %d, src: %d\n", |
2182 | sleep->pm_sleep_mode, sleep->pm_wakeup_src); | 2181 | sleep->pm_sleep_mode, sleep->pm_wakeup_src); |
@@ -2187,7 +2186,7 @@ EXPORT_SYMBOL(iwl_rx_pm_sleep_notif); | |||
2187 | void iwl_rx_pm_debug_statistics_notif(struct iwl_priv *priv, | 2186 | void iwl_rx_pm_debug_statistics_notif(struct iwl_priv *priv, |
2188 | struct iwl_rx_mem_buffer *rxb) | 2187 | struct iwl_rx_mem_buffer *rxb) |
2189 | { | 2188 | { |
2190 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | 2189 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
2191 | u32 len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; | 2190 | u32 len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; |
2192 | IWL_DEBUG_RADIO(priv, "Dumping %d bytes of unhandled " | 2191 | IWL_DEBUG_RADIO(priv, "Dumping %d bytes of unhandled " |
2193 | "notification for %s:\n", len, | 2192 | "notification for %s:\n", len, |
@@ -2199,7 +2198,7 @@ EXPORT_SYMBOL(iwl_rx_pm_debug_statistics_notif); | |||
2199 | void iwl_rx_reply_error(struct iwl_priv *priv, | 2198 | void iwl_rx_reply_error(struct iwl_priv *priv, |
2200 | struct iwl_rx_mem_buffer *rxb) | 2199 | struct iwl_rx_mem_buffer *rxb) |
2201 | { | 2200 | { |
2202 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | 2201 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
2203 | 2202 | ||
2204 | IWL_ERR(priv, "Error Reply type 0x%08X cmd %s (0x%02X) " | 2203 | IWL_ERR(priv, "Error Reply type 0x%08X cmd %s (0x%02X) " |
2205 | "seq 0x%04X ser 0x%08X\n", | 2204 | "seq 0x%04X ser 0x%08X\n", |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index cec673badf0e..b877f8893fdf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h | |||
@@ -531,7 +531,7 @@ int iwl_send_cmd_pdu_async(struct iwl_priv *priv, u8 id, u16 len, | |||
531 | const void *data, | 531 | const void *data, |
532 | void (*callback)(struct iwl_priv *priv, | 532 | void (*callback)(struct iwl_priv *priv, |
533 | struct iwl_device_cmd *cmd, | 533 | struct iwl_device_cmd *cmd, |
534 | struct sk_buff *skb)); | 534 | struct iwl_rx_packet *pkt)); |
535 | 535 | ||
536 | int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd); | 536 | int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd); |
537 | 537 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 451aa65b1a56..35d579455c3c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h | |||
@@ -146,12 +146,13 @@ extern void iwl5000_temperature(struct iwl_priv *priv); | |||
146 | #define DEFAULT_LONG_RETRY_LIMIT 4U | 146 | #define DEFAULT_LONG_RETRY_LIMIT 4U |
147 | 147 | ||
148 | struct iwl_rx_mem_buffer { | 148 | struct iwl_rx_mem_buffer { |
149 | dma_addr_t real_dma_addr; | 149 | dma_addr_t page_dma; |
150 | dma_addr_t aligned_dma_addr; | 150 | struct page *page; |
151 | struct sk_buff *skb; | ||
152 | struct list_head list; | 151 | struct list_head list; |
153 | }; | 152 | }; |
154 | 153 | ||
154 | #define rxb_addr(r) page_address(r->page) | ||
155 | |||
155 | /* defined below */ | 156 | /* defined below */ |
156 | struct iwl_device_cmd; | 157 | struct iwl_device_cmd; |
157 | 158 | ||
@@ -167,7 +168,7 @@ struct iwl_cmd_meta { | |||
167 | */ | 168 | */ |
168 | void (*callback)(struct iwl_priv *priv, | 169 | void (*callback)(struct iwl_priv *priv, |
169 | struct iwl_device_cmd *cmd, | 170 | struct iwl_device_cmd *cmd, |
170 | struct sk_buff *skb); | 171 | struct iwl_rx_packet *pkt); |
171 | 172 | ||
172 | /* The CMD_SIZE_HUGE flag bit indicates that the command | 173 | /* The CMD_SIZE_HUGE flag bit indicates that the command |
173 | * structure is stored at the end of the shared queue memory. */ | 174 | * structure is stored at the end of the shared queue memory. */ |
@@ -366,6 +367,13 @@ enum { | |||
366 | 367 | ||
367 | #define IWL_CMD_MAX_PAYLOAD 320 | 368 | #define IWL_CMD_MAX_PAYLOAD 320 |
368 | 369 | ||
370 | /* | ||
371 | * IWL_LINK_HDR_MAX should include ieee80211_hdr, radiotap header, | ||
372 | * SNAP header and alignment. It should also be big enough for 802.11 | ||
373 | * control frames. | ||
374 | */ | ||
375 | #define IWL_LINK_HDR_MAX 64 | ||
376 | |||
369 | /** | 377 | /** |
370 | * struct iwl_device_cmd | 378 | * struct iwl_device_cmd |
371 | * | 379 | * |
@@ -390,10 +398,10 @@ struct iwl_device_cmd { | |||
390 | 398 | ||
391 | struct iwl_host_cmd { | 399 | struct iwl_host_cmd { |
392 | const void *data; | 400 | const void *data; |
393 | struct sk_buff *reply_skb; | 401 | unsigned long reply_page; |
394 | void (*callback)(struct iwl_priv *priv, | 402 | void (*callback)(struct iwl_priv *priv, |
395 | struct iwl_device_cmd *cmd, | 403 | struct iwl_device_cmd *cmd, |
396 | struct sk_buff *skb); | 404 | struct iwl_rx_packet *pkt); |
397 | u32 flags; | 405 | u32 flags; |
398 | u16 len; | 406 | u16 len; |
399 | u8 id; | 407 | u8 id; |
@@ -650,7 +658,7 @@ struct iwl_sensitivity_ranges { | |||
650 | * @valid_tx/rx_ant: usable antennas | 658 | * @valid_tx/rx_ant: usable antennas |
651 | * @max_rxq_size: Max # Rx frames in Rx queue (must be power-of-2) | 659 | * @max_rxq_size: Max # Rx frames in Rx queue (must be power-of-2) |
652 | * @max_rxq_log: Log-base-2 of max_rxq_size | 660 | * @max_rxq_log: Log-base-2 of max_rxq_size |
653 | * @rx_buf_size: Rx buffer size | 661 | * @rx_page_order: Rx buffer page order |
654 | * @rx_wrt_ptr_reg: FH{39}_RSCSR_CHNL0_WPTR | 662 | * @rx_wrt_ptr_reg: FH{39}_RSCSR_CHNL0_WPTR |
655 | * @max_stations: | 663 | * @max_stations: |
656 | * @bcast_sta_id: | 664 | * @bcast_sta_id: |
@@ -673,9 +681,8 @@ struct iwl_hw_params { | |||
673 | u8 valid_rx_ant; | 681 | u8 valid_rx_ant; |
674 | u16 max_rxq_size; | 682 | u16 max_rxq_size; |
675 | u16 max_rxq_log; | 683 | u16 max_rxq_log; |
676 | u32 rx_buf_size; | 684 | u32 rx_page_order; |
677 | u32 rx_wrt_ptr_reg; | 685 | u32 rx_wrt_ptr_reg; |
678 | u32 max_pkt_size; | ||
679 | u8 max_stations; | 686 | u8 max_stations; |
680 | u8 bcast_sta_id; | 687 | u8 bcast_sta_id; |
681 | u8 ht40_channel; | 688 | u8 ht40_channel; |
@@ -987,7 +994,7 @@ struct iwl_priv { | |||
987 | int frames_count; | 994 | int frames_count; |
988 | 995 | ||
989 | enum ieee80211_band band; | 996 | enum ieee80211_band band; |
990 | int alloc_rxb_skb; | 997 | int alloc_rxb_page; |
991 | 998 | ||
992 | void (*rx_handlers[REPLY_MAX])(struct iwl_priv *priv, | 999 | void (*rx_handlers[REPLY_MAX])(struct iwl_priv *priv, |
993 | struct iwl_rx_mem_buffer *rxb); | 1000 | struct iwl_rx_mem_buffer *rxb); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c index 532c8d6cd8da..22a21a1c7f49 100644 --- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c | |||
@@ -103,17 +103,8 @@ EXPORT_SYMBOL(get_cmd_string); | |||
103 | 103 | ||
104 | static void iwl_generic_cmd_callback(struct iwl_priv *priv, | 104 | static void iwl_generic_cmd_callback(struct iwl_priv *priv, |
105 | struct iwl_device_cmd *cmd, | 105 | struct iwl_device_cmd *cmd, |
106 | struct sk_buff *skb) | 106 | struct iwl_rx_packet *pkt) |
107 | { | 107 | { |
108 | struct iwl_rx_packet *pkt = NULL; | ||
109 | |||
110 | if (!skb) { | ||
111 | IWL_ERR(priv, "Error: Response NULL in %s.\n", | ||
112 | get_cmd_string(cmd->hdr.cmd)); | ||
113 | return; | ||
114 | } | ||
115 | |||
116 | pkt = (struct iwl_rx_packet *)skb->data; | ||
117 | if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) { | 108 | if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) { |
118 | IWL_ERR(priv, "Bad return from %s (0x%08X)\n", | 109 | IWL_ERR(priv, "Bad return from %s (0x%08X)\n", |
119 | get_cmd_string(cmd->hdr.cmd), pkt->hdr.flags); | 110 | get_cmd_string(cmd->hdr.cmd), pkt->hdr.flags); |
@@ -215,7 +206,7 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | |||
215 | ret = -EIO; | 206 | ret = -EIO; |
216 | goto fail; | 207 | goto fail; |
217 | } | 208 | } |
218 | if ((cmd->flags & CMD_WANT_SKB) && !cmd->reply_skb) { | 209 | if ((cmd->flags & CMD_WANT_SKB) && !cmd->reply_page) { |
219 | IWL_ERR(priv, "Error: Response NULL in '%s'\n", | 210 | IWL_ERR(priv, "Error: Response NULL in '%s'\n", |
220 | get_cmd_string(cmd->id)); | 211 | get_cmd_string(cmd->id)); |
221 | ret = -EIO; | 212 | ret = -EIO; |
@@ -237,9 +228,9 @@ cancel: | |||
237 | ~CMD_WANT_SKB; | 228 | ~CMD_WANT_SKB; |
238 | } | 229 | } |
239 | fail: | 230 | fail: |
240 | if (cmd->reply_skb) { | 231 | if (cmd->reply_page) { |
241 | dev_kfree_skb_any(cmd->reply_skb); | 232 | free_pages(cmd->reply_page, priv->hw_params.rx_page_order); |
242 | cmd->reply_skb = NULL; | 233 | cmd->reply_page = 0; |
243 | } | 234 | } |
244 | out: | 235 | out: |
245 | clear_bit(STATUS_HCMD_SYNC_ACTIVE, &priv->status); | 236 | clear_bit(STATUS_HCMD_SYNC_ACTIVE, &priv->status); |
@@ -272,7 +263,7 @@ int iwl_send_cmd_pdu_async(struct iwl_priv *priv, | |||
272 | u8 id, u16 len, const void *data, | 263 | u8 id, u16 len, const void *data, |
273 | void (*callback)(struct iwl_priv *priv, | 264 | void (*callback)(struct iwl_priv *priv, |
274 | struct iwl_device_cmd *cmd, | 265 | struct iwl_device_cmd *cmd, |
275 | struct sk_buff *skb)) | 266 | struct iwl_rx_packet *pkt)) |
276 | { | 267 | { |
277 | struct iwl_host_cmd cmd = { | 268 | struct iwl_host_cmd cmd = { |
278 | .id = id, | 269 | .id = id, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index 7ad327ef9cb5..0a407f79de01 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c | |||
@@ -200,7 +200,7 @@ int iwl_rx_queue_restock(struct iwl_priv *priv) | |||
200 | list_del(element); | 200 | list_del(element); |
201 | 201 | ||
202 | /* Point to Rx buffer via next RBD in circular buffer */ | 202 | /* Point to Rx buffer via next RBD in circular buffer */ |
203 | rxq->bd[rxq->write] = iwl_dma_addr2rbd_ptr(priv, rxb->aligned_dma_addr); | 203 | rxq->bd[rxq->write] = iwl_dma_addr2rbd_ptr(priv, rxb->page_dma); |
204 | rxq->queue[rxq->write] = rxb; | 204 | rxq->queue[rxq->write] = rxb; |
205 | rxq->write = (rxq->write + 1) & RX_QUEUE_MASK; | 205 | rxq->write = (rxq->write + 1) & RX_QUEUE_MASK; |
206 | rxq->free_count--; | 206 | rxq->free_count--; |
@@ -239,7 +239,7 @@ void iwl_rx_allocate(struct iwl_priv *priv, gfp_t priority) | |||
239 | struct iwl_rx_queue *rxq = &priv->rxq; | 239 | struct iwl_rx_queue *rxq = &priv->rxq; |
240 | struct list_head *element; | 240 | struct list_head *element; |
241 | struct iwl_rx_mem_buffer *rxb; | 241 | struct iwl_rx_mem_buffer *rxb; |
242 | struct sk_buff *skb; | 242 | struct page *page; |
243 | unsigned long flags; | 243 | unsigned long flags; |
244 | 244 | ||
245 | while (1) { | 245 | while (1) { |
@@ -252,29 +252,34 @@ void iwl_rx_allocate(struct iwl_priv *priv, gfp_t priority) | |||
252 | 252 | ||
253 | if (rxq->free_count > RX_LOW_WATERMARK) | 253 | if (rxq->free_count > RX_LOW_WATERMARK) |
254 | priority |= __GFP_NOWARN; | 254 | priority |= __GFP_NOWARN; |
255 | /* Alloc a new receive buffer */ | ||
256 | skb = alloc_skb(priv->hw_params.rx_buf_size + 256, | ||
257 | priority); | ||
258 | 255 | ||
259 | if (!skb) { | 256 | if (priv->hw_params.rx_page_order > 0) |
257 | priority |= __GFP_COMP; | ||
258 | |||
259 | /* Alloc a new receive buffer */ | ||
260 | page = alloc_pages(priority, priv->hw_params.rx_page_order); | ||
261 | if (!page) { | ||
260 | if (net_ratelimit()) | 262 | if (net_ratelimit()) |
261 | IWL_DEBUG_INFO(priv, "Failed to allocate SKB buffer.\n"); | 263 | IWL_DEBUG_INFO(priv, "alloc_pages failed, " |
264 | "order: %d\n", | ||
265 | priv->hw_params.rx_page_order); | ||
266 | |||
262 | if ((rxq->free_count <= RX_LOW_WATERMARK) && | 267 | if ((rxq->free_count <= RX_LOW_WATERMARK) && |
263 | net_ratelimit()) | 268 | net_ratelimit()) |
264 | IWL_CRIT(priv, "Failed to allocate SKB buffer with %s. Only %u free buffers remaining.\n", | 269 | IWL_CRIT(priv, "Failed to alloc_pages with %s. Only %u free buffers remaining.\n", |
265 | priority == GFP_ATOMIC ? "GFP_ATOMIC" : "GFP_KERNEL", | 270 | priority == GFP_ATOMIC ? "GFP_ATOMIC" : "GFP_KERNEL", |
266 | rxq->free_count); | 271 | rxq->free_count); |
267 | /* We don't reschedule replenish work here -- we will | 272 | /* We don't reschedule replenish work here -- we will |
268 | * call the restock method and if it still needs | 273 | * call the restock method and if it still needs |
269 | * more buffers it will schedule replenish */ | 274 | * more buffers it will schedule replenish */ |
270 | break; | 275 | return; |
271 | } | 276 | } |
272 | 277 | ||
273 | spin_lock_irqsave(&rxq->lock, flags); | 278 | spin_lock_irqsave(&rxq->lock, flags); |
274 | 279 | ||
275 | if (list_empty(&rxq->rx_used)) { | 280 | if (list_empty(&rxq->rx_used)) { |
276 | spin_unlock_irqrestore(&rxq->lock, flags); | 281 | spin_unlock_irqrestore(&rxq->lock, flags); |
277 | dev_kfree_skb_any(skb); | 282 | __free_pages(page, priv->hw_params.rx_page_order); |
278 | return; | 283 | return; |
279 | } | 284 | } |
280 | element = rxq->rx_used.next; | 285 | element = rxq->rx_used.next; |
@@ -283,24 +288,21 @@ void iwl_rx_allocate(struct iwl_priv *priv, gfp_t priority) | |||
283 | 288 | ||
284 | spin_unlock_irqrestore(&rxq->lock, flags); | 289 | spin_unlock_irqrestore(&rxq->lock, flags); |
285 | 290 | ||
286 | rxb->skb = skb; | 291 | rxb->page = page; |
287 | /* Get physical address of RB/SKB */ | 292 | /* Get physical address of the RB */ |
288 | rxb->real_dma_addr = pci_map_single( | 293 | rxb->page_dma = pci_map_page(priv->pci_dev, page, 0, |
289 | priv->pci_dev, | 294 | PAGE_SIZE << priv->hw_params.rx_page_order, |
290 | rxb->skb->data, | 295 | PCI_DMA_FROMDEVICE); |
291 | priv->hw_params.rx_buf_size + 256, | ||
292 | PCI_DMA_FROMDEVICE); | ||
293 | /* dma address must be no more than 36 bits */ | 296 | /* dma address must be no more than 36 bits */ |
294 | BUG_ON(rxb->real_dma_addr & ~DMA_BIT_MASK(36)); | 297 | BUG_ON(rxb->page_dma & ~DMA_BIT_MASK(36)); |
295 | /* and also 256 byte aligned! */ | 298 | /* and also 256 byte aligned! */ |
296 | rxb->aligned_dma_addr = ALIGN(rxb->real_dma_addr, 256); | 299 | BUG_ON(rxb->page_dma & DMA_BIT_MASK(8)); |
297 | skb_reserve(rxb->skb, rxb->aligned_dma_addr - rxb->real_dma_addr); | ||
298 | 300 | ||
299 | spin_lock_irqsave(&rxq->lock, flags); | 301 | spin_lock_irqsave(&rxq->lock, flags); |
300 | 302 | ||
301 | list_add_tail(&rxb->list, &rxq->rx_free); | 303 | list_add_tail(&rxb->list, &rxq->rx_free); |
302 | rxq->free_count++; | 304 | rxq->free_count++; |
303 | priv->alloc_rxb_skb++; | 305 | priv->alloc_rxb_page++; |
304 | 306 | ||
305 | spin_unlock_irqrestore(&rxq->lock, flags); | 307 | spin_unlock_irqrestore(&rxq->lock, flags); |
306 | } | 308 | } |
@@ -336,12 +338,14 @@ void iwl_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq) | |||
336 | { | 338 | { |
337 | int i; | 339 | int i; |
338 | for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) { | 340 | for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) { |
339 | if (rxq->pool[i].skb != NULL) { | 341 | if (rxq->pool[i].page != NULL) { |
340 | pci_unmap_single(priv->pci_dev, | 342 | pci_unmap_page(priv->pci_dev, rxq->pool[i].page_dma, |
341 | rxq->pool[i].real_dma_addr, | 343 | PAGE_SIZE << priv->hw_params.rx_page_order, |
342 | priv->hw_params.rx_buf_size + 256, | 344 | PCI_DMA_FROMDEVICE); |
343 | PCI_DMA_FROMDEVICE); | 345 | __free_pages(rxq->pool[i].page, |
344 | dev_kfree_skb(rxq->pool[i].skb); | 346 | priv->hw_params.rx_page_order); |
347 | rxq->pool[i].page = NULL; | ||
348 | priv->alloc_rxb_page--; | ||
345 | } | 349 | } |
346 | } | 350 | } |
347 | 351 | ||
@@ -405,14 +409,14 @@ void iwl_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq) | |||
405 | for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) { | 409 | for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) { |
406 | /* In the reset function, these buffers may have been allocated | 410 | /* In the reset function, these buffers may have been allocated |
407 | * to an SKB, so we need to unmap and free potential storage */ | 411 | * to an SKB, so we need to unmap and free potential storage */ |
408 | if (rxq->pool[i].skb != NULL) { | 412 | if (rxq->pool[i].page != NULL) { |
409 | pci_unmap_single(priv->pci_dev, | 413 | pci_unmap_page(priv->pci_dev, rxq->pool[i].page_dma, |
410 | rxq->pool[i].real_dma_addr, | 414 | PAGE_SIZE << priv->hw_params.rx_page_order, |
411 | priv->hw_params.rx_buf_size + 256, | 415 | PCI_DMA_FROMDEVICE); |
412 | PCI_DMA_FROMDEVICE); | 416 | priv->alloc_rxb_page--; |
413 | priv->alloc_rxb_skb--; | 417 | __free_pages(rxq->pool[i].page, |
414 | dev_kfree_skb(rxq->pool[i].skb); | 418 | priv->hw_params.rx_page_order); |
415 | rxq->pool[i].skb = NULL; | 419 | rxq->pool[i].page = NULL; |
416 | } | 420 | } |
417 | list_add_tail(&rxq->pool[i].list, &rxq->rx_used); | 421 | list_add_tail(&rxq->pool[i].list, &rxq->rx_used); |
418 | } | 422 | } |
@@ -491,7 +495,7 @@ void iwl_rx_missed_beacon_notif(struct iwl_priv *priv, | |||
491 | struct iwl_rx_mem_buffer *rxb) | 495 | struct iwl_rx_mem_buffer *rxb) |
492 | 496 | ||
493 | { | 497 | { |
494 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | 498 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
495 | struct iwl_missed_beacon_notif *missed_beacon; | 499 | struct iwl_missed_beacon_notif *missed_beacon; |
496 | 500 | ||
497 | missed_beacon = &pkt->u.missed_beacon; | 501 | missed_beacon = &pkt->u.missed_beacon; |
@@ -592,7 +596,7 @@ void iwl_rx_statistics(struct iwl_priv *priv, | |||
592 | struct iwl_rx_mem_buffer *rxb) | 596 | struct iwl_rx_mem_buffer *rxb) |
593 | { | 597 | { |
594 | int change; | 598 | int change; |
595 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | 599 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
596 | 600 | ||
597 | IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n", | 601 | IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n", |
598 | (int)sizeof(priv->statistics), | 602 | (int)sizeof(priv->statistics), |
@@ -919,6 +923,9 @@ static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv, | |||
919 | struct iwl_rx_mem_buffer *rxb, | 923 | struct iwl_rx_mem_buffer *rxb, |
920 | struct ieee80211_rx_status *stats) | 924 | struct ieee80211_rx_status *stats) |
921 | { | 925 | { |
926 | struct sk_buff *skb; | ||
927 | int ret = 0; | ||
928 | |||
922 | /* We only process data packets if the interface is open */ | 929 | /* We only process data packets if the interface is open */ |
923 | if (unlikely(!priv->is_open)) { | 930 | if (unlikely(!priv->is_open)) { |
924 | IWL_DEBUG_DROP_LIMIT(priv, | 931 | IWL_DEBUG_DROP_LIMIT(priv, |
@@ -931,15 +938,38 @@ static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv, | |||
931 | iwl_set_decrypted_flag(priv, hdr, ampdu_status, stats)) | 938 | iwl_set_decrypted_flag(priv, hdr, ampdu_status, stats)) |
932 | return; | 939 | return; |
933 | 940 | ||
934 | /* Resize SKB from mac header to end of packet */ | 941 | skb = alloc_skb(IWL_LINK_HDR_MAX, GFP_ATOMIC); |
935 | skb_reserve(rxb->skb, (void *)hdr - (void *)rxb->skb->data); | 942 | if (!skb) { |
936 | skb_put(rxb->skb, len); | 943 | IWL_ERR(priv, "alloc_skb failed\n"); |
944 | return; | ||
945 | } | ||
946 | |||
947 | skb_add_rx_frag(skb, 0, rxb->page, (void *)hdr - rxb_addr(rxb), len); | ||
948 | |||
949 | /* mac80211 currently doesn't support paged SKB. Convert it to | ||
950 | * linear SKB for management frame and data frame requires | ||
951 | * software decryption or software defragementation. */ | ||
952 | if (ieee80211_is_mgmt(hdr->frame_control) || | ||
953 | ieee80211_has_protected(hdr->frame_control) || | ||
954 | ieee80211_has_morefrags(hdr->frame_control) || | ||
955 | le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG) | ||
956 | ret = skb_linearize(skb); | ||
957 | else | ||
958 | ret = __pskb_pull_tail(skb, min_t(u16, IWL_LINK_HDR_MAX, len)) ? | ||
959 | 0 : -ENOMEM; | ||
960 | |||
961 | if (ret) { | ||
962 | kfree_skb(skb); | ||
963 | goto out; | ||
964 | } | ||
937 | 965 | ||
938 | iwl_update_stats(priv, false, hdr->frame_control, len); | 966 | iwl_update_stats(priv, false, hdr->frame_control, len); |
939 | memcpy(IEEE80211_SKB_RXCB(rxb->skb), stats, sizeof(*stats)); | 967 | memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats)); |
940 | ieee80211_rx_irqsafe(priv->hw, rxb->skb); | 968 | |
941 | priv->alloc_rxb_skb--; | 969 | ieee80211_rx(priv->hw, skb); |
942 | rxb->skb = NULL; | 970 | out: |
971 | priv->alloc_rxb_page--; | ||
972 | rxb->page = NULL; | ||
943 | } | 973 | } |
944 | 974 | ||
945 | /* This is necessary only for a number of statistics, see the caller. */ | 975 | /* This is necessary only for a number of statistics, see the caller. */ |
@@ -967,7 +997,7 @@ void iwl_rx_reply_rx(struct iwl_priv *priv, | |||
967 | { | 997 | { |
968 | struct ieee80211_hdr *header; | 998 | struct ieee80211_hdr *header; |
969 | struct ieee80211_rx_status rx_status; | 999 | struct ieee80211_rx_status rx_status; |
970 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | 1000 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
971 | struct iwl_rx_phy_res *phy_res; | 1001 | struct iwl_rx_phy_res *phy_res; |
972 | __le32 rx_pkt_status; | 1002 | __le32 rx_pkt_status; |
973 | struct iwl4965_rx_mpdu_res_start *amsdu; | 1003 | struct iwl4965_rx_mpdu_res_start *amsdu; |
@@ -1128,7 +1158,7 @@ EXPORT_SYMBOL(iwl_rx_reply_rx); | |||
1128 | void iwl_rx_reply_rx_phy(struct iwl_priv *priv, | 1158 | void iwl_rx_reply_rx_phy(struct iwl_priv *priv, |
1129 | struct iwl_rx_mem_buffer *rxb) | 1159 | struct iwl_rx_mem_buffer *rxb) |
1130 | { | 1160 | { |
1131 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | 1161 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
1132 | priv->last_phy_res[0] = 1; | 1162 | priv->last_phy_res[0] = 1; |
1133 | memcpy(&priv->last_phy_res[1], &(pkt->u.raw[0]), | 1163 | memcpy(&priv->last_phy_res[1], &(pkt->u.raw[0]), |
1134 | sizeof(struct iwl_rx_phy_res)); | 1164 | sizeof(struct iwl_rx_phy_res)); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index 41f9a0621250..4fca65a2fe9c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c | |||
@@ -111,7 +111,7 @@ EXPORT_SYMBOL(iwl_scan_cancel_timeout); | |||
111 | static int iwl_send_scan_abort(struct iwl_priv *priv) | 111 | static int iwl_send_scan_abort(struct iwl_priv *priv) |
112 | { | 112 | { |
113 | int ret = 0; | 113 | int ret = 0; |
114 | struct iwl_rx_packet *res; | 114 | struct iwl_rx_packet *pkt; |
115 | struct iwl_host_cmd cmd = { | 115 | struct iwl_host_cmd cmd = { |
116 | .id = REPLY_SCAN_ABORT_CMD, | 116 | .id = REPLY_SCAN_ABORT_CMD, |
117 | .flags = CMD_WANT_SKB, | 117 | .flags = CMD_WANT_SKB, |
@@ -131,21 +131,21 @@ static int iwl_send_scan_abort(struct iwl_priv *priv) | |||
131 | return ret; | 131 | return ret; |
132 | } | 132 | } |
133 | 133 | ||
134 | res = (struct iwl_rx_packet *)cmd.reply_skb->data; | 134 | pkt = (struct iwl_rx_packet *)cmd.reply_page; |
135 | if (res->u.status != CAN_ABORT_STATUS) { | 135 | if (pkt->u.status != CAN_ABORT_STATUS) { |
136 | /* The scan abort will return 1 for success or | 136 | /* The scan abort will return 1 for success or |
137 | * 2 for "failure". A failure condition can be | 137 | * 2 for "failure". A failure condition can be |
138 | * due to simply not being in an active scan which | 138 | * due to simply not being in an active scan which |
139 | * can occur if we send the scan abort before we | 139 | * can occur if we send the scan abort before we |
140 | * the microcode has notified us that a scan is | 140 | * the microcode has notified us that a scan is |
141 | * completed. */ | 141 | * completed. */ |
142 | IWL_DEBUG_INFO(priv, "SCAN_ABORT returned %d.\n", res->u.status); | 142 | IWL_DEBUG_INFO(priv, "SCAN_ABORT returned %d.\n", pkt->u.status); |
143 | clear_bit(STATUS_SCAN_ABORTING, &priv->status); | 143 | clear_bit(STATUS_SCAN_ABORTING, &priv->status); |
144 | clear_bit(STATUS_SCAN_HW, &priv->status); | 144 | clear_bit(STATUS_SCAN_HW, &priv->status); |
145 | } | 145 | } |
146 | 146 | ||
147 | priv->alloc_rxb_skb--; | 147 | priv->alloc_rxb_page--; |
148 | dev_kfree_skb_any(cmd.reply_skb); | 148 | free_pages(cmd.reply_page, priv->hw_params.rx_page_order); |
149 | 149 | ||
150 | return ret; | 150 | return ret; |
151 | } | 151 | } |
@@ -155,7 +155,7 @@ static void iwl_rx_reply_scan(struct iwl_priv *priv, | |||
155 | struct iwl_rx_mem_buffer *rxb) | 155 | struct iwl_rx_mem_buffer *rxb) |
156 | { | 156 | { |
157 | #ifdef CONFIG_IWLWIFI_DEBUG | 157 | #ifdef CONFIG_IWLWIFI_DEBUG |
158 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | 158 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
159 | struct iwl_scanreq_notification *notif = | 159 | struct iwl_scanreq_notification *notif = |
160 | (struct iwl_scanreq_notification *)pkt->u.raw; | 160 | (struct iwl_scanreq_notification *)pkt->u.raw; |
161 | 161 | ||
@@ -167,7 +167,7 @@ static void iwl_rx_reply_scan(struct iwl_priv *priv, | |||
167 | static void iwl_rx_scan_start_notif(struct iwl_priv *priv, | 167 | static void iwl_rx_scan_start_notif(struct iwl_priv *priv, |
168 | struct iwl_rx_mem_buffer *rxb) | 168 | struct iwl_rx_mem_buffer *rxb) |
169 | { | 169 | { |
170 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | 170 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
171 | struct iwl_scanstart_notification *notif = | 171 | struct iwl_scanstart_notification *notif = |
172 | (struct iwl_scanstart_notification *)pkt->u.raw; | 172 | (struct iwl_scanstart_notification *)pkt->u.raw; |
173 | priv->scan_start_tsf = le32_to_cpu(notif->tsf_low); | 173 | priv->scan_start_tsf = le32_to_cpu(notif->tsf_low); |
@@ -186,7 +186,7 @@ static void iwl_rx_scan_results_notif(struct iwl_priv *priv, | |||
186 | struct iwl_rx_mem_buffer *rxb) | 186 | struct iwl_rx_mem_buffer *rxb) |
187 | { | 187 | { |
188 | #ifdef CONFIG_IWLWIFI_DEBUG | 188 | #ifdef CONFIG_IWLWIFI_DEBUG |
189 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | 189 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
190 | struct iwl_scanresults_notification *notif = | 190 | struct iwl_scanresults_notification *notif = |
191 | (struct iwl_scanresults_notification *)pkt->u.raw; | 191 | (struct iwl_scanresults_notification *)pkt->u.raw; |
192 | 192 | ||
@@ -213,7 +213,7 @@ static void iwl_rx_scan_complete_notif(struct iwl_priv *priv, | |||
213 | struct iwl_rx_mem_buffer *rxb) | 213 | struct iwl_rx_mem_buffer *rxb) |
214 | { | 214 | { |
215 | #ifdef CONFIG_IWLWIFI_DEBUG | 215 | #ifdef CONFIG_IWLWIFI_DEBUG |
216 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | 216 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
217 | struct iwl_scancomplete_notification *scan_notif = (void *)pkt->u.raw; | 217 | struct iwl_scancomplete_notification *scan_notif = (void *)pkt->u.raw; |
218 | 218 | ||
219 | IWL_DEBUG_SCAN(priv, "Scan complete: %d channels (TSF 0x%08X:%08X) - %d\n", | 219 | IWL_DEBUG_SCAN(priv, "Scan complete: %d channels (TSF 0x%08X:%08X) - %d\n", |
diff --git a/drivers/net/wireless/iwlwifi/iwl-spectrum.c b/drivers/net/wireless/iwlwifi/iwl-spectrum.c index 022bcf115731..1ea5cd345fe8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-spectrum.c +++ b/drivers/net/wireless/iwlwifi/iwl-spectrum.c | |||
@@ -177,7 +177,7 @@ static int iwl_get_measurement(struct iwl_priv *priv, | |||
177 | static void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv, | 177 | static void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv, |
178 | struct iwl_rx_mem_buffer *rxb) | 178 | struct iwl_rx_mem_buffer *rxb) |
179 | { | 179 | { |
180 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | 180 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
181 | struct iwl_spectrum_notification *report = &(pkt->u.spectrum_notif); | 181 | struct iwl_spectrum_notification *report = &(pkt->u.spectrum_notif); |
182 | 182 | ||
183 | if (!report->state) { | 183 | if (!report->state) { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index c6633fec8216..dc74c16d36a8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c | |||
@@ -99,32 +99,25 @@ static void iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id) | |||
99 | 99 | ||
100 | static void iwl_add_sta_callback(struct iwl_priv *priv, | 100 | static void iwl_add_sta_callback(struct iwl_priv *priv, |
101 | struct iwl_device_cmd *cmd, | 101 | struct iwl_device_cmd *cmd, |
102 | struct sk_buff *skb) | 102 | struct iwl_rx_packet *pkt) |
103 | { | 103 | { |
104 | struct iwl_rx_packet *res = NULL; | ||
105 | struct iwl_addsta_cmd *addsta = | 104 | struct iwl_addsta_cmd *addsta = |
106 | (struct iwl_addsta_cmd *)cmd->cmd.payload; | 105 | (struct iwl_addsta_cmd *)cmd->cmd.payload; |
107 | u8 sta_id = addsta->sta.sta_id; | 106 | u8 sta_id = addsta->sta.sta_id; |
108 | 107 | ||
109 | if (!skb) { | 108 | if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) { |
110 | IWL_ERR(priv, "Error: Response NULL in REPLY_ADD_STA.\n"); | ||
111 | return; | ||
112 | } | ||
113 | |||
114 | res = (struct iwl_rx_packet *)skb->data; | ||
115 | if (res->hdr.flags & IWL_CMD_FAILED_MSK) { | ||
116 | IWL_ERR(priv, "Bad return from REPLY_ADD_STA (0x%08X)\n", | 109 | IWL_ERR(priv, "Bad return from REPLY_ADD_STA (0x%08X)\n", |
117 | res->hdr.flags); | 110 | pkt->hdr.flags); |
118 | return; | 111 | return; |
119 | } | 112 | } |
120 | 113 | ||
121 | switch (res->u.add_sta.status) { | 114 | switch (pkt->u.add_sta.status) { |
122 | case ADD_STA_SUCCESS_MSK: | 115 | case ADD_STA_SUCCESS_MSK: |
123 | iwl_sta_ucode_activate(priv, sta_id); | 116 | iwl_sta_ucode_activate(priv, sta_id); |
124 | /* fall through */ | 117 | /* fall through */ |
125 | default: | 118 | default: |
126 | IWL_DEBUG_HC(priv, "Received REPLY_ADD_STA:(0x%08X)\n", | 119 | IWL_DEBUG_HC(priv, "Received REPLY_ADD_STA:(0x%08X)\n", |
127 | res->u.add_sta.status); | 120 | pkt->u.add_sta.status); |
128 | break; | 121 | break; |
129 | } | 122 | } |
130 | } | 123 | } |
@@ -132,7 +125,7 @@ static void iwl_add_sta_callback(struct iwl_priv *priv, | |||
132 | int iwl_send_add_sta(struct iwl_priv *priv, | 125 | int iwl_send_add_sta(struct iwl_priv *priv, |
133 | struct iwl_addsta_cmd *sta, u8 flags) | 126 | struct iwl_addsta_cmd *sta, u8 flags) |
134 | { | 127 | { |
135 | struct iwl_rx_packet *res = NULL; | 128 | struct iwl_rx_packet *pkt = NULL; |
136 | int ret = 0; | 129 | int ret = 0; |
137 | u8 data[sizeof(*sta)]; | 130 | u8 data[sizeof(*sta)]; |
138 | struct iwl_host_cmd cmd = { | 131 | struct iwl_host_cmd cmd = { |
@@ -152,15 +145,15 @@ int iwl_send_add_sta(struct iwl_priv *priv, | |||
152 | if (ret || (flags & CMD_ASYNC)) | 145 | if (ret || (flags & CMD_ASYNC)) |
153 | return ret; | 146 | return ret; |
154 | 147 | ||
155 | res = (struct iwl_rx_packet *)cmd.reply_skb->data; | 148 | pkt = (struct iwl_rx_packet *)cmd.reply_page; |
156 | if (res->hdr.flags & IWL_CMD_FAILED_MSK) { | 149 | if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) { |
157 | IWL_ERR(priv, "Bad return from REPLY_ADD_STA (0x%08X)\n", | 150 | IWL_ERR(priv, "Bad return from REPLY_ADD_STA (0x%08X)\n", |
158 | res->hdr.flags); | 151 | pkt->hdr.flags); |
159 | ret = -EIO; | 152 | ret = -EIO; |
160 | } | 153 | } |
161 | 154 | ||
162 | if (ret == 0) { | 155 | if (ret == 0) { |
163 | switch (res->u.add_sta.status) { | 156 | switch (pkt->u.add_sta.status) { |
164 | case ADD_STA_SUCCESS_MSK: | 157 | case ADD_STA_SUCCESS_MSK: |
165 | iwl_sta_ucode_activate(priv, sta->sta.sta_id); | 158 | iwl_sta_ucode_activate(priv, sta->sta.sta_id); |
166 | IWL_DEBUG_INFO(priv, "REPLY_ADD_STA PASSED\n"); | 159 | IWL_DEBUG_INFO(priv, "REPLY_ADD_STA PASSED\n"); |
@@ -172,8 +165,8 @@ int iwl_send_add_sta(struct iwl_priv *priv, | |||
172 | } | 165 | } |
173 | } | 166 | } |
174 | 167 | ||
175 | priv->alloc_rxb_skb--; | 168 | priv->alloc_rxb_page--; |
176 | dev_kfree_skb_any(cmd.reply_skb); | 169 | free_pages(cmd.reply_page, priv->hw_params.rx_page_order); |
177 | 170 | ||
178 | return ret; | 171 | return ret; |
179 | } | 172 | } |
@@ -324,26 +317,19 @@ static void iwl_sta_ucode_deactivate(struct iwl_priv *priv, const char *addr) | |||
324 | 317 | ||
325 | static void iwl_remove_sta_callback(struct iwl_priv *priv, | 318 | static void iwl_remove_sta_callback(struct iwl_priv *priv, |
326 | struct iwl_device_cmd *cmd, | 319 | struct iwl_device_cmd *cmd, |
327 | struct sk_buff *skb) | 320 | struct iwl_rx_packet *pkt) |
328 | { | 321 | { |
329 | struct iwl_rx_packet *res = NULL; | ||
330 | struct iwl_rem_sta_cmd *rm_sta = | 322 | struct iwl_rem_sta_cmd *rm_sta = |
331 | (struct iwl_rem_sta_cmd *)cmd->cmd.payload; | 323 | (struct iwl_rem_sta_cmd *)cmd->cmd.payload; |
332 | const char *addr = rm_sta->addr; | 324 | const char *addr = rm_sta->addr; |
333 | 325 | ||
334 | if (!skb) { | 326 | if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) { |
335 | IWL_ERR(priv, "Error: Response NULL in REPLY_REMOVE_STA.\n"); | ||
336 | return; | ||
337 | } | ||
338 | |||
339 | res = (struct iwl_rx_packet *)skb->data; | ||
340 | if (res->hdr.flags & IWL_CMD_FAILED_MSK) { | ||
341 | IWL_ERR(priv, "Bad return from REPLY_REMOVE_STA (0x%08X)\n", | 327 | IWL_ERR(priv, "Bad return from REPLY_REMOVE_STA (0x%08X)\n", |
342 | res->hdr.flags); | 328 | pkt->hdr.flags); |
343 | return; | 329 | return; |
344 | } | 330 | } |
345 | 331 | ||
346 | switch (res->u.rem_sta.status) { | 332 | switch (pkt->u.rem_sta.status) { |
347 | case REM_STA_SUCCESS_MSK: | 333 | case REM_STA_SUCCESS_MSK: |
348 | iwl_sta_ucode_deactivate(priv, addr); | 334 | iwl_sta_ucode_deactivate(priv, addr); |
349 | break; | 335 | break; |
@@ -356,7 +342,7 @@ static void iwl_remove_sta_callback(struct iwl_priv *priv, | |||
356 | static int iwl_send_remove_station(struct iwl_priv *priv, const u8 *addr, | 342 | static int iwl_send_remove_station(struct iwl_priv *priv, const u8 *addr, |
357 | u8 flags) | 343 | u8 flags) |
358 | { | 344 | { |
359 | struct iwl_rx_packet *res = NULL; | 345 | struct iwl_rx_packet *pkt; |
360 | int ret; | 346 | int ret; |
361 | 347 | ||
362 | struct iwl_rem_sta_cmd rm_sta_cmd; | 348 | struct iwl_rem_sta_cmd rm_sta_cmd; |
@@ -381,15 +367,15 @@ static int iwl_send_remove_station(struct iwl_priv *priv, const u8 *addr, | |||
381 | if (ret || (flags & CMD_ASYNC)) | 367 | if (ret || (flags & CMD_ASYNC)) |
382 | return ret; | 368 | return ret; |
383 | 369 | ||
384 | res = (struct iwl_rx_packet *)cmd.reply_skb->data; | 370 | pkt = (struct iwl_rx_packet *)cmd.reply_page; |
385 | if (res->hdr.flags & IWL_CMD_FAILED_MSK) { | 371 | if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) { |
386 | IWL_ERR(priv, "Bad return from REPLY_REMOVE_STA (0x%08X)\n", | 372 | IWL_ERR(priv, "Bad return from REPLY_REMOVE_STA (0x%08X)\n", |
387 | res->hdr.flags); | 373 | pkt->hdr.flags); |
388 | ret = -EIO; | 374 | ret = -EIO; |
389 | } | 375 | } |
390 | 376 | ||
391 | if (!ret) { | 377 | if (!ret) { |
392 | switch (res->u.rem_sta.status) { | 378 | switch (pkt->u.rem_sta.status) { |
393 | case REM_STA_SUCCESS_MSK: | 379 | case REM_STA_SUCCESS_MSK: |
394 | iwl_sta_ucode_deactivate(priv, addr); | 380 | iwl_sta_ucode_deactivate(priv, addr); |
395 | IWL_DEBUG_ASSOC(priv, "REPLY_REMOVE_STA PASSED\n"); | 381 | IWL_DEBUG_ASSOC(priv, "REPLY_REMOVE_STA PASSED\n"); |
@@ -401,8 +387,8 @@ static int iwl_send_remove_station(struct iwl_priv *priv, const u8 *addr, | |||
401 | } | 387 | } |
402 | } | 388 | } |
403 | 389 | ||
404 | priv->alloc_rxb_skb--; | 390 | priv->alloc_rxb_page--; |
405 | dev_kfree_skb_any(cmd.reply_skb); | 391 | free_pages(cmd.reply_page, priv->hw_params.rx_page_order); |
406 | 392 | ||
407 | return ret; | 393 | return ret; |
408 | } | 394 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index d0bd7cd024ad..5c43d7c43b30 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c | |||
@@ -1153,7 +1153,7 @@ static void iwl_hcmd_queue_reclaim(struct iwl_priv *priv, int txq_id, | |||
1153 | */ | 1153 | */ |
1154 | void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) | 1154 | void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) |
1155 | { | 1155 | { |
1156 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | 1156 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
1157 | u16 sequence = le16_to_cpu(pkt->hdr.sequence); | 1157 | u16 sequence = le16_to_cpu(pkt->hdr.sequence); |
1158 | int txq_id = SEQ_TO_QUEUE(sequence); | 1158 | int txq_id = SEQ_TO_QUEUE(sequence); |
1159 | int index = SEQ_TO_INDEX(sequence); | 1159 | int index = SEQ_TO_INDEX(sequence); |
@@ -1180,10 +1180,10 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) | |||
1180 | 1180 | ||
1181 | /* Input error checking is done when commands are added to queue. */ | 1181 | /* Input error checking is done when commands are added to queue. */ |
1182 | if (meta->flags & CMD_WANT_SKB) { | 1182 | if (meta->flags & CMD_WANT_SKB) { |
1183 | meta->source->reply_skb = rxb->skb; | 1183 | meta->source->reply_page = (unsigned long)rxb_addr(rxb); |
1184 | rxb->skb = NULL; | 1184 | rxb->page = NULL; |
1185 | } else if (meta->callback) | 1185 | } else if (meta->callback) |
1186 | meta->callback(priv, cmd, rxb->skb); | 1186 | meta->callback(priv, cmd, pkt); |
1187 | 1187 | ||
1188 | iwl_hcmd_queue_reclaim(priv, txq_id, index, cmd_index); | 1188 | iwl_hcmd_queue_reclaim(priv, txq_id, index, cmd_index); |
1189 | 1189 | ||
@@ -1442,7 +1442,7 @@ static int iwl_tx_status_reply_compressed_ba(struct iwl_priv *priv, | |||
1442 | void iwl_rx_reply_compressed_ba(struct iwl_priv *priv, | 1442 | void iwl_rx_reply_compressed_ba(struct iwl_priv *priv, |
1443 | struct iwl_rx_mem_buffer *rxb) | 1443 | struct iwl_rx_mem_buffer *rxb) |
1444 | { | 1444 | { |
1445 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | 1445 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
1446 | struct iwl_compressed_ba_resp *ba_resp = &pkt->u.compressed_ba; | 1446 | struct iwl_compressed_ba_resp *ba_resp = &pkt->u.compressed_ba; |
1447 | struct iwl_tx_queue *txq = NULL; | 1447 | struct iwl_tx_queue *txq = NULL; |
1448 | struct iwl_ht_agg *agg; | 1448 | struct iwl_ht_agg *agg; |
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 515f29b8a7a7..5977a57a234c 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c | |||
@@ -745,7 +745,7 @@ static int iwl3945_get_measurement(struct iwl_priv *priv, | |||
745 | u8 type) | 745 | u8 type) |
746 | { | 746 | { |
747 | struct iwl_spectrum_cmd spectrum; | 747 | struct iwl_spectrum_cmd spectrum; |
748 | struct iwl_rx_packet *res; | 748 | struct iwl_rx_packet *pkt; |
749 | struct iwl_host_cmd cmd = { | 749 | struct iwl_host_cmd cmd = { |
750 | .id = REPLY_SPECTRUM_MEASUREMENT_CMD, | 750 | .id = REPLY_SPECTRUM_MEASUREMENT_CMD, |
751 | .data = (void *)&spectrum, | 751 | .data = (void *)&spectrum, |
@@ -790,18 +790,18 @@ static int iwl3945_get_measurement(struct iwl_priv *priv, | |||
790 | if (rc) | 790 | if (rc) |
791 | return rc; | 791 | return rc; |
792 | 792 | ||
793 | res = (struct iwl_rx_packet *)cmd.reply_skb->data; | 793 | pkt = (struct iwl_rx_packet *)cmd.reply_page; |
794 | if (res->hdr.flags & IWL_CMD_FAILED_MSK) { | 794 | if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) { |
795 | IWL_ERR(priv, "Bad return from REPLY_RX_ON_ASSOC command\n"); | 795 | IWL_ERR(priv, "Bad return from REPLY_RX_ON_ASSOC command\n"); |
796 | rc = -EIO; | 796 | rc = -EIO; |
797 | } | 797 | } |
798 | 798 | ||
799 | spectrum_resp_status = le16_to_cpu(res->u.spectrum.status); | 799 | spectrum_resp_status = le16_to_cpu(pkt->u.spectrum.status); |
800 | switch (spectrum_resp_status) { | 800 | switch (spectrum_resp_status) { |
801 | case 0: /* Command will be handled */ | 801 | case 0: /* Command will be handled */ |
802 | if (res->u.spectrum.id != 0xff) { | 802 | if (pkt->u.spectrum.id != 0xff) { |
803 | IWL_DEBUG_INFO(priv, "Replaced existing measurement: %d\n", | 803 | IWL_DEBUG_INFO(priv, "Replaced existing measurement: %d\n", |
804 | res->u.spectrum.id); | 804 | pkt->u.spectrum.id); |
805 | priv->measurement_status &= ~MEASUREMENT_READY; | 805 | priv->measurement_status &= ~MEASUREMENT_READY; |
806 | } | 806 | } |
807 | priv->measurement_status |= MEASUREMENT_ACTIVE; | 807 | priv->measurement_status |= MEASUREMENT_ACTIVE; |
@@ -813,7 +813,7 @@ static int iwl3945_get_measurement(struct iwl_priv *priv, | |||
813 | break; | 813 | break; |
814 | } | 814 | } |
815 | 815 | ||
816 | dev_kfree_skb_any(cmd.reply_skb); | 816 | free_pages(cmd.reply_page, priv->hw_params.rx_page_order); |
817 | 817 | ||
818 | return rc; | 818 | return rc; |
819 | } | 819 | } |
@@ -822,7 +822,7 @@ static int iwl3945_get_measurement(struct iwl_priv *priv, | |||
822 | static void iwl3945_rx_reply_alive(struct iwl_priv *priv, | 822 | static void iwl3945_rx_reply_alive(struct iwl_priv *priv, |
823 | struct iwl_rx_mem_buffer *rxb) | 823 | struct iwl_rx_mem_buffer *rxb) |
824 | { | 824 | { |
825 | struct iwl_rx_packet *pkt = (void *)rxb->skb->data; | 825 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
826 | struct iwl_alive_resp *palive; | 826 | struct iwl_alive_resp *palive; |
827 | struct delayed_work *pwork; | 827 | struct delayed_work *pwork; |
828 | 828 | ||
@@ -859,7 +859,7 @@ static void iwl3945_rx_reply_add_sta(struct iwl_priv *priv, | |||
859 | struct iwl_rx_mem_buffer *rxb) | 859 | struct iwl_rx_mem_buffer *rxb) |
860 | { | 860 | { |
861 | #ifdef CONFIG_IWLWIFI_DEBUG | 861 | #ifdef CONFIG_IWLWIFI_DEBUG |
862 | struct iwl_rx_packet *pkt = (void *)rxb->skb->data; | 862 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
863 | #endif | 863 | #endif |
864 | 864 | ||
865 | IWL_DEBUG_RX(priv, "Received REPLY_ADD_STA: 0x%02X\n", pkt->u.status); | 865 | IWL_DEBUG_RX(priv, "Received REPLY_ADD_STA: 0x%02X\n", pkt->u.status); |
@@ -895,7 +895,7 @@ static void iwl3945_rx_beacon_notif(struct iwl_priv *priv, | |||
895 | struct iwl_rx_mem_buffer *rxb) | 895 | struct iwl_rx_mem_buffer *rxb) |
896 | { | 896 | { |
897 | #ifdef CONFIG_IWLWIFI_DEBUG | 897 | #ifdef CONFIG_IWLWIFI_DEBUG |
898 | struct iwl_rx_packet *pkt = (void *)rxb->skb->data; | 898 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
899 | struct iwl3945_beacon_notif *beacon = &(pkt->u.beacon_status); | 899 | struct iwl3945_beacon_notif *beacon = &(pkt->u.beacon_status); |
900 | u8 rate = beacon->beacon_notify_hdr.rate; | 900 | u8 rate = beacon->beacon_notify_hdr.rate; |
901 | 901 | ||
@@ -918,7 +918,7 @@ static void iwl3945_rx_beacon_notif(struct iwl_priv *priv, | |||
918 | static void iwl3945_rx_card_state_notif(struct iwl_priv *priv, | 918 | static void iwl3945_rx_card_state_notif(struct iwl_priv *priv, |
919 | struct iwl_rx_mem_buffer *rxb) | 919 | struct iwl_rx_mem_buffer *rxb) |
920 | { | 920 | { |
921 | struct iwl_rx_packet *pkt = (void *)rxb->skb->data; | 921 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
922 | u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags); | 922 | u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags); |
923 | unsigned long status = priv->status; | 923 | unsigned long status = priv->status; |
924 | 924 | ||
@@ -1082,7 +1082,7 @@ static int iwl3945_rx_queue_restock(struct iwl_priv *priv) | |||
1082 | list_del(element); | 1082 | list_del(element); |
1083 | 1083 | ||
1084 | /* Point to Rx buffer via next RBD in circular buffer */ | 1084 | /* Point to Rx buffer via next RBD in circular buffer */ |
1085 | rxq->bd[rxq->write] = iwl3945_dma_addr2rbd_ptr(priv, rxb->real_dma_addr); | 1085 | rxq->bd[rxq->write] = iwl3945_dma_addr2rbd_ptr(priv, rxb->page_dma); |
1086 | rxq->queue[rxq->write] = rxb; | 1086 | rxq->queue[rxq->write] = rxb; |
1087 | rxq->write = (rxq->write + 1) & RX_QUEUE_MASK; | 1087 | rxq->write = (rxq->write + 1) & RX_QUEUE_MASK; |
1088 | rxq->free_count--; | 1088 | rxq->free_count--; |
@@ -1122,7 +1122,7 @@ static void iwl3945_rx_allocate(struct iwl_priv *priv, gfp_t priority) | |||
1122 | struct iwl_rx_queue *rxq = &priv->rxq; | 1122 | struct iwl_rx_queue *rxq = &priv->rxq; |
1123 | struct list_head *element; | 1123 | struct list_head *element; |
1124 | struct iwl_rx_mem_buffer *rxb; | 1124 | struct iwl_rx_mem_buffer *rxb; |
1125 | struct sk_buff *skb; | 1125 | struct page *page; |
1126 | unsigned long flags; | 1126 | unsigned long flags; |
1127 | 1127 | ||
1128 | while (1) { | 1128 | while (1) { |
@@ -1136,9 +1136,13 @@ static void iwl3945_rx_allocate(struct iwl_priv *priv, gfp_t priority) | |||
1136 | 1136 | ||
1137 | if (rxq->free_count > RX_LOW_WATERMARK) | 1137 | if (rxq->free_count > RX_LOW_WATERMARK) |
1138 | priority |= __GFP_NOWARN; | 1138 | priority |= __GFP_NOWARN; |
1139 | |||
1140 | if (priv->hw_params.rx_page_order > 0) | ||
1141 | priority |= __GFP_COMP; | ||
1142 | |||
1139 | /* Alloc a new receive buffer */ | 1143 | /* Alloc a new receive buffer */ |
1140 | skb = alloc_skb(priv->hw_params.rx_buf_size, priority); | 1144 | page = alloc_pages(priority, priv->hw_params.rx_page_order); |
1141 | if (!skb) { | 1145 | if (!page) { |
1142 | if (net_ratelimit()) | 1146 | if (net_ratelimit()) |
1143 | IWL_DEBUG_INFO(priv, "Failed to allocate SKB buffer.\n"); | 1147 | IWL_DEBUG_INFO(priv, "Failed to allocate SKB buffer.\n"); |
1144 | if ((rxq->free_count <= RX_LOW_WATERMARK) && | 1148 | if ((rxq->free_count <= RX_LOW_WATERMARK) && |
@@ -1155,7 +1159,7 @@ static void iwl3945_rx_allocate(struct iwl_priv *priv, gfp_t priority) | |||
1155 | spin_lock_irqsave(&rxq->lock, flags); | 1159 | spin_lock_irqsave(&rxq->lock, flags); |
1156 | if (list_empty(&rxq->rx_used)) { | 1160 | if (list_empty(&rxq->rx_used)) { |
1157 | spin_unlock_irqrestore(&rxq->lock, flags); | 1161 | spin_unlock_irqrestore(&rxq->lock, flags); |
1158 | dev_kfree_skb_any(skb); | 1162 | __free_pages(page, priv->hw_params.rx_page_order); |
1159 | return; | 1163 | return; |
1160 | } | 1164 | } |
1161 | element = rxq->rx_used.next; | 1165 | element = rxq->rx_used.next; |
@@ -1163,26 +1167,18 @@ static void iwl3945_rx_allocate(struct iwl_priv *priv, gfp_t priority) | |||
1163 | list_del(element); | 1167 | list_del(element); |
1164 | spin_unlock_irqrestore(&rxq->lock, flags); | 1168 | spin_unlock_irqrestore(&rxq->lock, flags); |
1165 | 1169 | ||
1166 | rxb->skb = skb; | 1170 | rxb->page = page; |
1167 | |||
1168 | /* If radiotap head is required, reserve some headroom here. | ||
1169 | * The physical head count is a variable rx_stats->phy_count. | ||
1170 | * We reserve 4 bytes here. Plus these extra bytes, the | ||
1171 | * headroom of the physical head should be enough for the | ||
1172 | * radiotap head that iwl3945 supported. See iwl3945_rt. | ||
1173 | */ | ||
1174 | skb_reserve(rxb->skb, 4); | ||
1175 | |||
1176 | /* Get physical address of RB/SKB */ | 1171 | /* Get physical address of RB/SKB */ |
1177 | rxb->real_dma_addr = pci_map_single(priv->pci_dev, | 1172 | rxb->page_dma = pci_map_page(priv->pci_dev, page, 0, |
1178 | rxb->skb->data, | 1173 | PAGE_SIZE << priv->hw_params.rx_page_order, |
1179 | priv->hw_params.rx_buf_size, | 1174 | PCI_DMA_FROMDEVICE); |
1180 | PCI_DMA_FROMDEVICE); | ||
1181 | 1175 | ||
1182 | spin_lock_irqsave(&rxq->lock, flags); | 1176 | spin_lock_irqsave(&rxq->lock, flags); |
1177 | |||
1183 | list_add_tail(&rxb->list, &rxq->rx_free); | 1178 | list_add_tail(&rxb->list, &rxq->rx_free); |
1184 | priv->alloc_rxb_skb++; | ||
1185 | rxq->free_count++; | 1179 | rxq->free_count++; |
1180 | priv->alloc_rxb_page++; | ||
1181 | |||
1186 | spin_unlock_irqrestore(&rxq->lock, flags); | 1182 | spin_unlock_irqrestore(&rxq->lock, flags); |
1187 | } | 1183 | } |
1188 | } | 1184 | } |
@@ -1198,14 +1194,14 @@ void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq) | |||
1198 | for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) { | 1194 | for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) { |
1199 | /* In the reset function, these buffers may have been allocated | 1195 | /* In the reset function, these buffers may have been allocated |
1200 | * to an SKB, so we need to unmap and free potential storage */ | 1196 | * to an SKB, so we need to unmap and free potential storage */ |
1201 | if (rxq->pool[i].skb != NULL) { | 1197 | if (rxq->pool[i].page != NULL) { |
1202 | pci_unmap_single(priv->pci_dev, | 1198 | pci_unmap_page(priv->pci_dev, rxq->pool[i].page_dma, |
1203 | rxq->pool[i].real_dma_addr, | 1199 | PAGE_SIZE << priv->hw_params.rx_page_order, |
1204 | priv->hw_params.rx_buf_size, | 1200 | PCI_DMA_FROMDEVICE); |
1205 | PCI_DMA_FROMDEVICE); | 1201 | priv->alloc_rxb_page--; |
1206 | priv->alloc_rxb_skb--; | 1202 | __free_pages(rxq->pool[i].page, |
1207 | dev_kfree_skb(rxq->pool[i].skb); | 1203 | priv->hw_params.rx_page_order); |
1208 | rxq->pool[i].skb = NULL; | 1204 | rxq->pool[i].page = NULL; |
1209 | } | 1205 | } |
1210 | list_add_tail(&rxq->pool[i].list, &rxq->rx_used); | 1206 | list_add_tail(&rxq->pool[i].list, &rxq->rx_used); |
1211 | } | 1207 | } |
@@ -1213,8 +1209,8 @@ void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq) | |||
1213 | /* Set us so that we have processed and used all buffers, but have | 1209 | /* Set us so that we have processed and used all buffers, but have |
1214 | * not restocked the Rx queue with fresh buffers */ | 1210 | * not restocked the Rx queue with fresh buffers */ |
1215 | rxq->read = rxq->write = 0; | 1211 | rxq->read = rxq->write = 0; |
1216 | rxq->free_count = 0; | ||
1217 | rxq->write_actual = 0; | 1212 | rxq->write_actual = 0; |
1213 | rxq->free_count = 0; | ||
1218 | spin_unlock_irqrestore(&rxq->lock, flags); | 1214 | spin_unlock_irqrestore(&rxq->lock, flags); |
1219 | } | 1215 | } |
1220 | 1216 | ||
@@ -1247,12 +1243,14 @@ static void iwl3945_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rx | |||
1247 | { | 1243 | { |
1248 | int i; | 1244 | int i; |
1249 | for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) { | 1245 | for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) { |
1250 | if (rxq->pool[i].skb != NULL) { | 1246 | if (rxq->pool[i].page != NULL) { |
1251 | pci_unmap_single(priv->pci_dev, | 1247 | pci_unmap_page(priv->pci_dev, rxq->pool[i].page_dma, |
1252 | rxq->pool[i].real_dma_addr, | 1248 | PAGE_SIZE << priv->hw_params.rx_page_order, |
1253 | priv->hw_params.rx_buf_size, | 1249 | PCI_DMA_FROMDEVICE); |
1254 | PCI_DMA_FROMDEVICE); | 1250 | __free_pages(rxq->pool[i].page, |
1255 | dev_kfree_skb(rxq->pool[i].skb); | 1251 | priv->hw_params.rx_page_order); |
1252 | rxq->pool[i].page = NULL; | ||
1253 | priv->alloc_rxb_page--; | ||
1256 | } | 1254 | } |
1257 | } | 1255 | } |
1258 | 1256 | ||
@@ -1388,10 +1386,10 @@ static void iwl3945_rx_handle(struct iwl_priv *priv) | |||
1388 | 1386 | ||
1389 | rxq->queue[i] = NULL; | 1387 | rxq->queue[i] = NULL; |
1390 | 1388 | ||
1391 | pci_unmap_single(priv->pci_dev, rxb->real_dma_addr, | 1389 | pci_unmap_page(priv->pci_dev, rxb->page_dma, |
1392 | priv->hw_params.rx_buf_size, | 1390 | PAGE_SIZE << priv->hw_params.rx_page_order, |
1393 | PCI_DMA_FROMDEVICE); | 1391 | PCI_DMA_FROMDEVICE); |
1394 | pkt = (struct iwl_rx_packet *)rxb->skb->data; | 1392 | pkt = rxb_addr(rxb); |
1395 | 1393 | ||
1396 | trace_iwlwifi_dev_rx(priv, pkt, | 1394 | trace_iwlwifi_dev_rx(priv, pkt, |
1397 | le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK); | 1395 | le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK); |
@@ -1416,16 +1414,17 @@ static void iwl3945_rx_handle(struct iwl_priv *priv) | |||
1416 | priv->isr_stats.rx_handlers[pkt->hdr.cmd]++; | 1414 | priv->isr_stats.rx_handlers[pkt->hdr.cmd]++; |
1417 | } else { | 1415 | } else { |
1418 | /* No handling needed */ | 1416 | /* No handling needed */ |
1419 | IWL_DEBUG_RX(priv, "r %d i %d No handler needed for %s, 0x%02x\n", | 1417 | IWL_DEBUG_RX(priv, |
1418 | "r %d i %d No handler needed for %s, 0x%02x\n", | ||
1420 | r, i, get_cmd_string(pkt->hdr.cmd), | 1419 | r, i, get_cmd_string(pkt->hdr.cmd), |
1421 | pkt->hdr.cmd); | 1420 | pkt->hdr.cmd); |
1422 | } | 1421 | } |
1423 | 1422 | ||
1424 | if (reclaim) { | 1423 | if (reclaim) { |
1425 | /* Invoke any callbacks, transfer the skb to caller, and | 1424 | /* Invoke any callbacks, transfer the buffer to caller, |
1426 | * fire off the (possibly) blocking iwl_send_cmd() | 1425 | * and fire off the (possibly) blocking iwl_send_cmd() |
1427 | * as we reclaim the driver command queue */ | 1426 | * as we reclaim the driver command queue */ |
1428 | if (rxb && rxb->skb) | 1427 | if (rxb && rxb->page) |
1429 | iwl_tx_cmd_complete(priv, rxb); | 1428 | iwl_tx_cmd_complete(priv, rxb); |
1430 | else | 1429 | else |
1431 | IWL_WARN(priv, "Claim null rxb?\n"); | 1430 | IWL_WARN(priv, "Claim null rxb?\n"); |
@@ -1434,10 +1433,10 @@ static void iwl3945_rx_handle(struct iwl_priv *priv) | |||
1434 | /* For now we just don't re-use anything. We can tweak this | 1433 | /* For now we just don't re-use anything. We can tweak this |
1435 | * later to try and re-use notification packets and SKBs that | 1434 | * later to try and re-use notification packets and SKBs that |
1436 | * fail to Rx correctly */ | 1435 | * fail to Rx correctly */ |
1437 | if (rxb->skb != NULL) { | 1436 | if (rxb->page != NULL) { |
1438 | priv->alloc_rxb_skb--; | 1437 | priv->alloc_rxb_page--; |
1439 | dev_kfree_skb_any(rxb->skb); | 1438 | __free_pages(rxb->page, priv->hw_params.rx_page_order); |
1440 | rxb->skb = NULL; | 1439 | rxb->page = NULL; |
1441 | } | 1440 | } |
1442 | 1441 | ||
1443 | spin_lock_irqsave(&rxq->lock, flags); | 1442 | spin_lock_irqsave(&rxq->lock, flags); |
@@ -1678,6 +1677,8 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv) | |||
1678 | } | 1677 | } |
1679 | #endif | 1678 | #endif |
1680 | 1679 | ||
1680 | spin_unlock_irqrestore(&priv->lock, flags); | ||
1681 | |||
1681 | /* Since CSR_INT and CSR_FH_INT_STATUS reads and clears are not | 1682 | /* Since CSR_INT and CSR_FH_INT_STATUS reads and clears are not |
1682 | * atomic, make sure that inta covers all the interrupts that | 1683 | * atomic, make sure that inta covers all the interrupts that |
1683 | * we've discovered, even if FH interrupt came in just after | 1684 | * we've discovered, even if FH interrupt came in just after |
@@ -1699,8 +1700,6 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv) | |||
1699 | 1700 | ||
1700 | handled |= CSR_INT_BIT_HW_ERR; | 1701 | handled |= CSR_INT_BIT_HW_ERR; |
1701 | 1702 | ||
1702 | spin_unlock_irqrestore(&priv->lock, flags); | ||
1703 | |||
1704 | return; | 1703 | return; |
1705 | } | 1704 | } |
1706 | 1705 | ||
@@ -1792,7 +1791,6 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv) | |||
1792 | "flags 0x%08lx\n", inta, inta_mask, inta_fh, flags); | 1791 | "flags 0x%08lx\n", inta, inta_mask, inta_fh, flags); |
1793 | } | 1792 | } |
1794 | #endif | 1793 | #endif |
1795 | spin_unlock_irqrestore(&priv->lock, flags); | ||
1796 | } | 1794 | } |
1797 | 1795 | ||
1798 | static int iwl3945_get_channels_for_scan(struct iwl_priv *priv, | 1796 | static int iwl3945_get_channels_for_scan(struct iwl_priv *priv, |