diff options
author | David S. Miller <davem@davemloft.net> | 2015-04-09 14:43:13 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-04-09 14:43:13 -0400 |
commit | 3ab1a30fbded99936956442d8cf8f379064e4a26 (patch) | |
tree | d812d57c8855e4df36a616f9a67cf7c91b7d3203 | |
parent | 9399bdcbb54b1e224a8532c01d496ada87e526bd (diff) | |
parent | f56d9e23b78e311fbd992a1bd80b8bf2adaee29b (diff) |
Merge tag 'wireless-drivers-next-for-davem-2015-04-09' of git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next
Kalle Valo says:
====================
Major changes:
iwlwifi:
* some more work on LAR
* fixes for UMAC scan
* more work on debugging framework
* more work for 8000 devices
* cleanups and small bugfixes
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
55 files changed, 784 insertions, 344 deletions
diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c index 86d46c196966..284706798c71 100644 --- a/drivers/net/wireless/ath/ath9k/gpio.c +++ b/drivers/net/wireless/ath/ath9k/gpio.c | |||
@@ -69,9 +69,15 @@ void ath_fill_led_pin(struct ath_softc *sc) | |||
69 | { | 69 | { |
70 | struct ath_hw *ah = sc->sc_ah; | 70 | struct ath_hw *ah = sc->sc_ah; |
71 | 71 | ||
72 | if (AR_SREV_9100(ah) || (ah->led_pin >= 0)) | 72 | if (AR_SREV_9100(ah)) |
73 | return; | 73 | return; |
74 | 74 | ||
75 | if (ah->led_pin >= 0) { | ||
76 | if (!((1 << ah->led_pin) & AR_GPIO_OE_OUT_MASK)) | ||
77 | ath9k_hw_request_gpio(ah, ah->led_pin, "ath9k-led"); | ||
78 | return; | ||
79 | } | ||
80 | |||
75 | if (AR_SREV_9287(ah)) | 81 | if (AR_SREV_9287(ah)) |
76 | ah->led_pin = ATH_LED_PIN_9287; | 82 | ah->led_pin = ATH_LED_PIN_9287; |
77 | else if (AR_SREV_9485(sc->sc_ah)) | 83 | else if (AR_SREV_9485(sc->sc_ah)) |
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 5cdbdb038371..5e15e8e10ed3 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/time.h> | 20 | #include <linux/time.h> |
21 | #include <linux/bitops.h> | 21 | #include <linux/bitops.h> |
22 | #include <linux/etherdevice.h> | 22 | #include <linux/etherdevice.h> |
23 | #include <linux/gpio.h> | ||
23 | #include <asm/unaligned.h> | 24 | #include <asm/unaligned.h> |
24 | 25 | ||
25 | #include "hw.h" | 26 | #include "hw.h" |
@@ -2711,11 +2712,23 @@ void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val) | |||
2711 | if (AR_SREV_9271(ah)) | 2712 | if (AR_SREV_9271(ah)) |
2712 | val = ~val; | 2713 | val = ~val; |
2713 | 2714 | ||
2714 | REG_RMW(ah, AR_GPIO_IN_OUT, ((val & 1) << gpio), | 2715 | if ((1 << gpio) & AR_GPIO_OE_OUT_MASK) |
2715 | AR_GPIO_BIT(gpio)); | 2716 | REG_RMW(ah, AR_GPIO_IN_OUT, ((val & 1) << gpio), |
2717 | AR_GPIO_BIT(gpio)); | ||
2718 | else | ||
2719 | gpio_set_value(gpio, val & 1); | ||
2716 | } | 2720 | } |
2717 | EXPORT_SYMBOL(ath9k_hw_set_gpio); | 2721 | EXPORT_SYMBOL(ath9k_hw_set_gpio); |
2718 | 2722 | ||
2723 | void ath9k_hw_request_gpio(struct ath_hw *ah, u32 gpio, const char *label) | ||
2724 | { | ||
2725 | if (gpio >= ah->caps.num_gpio_pins) | ||
2726 | return; | ||
2727 | |||
2728 | gpio_request_one(gpio, GPIOF_DIR_OUT | GPIOF_INIT_LOW, label); | ||
2729 | } | ||
2730 | EXPORT_SYMBOL(ath9k_hw_request_gpio); | ||
2731 | |||
2719 | void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna) | 2732 | void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna) |
2720 | { | 2733 | { |
2721 | REG_WRITE(ah, AR_DEF_ANTENNA, (antenna & 0x7)); | 2734 | REG_WRITE(ah, AR_DEF_ANTENNA, (antenna & 0x7)); |
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 92fab1a54697..c1d2d0340feb 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h | |||
@@ -1024,6 +1024,7 @@ u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio); | |||
1024 | void ath9k_hw_cfg_output(struct ath_hw *ah, u32 gpio, | 1024 | void ath9k_hw_cfg_output(struct ath_hw *ah, u32 gpio, |
1025 | u32 ah_signal_type); | 1025 | u32 ah_signal_type); |
1026 | void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val); | 1026 | void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val); |
1027 | void ath9k_hw_request_gpio(struct ath_hw *ah, u32 gpio, const char *label); | ||
1027 | void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna); | 1028 | void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna); |
1028 | 1029 | ||
1029 | /* General Operation */ | 1030 | /* General Operation */ |
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index 1234399a43dd..caba54ddad25 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h | |||
@@ -958,6 +958,8 @@ | |||
958 | 958 | ||
959 | #define AR_SREV_9550(_ah) \ | 959 | #define AR_SREV_9550(_ah) \ |
960 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9550)) | 960 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9550)) |
961 | #define AR_SREV_9550_OR_LATER(_ah) \ | ||
962 | (((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9550)) | ||
961 | 963 | ||
962 | #define AR_SREV_9580(_ah) \ | 964 | #define AR_SREV_9580(_ah) \ |
963 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9580) && \ | 965 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9580) && \ |
@@ -1128,6 +1130,8 @@ enum { | |||
1128 | 1130 | ||
1129 | #define AR_GPIO_OE_OUT (AR_SREV_9340(ah) ? 0x4030 : \ | 1131 | #define AR_GPIO_OE_OUT (AR_SREV_9340(ah) ? 0x4030 : \ |
1130 | (AR_SREV_9300_20_OR_LATER(ah) ? 0x4050 : 0x404c)) | 1132 | (AR_SREV_9300_20_OR_LATER(ah) ? 0x4050 : 0x404c)) |
1133 | #define AR_GPIO_OE_OUT_MASK (AR_SREV_9550_OR_LATER(ah) ? \ | ||
1134 | 0x0000000F : 0xFFFFFFFF) | ||
1131 | #define AR_GPIO_OE_OUT_DRV 0x3 | 1135 | #define AR_GPIO_OE_OUT_DRV 0x3 |
1132 | #define AR_GPIO_OE_OUT_DRV_NO 0x0 | 1136 | #define AR_GPIO_OE_OUT_DRV_NO 0x0 |
1133 | #define AR_GPIO_OE_OUT_DRV_LOW 0x1 | 1137 | #define AR_GPIO_OE_OUT_DRV_LOW 0x1 |
diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c index 67a2f8c88829..ca533b4321bd 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.c +++ b/drivers/net/wireless/ath/ath9k/wmi.c | |||
@@ -227,7 +227,7 @@ static void ath9k_wmi_ctrl_rx(void *priv, struct sk_buff *skb, | |||
227 | 227 | ||
228 | /* Check if there has been a timeout. */ | 228 | /* Check if there has been a timeout. */ |
229 | spin_lock(&wmi->wmi_lock); | 229 | spin_lock(&wmi->wmi_lock); |
230 | if (cmd_id != wmi->last_cmd_id) { | 230 | if (be16_to_cpu(hdr->seq_no) != wmi->last_seq_id) { |
231 | spin_unlock(&wmi->wmi_lock); | 231 | spin_unlock(&wmi->wmi_lock); |
232 | goto free_skb; | 232 | goto free_skb; |
233 | } | 233 | } |
@@ -275,11 +275,16 @@ static int ath9k_wmi_cmd_issue(struct wmi *wmi, | |||
275 | enum wmi_cmd_id cmd, u16 len) | 275 | enum wmi_cmd_id cmd, u16 len) |
276 | { | 276 | { |
277 | struct wmi_cmd_hdr *hdr; | 277 | struct wmi_cmd_hdr *hdr; |
278 | unsigned long flags; | ||
278 | 279 | ||
279 | hdr = (struct wmi_cmd_hdr *) skb_push(skb, sizeof(struct wmi_cmd_hdr)); | 280 | hdr = (struct wmi_cmd_hdr *) skb_push(skb, sizeof(struct wmi_cmd_hdr)); |
280 | hdr->command_id = cpu_to_be16(cmd); | 281 | hdr->command_id = cpu_to_be16(cmd); |
281 | hdr->seq_no = cpu_to_be16(++wmi->tx_seq_id); | 282 | hdr->seq_no = cpu_to_be16(++wmi->tx_seq_id); |
282 | 283 | ||
284 | spin_lock_irqsave(&wmi->wmi_lock, flags); | ||
285 | wmi->last_seq_id = wmi->tx_seq_id; | ||
286 | spin_unlock_irqrestore(&wmi->wmi_lock, flags); | ||
287 | |||
283 | return htc_send_epid(wmi->htc, skb, wmi->ctrl_epid); | 288 | return htc_send_epid(wmi->htc, skb, wmi->ctrl_epid); |
284 | } | 289 | } |
285 | 290 | ||
@@ -295,7 +300,6 @@ int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id, | |||
295 | struct sk_buff *skb; | 300 | struct sk_buff *skb; |
296 | u8 *data; | 301 | u8 *data; |
297 | int time_left, ret = 0; | 302 | int time_left, ret = 0; |
298 | unsigned long flags; | ||
299 | 303 | ||
300 | if (ah->ah_flags & AH_UNPLUGGED) | 304 | if (ah->ah_flags & AH_UNPLUGGED) |
301 | return 0; | 305 | return 0; |
@@ -323,10 +327,6 @@ int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id, | |||
323 | wmi->cmd_rsp_buf = rsp_buf; | 327 | wmi->cmd_rsp_buf = rsp_buf; |
324 | wmi->cmd_rsp_len = rsp_len; | 328 | wmi->cmd_rsp_len = rsp_len; |
325 | 329 | ||
326 | spin_lock_irqsave(&wmi->wmi_lock, flags); | ||
327 | wmi->last_cmd_id = cmd_id; | ||
328 | spin_unlock_irqrestore(&wmi->wmi_lock, flags); | ||
329 | |||
330 | ret = ath9k_wmi_cmd_issue(wmi, skb, cmd_id, cmd_len); | 330 | ret = ath9k_wmi_cmd_issue(wmi, skb, cmd_id, cmd_len); |
331 | if (ret) | 331 | if (ret) |
332 | goto out; | 332 | goto out; |
diff --git a/drivers/net/wireless/ath/ath9k/wmi.h b/drivers/net/wireless/ath/ath9k/wmi.h index aa84a335289a..380175d5ecd7 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.h +++ b/drivers/net/wireless/ath/ath9k/wmi.h | |||
@@ -151,7 +151,7 @@ struct wmi { | |||
151 | enum htc_endpoint_id ctrl_epid; | 151 | enum htc_endpoint_id ctrl_epid; |
152 | struct mutex op_mutex; | 152 | struct mutex op_mutex; |
153 | struct completion cmd_wait; | 153 | struct completion cmd_wait; |
154 | enum wmi_cmd_id last_cmd_id; | 154 | u16 last_seq_id; |
155 | struct sk_buff_head wmi_event_queue; | 155 | struct sk_buff_head wmi_event_queue; |
156 | struct tasklet_struct wmi_event_tasklet; | 156 | struct tasklet_struct wmi_event_tasklet; |
157 | u16 tx_seq_id; | 157 | u16 tx_seq_id; |
diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c index 1d7982afc0ad..6837064908be 100644 --- a/drivers/net/wireless/b43/dma.c +++ b/drivers/net/wireless/b43/dma.c | |||
@@ -553,7 +553,7 @@ static bool b43_dma_mapping_error(struct b43_dmaring *ring, | |||
553 | size_t buffersize, bool dma_to_device) | 553 | size_t buffersize, bool dma_to_device) |
554 | { | 554 | { |
555 | if (unlikely(dma_mapping_error(ring->dev->dev->dma_dev, addr))) | 555 | if (unlikely(dma_mapping_error(ring->dev->dev->dma_dev, addr))) |
556 | return 1; | 556 | return true; |
557 | 557 | ||
558 | switch (ring->type) { | 558 | switch (ring->type) { |
559 | case B43_DMA_30BIT: | 559 | case B43_DMA_30BIT: |
@@ -571,13 +571,13 @@ static bool b43_dma_mapping_error(struct b43_dmaring *ring, | |||
571 | } | 571 | } |
572 | 572 | ||
573 | /* The address is OK. */ | 573 | /* The address is OK. */ |
574 | return 0; | 574 | return false; |
575 | 575 | ||
576 | address_error: | 576 | address_error: |
577 | /* We can't support this address. Unmap it again. */ | 577 | /* We can't support this address. Unmap it again. */ |
578 | unmap_descbuffer(ring, addr, buffersize, dma_to_device); | 578 | unmap_descbuffer(ring, addr, buffersize, dma_to_device); |
579 | 579 | ||
580 | return 1; | 580 | return true; |
581 | } | 581 | } |
582 | 582 | ||
583 | static bool b43_rx_buffer_is_poisoned(struct b43_dmaring *ring, struct sk_buff *skb) | 583 | static bool b43_rx_buffer_is_poisoned(struct b43_dmaring *ring, struct sk_buff *skb) |
@@ -1099,16 +1099,16 @@ static bool b43_dma_translation_in_low_word(struct b43_wldev *dev, | |||
1099 | enum b43_dmatype type) | 1099 | enum b43_dmatype type) |
1100 | { | 1100 | { |
1101 | if (type != B43_DMA_64BIT) | 1101 | if (type != B43_DMA_64BIT) |
1102 | return 1; | 1102 | return true; |
1103 | 1103 | ||
1104 | #ifdef CONFIG_B43_SSB | 1104 | #ifdef CONFIG_B43_SSB |
1105 | if (dev->dev->bus_type == B43_BUS_SSB && | 1105 | if (dev->dev->bus_type == B43_BUS_SSB && |
1106 | dev->dev->sdev->bus->bustype == SSB_BUSTYPE_PCI && | 1106 | dev->dev->sdev->bus->bustype == SSB_BUSTYPE_PCI && |
1107 | !(pci_is_pcie(dev->dev->sdev->bus->host_pci) && | 1107 | !(pci_is_pcie(dev->dev->sdev->bus->host_pci) && |
1108 | ssb_read32(dev->dev->sdev, SSB_TMSHIGH) & SSB_TMSHIGH_DMA64)) | 1108 | ssb_read32(dev->dev->sdev, SSB_TMSHIGH) & SSB_TMSHIGH_DMA64)) |
1109 | return 1; | 1109 | return true; |
1110 | #endif | 1110 | #endif |
1111 | return 0; | 1111 | return false; |
1112 | } | 1112 | } |
1113 | 1113 | ||
1114 | int b43_dma_init(struct b43_wldev *dev) | 1114 | int b43_dma_init(struct b43_wldev *dev) |
diff --git a/drivers/net/wireless/b43legacy/dma.c b/drivers/net/wireless/b43legacy/dma.c index b2ed1795130b..f9dd892b9f27 100644 --- a/drivers/net/wireless/b43legacy/dma.c +++ b/drivers/net/wireless/b43legacy/dma.c | |||
@@ -427,7 +427,7 @@ static bool b43legacy_dma_mapping_error(struct b43legacy_dmaring *ring, | |||
427 | bool dma_to_device) | 427 | bool dma_to_device) |
428 | { | 428 | { |
429 | if (unlikely(dma_mapping_error(ring->dev->dev->dma_dev, addr))) | 429 | if (unlikely(dma_mapping_error(ring->dev->dev->dma_dev, addr))) |
430 | return 1; | 430 | return true; |
431 | 431 | ||
432 | switch (ring->type) { | 432 | switch (ring->type) { |
433 | case B43legacy_DMA_30BIT: | 433 | case B43legacy_DMA_30BIT: |
@@ -441,13 +441,13 @@ static bool b43legacy_dma_mapping_error(struct b43legacy_dmaring *ring, | |||
441 | } | 441 | } |
442 | 442 | ||
443 | /* The address is OK. */ | 443 | /* The address is OK. */ |
444 | return 0; | 444 | return false; |
445 | 445 | ||
446 | address_error: | 446 | address_error: |
447 | /* We can't support this address. Unmap it again. */ | 447 | /* We can't support this address. Unmap it again. */ |
448 | unmap_descbuffer(ring, addr, buffersize, dma_to_device); | 448 | unmap_descbuffer(ring, addr, buffersize, dma_to_device); |
449 | 449 | ||
450 | return 1; | 450 | return true; |
451 | } | 451 | } |
452 | 452 | ||
453 | static int setup_rx_descbuffer(struct b43legacy_dmaring *ring, | 453 | static int setup_rx_descbuffer(struct b43legacy_dmaring *ring, |
diff --git a/drivers/net/wireless/b43legacy/rfkill.c b/drivers/net/wireless/b43legacy/rfkill.c index c4559bcbc707..7c1bdbc02569 100644 --- a/drivers/net/wireless/b43legacy/rfkill.c +++ b/drivers/net/wireless/b43legacy/rfkill.c | |||
@@ -32,7 +32,7 @@ bool b43legacy_is_hw_radio_enabled(struct b43legacy_wldev *dev) | |||
32 | if (dev->dev->id.revision >= 3) { | 32 | if (dev->dev->id.revision >= 3) { |
33 | if (!(b43legacy_read32(dev, B43legacy_MMIO_RADIO_HWENABLED_HI) | 33 | if (!(b43legacy_read32(dev, B43legacy_MMIO_RADIO_HWENABLED_HI) |
34 | & B43legacy_MMIO_RADIO_HWENABLED_HI_MASK)) | 34 | & B43legacy_MMIO_RADIO_HWENABLED_HI_MASK)) |
35 | return 1; | 35 | return true; |
36 | } else { | 36 | } else { |
37 | /* To prevent CPU fault on PPC, do not read a register | 37 | /* To prevent CPU fault on PPC, do not read a register |
38 | * unless the interface is started; however, on resume | 38 | * unless the interface is started; however, on resume |
@@ -40,12 +40,12 @@ bool b43legacy_is_hw_radio_enabled(struct b43legacy_wldev *dev) | |||
40 | * that happens, unconditionally return TRUE. | 40 | * that happens, unconditionally return TRUE. |
41 | */ | 41 | */ |
42 | if (b43legacy_status(dev) < B43legacy_STAT_STARTED) | 42 | if (b43legacy_status(dev) < B43legacy_STAT_STARTED) |
43 | return 1; | 43 | return true; |
44 | if (b43legacy_read16(dev, B43legacy_MMIO_RADIO_HWENABLED_LO) | 44 | if (b43legacy_read16(dev, B43legacy_MMIO_RADIO_HWENABLED_LO) |
45 | & B43legacy_MMIO_RADIO_HWENABLED_LO_MASK) | 45 | & B43legacy_MMIO_RADIO_HWENABLED_LO_MASK) |
46 | return 1; | 46 | return true; |
47 | } | 47 | } |
48 | return 0; | 48 | return false; |
49 | } | 49 | } |
50 | 50 | ||
51 | /* The poll callback for the hardware button. */ | 51 | /* The poll callback for the hardware button. */ |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c index 941b1e41f366..1c4e9dd57960 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c | |||
@@ -2949,5 +2949,5 @@ bool wlc_phy_txpower_ipa_ison(struct brcms_phy_pub *ppi) | |||
2949 | if (ISNPHY(pi)) | 2949 | if (ISNPHY(pi)) |
2950 | return wlc_phy_n_txpower_ipa_ison(pi); | 2950 | return wlc_phy_n_txpower_ipa_ison(pi); |
2951 | else | 2951 | else |
2952 | return 0; | 2952 | return false; |
2953 | } | 2953 | } |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c index 5f1366234a0d..93d4cde0eb31 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c | |||
@@ -4999,7 +4999,7 @@ void wlc_2064_vco_cal(struct brcms_phy *pi) | |||
4999 | bool wlc_phy_tpc_isenabled_lcnphy(struct brcms_phy *pi) | 4999 | bool wlc_phy_tpc_isenabled_lcnphy(struct brcms_phy *pi) |
5000 | { | 5000 | { |
5001 | if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) | 5001 | if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) |
5002 | return 0; | 5002 | return false; |
5003 | else | 5003 | else |
5004 | return (LCNPHY_TX_PWR_CTRL_HW == | 5004 | return (LCNPHY_TX_PWR_CTRL_HW == |
5005 | wlc_lcnphy_get_tx_pwr_ctrl((pi))); | 5005 | wlc_lcnphy_get_tx_pwr_ctrl((pi))); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-8000.c b/drivers/net/wireless/iwlwifi/iwl-8000.c index 9c396a42aec8..ce6321b7d241 100644 --- a/drivers/net/wireless/iwlwifi/iwl-8000.c +++ b/drivers/net/wireless/iwlwifi/iwl-8000.c | |||
@@ -94,8 +94,8 @@ | |||
94 | IWL8000_FW_PRE "-" __stringify(api) ".ucode" | 94 | IWL8000_FW_PRE "-" __stringify(api) ".ucode" |
95 | 95 | ||
96 | #define NVM_HW_SECTION_NUM_FAMILY_8000 10 | 96 | #define NVM_HW_SECTION_NUM_FAMILY_8000 10 |
97 | #define DEFAULT_NVM_FILE_FAMILY_8000A "iwl_nvm_8000.bin" | 97 | #define DEFAULT_NVM_FILE_FAMILY_8000B "nvmData-8000B" |
98 | #define DEFAULT_NVM_FILE_FAMILY_8000 "iwl_nvm_8000B.bin" | 98 | #define DEFAULT_NVM_FILE_FAMILY_8000C "nvmData-8000C" |
99 | 99 | ||
100 | /* Max SDIO RX aggregation size of the ADDBA request/response */ | 100 | /* Max SDIO RX aggregation size of the ADDBA request/response */ |
101 | #define MAX_RX_AGG_SIZE_8260_SDIO 28 | 101 | #define MAX_RX_AGG_SIZE_8260_SDIO 28 |
@@ -177,8 +177,8 @@ const struct iwl_cfg iwl8260_2ac_sdio_cfg = { | |||
177 | .ht_params = &iwl8000_ht_params, | 177 | .ht_params = &iwl8000_ht_params, |
178 | .nvm_ver = IWL8000_NVM_VERSION, | 178 | .nvm_ver = IWL8000_NVM_VERSION, |
179 | .nvm_calib_ver = IWL8000_TX_POWER_VERSION, | 179 | .nvm_calib_ver = IWL8000_TX_POWER_VERSION, |
180 | .default_nvm_file = DEFAULT_NVM_FILE_FAMILY_8000, | 180 | .default_nvm_file_B_step = DEFAULT_NVM_FILE_FAMILY_8000B, |
181 | .default_nvm_file_8000A = DEFAULT_NVM_FILE_FAMILY_8000A, | 181 | .default_nvm_file_C_step = DEFAULT_NVM_FILE_FAMILY_8000C, |
182 | .max_rx_agg_size = MAX_RX_AGG_SIZE_8260_SDIO, | 182 | .max_rx_agg_size = MAX_RX_AGG_SIZE_8260_SDIO, |
183 | .disable_dummy_notification = true, | 183 | .disable_dummy_notification = true, |
184 | .max_ht_ampdu_exponent = MAX_HT_AMPDU_EXPONENT_8260_SDIO, | 184 | .max_ht_ampdu_exponent = MAX_HT_AMPDU_EXPONENT_8260_SDIO, |
@@ -192,8 +192,8 @@ const struct iwl_cfg iwl4165_2ac_sdio_cfg = { | |||
192 | .ht_params = &iwl8000_ht_params, | 192 | .ht_params = &iwl8000_ht_params, |
193 | .nvm_ver = IWL8000_NVM_VERSION, | 193 | .nvm_ver = IWL8000_NVM_VERSION, |
194 | .nvm_calib_ver = IWL8000_TX_POWER_VERSION, | 194 | .nvm_calib_ver = IWL8000_TX_POWER_VERSION, |
195 | .default_nvm_file = DEFAULT_NVM_FILE_FAMILY_8000, | 195 | .default_nvm_file_B_step = DEFAULT_NVM_FILE_FAMILY_8000B, |
196 | .default_nvm_file_8000A = DEFAULT_NVM_FILE_FAMILY_8000A, | 196 | .default_nvm_file_C_step = DEFAULT_NVM_FILE_FAMILY_8000C, |
197 | .max_rx_agg_size = MAX_RX_AGG_SIZE_8260_SDIO, | 197 | .max_rx_agg_size = MAX_RX_AGG_SIZE_8260_SDIO, |
198 | .bt_shared_single_ant = true, | 198 | .bt_shared_single_ant = true, |
199 | .disable_dummy_notification = true, | 199 | .disable_dummy_notification = true, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-config.h b/drivers/net/wireless/iwlwifi/iwl-config.h index 4b190d98a1ec..3f33f753ce2f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/iwlwifi/iwl-config.h | |||
@@ -92,9 +92,9 @@ static inline bool iwl_has_secure_boot(u32 hw_rev, | |||
92 | { | 92 | { |
93 | /* return 1 only for family 8000 B0 */ | 93 | /* return 1 only for family 8000 B0 */ |
94 | if ((family == IWL_DEVICE_FAMILY_8000) && (hw_rev & 0xC)) | 94 | if ((family == IWL_DEVICE_FAMILY_8000) && (hw_rev & 0xC)) |
95 | return 1; | 95 | return true; |
96 | 96 | ||
97 | return 0; | 97 | return false; |
98 | } | 98 | } |
99 | 99 | ||
100 | /* | 100 | /* |
@@ -228,7 +228,7 @@ struct iwl_pwr_tx_backoff { | |||
228 | 228 | ||
229 | /** | 229 | /** |
230 | * struct iwl_cfg | 230 | * struct iwl_cfg |
231 | * @name: Offical name of the device | 231 | * @name: Official name of the device |
232 | * @fw_name_pre: Firmware filename prefix. The api version and extension | 232 | * @fw_name_pre: Firmware filename prefix. The api version and extension |
233 | * (.ucode) will be added to filename before loading from disk. The | 233 | * (.ucode) will be added to filename before loading from disk. The |
234 | * filename is constructed as fw_name_pre<api>.ucode. | 234 | * filename is constructed as fw_name_pre<api>.ucode. |
@@ -303,8 +303,8 @@ struct iwl_cfg { | |||
303 | bool lp_xtal_workaround; | 303 | bool lp_xtal_workaround; |
304 | const struct iwl_pwr_tx_backoff *pwr_tx_backoffs; | 304 | const struct iwl_pwr_tx_backoff *pwr_tx_backoffs; |
305 | bool no_power_up_nic_in_init; | 305 | bool no_power_up_nic_in_init; |
306 | const char *default_nvm_file; | 306 | const char *default_nvm_file_B_step; |
307 | const char *default_nvm_file_8000A; | 307 | const char *default_nvm_file_C_step; |
308 | unsigned int max_rx_agg_size; | 308 | unsigned int max_rx_agg_size; |
309 | bool disable_dummy_notification; | 309 | bool disable_dummy_notification; |
310 | unsigned int max_tx_agg_size; | 310 | unsigned int max_tx_agg_size; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c index aefdd9b7c105..7267152e7dc7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/iwlwifi/iwl-drv.c | |||
@@ -145,7 +145,7 @@ static struct iwlwifi_opmode_table { | |||
145 | #define IWL_DEFAULT_SCAN_CHANNELS 40 | 145 | #define IWL_DEFAULT_SCAN_CHANNELS 40 |
146 | 146 | ||
147 | /* | 147 | /* |
148 | * struct fw_sec: Just for the image parsing proccess. | 148 | * struct fw_sec: Just for the image parsing process. |
149 | * For the fw storage we are using struct fw_desc. | 149 | * For the fw storage we are using struct fw_desc. |
150 | */ | 150 | */ |
151 | struct fw_sec { | 151 | struct fw_sec { |
@@ -241,16 +241,10 @@ static int iwl_request_firmware(struct iwl_drv *drv, bool first) | |||
241 | * previous name and uses the new format. | 241 | * previous name and uses the new format. |
242 | */ | 242 | */ |
243 | if (drv->trans->cfg->device_family == IWL_DEVICE_FAMILY_8000) { | 243 | if (drv->trans->cfg->device_family == IWL_DEVICE_FAMILY_8000) { |
244 | char rev_step[2] = { | 244 | char rev_step = 'A' + CSR_HW_REV_STEP(drv->trans->hw_rev); |
245 | 'A' + CSR_HW_REV_STEP(drv->trans->hw_rev), 0 | ||
246 | }; | ||
247 | |||
248 | /* A-step doesn't have an indication */ | ||
249 | if (CSR_HW_REV_STEP(drv->trans->hw_rev) == SILICON_A_STEP) | ||
250 | rev_step[0] = 0; | ||
251 | 245 | ||
252 | snprintf(drv->firmware_name, sizeof(drv->firmware_name), | 246 | snprintf(drv->firmware_name, sizeof(drv->firmware_name), |
253 | "%s%s-%s.ucode", name_pre, rev_step, tag); | 247 | "%s%c-%s.ucode", name_pre, rev_step, tag); |
254 | } | 248 | } |
255 | 249 | ||
256 | IWL_DEBUG_INFO(drv, "attempting to load firmware %s'%s'\n", | 250 | IWL_DEBUG_INFO(drv, "attempting to load firmware %s'%s'\n", |
@@ -1108,6 +1102,7 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context) | |||
1108 | const unsigned int api_max = drv->cfg->ucode_api_max; | 1102 | const unsigned int api_max = drv->cfg->ucode_api_max; |
1109 | unsigned int api_ok = drv->cfg->ucode_api_ok; | 1103 | unsigned int api_ok = drv->cfg->ucode_api_ok; |
1110 | const unsigned int api_min = drv->cfg->ucode_api_min; | 1104 | const unsigned int api_min = drv->cfg->ucode_api_min; |
1105 | size_t trigger_tlv_sz[FW_DBG_TRIGGER_MAX]; | ||
1111 | u32 api_ver; | 1106 | u32 api_ver; |
1112 | int i; | 1107 | int i; |
1113 | bool load_module = false; | 1108 | bool load_module = false; |
@@ -1227,8 +1222,37 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context) | |||
1227 | } | 1222 | } |
1228 | } | 1223 | } |
1229 | 1224 | ||
1225 | memset(&trigger_tlv_sz, 0xff, sizeof(trigger_tlv_sz)); | ||
1226 | |||
1227 | trigger_tlv_sz[FW_DBG_TRIGGER_MISSED_BEACONS] = | ||
1228 | sizeof(struct iwl_fw_dbg_trigger_missed_bcon); | ||
1229 | trigger_tlv_sz[FW_DBG_TRIGGER_CHANNEL_SWITCH] = 0; | ||
1230 | trigger_tlv_sz[FW_DBG_TRIGGER_FW_NOTIF] = | ||
1231 | sizeof(struct iwl_fw_dbg_trigger_cmd); | ||
1232 | trigger_tlv_sz[FW_DBG_TRIGGER_MLME] = | ||
1233 | sizeof(struct iwl_fw_dbg_trigger_mlme); | ||
1234 | trigger_tlv_sz[FW_DBG_TRIGGER_STATS] = | ||
1235 | sizeof(struct iwl_fw_dbg_trigger_stats); | ||
1236 | trigger_tlv_sz[FW_DBG_TRIGGER_RSSI] = | ||
1237 | sizeof(struct iwl_fw_dbg_trigger_low_rssi); | ||
1238 | trigger_tlv_sz[FW_DBG_TRIGGER_TXQ_TIMERS] = | ||
1239 | sizeof(struct iwl_fw_dbg_trigger_txq_timer); | ||
1240 | trigger_tlv_sz[FW_DBG_TRIGGER_TIME_EVENT] = | ||
1241 | sizeof(struct iwl_fw_dbg_trigger_time_event); | ||
1242 | |||
1230 | for (i = 0; i < ARRAY_SIZE(drv->fw.dbg_trigger_tlv); i++) { | 1243 | for (i = 0; i < ARRAY_SIZE(drv->fw.dbg_trigger_tlv); i++) { |
1231 | if (pieces->dbg_trigger_tlv[i]) { | 1244 | if (pieces->dbg_trigger_tlv[i]) { |
1245 | /* | ||
1246 | * If the trigger isn't long enough, WARN and exit. | ||
1247 | * Someone is trying to debug something and he won't | ||
1248 | * be able to catch the bug he is trying to chase. | ||
1249 | * We'd better be noisy to be sure he knows what's | ||
1250 | * going on. | ||
1251 | */ | ||
1252 | if (WARN_ON(pieces->dbg_trigger_tlv_len[i] < | ||
1253 | (trigger_tlv_sz[i] + | ||
1254 | sizeof(struct iwl_fw_dbg_trigger_tlv)))) | ||
1255 | goto out_free_fw; | ||
1232 | drv->fw.dbg_trigger_tlv_len[i] = | 1256 | drv->fw.dbg_trigger_tlv_len[i] = |
1233 | pieces->dbg_trigger_tlv_len[i]; | 1257 | pieces->dbg_trigger_tlv_len[i]; |
1234 | drv->fw.dbg_trigger_tlv[i] = | 1258 | drv->fw.dbg_trigger_tlv[i] = |
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.h b/drivers/net/wireless/iwlwifi/iwl-drv.h index 67a3a241b331..cda746b33db1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.h +++ b/drivers/net/wireless/iwlwifi/iwl-drv.h | |||
@@ -123,7 +123,7 @@ struct iwl_cfg; | |||
123 | * starts the driver: fetches the firmware. This should be called by bus | 123 | * starts the driver: fetches the firmware. This should be called by bus |
124 | * specific system flows implementations. For example, the bus specific probe | 124 | * specific system flows implementations. For example, the bus specific probe |
125 | * function should do bus related operations only, and then call to this | 125 | * function should do bus related operations only, and then call to this |
126 | * function. It returns the driver object or %NULL if an error occured. | 126 | * function. It returns the driver object or %NULL if an error occurred. |
127 | */ | 127 | */ |
128 | struct iwl_drv *iwl_drv_start(struct iwl_trans *trans, | 128 | struct iwl_drv *iwl_drv_start(struct iwl_trans *trans, |
129 | const struct iwl_cfg *cfg); | 129 | const struct iwl_cfg *cfg); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-read.c b/drivers/net/wireless/iwlwifi/iwl-eeprom-read.c index 25d0105741db..219ca8acca62 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom-read.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-read.c | |||
@@ -248,7 +248,7 @@ static int iwl_read_otp_word(struct iwl_trans *trans, u16 addr, | |||
248 | otpgp = iwl_read32(trans, CSR_OTP_GP_REG); | 248 | otpgp = iwl_read32(trans, CSR_OTP_GP_REG); |
249 | if (otpgp & CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK) { | 249 | if (otpgp & CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK) { |
250 | /* stop in this case */ | 250 | /* stop in this case */ |
251 | /* set the uncorrectable OTP ECC bit for acknowledgement */ | 251 | /* set the uncorrectable OTP ECC bit for acknowledgment */ |
252 | iwl_set_bit(trans, CSR_OTP_GP_REG, | 252 | iwl_set_bit(trans, CSR_OTP_GP_REG, |
253 | CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK); | 253 | CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK); |
254 | IWL_ERR(trans, "Uncorrectable OTP ECC error, abort OTP read\n"); | 254 | IWL_ERR(trans, "Uncorrectable OTP ECC error, abort OTP read\n"); |
@@ -256,7 +256,7 @@ static int iwl_read_otp_word(struct iwl_trans *trans, u16 addr, | |||
256 | } | 256 | } |
257 | if (otpgp & CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK) { | 257 | if (otpgp & CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK) { |
258 | /* continue in this case */ | 258 | /* continue in this case */ |
259 | /* set the correctable OTP ECC bit for acknowledgement */ | 259 | /* set the correctable OTP ECC bit for acknowledgment */ |
260 | iwl_set_bit(trans, CSR_OTP_GP_REG, | 260 | iwl_set_bit(trans, CSR_OTP_GP_REG, |
261 | CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK); | 261 | CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK); |
262 | IWL_ERR(trans, "Correctable OTP ECC error, continue read\n"); | 262 | IWL_ERR(trans, "Correctable OTP ECC error, continue read\n"); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-fh.h b/drivers/net/wireless/iwlwifi/iwl-fh.h index 1f7f15eb86da..d45dc021cda2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fh.h +++ b/drivers/net/wireless/iwlwifi/iwl-fh.h | |||
@@ -445,7 +445,7 @@ static inline unsigned int FH_MEM_CBBC_QUEUE(unsigned int chnl) | |||
445 | #define RX_LOW_WATERMARK 8 | 445 | #define RX_LOW_WATERMARK 8 |
446 | 446 | ||
447 | /** | 447 | /** |
448 | * struct iwl_rb_status - reseve buffer status | 448 | * struct iwl_rb_status - reserve buffer status |
449 | * host memory mapped FH registers | 449 | * host memory mapped FH registers |
450 | * @closed_rb_num [0:11] - Indicates the index of the RB which was closed | 450 | * @closed_rb_num [0:11] - Indicates the index of the RB which was closed |
451 | * @closed_fr_num [0:11] - Indicates the index of the RX Frame which was closed | 451 | * @closed_fr_num [0:11] - Indicates the index of the RX Frame which was closed |
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h b/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h index 37b38a585dd1..251bf8dc4a12 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h | |||
@@ -183,7 +183,7 @@ struct iwl_fw_error_dump_info { | |||
183 | * struct iwl_fw_error_dump_fw_mon - FW monitor data | 183 | * struct iwl_fw_error_dump_fw_mon - FW monitor data |
184 | * @fw_mon_wr_ptr: the position of the write pointer in the cyclic buffer | 184 | * @fw_mon_wr_ptr: the position of the write pointer in the cyclic buffer |
185 | * @fw_mon_base_ptr: base pointer of the data | 185 | * @fw_mon_base_ptr: base pointer of the data |
186 | * @fw_mon_cycle_cnt: number of wrap arounds | 186 | * @fw_mon_cycle_cnt: number of wraparounds |
187 | * @reserved: for future use | 187 | * @reserved: for future use |
188 | * @data: captured data | 188 | * @data: captured data |
189 | */ | 189 | */ |
@@ -246,10 +246,14 @@ iwl_fw_error_next_data(struct iwl_fw_error_dump_data *data) | |||
246 | * @FW_DBG_TRIGGER_CHANNEL_SWITCH: trigger log collection upon channel switch. | 246 | * @FW_DBG_TRIGGER_CHANNEL_SWITCH: trigger log collection upon channel switch. |
247 | * @FW_DBG_TRIGGER_FW_NOTIF: trigger log collection when the firmware sends a | 247 | * @FW_DBG_TRIGGER_FW_NOTIF: trigger log collection when the firmware sends a |
248 | * command response or a notification. | 248 | * command response or a notification. |
249 | * @FW_DB_TRIGGER_RESERVED: reserved | 249 | * @FW_DBG_TRIGGER_MLME: trigger log collection upon MLME event. |
250 | * @FW_DBG_TRIGGER_STATS: trigger log collection upon statistics threshold. | 250 | * @FW_DBG_TRIGGER_STATS: trigger log collection upon statistics threshold. |
251 | * @FW_DBG_TRIGGER_RSSI: trigger log collection when the rssi of the beacon | 251 | * @FW_DBG_TRIGGER_RSSI: trigger log collection when the rssi of the beacon |
252 | * goes below a threshold. | 252 | * goes below a threshold. |
253 | * @FW_DBG_TRIGGER_TXQ_TIMERS: configures the timers for the Tx queue hang | ||
254 | * detection. | ||
255 | * @FW_DBG_TRIGGER_TIME_EVENT: trigger log collection upon time events related | ||
256 | * events. | ||
253 | */ | 257 | */ |
254 | enum iwl_fw_dbg_trigger { | 258 | enum iwl_fw_dbg_trigger { |
255 | FW_DBG_TRIGGER_INVALID = 0, | 259 | FW_DBG_TRIGGER_INVALID = 0, |
@@ -258,9 +262,11 @@ enum iwl_fw_dbg_trigger { | |||
258 | FW_DBG_TRIGGER_MISSED_BEACONS, | 262 | FW_DBG_TRIGGER_MISSED_BEACONS, |
259 | FW_DBG_TRIGGER_CHANNEL_SWITCH, | 263 | FW_DBG_TRIGGER_CHANNEL_SWITCH, |
260 | FW_DBG_TRIGGER_FW_NOTIF, | 264 | FW_DBG_TRIGGER_FW_NOTIF, |
261 | FW_DB_TRIGGER_RESERVED, | 265 | FW_DBG_TRIGGER_MLME, |
262 | FW_DBG_TRIGGER_STATS, | 266 | FW_DBG_TRIGGER_STATS, |
263 | FW_DBG_TRIGGER_RSSI, | 267 | FW_DBG_TRIGGER_RSSI, |
268 | FW_DBG_TRIGGER_TXQ_TIMERS, | ||
269 | FW_DBG_TRIGGER_TIME_EVENT, | ||
264 | 270 | ||
265 | /* must be last */ | 271 | /* must be last */ |
266 | FW_DBG_TRIGGER_MAX, | 272 | FW_DBG_TRIGGER_MAX, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-file.h b/drivers/net/wireless/iwlwifi/iwl-fw-file.h index 291a3382aa3f..bfdf3faa6c47 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fw-file.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw-file.h | |||
@@ -191,7 +191,7 @@ struct iwl_ucode_capa { | |||
191 | * enum iwl_ucode_tlv_flag - ucode API flags | 191 | * enum iwl_ucode_tlv_flag - ucode API flags |
192 | * @IWL_UCODE_TLV_FLAGS_PAN: This is PAN capable microcode; this previously | 192 | * @IWL_UCODE_TLV_FLAGS_PAN: This is PAN capable microcode; this previously |
193 | * was a separate TLV but moved here to save space. | 193 | * was a separate TLV but moved here to save space. |
194 | * @IWL_UCODE_TLV_FLAGS_NEWSCAN: new uCode scan behaviour on hidden SSID, | 194 | * @IWL_UCODE_TLV_FLAGS_NEWSCAN: new uCode scan behavior on hidden SSID, |
195 | * treats good CRC threshold as a boolean | 195 | * treats good CRC threshold as a boolean |
196 | * @IWL_UCODE_TLV_FLAGS_MFP: This uCode image supports MFP (802.11w). | 196 | * @IWL_UCODE_TLV_FLAGS_MFP: This uCode image supports MFP (802.11w). |
197 | * @IWL_UCODE_TLV_FLAGS_P2P: This uCode image supports P2P. | 197 | * @IWL_UCODE_TLV_FLAGS_P2P: This uCode image supports P2P. |
@@ -290,6 +290,10 @@ enum iwl_ucode_tlv_api { | |||
290 | * @IWL_UCODE_TLV_CAPA_HOTSPOT_SUPPORT: supports Hot Spot Command | 290 | * @IWL_UCODE_TLV_CAPA_HOTSPOT_SUPPORT: supports Hot Spot Command |
291 | * @IWL_UCODE_TLV_CAPA_RADIO_BEACON_STATS: support radio and beacon statistics | 291 | * @IWL_UCODE_TLV_CAPA_RADIO_BEACON_STATS: support radio and beacon statistics |
292 | * @IWL_UCODE_TLV_CAPA_BT_COEX_PLCR: enabled BT Coex packet level co-running | 292 | * @IWL_UCODE_TLV_CAPA_BT_COEX_PLCR: enabled BT Coex packet level co-running |
293 | * @IWL_UCODE_TLV_CAPA_LAR_MULTI_MCC: ucode supports LAR updates with different | ||
294 | * sources for the MCC. This TLV bit is a future replacement to | ||
295 | * IWL_UCODE_TLV_API_WIFI_MCC_UPDATE. When either is set, multi-source LAR | ||
296 | * is supported. | ||
293 | * @IWL_UCODE_TLV_CAPA_BT_COEX_RRC: supports BT Coex RRC | 297 | * @IWL_UCODE_TLV_CAPA_BT_COEX_RRC: supports BT Coex RRC |
294 | */ | 298 | */ |
295 | enum iwl_ucode_tlv_capa { | 299 | enum iwl_ucode_tlv_capa { |
@@ -307,6 +311,7 @@ enum iwl_ucode_tlv_capa { | |||
307 | IWL_UCODE_TLV_CAPA_HOTSPOT_SUPPORT = BIT(18), | 311 | IWL_UCODE_TLV_CAPA_HOTSPOT_SUPPORT = BIT(18), |
308 | IWL_UCODE_TLV_CAPA_RADIO_BEACON_STATS = BIT(22), | 312 | IWL_UCODE_TLV_CAPA_RADIO_BEACON_STATS = BIT(22), |
309 | IWL_UCODE_TLV_CAPA_BT_COEX_PLCR = BIT(28), | 313 | IWL_UCODE_TLV_CAPA_BT_COEX_PLCR = BIT(28), |
314 | IWL_UCODE_TLV_CAPA_LAR_MULTI_MCC = BIT(29), | ||
310 | IWL_UCODE_TLV_CAPA_BT_COEX_RRC = BIT(30), | 315 | IWL_UCODE_TLV_CAPA_BT_COEX_RRC = BIT(30), |
311 | }; | 316 | }; |
312 | 317 | ||
@@ -574,6 +579,84 @@ struct iwl_fw_dbg_trigger_low_rssi { | |||
574 | } __packed; | 579 | } __packed; |
575 | 580 | ||
576 | /** | 581 | /** |
582 | * struct iwl_fw_dbg_trigger_mlme - configures trigger for mlme events | ||
583 | * @stop_auth_denied: number of denied authentication to collect | ||
584 | * @stop_auth_timeout: number of authentication timeout to collect | ||
585 | * @stop_rx_deauth: number of Rx deauth before to collect | ||
586 | * @stop_tx_deauth: number of Tx deauth before to collect | ||
587 | * @stop_assoc_denied: number of denied association to collect | ||
588 | * @stop_assoc_timeout: number of association timeout to collect | ||
589 | * @stop_connection_loss: number of connection loss to collect | ||
590 | * @start_auth_denied: number of denied authentication to start recording | ||
591 | * @start_auth_timeout: number of authentication timeout to start recording | ||
592 | * @start_rx_deauth: number of Rx deauth to start recording | ||
593 | * @start_tx_deauth: number of Tx deauth to start recording | ||
594 | * @start_assoc_denied: number of denied association to start recording | ||
595 | * @start_assoc_timeout: number of association timeout to start recording | ||
596 | * @start_connection_loss: number of connection loss to start recording | ||
597 | */ | ||
598 | struct iwl_fw_dbg_trigger_mlme { | ||
599 | u8 stop_auth_denied; | ||
600 | u8 stop_auth_timeout; | ||
601 | u8 stop_rx_deauth; | ||
602 | u8 stop_tx_deauth; | ||
603 | |||
604 | u8 stop_assoc_denied; | ||
605 | u8 stop_assoc_timeout; | ||
606 | u8 stop_connection_loss; | ||
607 | u8 reserved; | ||
608 | |||
609 | u8 start_auth_denied; | ||
610 | u8 start_auth_timeout; | ||
611 | u8 start_rx_deauth; | ||
612 | u8 start_tx_deauth; | ||
613 | |||
614 | u8 start_assoc_denied; | ||
615 | u8 start_assoc_timeout; | ||
616 | u8 start_connection_loss; | ||
617 | u8 reserved2; | ||
618 | } __packed; | ||
619 | |||
620 | /** | ||
621 | * struct iwl_fw_dbg_trigger_txq_timer - configures the Tx queue's timer | ||
622 | * @command_queue: timeout for the command queue in ms | ||
623 | * @bss: timeout for the queues of a BSS (except for TDLS queues) in ms | ||
624 | * @softap: timeout for the queues of a softAP in ms | ||
625 | * @p2p_go: timeout for the queues of a P2P GO in ms | ||
626 | * @p2p_client: timeout for the queues of a P2P client in ms | ||
627 | * @p2p_device: timeout for the queues of a P2P device in ms | ||
628 | * @ibss: timeout for the queues of an IBSS in ms | ||
629 | * @tdls: timeout for the queues of a TDLS station in ms | ||
630 | */ | ||
631 | struct iwl_fw_dbg_trigger_txq_timer { | ||
632 | __le32 command_queue; | ||
633 | __le32 bss; | ||
634 | __le32 softap; | ||
635 | __le32 p2p_go; | ||
636 | __le32 p2p_client; | ||
637 | __le32 p2p_device; | ||
638 | __le32 ibss; | ||
639 | __le32 tdls; | ||
640 | __le32 reserved[4]; | ||
641 | } __packed; | ||
642 | |||
643 | /** | ||
644 | * struct iwl_fw_dbg_trigger_time_event - configures a time event trigger | ||
645 | * time_Events: a list of tuples <id, action_bitmap>. The driver will issue a | ||
646 | * trigger each time a time event notification that relates to time event | ||
647 | * id with one of the actions in the bitmap is received and | ||
648 | * BIT(notif->status) is set in status_bitmap. | ||
649 | * | ||
650 | */ | ||
651 | struct iwl_fw_dbg_trigger_time_event { | ||
652 | struct { | ||
653 | __le32 id; | ||
654 | __le32 action_bitmap; | ||
655 | __le32 status_bitmap; | ||
656 | } __packed time_events[16]; | ||
657 | } __packed; | ||
658 | |||
659 | /** | ||
577 | * struct iwl_fw_dbg_conf_tlv - a TLV that describes a debug configuration. | 660 | * struct iwl_fw_dbg_conf_tlv - a TLV that describes a debug configuration. |
578 | * @id: conf id | 661 | * @id: conf id |
579 | * @usniffer: should the uSniffer image be used | 662 | * @usniffer: should the uSniffer image be used |
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.c b/drivers/net/wireless/iwlwifi/iwl-io.c index 78cac43e2bcd..27c66e477833 100644 --- a/drivers/net/wireless/iwlwifi/iwl-io.c +++ b/drivers/net/wireless/iwlwifi/iwl-io.c | |||
@@ -186,21 +186,14 @@ IWL_EXPORT_SYMBOL(iwl_clear_bits_prph); | |||
186 | 186 | ||
187 | void iwl_force_nmi(struct iwl_trans *trans) | 187 | void iwl_force_nmi(struct iwl_trans *trans) |
188 | { | 188 | { |
189 | /* | 189 | if (trans->cfg->device_family != IWL_DEVICE_FAMILY_8000) { |
190 | * In HW previous to the 8000 HW family, and in the 8000 HW family | ||
191 | * itself when the revision step==0, the DEVICE_SET_NMI_REG is used | ||
192 | * to force an NMI. Otherwise, a different register - | ||
193 | * DEVICE_SET_NMI_8000B_REG - is used. | ||
194 | */ | ||
195 | if ((trans->cfg->device_family != IWL_DEVICE_FAMILY_8000) || | ||
196 | (CSR_HW_REV_STEP(trans->hw_rev) == SILICON_A_STEP)) { | ||
197 | iwl_write_prph(trans, DEVICE_SET_NMI_REG, | 190 | iwl_write_prph(trans, DEVICE_SET_NMI_REG, |
198 | DEVICE_SET_NMI_VAL_DRV); | 191 | DEVICE_SET_NMI_VAL_DRV); |
199 | iwl_write_prph(trans, DEVICE_SET_NMI_REG, | 192 | iwl_write_prph(trans, DEVICE_SET_NMI_REG, |
200 | DEVICE_SET_NMI_VAL_HW); | 193 | DEVICE_SET_NMI_VAL_HW); |
201 | } else { | 194 | } else { |
202 | iwl_write_prph(trans, DEVICE_SET_NMI_8000B_REG, | 195 | iwl_write_prph(trans, DEVICE_SET_NMI_8000_REG, |
203 | DEVICE_SET_NMI_8000B_VAL); | 196 | DEVICE_SET_NMI_8000_VAL); |
204 | iwl_write_prph(trans, DEVICE_SET_NMI_REG, | 197 | iwl_write_prph(trans, DEVICE_SET_NMI_REG, |
205 | DEVICE_SET_NMI_VAL_DRV); | 198 | DEVICE_SET_NMI_VAL_DRV); |
206 | } | 199 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c index 774637746427..83903a5025c2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c +++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c | |||
@@ -99,14 +99,9 @@ enum family_8000_nvm_offsets { | |||
99 | /* NVM SW-Section offset (in words) definitions */ | 99 | /* NVM SW-Section offset (in words) definitions */ |
100 | NVM_SW_SECTION_FAMILY_8000 = 0x1C0, | 100 | NVM_SW_SECTION_FAMILY_8000 = 0x1C0, |
101 | NVM_VERSION_FAMILY_8000 = 0, | 101 | NVM_VERSION_FAMILY_8000 = 0, |
102 | RADIO_CFG_FAMILY_8000 = 2, | 102 | RADIO_CFG_FAMILY_8000 = 0, |
103 | SKU_FAMILY_8000 = 4, | 103 | SKU_FAMILY_8000 = 2, |
104 | N_HW_ADDRS_FAMILY_8000 = 5, | 104 | N_HW_ADDRS_FAMILY_8000 = 3, |
105 | |||
106 | /* NVM PHY-SKU-Section offset (in words) for B0 */ | ||
107 | RADIO_CFG_FAMILY_8000_B0 = 0, | ||
108 | SKU_FAMILY_8000_B0 = 2, | ||
109 | N_HW_ADDRS_FAMILY_8000_B0 = 3, | ||
110 | 105 | ||
111 | /* NVM REGULATORY -Section offset (in words) definitions */ | 106 | /* NVM REGULATORY -Section offset (in words) definitions */ |
112 | NVM_CHANNELS_FAMILY_8000 = 0, | 107 | NVM_CHANNELS_FAMILY_8000 = 0, |
@@ -446,22 +441,16 @@ static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg, | |||
446 | n_used, n_channels); | 441 | n_used, n_channels); |
447 | } | 442 | } |
448 | 443 | ||
449 | static int iwl_get_sku(const struct iwl_cfg *cfg, | 444 | static int iwl_get_sku(const struct iwl_cfg *cfg, const __le16 *nvm_sw, |
450 | const __le16 *nvm_sw, const __le16 *phy_sku, | 445 | const __le16 *phy_sku) |
451 | bool is_family_8000_a_step) | ||
452 | { | 446 | { |
453 | if (cfg->device_family != IWL_DEVICE_FAMILY_8000) | 447 | if (cfg->device_family != IWL_DEVICE_FAMILY_8000) |
454 | return le16_to_cpup(nvm_sw + SKU); | 448 | return le16_to_cpup(nvm_sw + SKU); |
455 | 449 | ||
456 | if (!is_family_8000_a_step) | 450 | return le32_to_cpup((__le32 *)(phy_sku + SKU_FAMILY_8000)); |
457 | return le32_to_cpup((__le32 *)(phy_sku + | ||
458 | SKU_FAMILY_8000_B0)); | ||
459 | else | ||
460 | return le32_to_cpup((__le32 *)(nvm_sw + SKU_FAMILY_8000)); | ||
461 | } | 451 | } |
462 | 452 | ||
463 | static int iwl_get_nvm_version(const struct iwl_cfg *cfg, | 453 | static int iwl_get_nvm_version(const struct iwl_cfg *cfg, const __le16 *nvm_sw) |
464 | const __le16 *nvm_sw) | ||
465 | { | 454 | { |
466 | if (cfg->device_family != IWL_DEVICE_FAMILY_8000) | 455 | if (cfg->device_family != IWL_DEVICE_FAMILY_8000) |
467 | return le16_to_cpup(nvm_sw + NVM_VERSION); | 456 | return le16_to_cpup(nvm_sw + NVM_VERSION); |
@@ -470,35 +459,24 @@ static int iwl_get_nvm_version(const struct iwl_cfg *cfg, | |||
470 | NVM_VERSION_FAMILY_8000)); | 459 | NVM_VERSION_FAMILY_8000)); |
471 | } | 460 | } |
472 | 461 | ||
473 | static int iwl_get_radio_cfg(const struct iwl_cfg *cfg, | 462 | static int iwl_get_radio_cfg(const struct iwl_cfg *cfg, const __le16 *nvm_sw, |
474 | const __le16 *nvm_sw, const __le16 *phy_sku, | 463 | const __le16 *phy_sku) |
475 | bool is_family_8000_a_step) | ||
476 | { | 464 | { |
477 | if (cfg->device_family != IWL_DEVICE_FAMILY_8000) | 465 | if (cfg->device_family != IWL_DEVICE_FAMILY_8000) |
478 | return le16_to_cpup(nvm_sw + RADIO_CFG); | 466 | return le16_to_cpup(nvm_sw + RADIO_CFG); |
479 | 467 | ||
480 | if (!is_family_8000_a_step) | 468 | return le32_to_cpup((__le32 *)(nvm_sw + RADIO_CFG_FAMILY_8000)); |
481 | return le32_to_cpup((__le32 *)(phy_sku + | ||
482 | RADIO_CFG_FAMILY_8000_B0)); | ||
483 | else | ||
484 | return le32_to_cpup((__le32 *)(nvm_sw + RADIO_CFG_FAMILY_8000)); | ||
485 | 469 | ||
486 | } | 470 | } |
487 | 471 | ||
488 | static int iwl_get_n_hw_addrs(const struct iwl_cfg *cfg, | 472 | static int iwl_get_n_hw_addrs(const struct iwl_cfg *cfg, const __le16 *nvm_sw) |
489 | const __le16 *nvm_sw, bool is_family_8000_a_step) | ||
490 | { | 473 | { |
491 | int n_hw_addr; | 474 | int n_hw_addr; |
492 | 475 | ||
493 | if (cfg->device_family != IWL_DEVICE_FAMILY_8000) | 476 | if (cfg->device_family != IWL_DEVICE_FAMILY_8000) |
494 | return le16_to_cpup(nvm_sw + N_HW_ADDRS); | 477 | return le16_to_cpup(nvm_sw + N_HW_ADDRS); |
495 | 478 | ||
496 | if (!is_family_8000_a_step) | 479 | n_hw_addr = le32_to_cpup((__le32 *)(nvm_sw + N_HW_ADDRS_FAMILY_8000)); |
497 | n_hw_addr = le32_to_cpup((__le32 *)(nvm_sw + | ||
498 | N_HW_ADDRS_FAMILY_8000_B0)); | ||
499 | else | ||
500 | n_hw_addr = le32_to_cpup((__le32 *)(nvm_sw + | ||
501 | N_HW_ADDRS_FAMILY_8000)); | ||
502 | 480 | ||
503 | return n_hw_addr & N_HW_ADDR_MASK; | 481 | return n_hw_addr & N_HW_ADDR_MASK; |
504 | } | 482 | } |
@@ -594,8 +572,7 @@ iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg, | |||
594 | const __le16 *nvm_hw, const __le16 *nvm_sw, | 572 | const __le16 *nvm_hw, const __le16 *nvm_sw, |
595 | const __le16 *nvm_calib, const __le16 *regulatory, | 573 | const __le16 *nvm_calib, const __le16 *regulatory, |
596 | const __le16 *mac_override, const __le16 *phy_sku, | 574 | const __le16 *mac_override, const __le16 *phy_sku, |
597 | u8 tx_chains, u8 rx_chains, | 575 | u8 tx_chains, u8 rx_chains, bool lar_fw_supported, |
598 | bool lar_fw_supported, bool is_family_8000_a_step, | ||
599 | u32 mac_addr0, u32 mac_addr1) | 576 | u32 mac_addr0, u32 mac_addr1) |
600 | { | 577 | { |
601 | struct iwl_nvm_data *data; | 578 | struct iwl_nvm_data *data; |
@@ -618,15 +595,14 @@ iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg, | |||
618 | 595 | ||
619 | data->nvm_version = iwl_get_nvm_version(cfg, nvm_sw); | 596 | data->nvm_version = iwl_get_nvm_version(cfg, nvm_sw); |
620 | 597 | ||
621 | radio_cfg = | 598 | radio_cfg = iwl_get_radio_cfg(cfg, nvm_sw, phy_sku); |
622 | iwl_get_radio_cfg(cfg, nvm_sw, phy_sku, is_family_8000_a_step); | ||
623 | iwl_set_radio_cfg(cfg, data, radio_cfg); | 599 | iwl_set_radio_cfg(cfg, data, radio_cfg); |
624 | if (data->valid_tx_ant) | 600 | if (data->valid_tx_ant) |
625 | tx_chains &= data->valid_tx_ant; | 601 | tx_chains &= data->valid_tx_ant; |
626 | if (data->valid_rx_ant) | 602 | if (data->valid_rx_ant) |
627 | rx_chains &= data->valid_rx_ant; | 603 | rx_chains &= data->valid_rx_ant; |
628 | 604 | ||
629 | sku = iwl_get_sku(cfg, nvm_sw, phy_sku, is_family_8000_a_step); | 605 | sku = iwl_get_sku(cfg, nvm_sw, phy_sku); |
630 | data->sku_cap_band_24GHz_enable = sku & NVM_SKU_CAP_BAND_24GHZ; | 606 | data->sku_cap_band_24GHz_enable = sku & NVM_SKU_CAP_BAND_24GHZ; |
631 | data->sku_cap_band_52GHz_enable = sku & NVM_SKU_CAP_BAND_52GHZ; | 607 | data->sku_cap_band_52GHz_enable = sku & NVM_SKU_CAP_BAND_52GHZ; |
632 | data->sku_cap_11n_enable = sku & NVM_SKU_CAP_11N_ENABLE; | 608 | data->sku_cap_11n_enable = sku & NVM_SKU_CAP_11N_ENABLE; |
@@ -635,8 +611,7 @@ iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg, | |||
635 | data->sku_cap_11ac_enable = data->sku_cap_11n_enable && | 611 | data->sku_cap_11ac_enable = data->sku_cap_11n_enable && |
636 | (sku & NVM_SKU_CAP_11AC_ENABLE); | 612 | (sku & NVM_SKU_CAP_11AC_ENABLE); |
637 | 613 | ||
638 | data->n_hw_addrs = | 614 | data->n_hw_addrs = iwl_get_n_hw_addrs(cfg, nvm_sw); |
639 | iwl_get_n_hw_addrs(cfg, nvm_sw, is_family_8000_a_step); | ||
640 | 615 | ||
641 | if (cfg->device_family != IWL_DEVICE_FAMILY_8000) { | 616 | if (cfg->device_family != IWL_DEVICE_FAMILY_8000) { |
642 | /* Checking for required sections */ | 617 | /* Checking for required sections */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h index c995d2cee3f6..822ba52e0e5a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h +++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h | |||
@@ -78,8 +78,7 @@ iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg, | |||
78 | const __le16 *nvm_hw, const __le16 *nvm_sw, | 78 | const __le16 *nvm_hw, const __le16 *nvm_sw, |
79 | const __le16 *nvm_calib, const __le16 *regulatory, | 79 | const __le16 *nvm_calib, const __le16 *regulatory, |
80 | const __le16 *mac_override, const __le16 *phy_sku, | 80 | const __le16 *mac_override, const __le16 *phy_sku, |
81 | u8 tx_chains, u8 rx_chains, | 81 | u8 tx_chains, u8 rx_chains, bool lar_fw_supported, |
82 | bool lar_fw_supported, bool is_family_8000_a_step, | ||
83 | u32 mac_addr0, u32 mac_addr1); | 82 | u32 mac_addr0, u32 mac_addr1); |
84 | 83 | ||
85 | /** | 84 | /** |
diff --git a/drivers/net/wireless/iwlwifi/iwl-op-mode.h b/drivers/net/wireless/iwlwifi/iwl-op-mode.h index 17de6d46222a..ce1cdd7604e8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-op-mode.h +++ b/drivers/net/wireless/iwlwifi/iwl-op-mode.h | |||
@@ -94,7 +94,7 @@ struct iwl_cfg; | |||
94 | * The operational mode has a very simple life cycle. | 94 | * The operational mode has a very simple life cycle. |
95 | * | 95 | * |
96 | * 1) The driver layer (iwl-drv.c) chooses the op_mode based on the | 96 | * 1) The driver layer (iwl-drv.c) chooses the op_mode based on the |
97 | * capabilities advertized by the fw file (in TLV format). | 97 | * capabilities advertised by the fw file (in TLV format). |
98 | * 2) The driver layer starts the op_mode (ops->start) | 98 | * 2) The driver layer starts the op_mode (ops->start) |
99 | * 3) The op_mode registers mac80211 | 99 | * 3) The op_mode registers mac80211 |
100 | * 4) The op_mode is governed by mac80211 | 100 | * 4) The op_mode is governed by mac80211 |
@@ -116,7 +116,7 @@ struct iwl_cfg; | |||
116 | * May sleep | 116 | * May sleep |
117 | * @rx: Rx notification to the op_mode. rxb is the Rx buffer itself. Cmd is the | 117 | * @rx: Rx notification to the op_mode. rxb is the Rx buffer itself. Cmd is the |
118 | * HCMD this Rx responds to. Can't sleep. | 118 | * HCMD this Rx responds to. Can't sleep. |
119 | * @napi_add: NAPI initialisation. The transport is fully responsible for NAPI, | 119 | * @napi_add: NAPI initialization. The transport is fully responsible for NAPI, |
120 | * but the higher layers need to know about it (in particular mac80211 to | 120 | * but the higher layers need to know about it (in particular mac80211 to |
121 | * to able to call the right NAPI RX functions); this function is needed | 121 | * to able to call the right NAPI RX functions); this function is needed |
122 | * to eventually call netif_napi_add() with higher layer involvement. | 122 | * to eventually call netif_napi_add() with higher layer involvement. |
diff --git a/drivers/net/wireless/iwlwifi/iwl-phy-db.c b/drivers/net/wireless/iwlwifi/iwl-phy-db.c index e893c6eb260c..a105455b6a24 100644 --- a/drivers/net/wireless/iwlwifi/iwl-phy-db.c +++ b/drivers/net/wireless/iwlwifi/iwl-phy-db.c | |||
@@ -125,7 +125,7 @@ struct iwl_phy_db_chg_txp { | |||
125 | } __packed; | 125 | } __packed; |
126 | 126 | ||
127 | /* | 127 | /* |
128 | * phy db - Receieve phy db chunk after calibrations | 128 | * phy db - Receive phy db chunk after calibrations |
129 | */ | 129 | */ |
130 | struct iwl_calib_res_notif_phy_db { | 130 | struct iwl_calib_res_notif_phy_db { |
131 | __le16 type; | 131 | __le16 type; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h index bc962888c583..88a57e6e232f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-prph.h +++ b/drivers/net/wireless/iwlwifi/iwl-prph.h | |||
@@ -110,8 +110,8 @@ | |||
110 | #define DEVICE_SET_NMI_REG 0x00a01c30 | 110 | #define DEVICE_SET_NMI_REG 0x00a01c30 |
111 | #define DEVICE_SET_NMI_VAL_HW BIT(0) | 111 | #define DEVICE_SET_NMI_VAL_HW BIT(0) |
112 | #define DEVICE_SET_NMI_VAL_DRV BIT(7) | 112 | #define DEVICE_SET_NMI_VAL_DRV BIT(7) |
113 | #define DEVICE_SET_NMI_8000B_REG 0x00a01c24 | 113 | #define DEVICE_SET_NMI_8000_REG 0x00a01c24 |
114 | #define DEVICE_SET_NMI_8000B_VAL 0x1000000 | 114 | #define DEVICE_SET_NMI_8000_VAL 0x1000000 |
115 | 115 | ||
116 | /* Shared registers (0x0..0x3ff, via target indirect or periphery */ | 116 | /* Shared registers (0x0..0x3ff, via target indirect or periphery */ |
117 | #define SHR_BASE 0x00a10000 | 117 | #define SHR_BASE 0x00a10000 |
@@ -295,25 +295,6 @@ | |||
295 | #define OSC_CLK (0xa04068) | 295 | #define OSC_CLK (0xa04068) |
296 | #define OSC_CLK_FORCE_CONTROL (0x8) | 296 | #define OSC_CLK_FORCE_CONTROL (0x8) |
297 | 297 | ||
298 | /* SECURE boot registers */ | ||
299 | #define LMPM_SECURE_BOOT_CONFIG_ADDR (0x100) | ||
300 | enum secure_boot_config_reg { | ||
301 | LMPM_SECURE_BOOT_CONFIG_INSPECTOR_BURNED_IN_OTP = 0x00000001, | ||
302 | LMPM_SECURE_BOOT_CONFIG_INSPECTOR_NOT_REQ = 0x00000002, | ||
303 | }; | ||
304 | |||
305 | #define LMPM_SECURE_BOOT_CPU1_STATUS_ADDR_B0 (0xA01E30) | ||
306 | #define LMPM_SECURE_BOOT_CPU1_STATUS_ADDR (0x1E30) | ||
307 | #define LMPM_SECURE_BOOT_CPU2_STATUS_ADDR (0x1E34) | ||
308 | enum secure_boot_status_reg { | ||
309 | LMPM_SECURE_BOOT_CPU_STATUS_VERF_STATUS = 0x00000001, | ||
310 | LMPM_SECURE_BOOT_CPU_STATUS_VERF_COMPLETED = 0x00000002, | ||
311 | LMPM_SECURE_BOOT_CPU_STATUS_VERF_SUCCESS = 0x00000004, | ||
312 | LMPM_SECURE_BOOT_CPU_STATUS_VERF_FAIL = 0x00000008, | ||
313 | LMPM_SECURE_BOOT_CPU_STATUS_SIGN_VERF_FAIL = 0x00000010, | ||
314 | LMPM_SECURE_BOOT_STATUS_SUCCESS = 0x00000003, | ||
315 | }; | ||
316 | |||
317 | #define FH_UCODE_LOAD_STATUS (0x1AF0) | 298 | #define FH_UCODE_LOAD_STATUS (0x1AF0) |
318 | #define CSR_UCODE_LOAD_STATUS_ADDR (0x1E70) | 299 | #define CSR_UCODE_LOAD_STATUS_ADDR (0x1E70) |
319 | enum secure_load_status_reg { | 300 | enum secure_load_status_reg { |
@@ -334,8 +315,6 @@ enum secure_load_status_reg { | |||
334 | #define LMPM_SECURE_CPU1_HDR_MEM_SPACE (0x420000) | 315 | #define LMPM_SECURE_CPU1_HDR_MEM_SPACE (0x420000) |
335 | #define LMPM_SECURE_CPU2_HDR_MEM_SPACE (0x420400) | 316 | #define LMPM_SECURE_CPU2_HDR_MEM_SPACE (0x420400) |
336 | 317 | ||
337 | #define LMPM_SECURE_TIME_OUT (100) /* 10 micro */ | ||
338 | |||
339 | /* Rx FIFO */ | 318 | /* Rx FIFO */ |
340 | #define RXF_SIZE_ADDR (0xa00c88) | 319 | #define RXF_SIZE_ADDR (0xa00c88) |
341 | #define RXF_RD_D_SPACE (0xa00c40) | 320 | #define RXF_RD_D_SPACE (0xa00c40) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 11ac5c58527f..6dfed1259260 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h | |||
@@ -77,10 +77,10 @@ | |||
77 | /** | 77 | /** |
78 | * DOC: Transport layer - what is it ? | 78 | * DOC: Transport layer - what is it ? |
79 | * | 79 | * |
80 | * The tranport layer is the layer that deals with the HW directly. It provides | 80 | * The transport layer is the layer that deals with the HW directly. It provides |
81 | * an abstraction of the underlying HW to the upper layer. The transport layer | 81 | * an abstraction of the underlying HW to the upper layer. The transport layer |
82 | * doesn't provide any policy, algorithm or anything of this kind, but only | 82 | * doesn't provide any policy, algorithm or anything of this kind, but only |
83 | * mechanisms to make the HW do something.It is not completely stateless but | 83 | * mechanisms to make the HW do something. It is not completely stateless but |
84 | * close to it. | 84 | * close to it. |
85 | * We will have an implementation for each different supported bus. | 85 | * We will have an implementation for each different supported bus. |
86 | */ | 86 | */ |
@@ -111,10 +111,10 @@ | |||
111 | /** | 111 | /** |
112 | * DOC: Host command section | 112 | * DOC: Host command section |
113 | * | 113 | * |
114 | * A host command is a commaned issued by the upper layer to the fw. There are | 114 | * A host command is a command issued by the upper layer to the fw. There are |
115 | * several versions of fw that have several APIs. The transport layer is | 115 | * several versions of fw that have several APIs. The transport layer is |
116 | * completely agnostic to these differences. | 116 | * completely agnostic to these differences. |
117 | * The transport does provide helper functionnality (i.e. SYNC / ASYNC mode), | 117 | * The transport does provide helper functionality (i.e. SYNC / ASYNC mode), |
118 | */ | 118 | */ |
119 | #define SEQ_TO_QUEUE(s) (((s) >> 8) & 0x1f) | 119 | #define SEQ_TO_QUEUE(s) (((s) >> 8) & 0x1f) |
120 | #define QUEUE_TO_SEQ(q) (((q) & 0x1f) << 8) | 120 | #define QUEUE_TO_SEQ(q) (((q) & 0x1f) << 8) |
@@ -195,7 +195,7 @@ static inline u32 iwl_rx_packet_payload_len(const struct iwl_rx_packet *pkt) | |||
195 | * @CMD_WANT_SKB: Not valid with CMD_ASYNC. The caller needs the buffer of | 195 | * @CMD_WANT_SKB: Not valid with CMD_ASYNC. The caller needs the buffer of |
196 | * the response. The caller needs to call iwl_free_resp when done. | 196 | * the response. The caller needs to call iwl_free_resp when done. |
197 | * @CMD_HIGH_PRIO: The command is high priority - it goes to the front of the | 197 | * @CMD_HIGH_PRIO: The command is high priority - it goes to the front of the |
198 | * command queue, but after other high priority commands. valid only | 198 | * command queue, but after other high priority commands. Valid only |
199 | * with CMD_ASYNC. | 199 | * with CMD_ASYNC. |
200 | * @CMD_SEND_IN_IDLE: The command should be sent even when the trans is idle. | 200 | * @CMD_SEND_IN_IDLE: The command should be sent even when the trans is idle. |
201 | * @CMD_MAKE_TRANS_IDLE: The command response should mark the trans as idle. | 201 | * @CMD_MAKE_TRANS_IDLE: The command response should mark the trans as idle. |
@@ -582,7 +582,7 @@ enum iwl_d0i3_mode { | |||
582 | * @cfg - pointer to the configuration | 582 | * @cfg - pointer to the configuration |
583 | * @status: a bit-mask of transport status flags | 583 | * @status: a bit-mask of transport status flags |
584 | * @dev - pointer to struct device * that represents the device | 584 | * @dev - pointer to struct device * that represents the device |
585 | * @hw_id: a u32 with the ID of the device / subdevice. | 585 | * @hw_id: a u32 with the ID of the device / sub-device. |
586 | * Set during transport allocation. | 586 | * Set during transport allocation. |
587 | * @hw_id_str: a string with info about HW ID. Set during transport allocation. | 587 | * @hw_id_str: a string with info about HW ID. Set during transport allocation. |
588 | * @pm_support: set to true in start_hw if link pm is supported | 588 | * @pm_support: set to true in start_hw if link pm is supported |
diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c index 5f8afa5f11a3..a6c48c7b1e16 100644 --- a/drivers/net/wireless/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/iwlwifi/mvm/d3.c | |||
@@ -1131,6 +1131,7 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw, | |||
1131 | iwl_trans_d3_suspend(mvm->trans, test); | 1131 | iwl_trans_d3_suspend(mvm->trans, test); |
1132 | out: | 1132 | out: |
1133 | if (ret < 0) { | 1133 | if (ret < 0) { |
1134 | iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN); | ||
1134 | ieee80211_restart_hw(mvm->hw); | 1135 | ieee80211_restart_hw(mvm->hw); |
1135 | iwl_mvm_free_nd(mvm); | 1136 | iwl_mvm_free_nd(mvm); |
1136 | } | 1137 | } |
@@ -1725,6 +1726,10 @@ iwl_mvm_netdetect_query_results(struct iwl_mvm *mvm, | |||
1725 | results->matched_profiles = le32_to_cpu(query->matched_profiles); | 1726 | results->matched_profiles = le32_to_cpu(query->matched_profiles); |
1726 | memcpy(results->matches, query->matches, sizeof(results->matches)); | 1727 | memcpy(results->matches, query->matches, sizeof(results->matches)); |
1727 | 1728 | ||
1729 | #ifdef CPTCFG_IWLWIFI_DEBUGFS | ||
1730 | mvm->last_netdetect_scans = le32_to_cpu(query->n_scans_done); | ||
1731 | #endif | ||
1732 | |||
1728 | out_free_resp: | 1733 | out_free_resp: |
1729 | iwl_free_resp(&cmd); | 1734 | iwl_free_resp(&cmd); |
1730 | return ret; | 1735 | return ret; |
@@ -2016,6 +2021,7 @@ static int iwl_mvm_d3_test_release(struct inode *inode, struct file *file) | |||
2016 | __iwl_mvm_resume(mvm, true); | 2021 | __iwl_mvm_resume(mvm, true); |
2017 | rtnl_unlock(); | 2022 | rtnl_unlock(); |
2018 | iwl_abort_notification_waits(&mvm->notif_wait); | 2023 | iwl_abort_notification_waits(&mvm->notif_wait); |
2024 | iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN); | ||
2019 | ieee80211_restart_hw(mvm->hw); | 2025 | ieee80211_restart_hw(mvm->hw); |
2020 | 2026 | ||
2021 | /* wait for restart and disconnect all interfaces */ | 2027 | /* wait for restart and disconnect all interfaces */ |
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c index 8c5229892e57..9ac04c1ea706 100644 --- a/drivers/net/wireless/iwlwifi/mvm/debugfs.c +++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c | |||
@@ -1473,26 +1473,6 @@ out: | |||
1473 | return count; | 1473 | return count; |
1474 | } | 1474 | } |
1475 | 1475 | ||
1476 | static ssize_t iwl_dbgfs_enable_scan_iteration_notif_write(struct iwl_mvm *mvm, | ||
1477 | char *buf, | ||
1478 | size_t count, | ||
1479 | loff_t *ppos) | ||
1480 | { | ||
1481 | int val; | ||
1482 | |||
1483 | mutex_lock(&mvm->mutex); | ||
1484 | |||
1485 | if (kstrtoint(buf, 10, &val)) { | ||
1486 | mutex_unlock(&mvm->mutex); | ||
1487 | return -EINVAL; | ||
1488 | } | ||
1489 | |||
1490 | mvm->scan_iter_notif_enabled = val; | ||
1491 | mutex_unlock(&mvm->mutex); | ||
1492 | |||
1493 | return count; | ||
1494 | } | ||
1495 | |||
1496 | MVM_DEBUGFS_READ_WRITE_FILE_OPS(prph_reg, 64); | 1476 | MVM_DEBUGFS_READ_WRITE_FILE_OPS(prph_reg, 64); |
1497 | 1477 | ||
1498 | /* Device wide debugfs entries */ | 1478 | /* Device wide debugfs entries */ |
@@ -1515,7 +1495,6 @@ MVM_DEBUGFS_READ_WRITE_FILE_OPS(scan_ant_rxchain, 8); | |||
1515 | MVM_DEBUGFS_READ_WRITE_FILE_OPS(d0i3_refs, 8); | 1495 | MVM_DEBUGFS_READ_WRITE_FILE_OPS(d0i3_refs, 8); |
1516 | MVM_DEBUGFS_READ_WRITE_FILE_OPS(fw_dbg_conf, 8); | 1496 | MVM_DEBUGFS_READ_WRITE_FILE_OPS(fw_dbg_conf, 8); |
1517 | MVM_DEBUGFS_WRITE_FILE_OPS(fw_dbg_collect, 8); | 1497 | MVM_DEBUGFS_WRITE_FILE_OPS(fw_dbg_collect, 8); |
1518 | MVM_DEBUGFS_WRITE_FILE_OPS(enable_scan_iteration_notif, 8); | ||
1519 | 1498 | ||
1520 | #ifdef CONFIG_IWLWIFI_BCAST_FILTERING | 1499 | #ifdef CONFIG_IWLWIFI_BCAST_FILTERING |
1521 | MVM_DEBUGFS_READ_WRITE_FILE_OPS(bcast_filters, 256); | 1500 | MVM_DEBUGFS_READ_WRITE_FILE_OPS(bcast_filters, 256); |
@@ -1559,8 +1538,11 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir) | |||
1559 | MVM_DEBUGFS_ADD_FILE(d0i3_refs, mvm->debugfs_dir, S_IRUSR | S_IWUSR); | 1538 | MVM_DEBUGFS_ADD_FILE(d0i3_refs, mvm->debugfs_dir, S_IRUSR | S_IWUSR); |
1560 | MVM_DEBUGFS_ADD_FILE(fw_dbg_conf, mvm->debugfs_dir, S_IRUSR | S_IWUSR); | 1539 | MVM_DEBUGFS_ADD_FILE(fw_dbg_conf, mvm->debugfs_dir, S_IRUSR | S_IWUSR); |
1561 | MVM_DEBUGFS_ADD_FILE(fw_dbg_collect, mvm->debugfs_dir, S_IWUSR); | 1540 | MVM_DEBUGFS_ADD_FILE(fw_dbg_collect, mvm->debugfs_dir, S_IWUSR); |
1562 | MVM_DEBUGFS_ADD_FILE(enable_scan_iteration_notif, mvm->debugfs_dir, | 1541 | if (!debugfs_create_bool("enable_scan_iteration_notif", |
1563 | S_IWUSR); | 1542 | S_IRUSR | S_IWUSR, |
1543 | mvm->debugfs_dir, | ||
1544 | &mvm->scan_iter_notif_enabled)) | ||
1545 | goto err; | ||
1564 | 1546 | ||
1565 | #ifdef CONFIG_IWLWIFI_BCAST_FILTERING | 1547 | #ifdef CONFIG_IWLWIFI_BCAST_FILTERING |
1566 | if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_BCAST_FILTERING) { | 1548 | if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_BCAST_FILTERING) { |
@@ -1587,6 +1569,9 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir) | |||
1587 | if (!debugfs_create_bool("d3_wake_sysassert", S_IRUSR | S_IWUSR, | 1569 | if (!debugfs_create_bool("d3_wake_sysassert", S_IRUSR | S_IWUSR, |
1588 | mvm->debugfs_dir, &mvm->d3_wake_sysassert)) | 1570 | mvm->debugfs_dir, &mvm->d3_wake_sysassert)) |
1589 | goto err; | 1571 | goto err; |
1572 | if (!debugfs_create_u32("last_netdetect_scans", S_IRUSR, | ||
1573 | mvm->debugfs_dir, &mvm->last_netdetect_scans)) | ||
1574 | goto err; | ||
1590 | MVM_DEBUGFS_ADD_FILE(netdetect, mvm->debugfs_dir, S_IRUSR | S_IWUSR); | 1575 | MVM_DEBUGFS_ADD_FILE(netdetect, mvm->debugfs_dir, S_IRUSR | S_IWUSR); |
1591 | #endif | 1576 | #endif |
1592 | 1577 | ||
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h index 6d3bea5c59d1..d7658d16e965 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h | |||
@@ -132,7 +132,7 @@ struct iwl_proto_offload_cmd_common { | |||
132 | * @solicited_node_ipv6_addr: broken -- solicited node address exists | 132 | * @solicited_node_ipv6_addr: broken -- solicited node address exists |
133 | * for each target address | 133 | * for each target address |
134 | * @target_ipv6_addr: our target addresses | 134 | * @target_ipv6_addr: our target addresses |
135 | * @ndp_mac_addr: neighbor soliciation response MAC address | 135 | * @ndp_mac_addr: neighbor solicitation response MAC address |
136 | */ | 136 | */ |
137 | struct iwl_proto_offload_cmd_v1 { | 137 | struct iwl_proto_offload_cmd_v1 { |
138 | struct iwl_proto_offload_cmd_common common; | 138 | struct iwl_proto_offload_cmd_common common; |
@@ -150,7 +150,7 @@ struct iwl_proto_offload_cmd_v1 { | |||
150 | * @solicited_node_ipv6_addr: broken -- solicited node address exists | 150 | * @solicited_node_ipv6_addr: broken -- solicited node address exists |
151 | * for each target address | 151 | * for each target address |
152 | * @target_ipv6_addr: our target addresses | 152 | * @target_ipv6_addr: our target addresses |
153 | * @ndp_mac_addr: neighbor soliciation response MAC address | 153 | * @ndp_mac_addr: neighbor solicitation response MAC address |
154 | */ | 154 | */ |
155 | struct iwl_proto_offload_cmd_v2 { | 155 | struct iwl_proto_offload_cmd_v2 { |
156 | struct iwl_proto_offload_cmd_common common; | 156 | struct iwl_proto_offload_cmd_common common; |
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h index aabaedd3b3ee..f3f3ee0a766b 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h | |||
@@ -255,7 +255,7 @@ struct iwl_mac_data_p2p_dev { | |||
255 | /** | 255 | /** |
256 | * enum iwl_mac_filter_flags - MAC context filter flags | 256 | * enum iwl_mac_filter_flags - MAC context filter flags |
257 | * @MAC_FILTER_IN_PROMISC: accept all data frames | 257 | * @MAC_FILTER_IN_PROMISC: accept all data frames |
258 | * @MAC_FILTER_IN_CONTROL_AND_MGMT: pass all mangement and | 258 | * @MAC_FILTER_IN_CONTROL_AND_MGMT: pass all management and |
259 | * control frames to the host | 259 | * control frames to the host |
260 | * @MAC_FILTER_ACCEPT_GRP: accept multicast frames | 260 | * @MAC_FILTER_ACCEPT_GRP: accept multicast frames |
261 | * @MAC_FILTER_DIS_DECRYPT: don't decrypt unicast frames | 261 | * @MAC_FILTER_DIS_DECRYPT: don't decrypt unicast frames |
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h index a5fbbd637070..4f81dcf57a73 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h | |||
@@ -103,7 +103,7 @@ struct iwl_ssid_ie { | |||
103 | * @SCAN_COMP_STATUS_ERR_COEX: medium was lost ot WiMax | 103 | * @SCAN_COMP_STATUS_ERR_COEX: medium was lost ot WiMax |
104 | * @SCAN_COMP_STATUS_P2P_ACTION_OK: P2P public action frame TX was successful | 104 | * @SCAN_COMP_STATUS_P2P_ACTION_OK: P2P public action frame TX was successful |
105 | * (not an error!) | 105 | * (not an error!) |
106 | * @SCAN_COMP_STATUS_ITERATION_END: indicates end of one repeatition the driver | 106 | * @SCAN_COMP_STATUS_ITERATION_END: indicates end of one repetition the driver |
107 | * asked for | 107 | * asked for |
108 | * @SCAN_COMP_STATUS_ERR_ALLOC_TE: scan could not allocate time events | 108 | * @SCAN_COMP_STATUS_ERR_ALLOC_TE: scan could not allocate time events |
109 | */ | 109 | */ |
@@ -187,11 +187,11 @@ enum scan_framework_client { | |||
187 | * struct iwl_scan_offload_cmd - SCAN_REQUEST_FIXED_PART_API_S_VER_6 | 187 | * struct iwl_scan_offload_cmd - SCAN_REQUEST_FIXED_PART_API_S_VER_6 |
188 | * @scan_flags: see enum iwl_scan_flags | 188 | * @scan_flags: see enum iwl_scan_flags |
189 | * @channel_count: channels in channel list | 189 | * @channel_count: channels in channel list |
190 | * @quiet_time: dwell time, in milisiconds, on quiet channel | 190 | * @quiet_time: dwell time, in milliseconds, on quiet channel |
191 | * @quiet_plcp_th: quiet channel num of packets threshold | 191 | * @quiet_plcp_th: quiet channel num of packets threshold |
192 | * @good_CRC_th: passive to active promotion threshold | 192 | * @good_CRC_th: passive to active promotion threshold |
193 | * @rx_chain: RXON rx chain. | 193 | * @rx_chain: RXON rx chain. |
194 | * @max_out_time: max TUs to be out of assoceated channel | 194 | * @max_out_time: max TUs to be out of associated channel |
195 | * @suspend_time: pause scan this TUs when returning to service channel | 195 | * @suspend_time: pause scan this TUs when returning to service channel |
196 | * @flags: RXON flags | 196 | * @flags: RXON flags |
197 | * @filter_flags: RXONfilter | 197 | * @filter_flags: RXONfilter |
@@ -232,7 +232,7 @@ enum iwl_scan_offload_channel_flags { | |||
232 | * see enum iwl_scan_offload_channel_flags. | 232 | * see enum iwl_scan_offload_channel_flags. |
233 | * __le16 channel_number: channel number 1-13 etc. | 233 | * __le16 channel_number: channel number 1-13 etc. |
234 | * __le16 iter_count: repetition count for the channel. | 234 | * __le16 iter_count: repetition count for the channel. |
235 | * __le32 iter_interval: interval between two innteration on one channel. | 235 | * __le32 iter_interval: interval between two iterations on one channel. |
236 | * u8 active_dwell. | 236 | * u8 active_dwell. |
237 | * u8 passive_dwell. | 237 | * u8 passive_dwell. |
238 | */ | 238 | */ |
@@ -275,8 +275,8 @@ enum iwl_scan_offload_band_selection { | |||
275 | /** | 275 | /** |
276 | * iwl_scan_offload_profile - SCAN_OFFLOAD_PROFILE_S | 276 | * iwl_scan_offload_profile - SCAN_OFFLOAD_PROFILE_S |
277 | * @ssid_index: index to ssid list in fixed part | 277 | * @ssid_index: index to ssid list in fixed part |
278 | * @unicast_cipher: encryption olgorithm to match - bitmap | 278 | * @unicast_cipher: encryption algorithm to match - bitmap |
279 | * @aut_alg: authentication olgorithm to match - bitmap | 279 | * @aut_alg: authentication algorithm to match - bitmap |
280 | * @network_type: enum iwl_scan_offload_network_type | 280 | * @network_type: enum iwl_scan_offload_network_type |
281 | * @band_selection: enum iwl_scan_offload_band_selection | 281 | * @band_selection: enum iwl_scan_offload_band_selection |
282 | * @client_bitmap: clients waiting for match - enum scan_framework_client | 282 | * @client_bitmap: clients waiting for match - enum scan_framework_client |
@@ -748,7 +748,7 @@ enum iwl_umac_scan_general_flags { | |||
748 | * @flags: bitmap - 0-19: directed scan to i'th ssid. | 748 | * @flags: bitmap - 0-19: directed scan to i'th ssid. |
749 | * @channel_num: channel number 1-13 etc. | 749 | * @channel_num: channel number 1-13 etc. |
750 | * @iter_count: repetition count for the channel. | 750 | * @iter_count: repetition count for the channel. |
751 | * @iter_interval: interval between two scan interations on one channel. | 751 | * @iter_interval: interval between two scan iterations on one channel. |
752 | */ | 752 | */ |
753 | struct iwl_scan_channel_cfg_umac { | 753 | struct iwl_scan_channel_cfg_umac { |
754 | __le32 flags; | 754 | __le32 flags; |
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c index 6cf7d9837ca5..bc5eac4960e1 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/iwlwifi/mvm/fw.c | |||
@@ -526,16 +526,33 @@ int iwl_mvm_fw_dbg_collect(struct iwl_mvm *mvm, enum iwl_fw_dbg_trigger trig, | |||
526 | 526 | ||
527 | int iwl_mvm_fw_dbg_collect_trig(struct iwl_mvm *mvm, | 527 | int iwl_mvm_fw_dbg_collect_trig(struct iwl_mvm *mvm, |
528 | struct iwl_fw_dbg_trigger_tlv *trigger, | 528 | struct iwl_fw_dbg_trigger_tlv *trigger, |
529 | const char *str, size_t len) | 529 | const char *fmt, ...) |
530 | { | 530 | { |
531 | unsigned int delay = msecs_to_jiffies(le32_to_cpu(trigger->stop_delay)); | 531 | unsigned int delay = msecs_to_jiffies(le32_to_cpu(trigger->stop_delay)); |
532 | u16 occurrences = le16_to_cpu(trigger->occurrences); | 532 | u16 occurrences = le16_to_cpu(trigger->occurrences); |
533 | int ret; | 533 | int ret, len = 0; |
534 | char buf[64]; | ||
534 | 535 | ||
535 | if (!occurrences) | 536 | if (!occurrences) |
536 | return 0; | 537 | return 0; |
537 | 538 | ||
538 | ret = iwl_mvm_fw_dbg_collect(mvm, le32_to_cpu(trigger->id), str, | 539 | if (fmt) { |
540 | va_list ap; | ||
541 | |||
542 | buf[sizeof(buf) - 1] = '\0'; | ||
543 | |||
544 | va_start(ap, fmt); | ||
545 | vsnprintf(buf, sizeof(buf), fmt, ap); | ||
546 | va_end(ap); | ||
547 | |||
548 | /* check for truncation */ | ||
549 | if (WARN_ON_ONCE(buf[sizeof(buf) - 1])) | ||
550 | buf[sizeof(buf) - 1] = '\0'; | ||
551 | |||
552 | len = strlen(buf) + 1; | ||
553 | } | ||
554 | |||
555 | ret = iwl_mvm_fw_dbg_collect(mvm, le32_to_cpu(trigger->id), buf, | ||
539 | len, delay); | 556 | len, delay); |
540 | if (ret) | 557 | if (ret) |
541 | return ret; | 558 | return ret; |
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c index 581b3b8f29f9..8088c7137f7c 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c | |||
@@ -470,9 +470,8 @@ exit_fail: | |||
470 | 470 | ||
471 | int iwl_mvm_mac_ctxt_init(struct iwl_mvm *mvm, struct ieee80211_vif *vif) | 471 | int iwl_mvm_mac_ctxt_init(struct iwl_mvm *mvm, struct ieee80211_vif *vif) |
472 | { | 472 | { |
473 | unsigned int wdg_timeout = iwlmvm_mod_params.tfd_q_hang_detect ? | 473 | unsigned int wdg_timeout = |
474 | mvm->cfg->base_params->wd_timeout : | 474 | iwl_mvm_get_wd_timeout(mvm, vif, false, false); |
475 | IWL_WATCHDOG_DISABLED; | ||
476 | u32 ac; | 475 | u32 ac; |
477 | int ret; | 476 | int ret; |
478 | 477 | ||
@@ -1413,7 +1412,7 @@ static void iwl_mvm_beacon_loss_iterator(void *_data, u8 *mac, | |||
1413 | 1412 | ||
1414 | if (rx_missed_bcon_since_rx >= stop_trig_missed_bcon_since_rx || | 1413 | if (rx_missed_bcon_since_rx >= stop_trig_missed_bcon_since_rx || |
1415 | rx_missed_bcon >= stop_trig_missed_bcon) | 1414 | rx_missed_bcon >= stop_trig_missed_bcon) |
1416 | iwl_mvm_fw_dbg_collect_trig(mvm, trigger, NULL, 0); | 1415 | iwl_mvm_fw_dbg_collect_trig(mvm, trigger, NULL); |
1417 | } | 1416 | } |
1418 | 1417 | ||
1419 | int iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm, | 1418 | int iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm, |
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 302c8cc50f25..84555170b6f7 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c | |||
@@ -379,11 +379,13 @@ int iwl_mvm_init_fw_regd(struct iwl_mvm *mvm) | |||
379 | { | 379 | { |
380 | enum iwl_mcc_source used_src; | 380 | enum iwl_mcc_source used_src; |
381 | struct ieee80211_regdomain *regd; | 381 | struct ieee80211_regdomain *regd; |
382 | int ret; | ||
383 | bool changed; | ||
382 | const struct ieee80211_regdomain *r = | 384 | const struct ieee80211_regdomain *r = |
383 | rtnl_dereference(mvm->hw->wiphy->regd); | 385 | rtnl_dereference(mvm->hw->wiphy->regd); |
384 | 386 | ||
385 | if (!r) | 387 | if (!r) |
386 | return 0; | 388 | return -ENOENT; |
387 | 389 | ||
388 | /* save the last source in case we overwrite it below */ | 390 | /* save the last source in case we overwrite it below */ |
389 | used_src = mvm->mcc_src; | 391 | used_src = mvm->mcc_src; |
@@ -395,14 +397,19 @@ int iwl_mvm_init_fw_regd(struct iwl_mvm *mvm) | |||
395 | } | 397 | } |
396 | 398 | ||
397 | /* Now set our last stored MCC and source */ | 399 | /* Now set our last stored MCC and source */ |
398 | regd = iwl_mvm_get_regdomain(mvm->hw->wiphy, r->alpha2, used_src, NULL); | 400 | regd = iwl_mvm_get_regdomain(mvm->hw->wiphy, r->alpha2, used_src, |
401 | &changed); | ||
399 | if (IS_ERR_OR_NULL(regd)) | 402 | if (IS_ERR_OR_NULL(regd)) |
400 | return -EIO; | 403 | return -EIO; |
401 | 404 | ||
402 | regulatory_set_wiphy_regd(mvm->hw->wiphy, regd); | 405 | /* update cfg80211 if the regdomain was changed */ |
403 | kfree(regd); | 406 | if (changed) |
407 | ret = regulatory_set_wiphy_regd_sync_rtnl(mvm->hw->wiphy, regd); | ||
408 | else | ||
409 | ret = 0; | ||
404 | 410 | ||
405 | return 0; | 411 | kfree(regd); |
412 | return ret; | ||
406 | } | 413 | } |
407 | 414 | ||
408 | int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) | 415 | int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) |
@@ -1007,6 +1014,9 @@ void iwl_mvm_free_fw_dump_desc(struct iwl_mvm *mvm) | |||
1007 | mvm->fw_dump_desc = NULL; | 1014 | mvm->fw_dump_desc = NULL; |
1008 | } | 1015 | } |
1009 | 1016 | ||
1017 | #define IWL8260_ICCM_OFFSET 0x44000 /* Only for B-step */ | ||
1018 | #define IWL8260_ICCM_LEN 0xC000 /* Only for B-step */ | ||
1019 | |||
1010 | void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm) | 1020 | void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm) |
1011 | { | 1021 | { |
1012 | struct iwl_fw_error_dump_file *dump_file; | 1022 | struct iwl_fw_error_dump_file *dump_file; |
@@ -1022,16 +1032,6 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm) | |||
1022 | 1032 | ||
1023 | lockdep_assert_held(&mvm->mutex); | 1033 | lockdep_assert_held(&mvm->mutex); |
1024 | 1034 | ||
1025 | /* W/A for 8000 HW family A-step */ | ||
1026 | if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_8000 && | ||
1027 | CSR_HW_REV_STEP(mvm->trans->hw_rev) == SILICON_A_STEP) { | ||
1028 | if (smem_len) | ||
1029 | smem_len = 0x38000; | ||
1030 | |||
1031 | if (sram2_len) | ||
1032 | sram2_len = 0x10000; | ||
1033 | } | ||
1034 | |||
1035 | fw_error_dump = kzalloc(sizeof(*fw_error_dump), GFP_KERNEL); | 1035 | fw_error_dump = kzalloc(sizeof(*fw_error_dump), GFP_KERNEL); |
1036 | if (!fw_error_dump) | 1036 | if (!fw_error_dump) |
1037 | return; | 1037 | return; |
@@ -1083,6 +1083,14 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm) | |||
1083 | fifo_data_len + | 1083 | fifo_data_len + |
1084 | sizeof(*dump_info); | 1084 | sizeof(*dump_info); |
1085 | 1085 | ||
1086 | /* | ||
1087 | * In 8000 HW family B-step include the ICCM (which resides separately) | ||
1088 | */ | ||
1089 | if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_8000 && | ||
1090 | CSR_HW_REV_STEP(mvm->trans->hw_rev) == SILICON_B_STEP) | ||
1091 | file_len += sizeof(*dump_data) + sizeof(*dump_mem) + | ||
1092 | IWL8260_ICCM_LEN; | ||
1093 | |||
1086 | if (mvm->fw_dump_desc) | 1094 | if (mvm->fw_dump_desc) |
1087 | file_len += sizeof(*dump_data) + sizeof(*dump_trig) + | 1095 | file_len += sizeof(*dump_data) + sizeof(*dump_trig) + |
1088 | mvm->fw_dump_desc->len; | 1096 | mvm->fw_dump_desc->len; |
@@ -1170,6 +1178,19 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm) | |||
1170 | dump_mem->data, sram2_len); | 1178 | dump_mem->data, sram2_len); |
1171 | } | 1179 | } |
1172 | 1180 | ||
1181 | if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_8000 && | ||
1182 | CSR_HW_REV_STEP(mvm->trans->hw_rev) == SILICON_B_STEP) { | ||
1183 | dump_data = iwl_fw_error_next_data(dump_data); | ||
1184 | dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM); | ||
1185 | dump_data->len = cpu_to_le32(IWL8260_ICCM_LEN + | ||
1186 | sizeof(*dump_mem)); | ||
1187 | dump_mem = (void *)dump_data->data; | ||
1188 | dump_mem->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM_SRAM); | ||
1189 | dump_mem->offset = cpu_to_le32(IWL8260_ICCM_OFFSET); | ||
1190 | iwl_trans_read_mem_bytes(mvm->trans, IWL8260_ICCM_OFFSET, | ||
1191 | dump_mem->data, IWL8260_ICCM_LEN); | ||
1192 | } | ||
1193 | |||
1173 | fw_error_dump->trans_ptr = iwl_trans_dump_data(mvm->trans); | 1194 | fw_error_dump->trans_ptr = iwl_trans_dump_data(mvm->trans); |
1174 | fw_error_dump->op_mode_len = file_len; | 1195 | fw_error_dump->op_mode_len = file_len; |
1175 | if (fw_error_dump->trans_ptr) | 1196 | if (fw_error_dump->trans_ptr) |
@@ -1399,6 +1420,20 @@ void __iwl_mvm_mac_stop(struct iwl_mvm *mvm) | |||
1399 | */ | 1420 | */ |
1400 | clear_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status); | 1421 | clear_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status); |
1401 | 1422 | ||
1423 | /* We shouldn't have any UIDs still set. Loop over all the UIDs to | ||
1424 | * make sure there's nothing left there and warn if any is found. | ||
1425 | */ | ||
1426 | if (mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_UMAC_SCAN) { | ||
1427 | int i; | ||
1428 | |||
1429 | for (i = 0; i < IWL_MVM_MAX_SIMULTANEOUS_SCANS; i++) { | ||
1430 | if (WARN_ONCE(mvm->scan_uid[i], | ||
1431 | "UMAC scan UID %d was not cleaned\n", | ||
1432 | mvm->scan_uid[i])) | ||
1433 | mvm->scan_uid[i] = 0; | ||
1434 | } | ||
1435 | } | ||
1436 | |||
1402 | mvm->ucode_loaded = false; | 1437 | mvm->ucode_loaded = false; |
1403 | } | 1438 | } |
1404 | 1439 | ||
@@ -1595,9 +1630,33 @@ static void iwl_mvm_prepare_mac_removal(struct iwl_mvm *mvm, | |||
1595 | u32 tfd_msk = iwl_mvm_mac_get_queues_mask(vif); | 1630 | u32 tfd_msk = iwl_mvm_mac_get_queues_mask(vif); |
1596 | 1631 | ||
1597 | if (tfd_msk) { | 1632 | if (tfd_msk) { |
1633 | /* | ||
1634 | * mac80211 first removes all the stations of the vif and | ||
1635 | * then removes the vif. When it removes a station it also | ||
1636 | * flushes the AMPDU session. So by now, all the AMPDU sessions | ||
1637 | * of all the stations of this vif are closed, and the queues | ||
1638 | * of these AMPDU sessions are properly closed. | ||
1639 | * We still need to take care of the shared queues of the vif. | ||
1640 | * Flush them here. | ||
1641 | */ | ||
1598 | mutex_lock(&mvm->mutex); | 1642 | mutex_lock(&mvm->mutex); |
1599 | iwl_mvm_flush_tx_path(mvm, tfd_msk, true); | 1643 | iwl_mvm_flush_tx_path(mvm, tfd_msk, true); |
1600 | mutex_unlock(&mvm->mutex); | 1644 | mutex_unlock(&mvm->mutex); |
1645 | |||
1646 | /* | ||
1647 | * There are transports that buffer a few frames in the host. | ||
1648 | * For these, the flush above isn't enough since while we were | ||
1649 | * flushing, the transport might have sent more frames to the | ||
1650 | * device. To solve this, wait here until the transport is | ||
1651 | * empty. Technically, this could have replaced the flush | ||
1652 | * above, but flush is much faster than draining. So flush | ||
1653 | * first, and drain to make sure we have no frames in the | ||
1654 | * transport anymore. | ||
1655 | * If a station still had frames on the shared queues, it is | ||
1656 | * already marked as draining, so to complete the draining, we | ||
1657 | * just need to wait until the transport is empty. | ||
1658 | */ | ||
1659 | iwl_trans_wait_tx_queue_empty(mvm->trans, tfd_msk); | ||
1601 | } | 1660 | } |
1602 | 1661 | ||
1603 | if (vif->type == NL80211_IFTYPE_P2P_DEVICE) { | 1662 | if (vif->type == NL80211_IFTYPE_P2P_DEVICE) { |
@@ -2167,8 +2226,7 @@ static int iwl_mvm_start_ap_ibss(struct ieee80211_hw *hw, | |||
2167 | if (iwl_mvm_phy_ctx_count(mvm) > 1) | 2226 | if (iwl_mvm_phy_ctx_count(mvm) > 1) |
2168 | iwl_mvm_teardown_tdls_peers(mvm); | 2227 | iwl_mvm_teardown_tdls_peers(mvm); |
2169 | 2228 | ||
2170 | mutex_unlock(&mvm->mutex); | 2229 | goto out_unlock; |
2171 | return 0; | ||
2172 | 2230 | ||
2173 | out_quota_failed: | 2231 | out_quota_failed: |
2174 | iwl_mvm_power_update_mac(mvm); | 2232 | iwl_mvm_power_update_mac(mvm); |
@@ -3022,6 +3080,8 @@ static int iwl_mvm_roc(struct ieee80211_hw *hw, | |||
3022 | IWL_DEBUG_MAC80211(mvm, "enter (%d, %d, %d)\n", channel->hw_value, | 3080 | IWL_DEBUG_MAC80211(mvm, "enter (%d, %d, %d)\n", channel->hw_value, |
3023 | duration, type); | 3081 | duration, type); |
3024 | 3082 | ||
3083 | flush_work(&mvm->roc_done_wk); | ||
3084 | |||
3025 | mutex_lock(&mvm->mutex); | 3085 | mutex_lock(&mvm->mutex); |
3026 | 3086 | ||
3027 | switch (vif->type) { | 3087 | switch (vif->type) { |
@@ -3646,11 +3706,12 @@ static int iwl_mvm_pre_channel_switch(struct ieee80211_hw *hw, | |||
3646 | 3706 | ||
3647 | mutex_lock(&mvm->mutex); | 3707 | mutex_lock(&mvm->mutex); |
3648 | 3708 | ||
3709 | mvmvif->csa_failed = false; | ||
3710 | |||
3649 | IWL_DEBUG_MAC80211(mvm, "pre CSA to freq %d\n", | 3711 | IWL_DEBUG_MAC80211(mvm, "pre CSA to freq %d\n", |
3650 | chsw->chandef.center_freq1); | 3712 | chsw->chandef.center_freq1); |
3651 | 3713 | ||
3652 | iwl_fw_dbg_trigger_simple_stop(mvm, vif, FW_DBG_TRIGGER_CHANNEL_SWITCH, | 3714 | iwl_fw_dbg_trigger_simple_stop(mvm, vif, FW_DBG_TRIGGER_CHANNEL_SWITCH); |
3653 | NULL, 0); | ||
3654 | 3715 | ||
3655 | switch (vif->type) { | 3716 | switch (vif->type) { |
3656 | case NL80211_IFTYPE_AP: | 3717 | case NL80211_IFTYPE_AP: |
@@ -3721,6 +3782,12 @@ static int iwl_mvm_post_channel_switch(struct ieee80211_hw *hw, | |||
3721 | 3782 | ||
3722 | mutex_lock(&mvm->mutex); | 3783 | mutex_lock(&mvm->mutex); |
3723 | 3784 | ||
3785 | if (mvmvif->csa_failed) { | ||
3786 | mvmvif->csa_failed = false; | ||
3787 | ret = -EIO; | ||
3788 | goto out_unlock; | ||
3789 | } | ||
3790 | |||
3724 | if (vif->type == NL80211_IFTYPE_STATION) { | 3791 | if (vif->type == NL80211_IFTYPE_STATION) { |
3725 | struct iwl_mvm_sta *mvmsta; | 3792 | struct iwl_mvm_sta *mvmsta; |
3726 | 3793 | ||
@@ -3844,6 +3911,7 @@ static int iwl_mvm_mac_get_survey(struct ieee80211_hw *hw, int idx, | |||
3844 | mvm->radio_stats.on_time_scan; | 3911 | mvm->radio_stats.on_time_scan; |
3845 | do_div(survey->time_scan, USEC_PER_MSEC); | 3912 | do_div(survey->time_scan, USEC_PER_MSEC); |
3846 | 3913 | ||
3914 | ret = 0; | ||
3847 | out: | 3915 | out: |
3848 | mutex_unlock(&mvm->mutex); | 3916 | mutex_unlock(&mvm->mutex); |
3849 | return ret; | 3917 | return ret; |
@@ -3889,6 +3957,64 @@ static void iwl_mvm_mac_sta_statistics(struct ieee80211_hw *hw, | |||
3889 | mutex_unlock(&mvm->mutex); | 3957 | mutex_unlock(&mvm->mutex); |
3890 | } | 3958 | } |
3891 | 3959 | ||
3960 | static void iwl_mvm_mac_event_callback(struct ieee80211_hw *hw, | ||
3961 | struct ieee80211_vif *vif, | ||
3962 | const struct ieee80211_event *event) | ||
3963 | { | ||
3964 | #define CHECK_MLME_TRIGGER(_mvm, _trig, _buf, _cnt, _fmt...) \ | ||
3965 | do { \ | ||
3966 | if ((_cnt) && --(_cnt)) \ | ||
3967 | break; \ | ||
3968 | iwl_mvm_fw_dbg_collect_trig(_mvm, _trig, _fmt);\ | ||
3969 | } while (0) | ||
3970 | |||
3971 | struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); | ||
3972 | struct iwl_fw_dbg_trigger_tlv *trig; | ||
3973 | struct iwl_fw_dbg_trigger_mlme *trig_mlme; | ||
3974 | |||
3975 | if (!iwl_fw_dbg_trigger_enabled(mvm->fw, FW_DBG_TRIGGER_MLME)) | ||
3976 | return; | ||
3977 | |||
3978 | if (event->u.mlme.status == MLME_SUCCESS) | ||
3979 | return; | ||
3980 | |||
3981 | trig = iwl_fw_dbg_get_trigger(mvm->fw, FW_DBG_TRIGGER_MLME); | ||
3982 | trig_mlme = (void *)trig->data; | ||
3983 | if (!iwl_fw_dbg_trigger_check_stop(mvm, vif, trig)) | ||
3984 | return; | ||
3985 | |||
3986 | if (event->u.mlme.data == ASSOC_EVENT) { | ||
3987 | if (event->u.mlme.status == MLME_DENIED) | ||
3988 | CHECK_MLME_TRIGGER(mvm, trig, buf, | ||
3989 | trig_mlme->stop_assoc_denied, | ||
3990 | "DENIED ASSOC: reason %d", | ||
3991 | event->u.mlme.reason); | ||
3992 | else if (event->u.mlme.status == MLME_TIMEOUT) | ||
3993 | CHECK_MLME_TRIGGER(mvm, trig, buf, | ||
3994 | trig_mlme->stop_assoc_timeout, | ||
3995 | "ASSOC TIMEOUT"); | ||
3996 | } else if (event->u.mlme.data == AUTH_EVENT) { | ||
3997 | if (event->u.mlme.status == MLME_DENIED) | ||
3998 | CHECK_MLME_TRIGGER(mvm, trig, buf, | ||
3999 | trig_mlme->stop_auth_denied, | ||
4000 | "DENIED AUTH: reason %d", | ||
4001 | event->u.mlme.reason); | ||
4002 | else if (event->u.mlme.status == MLME_TIMEOUT) | ||
4003 | CHECK_MLME_TRIGGER(mvm, trig, buf, | ||
4004 | trig_mlme->stop_auth_timeout, | ||
4005 | "AUTH TIMEOUT"); | ||
4006 | } else if (event->u.mlme.data == DEAUTH_RX_EVENT) { | ||
4007 | CHECK_MLME_TRIGGER(mvm, trig, buf, | ||
4008 | trig_mlme->stop_rx_deauth, | ||
4009 | "DEAUTH RX %d", event->u.mlme.reason); | ||
4010 | } else if (event->u.mlme.data == DEAUTH_TX_EVENT) { | ||
4011 | CHECK_MLME_TRIGGER(mvm, trig, buf, | ||
4012 | trig_mlme->stop_tx_deauth, | ||
4013 | "DEAUTH TX %d", event->u.mlme.reason); | ||
4014 | } | ||
4015 | #undef CHECK_MLME_TRIGGER | ||
4016 | } | ||
4017 | |||
3892 | const struct ieee80211_ops iwl_mvm_hw_ops = { | 4018 | const struct ieee80211_ops iwl_mvm_hw_ops = { |
3893 | .tx = iwl_mvm_mac_tx, | 4019 | .tx = iwl_mvm_mac_tx, |
3894 | .ampdu_action = iwl_mvm_mac_ampdu_action, | 4020 | .ampdu_action = iwl_mvm_mac_ampdu_action, |
@@ -3942,6 +4068,8 @@ const struct ieee80211_ops iwl_mvm_hw_ops = { | |||
3942 | .tdls_cancel_channel_switch = iwl_mvm_tdls_cancel_channel_switch, | 4068 | .tdls_cancel_channel_switch = iwl_mvm_tdls_cancel_channel_switch, |
3943 | .tdls_recv_channel_switch = iwl_mvm_tdls_recv_channel_switch, | 4069 | .tdls_recv_channel_switch = iwl_mvm_tdls_recv_channel_switch, |
3944 | 4070 | ||
4071 | .event_callback = iwl_mvm_mac_event_callback, | ||
4072 | |||
3945 | CFG80211_TESTMODE_CMD(iwl_mvm_mac_testmode_cmd) | 4073 | CFG80211_TESTMODE_CMD(iwl_mvm_mac_testmode_cmd) |
3946 | 4074 | ||
3947 | #ifdef CONFIG_PM_SLEEP | 4075 | #ifdef CONFIG_PM_SLEEP |
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index 4b5c8f66df8b..d5522a161242 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h | |||
@@ -349,11 +349,12 @@ struct iwl_mvm_vif_bf_data { | |||
349 | * @bcast_sta: station used for broadcast packets. Used by the following | 349 | * @bcast_sta: station used for broadcast packets. Used by the following |
350 | * vifs: P2P_DEVICE, GO and AP. | 350 | * vifs: P2P_DEVICE, GO and AP. |
351 | * @beacon_skb: the skb used to hold the AP/GO beacon template | 351 | * @beacon_skb: the skb used to hold the AP/GO beacon template |
352 | * @smps_requests: the SMPS requests of differents parts of the driver, | 352 | * @smps_requests: the SMPS requests of different parts of the driver, |
353 | * combined on update to yield the overall request to mac80211. | 353 | * combined on update to yield the overall request to mac80211. |
354 | * @beacon_stats: beacon statistics, containing the # of received beacons, | 354 | * @beacon_stats: beacon statistics, containing the # of received beacons, |
355 | * # of received beacons accumulated over FW restart, and the current | 355 | * # of received beacons accumulated over FW restart, and the current |
356 | * average signal of beacons retrieved from the firmware | 356 | * average signal of beacons retrieved from the firmware |
357 | * @csa_failed: CSA failed to schedule time event, report an error later | ||
357 | */ | 358 | */ |
358 | struct iwl_mvm_vif { | 359 | struct iwl_mvm_vif { |
359 | struct iwl_mvm *mvm; | 360 | struct iwl_mvm *mvm; |
@@ -433,6 +434,7 @@ struct iwl_mvm_vif { | |||
433 | 434 | ||
434 | /* Indicates that CSA countdown may be started */ | 435 | /* Indicates that CSA countdown may be started */ |
435 | bool csa_countdown; | 436 | bool csa_countdown; |
437 | bool csa_failed; | ||
436 | }; | 438 | }; |
437 | 439 | ||
438 | static inline struct iwl_mvm_vif * | 440 | static inline struct iwl_mvm_vif * |
@@ -686,7 +688,7 @@ struct iwl_mvm { | |||
686 | bool disable_power_off; | 688 | bool disable_power_off; |
687 | bool disable_power_off_d3; | 689 | bool disable_power_off_d3; |
688 | 690 | ||
689 | bool scan_iter_notif_enabled; | 691 | u32 scan_iter_notif_enabled; /* must be u32 for debugfs_create_bool */ |
690 | 692 | ||
691 | struct debugfs_blob_wrapper nvm_hw_blob; | 693 | struct debugfs_blob_wrapper nvm_hw_blob; |
692 | struct debugfs_blob_wrapper nvm_sw_blob; | 694 | struct debugfs_blob_wrapper nvm_sw_blob; |
@@ -746,6 +748,7 @@ struct iwl_mvm { | |||
746 | void *d3_resume_sram; | 748 | void *d3_resume_sram; |
747 | u32 d3_test_pme_ptr; | 749 | u32 d3_test_pme_ptr; |
748 | struct ieee80211_vif *keep_vif; | 750 | struct ieee80211_vif *keep_vif; |
751 | u32 last_netdetect_scans; /* no. of scans in the last net-detect wake */ | ||
749 | #endif | 752 | #endif |
750 | #endif | 753 | #endif |
751 | 754 | ||
@@ -934,7 +937,8 @@ static inline bool iwl_mvm_is_lar_supported(struct iwl_mvm *mvm) | |||
934 | 937 | ||
935 | static inline bool iwl_mvm_is_wifi_mcc_supported(struct iwl_mvm *mvm) | 938 | static inline bool iwl_mvm_is_wifi_mcc_supported(struct iwl_mvm *mvm) |
936 | { | 939 | { |
937 | return mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_WIFI_MCC_UPDATE; | 940 | return mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_WIFI_MCC_UPDATE || |
941 | mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_LAR_MULTI_MCC; | ||
938 | } | 942 | } |
939 | 943 | ||
940 | static inline bool iwl_mvm_is_scd_cfg_supported(struct iwl_mvm *mvm) | 944 | static inline bool iwl_mvm_is_scd_cfg_supported(struct iwl_mvm *mvm) |
@@ -1146,6 +1150,7 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm, bool force_upload, | |||
1146 | int iwl_mvm_scan_size(struct iwl_mvm *mvm); | 1150 | int iwl_mvm_scan_size(struct iwl_mvm *mvm); |
1147 | int iwl_mvm_cancel_scan(struct iwl_mvm *mvm); | 1151 | int iwl_mvm_cancel_scan(struct iwl_mvm *mvm); |
1148 | int iwl_mvm_max_scan_ie_len(struct iwl_mvm *mvm, bool is_sched_scan); | 1152 | int iwl_mvm_max_scan_ie_len(struct iwl_mvm *mvm, bool is_sched_scan); |
1153 | void iwl_mvm_report_scan_aborted(struct iwl_mvm *mvm); | ||
1149 | 1154 | ||
1150 | /* Scheduled scan */ | 1155 | /* Scheduled scan */ |
1151 | int iwl_mvm_rx_scan_offload_complete_notif(struct iwl_mvm *mvm, | 1156 | int iwl_mvm_rx_scan_offload_complete_notif(struct iwl_mvm *mvm, |
@@ -1475,8 +1480,12 @@ int iwl_mvm_fw_dbg_collect_desc(struct iwl_mvm *mvm, | |||
1475 | void iwl_mvm_free_fw_dump_desc(struct iwl_mvm *mvm); | 1480 | void iwl_mvm_free_fw_dump_desc(struct iwl_mvm *mvm); |
1476 | int iwl_mvm_fw_dbg_collect_trig(struct iwl_mvm *mvm, | 1481 | int iwl_mvm_fw_dbg_collect_trig(struct iwl_mvm *mvm, |
1477 | struct iwl_fw_dbg_trigger_tlv *trigger, | 1482 | struct iwl_fw_dbg_trigger_tlv *trigger, |
1478 | const char *str, size_t len); | 1483 | const char *fmt, ...) __printf(3, 4); |
1479 | 1484 | unsigned int iwl_mvm_get_wd_timeout(struct iwl_mvm *mvm, | |
1485 | struct ieee80211_vif *vif, | ||
1486 | bool tdls, bool cmd_q); | ||
1487 | void iwl_mvm_connection_loss(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | ||
1488 | const char *errmsg); | ||
1480 | static inline bool | 1489 | static inline bool |
1481 | iwl_fw_dbg_trigger_vif_match(struct iwl_fw_dbg_trigger_tlv *trig, | 1490 | iwl_fw_dbg_trigger_vif_match(struct iwl_fw_dbg_trigger_tlv *trig, |
1482 | struct ieee80211_vif *vif) | 1491 | struct ieee80211_vif *vif) |
@@ -1509,8 +1518,7 @@ iwl_fw_dbg_trigger_check_stop(struct iwl_mvm *mvm, | |||
1509 | static inline void | 1518 | static inline void |
1510 | iwl_fw_dbg_trigger_simple_stop(struct iwl_mvm *mvm, | 1519 | iwl_fw_dbg_trigger_simple_stop(struct iwl_mvm *mvm, |
1511 | struct ieee80211_vif *vif, | 1520 | struct ieee80211_vif *vif, |
1512 | enum iwl_fw_dbg_trigger trig, | 1521 | enum iwl_fw_dbg_trigger trig) |
1513 | const char *str, size_t len) | ||
1514 | { | 1522 | { |
1515 | struct iwl_fw_dbg_trigger_tlv *trigger; | 1523 | struct iwl_fw_dbg_trigger_tlv *trigger; |
1516 | 1524 | ||
@@ -1521,7 +1529,7 @@ iwl_fw_dbg_trigger_simple_stop(struct iwl_mvm *mvm, | |||
1521 | if (!iwl_fw_dbg_trigger_check_stop(mvm, vif, trigger)) | 1529 | if (!iwl_fw_dbg_trigger_check_stop(mvm, vif, trigger)) |
1522 | return; | 1530 | return; |
1523 | 1531 | ||
1524 | iwl_mvm_fw_dbg_collect_trig(mvm, trigger, str, len); | 1532 | iwl_mvm_fw_dbg_collect_trig(mvm, trigger, NULL); |
1525 | } | 1533 | } |
1526 | 1534 | ||
1527 | #endif /* __IWL_MVM_H__ */ | 1535 | #endif /* __IWL_MVM_H__ */ |
diff --git a/drivers/net/wireless/iwlwifi/mvm/nvm.c b/drivers/net/wireless/iwlwifi/mvm/nvm.c index 123e0a16aea8..87b2a30a2308 100644 --- a/drivers/net/wireless/iwlwifi/mvm/nvm.c +++ b/drivers/net/wireless/iwlwifi/mvm/nvm.c | |||
@@ -77,8 +77,7 @@ | |||
77 | /* Default NVM size to read */ | 77 | /* Default NVM size to read */ |
78 | #define IWL_NVM_DEFAULT_CHUNK_SIZE (2*1024) | 78 | #define IWL_NVM_DEFAULT_CHUNK_SIZE (2*1024) |
79 | #define IWL_MAX_NVM_SECTION_SIZE 0x1b58 | 79 | #define IWL_MAX_NVM_SECTION_SIZE 0x1b58 |
80 | #define IWL_MAX_NVM_8000A_SECTION_SIZE 0xffc | 80 | #define IWL_MAX_NVM_8000_SECTION_SIZE 0x1ffc |
81 | #define IWL_MAX_NVM_8000B_SECTION_SIZE 0x1ffc | ||
82 | 81 | ||
83 | #define NVM_WRITE_OPCODE 1 | 82 | #define NVM_WRITE_OPCODE 1 |
84 | #define NVM_READ_OPCODE 0 | 83 | #define NVM_READ_OPCODE 0 |
@@ -267,7 +266,7 @@ iwl_parse_nvm_sections(struct iwl_mvm *mvm) | |||
267 | { | 266 | { |
268 | struct iwl_nvm_section *sections = mvm->nvm_sections; | 267 | struct iwl_nvm_section *sections = mvm->nvm_sections; |
269 | const __le16 *hw, *sw, *calib, *regulatory, *mac_override, *phy_sku; | 268 | const __le16 *hw, *sw, *calib, *regulatory, *mac_override, *phy_sku; |
270 | bool is_family_8000_a_step = false, lar_enabled; | 269 | bool lar_enabled; |
271 | u32 mac_addr0, mac_addr1; | 270 | u32 mac_addr0, mac_addr1; |
272 | 271 | ||
273 | /* Checking for required sections */ | 272 | /* Checking for required sections */ |
@@ -293,12 +292,8 @@ iwl_parse_nvm_sections(struct iwl_mvm *mvm) | |||
293 | return NULL; | 292 | return NULL; |
294 | } | 293 | } |
295 | 294 | ||
296 | if (CSR_HW_REV_STEP(mvm->trans->hw_rev) == SILICON_A_STEP) | ||
297 | is_family_8000_a_step = true; | ||
298 | |||
299 | /* PHY_SKU section is mandatory in B0 */ | 295 | /* PHY_SKU section is mandatory in B0 */ |
300 | if (!is_family_8000_a_step && | 296 | if (!mvm->nvm_sections[NVM_SECTION_TYPE_PHY_SKU].data) { |
301 | !mvm->nvm_sections[NVM_SECTION_TYPE_PHY_SKU].data) { | ||
302 | IWL_ERR(mvm, | 297 | IWL_ERR(mvm, |
303 | "Can't parse phy_sku in B0, empty sections\n"); | 298 | "Can't parse phy_sku in B0, empty sections\n"); |
304 | return NULL; | 299 | return NULL; |
@@ -327,8 +322,7 @@ iwl_parse_nvm_sections(struct iwl_mvm *mvm) | |||
327 | return iwl_parse_nvm_data(mvm->trans->dev, mvm->cfg, hw, sw, calib, | 322 | return iwl_parse_nvm_data(mvm->trans->dev, mvm->cfg, hw, sw, calib, |
328 | regulatory, mac_override, phy_sku, | 323 | regulatory, mac_override, phy_sku, |
329 | mvm->fw->valid_tx_ant, mvm->fw->valid_rx_ant, | 324 | mvm->fw->valid_tx_ant, mvm->fw->valid_rx_ant, |
330 | lar_enabled, is_family_8000_a_step, | 325 | lar_enabled, mac_addr0, mac_addr1); |
331 | mac_addr0, mac_addr1); | ||
332 | } | 326 | } |
333 | 327 | ||
334 | #define MAX_NVM_FILE_LEN 16384 | 328 | #define MAX_NVM_FILE_LEN 16384 |
@@ -381,10 +375,8 @@ static int iwl_mvm_read_external_nvm(struct iwl_mvm *mvm) | |||
381 | /* Maximal size depends on HW family and step */ | 375 | /* Maximal size depends on HW family and step */ |
382 | if (mvm->trans->cfg->device_family != IWL_DEVICE_FAMILY_8000) | 376 | if (mvm->trans->cfg->device_family != IWL_DEVICE_FAMILY_8000) |
383 | max_section_size = IWL_MAX_NVM_SECTION_SIZE; | 377 | max_section_size = IWL_MAX_NVM_SECTION_SIZE; |
384 | else if (CSR_HW_REV_STEP(mvm->trans->hw_rev) == SILICON_A_STEP) | 378 | else |
385 | max_section_size = IWL_MAX_NVM_8000A_SECTION_SIZE; | 379 | max_section_size = IWL_MAX_NVM_8000_SECTION_SIZE; |
386 | else /* Family 8000 B-step or C-step */ | ||
387 | max_section_size = IWL_MAX_NVM_8000B_SECTION_SIZE; | ||
388 | 380 | ||
389 | /* | 381 | /* |
390 | * Obtain NVM image via request_firmware. Since we already used | 382 | * Obtain NVM image via request_firmware. Since we already used |
@@ -426,6 +418,15 @@ static int iwl_mvm_read_external_nvm(struct iwl_mvm *mvm) | |||
426 | IWL_INFO(mvm, "NVM Version %08X\n", le32_to_cpu(dword_buff[2])); | 418 | IWL_INFO(mvm, "NVM Version %08X\n", le32_to_cpu(dword_buff[2])); |
427 | IWL_INFO(mvm, "NVM Manufacturing date %08X\n", | 419 | IWL_INFO(mvm, "NVM Manufacturing date %08X\n", |
428 | le32_to_cpu(dword_buff[3])); | 420 | le32_to_cpu(dword_buff[3])); |
421 | |||
422 | /* nvm file validation, dword_buff[2] holds the file version */ | ||
423 | if ((CSR_HW_REV_STEP(mvm->trans->hw_rev) == SILICON_C_STEP && | ||
424 | le32_to_cpu(dword_buff[2]) < 0xE4A) || | ||
425 | (CSR_HW_REV_STEP(mvm->trans->hw_rev) == SILICON_B_STEP && | ||
426 | le32_to_cpu(dword_buff[2]) >= 0xE4A)) { | ||
427 | ret = -EFAULT; | ||
428 | goto out; | ||
429 | } | ||
429 | } else { | 430 | } else { |
430 | file_sec = (void *)fw_entry->data; | 431 | file_sec = (void *)fw_entry->data; |
431 | } | 432 | } |
@@ -524,6 +525,8 @@ int iwl_nvm_init(struct iwl_mvm *mvm, bool read_nvm_from_nic) | |||
524 | int ret, section; | 525 | int ret, section; |
525 | u32 size_read = 0; | 526 | u32 size_read = 0; |
526 | u8 *nvm_buffer, *temp; | 527 | u8 *nvm_buffer, *temp; |
528 | const char *nvm_file_B = mvm->cfg->default_nvm_file_B_step; | ||
529 | const char *nvm_file_C = mvm->cfg->default_nvm_file_C_step; | ||
527 | 530 | ||
528 | if (WARN_ON_ONCE(mvm->cfg->nvm_hw_section_num >= NVM_MAX_NUM_SECTIONS)) | 531 | if (WARN_ON_ONCE(mvm->cfg->nvm_hw_section_num >= NVM_MAX_NUM_SECTIONS)) |
529 | return -EINVAL; | 532 | return -EINVAL; |
@@ -582,10 +585,27 @@ int iwl_nvm_init(struct iwl_mvm *mvm, bool read_nvm_from_nic) | |||
582 | 585 | ||
583 | /* load external NVM if configured */ | 586 | /* load external NVM if configured */ |
584 | if (mvm->nvm_file_name) { | 587 | if (mvm->nvm_file_name) { |
585 | /* move to External NVM flow */ | 588 | /* read External NVM file - take the default */ |
586 | ret = iwl_mvm_read_external_nvm(mvm); | 589 | ret = iwl_mvm_read_external_nvm(mvm); |
587 | if (ret) | 590 | if (ret) { |
588 | return ret; | 591 | /* choose the nvm_file name according to the |
592 | * HW step | ||
593 | */ | ||
594 | if (CSR_HW_REV_STEP(mvm->trans->hw_rev) == | ||
595 | SILICON_B_STEP) | ||
596 | mvm->nvm_file_name = nvm_file_B; | ||
597 | else | ||
598 | mvm->nvm_file_name = nvm_file_C; | ||
599 | |||
600 | if (ret == -EFAULT && mvm->nvm_file_name) { | ||
601 | /* in case nvm file was failed try again */ | ||
602 | ret = iwl_mvm_read_external_nvm(mvm); | ||
603 | if (ret) | ||
604 | return ret; | ||
605 | } else { | ||
606 | return ret; | ||
607 | } | ||
608 | } | ||
589 | } | 609 | } |
590 | 610 | ||
591 | /* parse the relevant nvm sections */ | 611 | /* parse the relevant nvm sections */ |
@@ -786,13 +806,12 @@ int iwl_mvm_init_mcc(struct iwl_mvm *mvm) | |||
786 | return 0; | 806 | return 0; |
787 | 807 | ||
788 | /* | 808 | /* |
789 | * During HW restart, only replay the last set MCC to FW. Otherwise, | 809 | * try to replay the last set MCC to FW. If it doesn't exist, |
790 | * queue an update to cfg80211 to retrieve the default alpha2 from FW. | 810 | * queue an update to cfg80211 to retrieve the default alpha2 from FW. |
791 | */ | 811 | */ |
792 | if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) { | 812 | retval = iwl_mvm_init_fw_regd(mvm); |
793 | /* This should only be called during vif up and hold RTNL */ | 813 | if (retval != -ENOENT) |
794 | return iwl_mvm_init_fw_regd(mvm); | 814 | return retval; |
795 | } | ||
796 | 815 | ||
797 | /* | 816 | /* |
798 | * Driver regulatory hint for initial update, this also informs the | 817 | * Driver regulatory hint for initial update, this also informs the |
diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c index 80121e41ca22..a08b03d58d4b 100644 --- a/drivers/net/wireless/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/iwlwifi/mvm/ops.c | |||
@@ -488,8 +488,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, | |||
488 | 488 | ||
489 | /* Set a short watchdog for the command queue */ | 489 | /* Set a short watchdog for the command queue */ |
490 | trans_cfg.cmd_q_wdg_timeout = | 490 | trans_cfg.cmd_q_wdg_timeout = |
491 | iwlmvm_mod_params.tfd_q_hang_detect ? IWL_DEF_WD_TIMEOUT : | 491 | iwl_mvm_get_wd_timeout(mvm, NULL, false, true); |
492 | IWL_WATCHDOG_DISABLED; | ||
493 | 492 | ||
494 | snprintf(mvm->hw->wiphy->fw_version, | 493 | snprintf(mvm->hw->wiphy->fw_version, |
495 | sizeof(mvm->hw->wiphy->fw_version), | 494 | sizeof(mvm->hw->wiphy->fw_version), |
@@ -524,12 +523,11 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, | |||
524 | /* set the nvm_file_name according to priority */ | 523 | /* set the nvm_file_name according to priority */ |
525 | if (iwlwifi_mod_params.nvm_file) { | 524 | if (iwlwifi_mod_params.nvm_file) { |
526 | mvm->nvm_file_name = iwlwifi_mod_params.nvm_file; | 525 | mvm->nvm_file_name = iwlwifi_mod_params.nvm_file; |
527 | } else { | 526 | } else if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000) { |
528 | if ((trans->cfg->device_family == IWL_DEVICE_FAMILY_8000) && | 527 | if (CSR_HW_REV_STEP(trans->hw_rev) == SILICON_B_STEP) |
529 | (CSR_HW_REV_STEP(trans->hw_rev) == SILICON_A_STEP)) | 528 | mvm->nvm_file_name = mvm->cfg->default_nvm_file_B_step; |
530 | mvm->nvm_file_name = mvm->cfg->default_nvm_file_8000A; | ||
531 | else | 529 | else |
532 | mvm->nvm_file_name = mvm->cfg->default_nvm_file; | 530 | mvm->nvm_file_name = mvm->cfg->default_nvm_file_C_step; |
533 | } | 531 | } |
534 | 532 | ||
535 | if (WARN(cfg->no_power_up_nic_in_init && !mvm->nvm_file_name, | 533 | if (WARN(cfg->no_power_up_nic_in_init && !mvm->nvm_file_name, |
@@ -691,7 +689,6 @@ static inline void iwl_mvm_rx_check_trigger(struct iwl_mvm *mvm, | |||
691 | { | 689 | { |
692 | struct iwl_fw_dbg_trigger_tlv *trig; | 690 | struct iwl_fw_dbg_trigger_tlv *trig; |
693 | struct iwl_fw_dbg_trigger_cmd *cmds_trig; | 691 | struct iwl_fw_dbg_trigger_cmd *cmds_trig; |
694 | char buf[32]; | ||
695 | int i; | 692 | int i; |
696 | 693 | ||
697 | if (!iwl_fw_dbg_trigger_enabled(mvm->fw, FW_DBG_TRIGGER_FW_NOTIF)) | 694 | if (!iwl_fw_dbg_trigger_enabled(mvm->fw, FW_DBG_TRIGGER_FW_NOTIF)) |
@@ -711,9 +708,9 @@ static inline void iwl_mvm_rx_check_trigger(struct iwl_mvm *mvm, | |||
711 | if (cmds_trig->cmds[i].cmd_id != pkt->hdr.cmd) | 708 | if (cmds_trig->cmds[i].cmd_id != pkt->hdr.cmd) |
712 | continue; | 709 | continue; |
713 | 710 | ||
714 | memset(buf, 0, sizeof(buf)); | 711 | iwl_mvm_fw_dbg_collect_trig(mvm, trig, |
715 | snprintf(buf, sizeof(buf), "CMD 0x%02x received", pkt->hdr.cmd); | 712 | "CMD 0x%02x received", |
716 | iwl_mvm_fw_dbg_collect_trig(mvm, trig, buf, sizeof(buf)); | 713 | pkt->hdr.cmd); |
717 | break; | 714 | break; |
718 | } | 715 | } |
719 | } | 716 | } |
@@ -894,18 +891,7 @@ void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error) | |||
894 | * the next start() call from mac80211. If restart isn't called | 891 | * the next start() call from mac80211. If restart isn't called |
895 | * (no fw restart) scan status will stay busy. | 892 | * (no fw restart) scan status will stay busy. |
896 | */ | 893 | */ |
897 | switch (mvm->scan_status) { | 894 | iwl_mvm_report_scan_aborted(mvm); |
898 | case IWL_MVM_SCAN_NONE: | ||
899 | break; | ||
900 | case IWL_MVM_SCAN_OS: | ||
901 | ieee80211_scan_completed(mvm->hw, true); | ||
902 | break; | ||
903 | case IWL_MVM_SCAN_SCHED: | ||
904 | /* Sched scan will be restarted by mac80211 in restart_hw. */ | ||
905 | if (!mvm->restart_fw) | ||
906 | ieee80211_sched_scan_stopped(mvm->hw); | ||
907 | break; | ||
908 | } | ||
909 | 895 | ||
910 | /* | 896 | /* |
911 | * If we're restarting already, don't cycle restarts. | 897 | * If we're restarting already, don't cycle restarts. |
@@ -1175,7 +1161,7 @@ static void iwl_mvm_d0i3_disconnect_iter(void *data, u8 *mac, | |||
1175 | 1161 | ||
1176 | if (vif->type == NL80211_IFTYPE_STATION && vif->bss_conf.assoc && | 1162 | if (vif->type == NL80211_IFTYPE_STATION && vif->bss_conf.assoc && |
1177 | mvm->d0i3_ap_sta_id == mvmvif->ap_sta_id) | 1163 | mvm->d0i3_ap_sta_id == mvmvif->ap_sta_id) |
1178 | ieee80211_connection_loss(vif); | 1164 | iwl_mvm_connection_loss(mvm, vif, "D0i3"); |
1179 | } | 1165 | } |
1180 | 1166 | ||
1181 | void iwl_mvm_d0i3_enable_tx(struct iwl_mvm *mvm, __le16 *qos_seq) | 1167 | void iwl_mvm_d0i3_enable_tx(struct iwl_mvm *mvm, __le16 *qos_seq) |
diff --git a/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c index 192b74bc8cf6..e68a475e3071 100644 --- a/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c +++ b/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c | |||
@@ -67,7 +67,7 @@ | |||
67 | #include "fw-api.h" | 67 | #include "fw-api.h" |
68 | #include "mvm.h" | 68 | #include "mvm.h" |
69 | 69 | ||
70 | /* Maps the driver specific channel width definition to the the fw values */ | 70 | /* Maps the driver specific channel width definition to the fw values */ |
71 | u8 iwl_mvm_get_channel_width(struct cfg80211_chan_def *chandef) | 71 | u8 iwl_mvm_get_channel_width(struct cfg80211_chan_def *chandef) |
72 | { | 72 | { |
73 | switch (chandef->width) { | 73 | switch (chandef->width) { |
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c index 9140b0b701c7..f9928f2c125f 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/iwlwifi/mvm/rs.c | |||
@@ -1277,9 +1277,7 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta, | |||
1277 | info->status.ampdu_ack_len); | 1277 | info->status.ampdu_ack_len); |
1278 | } | 1278 | } |
1279 | } else { | 1279 | } else { |
1280 | /* | 1280 | /* For legacy, update frame history with for each Tx retry. */ |
1281 | * For legacy, update frame history with for each Tx retry. | ||
1282 | */ | ||
1283 | retries = info->status.rates[0].count - 1; | 1281 | retries = info->status.rates[0].count - 1; |
1284 | /* HW doesn't send more than 15 retries */ | 1282 | /* HW doesn't send more than 15 retries */ |
1285 | retries = min(retries, 15); | 1283 | retries = min(retries, 15); |
@@ -1615,9 +1613,9 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search) | |||
1615 | static void rs_update_rate_tbl(struct iwl_mvm *mvm, | 1613 | static void rs_update_rate_tbl(struct iwl_mvm *mvm, |
1616 | struct ieee80211_sta *sta, | 1614 | struct ieee80211_sta *sta, |
1617 | struct iwl_lq_sta *lq_sta, | 1615 | struct iwl_lq_sta *lq_sta, |
1618 | struct rs_rate *rate) | 1616 | struct iwl_scale_tbl_info *tbl) |
1619 | { | 1617 | { |
1620 | rs_fill_lq_cmd(mvm, sta, lq_sta, rate); | 1618 | rs_fill_lq_cmd(mvm, sta, lq_sta, &tbl->rate); |
1621 | iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, false); | 1619 | iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, false); |
1622 | } | 1620 | } |
1623 | 1621 | ||
@@ -2147,7 +2145,7 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm, | |||
2147 | rate->type = LQ_NONE; | 2145 | rate->type = LQ_NONE; |
2148 | lq_sta->search_better_tbl = 0; | 2146 | lq_sta->search_better_tbl = 0; |
2149 | tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); | 2147 | tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); |
2150 | rs_update_rate_tbl(mvm, sta, lq_sta, &tbl->rate); | 2148 | rs_update_rate_tbl(mvm, sta, lq_sta, tbl); |
2151 | } | 2149 | } |
2152 | return; | 2150 | return; |
2153 | } | 2151 | } |
@@ -2310,7 +2308,7 @@ lq_update: | |||
2310 | /* Replace uCode's rate table for the destination station. */ | 2308 | /* Replace uCode's rate table for the destination station. */ |
2311 | if (update_lq) { | 2309 | if (update_lq) { |
2312 | tbl->rate.index = index; | 2310 | tbl->rate.index = index; |
2313 | rs_update_rate_tbl(mvm, sta, lq_sta, &tbl->rate); | 2311 | rs_update_rate_tbl(mvm, sta, lq_sta, tbl); |
2314 | } | 2312 | } |
2315 | 2313 | ||
2316 | rs_stay_in_table(lq_sta, false); | 2314 | rs_stay_in_table(lq_sta, false); |
@@ -2357,8 +2355,7 @@ lq_update: | |||
2357 | 2355 | ||
2358 | rs_dump_rate(mvm, &tbl->rate, | 2356 | rs_dump_rate(mvm, &tbl->rate, |
2359 | "Switch to SEARCH TABLE:"); | 2357 | "Switch to SEARCH TABLE:"); |
2360 | rs_fill_lq_cmd(mvm, sta, lq_sta, &tbl->rate); | 2358 | rs_update_rate_tbl(mvm, sta, lq_sta, tbl); |
2361 | iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, false); | ||
2362 | } else { | 2359 | } else { |
2363 | done_search = 1; | 2360 | done_search = 1; |
2364 | } | 2361 | } |
@@ -3238,7 +3235,7 @@ static void rs_fill_lq_cmd(struct iwl_mvm *mvm, | |||
3238 | lq_cmd->agg_frame_cnt_limit = mvmsta->max_agg_bufsize; | 3235 | lq_cmd->agg_frame_cnt_limit = mvmsta->max_agg_bufsize; |
3239 | 3236 | ||
3240 | /* | 3237 | /* |
3241 | * In case of low latency, tell the firwmare to leave a frame in the | 3238 | * In case of low latency, tell the firmware to leave a frame in the |
3242 | * Tx Fifo so that it can start a transaction in the same TxOP. This | 3239 | * Tx Fifo so that it can start a transaction in the same TxOP. This |
3243 | * basically allows the firmware to send bursts. | 3240 | * basically allows the firmware to send bursts. |
3244 | */ | 3241 | */ |
@@ -3745,7 +3742,7 @@ void iwl_mvm_rate_control_unregister(void) | |||
3745 | 3742 | ||
3746 | /** | 3743 | /** |
3747 | * iwl_mvm_tx_protection - Gets LQ command, change it to enable/disable | 3744 | * iwl_mvm_tx_protection - Gets LQ command, change it to enable/disable |
3748 | * Tx protection, according to this rquest and previous requests, | 3745 | * Tx protection, according to this request and previous requests, |
3749 | * and send the LQ command. | 3746 | * and send the LQ command. |
3750 | * @mvmsta: The station | 3747 | * @mvmsta: The station |
3751 | * @enable: Enable Tx protection? | 3748 | * @enable: Enable Tx protection? |
diff --git a/drivers/net/wireless/iwlwifi/mvm/rx.c b/drivers/net/wireless/iwlwifi/mvm/rx.c index 6177e24f4c01..78ec7db64ba5 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rx.c +++ b/drivers/net/wireless/iwlwifi/mvm/rx.c | |||
@@ -362,7 +362,7 @@ int iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb, | |||
362 | iwl_fw_dbg_trigger_check_stop(mvm, mvmsta->vif, | 362 | iwl_fw_dbg_trigger_check_stop(mvm, mvmsta->vif, |
363 | trig); | 363 | trig); |
364 | if (trig_check && rx_status->signal < rssi) | 364 | if (trig_check && rx_status->signal < rssi) |
365 | iwl_mvm_fw_dbg_collect_trig(mvm, trig, NULL, 0); | 365 | iwl_mvm_fw_dbg_collect_trig(mvm, trig, NULL); |
366 | } | 366 | } |
367 | } | 367 | } |
368 | 368 | ||
@@ -552,7 +552,7 @@ iwl_mvm_rx_stats_check_trigger(struct iwl_mvm *mvm, struct iwl_rx_packet *pkt) | |||
552 | if (le32_to_cpup((__le32 *) (pkt->data + trig_offset)) < trig_thold) | 552 | if (le32_to_cpup((__le32 *) (pkt->data + trig_offset)) < trig_thold) |
553 | return; | 553 | return; |
554 | 554 | ||
555 | iwl_mvm_fw_dbg_collect_trig(mvm, trig, NULL, 0); | 555 | iwl_mvm_fw_dbg_collect_trig(mvm, trig, NULL); |
556 | } | 556 | } |
557 | 557 | ||
558 | void iwl_mvm_handle_rx_statistics(struct iwl_mvm *mvm, | 558 | void iwl_mvm_handle_rx_statistics(struct iwl_mvm *mvm, |
diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c index a75bb150ea27..74e1c86289dc 100644 --- a/drivers/net/wireless/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/iwlwifi/mvm/scan.c | |||
@@ -935,6 +935,8 @@ int iwl_mvm_unified_sched_scan_lmac(struct iwl_mvm *mvm, | |||
935 | 935 | ||
936 | cmd->n_channels = (u8)req->n_channels; | 936 | cmd->n_channels = (u8)req->n_channels; |
937 | 937 | ||
938 | cmd->delay = cpu_to_le32(req->delay); | ||
939 | |||
938 | if (iwl_mvm_scan_pass_all(mvm, req)) | 940 | if (iwl_mvm_scan_pass_all(mvm, req)) |
939 | flags |= IWL_MVM_LMAC_SCAN_FLAG_PASS_ALL; | 941 | flags |= IWL_MVM_LMAC_SCAN_FLAG_PASS_ALL; |
940 | else | 942 | else |
@@ -1177,6 +1179,18 @@ static bool iwl_mvm_find_scan_type(struct iwl_mvm *mvm, | |||
1177 | return false; | 1179 | return false; |
1178 | } | 1180 | } |
1179 | 1181 | ||
1182 | static int iwl_mvm_find_first_scan(struct iwl_mvm *mvm, | ||
1183 | enum iwl_umac_scan_uid_type type) | ||
1184 | { | ||
1185 | int i; | ||
1186 | |||
1187 | for (i = 0; i < IWL_MVM_MAX_SIMULTANEOUS_SCANS; i++) | ||
1188 | if (mvm->scan_uid[i] & type) | ||
1189 | return i; | ||
1190 | |||
1191 | return i; | ||
1192 | } | ||
1193 | |||
1180 | static u32 iwl_generate_scan_uid(struct iwl_mvm *mvm, | 1194 | static u32 iwl_generate_scan_uid(struct iwl_mvm *mvm, |
1181 | enum iwl_umac_scan_uid_type type) | 1195 | enum iwl_umac_scan_uid_type type) |
1182 | { | 1196 | { |
@@ -1436,7 +1450,13 @@ int iwl_mvm_sched_scan_umac(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | |||
1436 | cpu_to_le16(req->interval / MSEC_PER_SEC); | 1450 | cpu_to_le16(req->interval / MSEC_PER_SEC); |
1437 | sec_part->schedule[0].iter_count = 0xff; | 1451 | sec_part->schedule[0].iter_count = 0xff; |
1438 | 1452 | ||
1439 | sec_part->delay = 0; | 1453 | if (req->delay > U16_MAX) { |
1454 | IWL_DEBUG_SCAN(mvm, | ||
1455 | "delay value is > 16-bits, set to max possible\n"); | ||
1456 | sec_part->delay = cpu_to_le16(U16_MAX); | ||
1457 | } else { | ||
1458 | sec_part->delay = cpu_to_le16(req->delay); | ||
1459 | } | ||
1440 | 1460 | ||
1441 | iwl_mvm_build_unified_scan_probe(mvm, vif, ies, &sec_part->preq, | 1461 | iwl_mvm_build_unified_scan_probe(mvm, vif, ies, &sec_part->preq, |
1442 | req->flags & NL80211_SCAN_FLAG_RANDOM_ADDR ? | 1462 | req->flags & NL80211_SCAN_FLAG_RANDOM_ADDR ? |
@@ -1613,3 +1633,54 @@ int iwl_mvm_scan_size(struct iwl_mvm *mvm) | |||
1613 | mvm->fw->ucode_capa.n_scan_channels + | 1633 | mvm->fw->ucode_capa.n_scan_channels + |
1614 | sizeof(struct iwl_scan_probe_req); | 1634 | sizeof(struct iwl_scan_probe_req); |
1615 | } | 1635 | } |
1636 | |||
1637 | /* | ||
1638 | * This function is used in nic restart flow, to inform mac80211 about scans | ||
1639 | * that was aborted by restart flow or by an assert. | ||
1640 | */ | ||
1641 | void iwl_mvm_report_scan_aborted(struct iwl_mvm *mvm) | ||
1642 | { | ||
1643 | if (mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_UMAC_SCAN) { | ||
1644 | u32 uid, i; | ||
1645 | |||
1646 | uid = iwl_mvm_find_first_scan(mvm, IWL_UMAC_SCAN_UID_REG_SCAN); | ||
1647 | if (uid < IWL_MVM_MAX_SIMULTANEOUS_SCANS) { | ||
1648 | ieee80211_scan_completed(mvm->hw, true); | ||
1649 | mvm->scan_uid[uid] = 0; | ||
1650 | } | ||
1651 | uid = iwl_mvm_find_first_scan(mvm, | ||
1652 | IWL_UMAC_SCAN_UID_SCHED_SCAN); | ||
1653 | if (uid < IWL_MVM_MAX_SIMULTANEOUS_SCANS && !mvm->restart_fw) { | ||
1654 | ieee80211_sched_scan_stopped(mvm->hw); | ||
1655 | mvm->scan_uid[uid] = 0; | ||
1656 | } | ||
1657 | |||
1658 | /* We shouldn't have any UIDs still set. Loop over all the | ||
1659 | * UIDs to make sure there's nothing left there and warn if | ||
1660 | * any is found. | ||
1661 | */ | ||
1662 | for (i = 0; i < IWL_MVM_MAX_SIMULTANEOUS_SCANS; i++) { | ||
1663 | if (WARN_ONCE(mvm->scan_uid[i], | ||
1664 | "UMAC scan UID %d was not cleaned\n", | ||
1665 | mvm->scan_uid[i])) | ||
1666 | mvm->scan_uid[i] = 0; | ||
1667 | } | ||
1668 | } else { | ||
1669 | switch (mvm->scan_status) { | ||
1670 | case IWL_MVM_SCAN_NONE: | ||
1671 | break; | ||
1672 | case IWL_MVM_SCAN_OS: | ||
1673 | ieee80211_scan_completed(mvm->hw, true); | ||
1674 | break; | ||
1675 | case IWL_MVM_SCAN_SCHED: | ||
1676 | /* | ||
1677 | * Sched scan will be restarted by mac80211 in | ||
1678 | * restart_hw, so do not report if FW is about to be | ||
1679 | * restarted. | ||
1680 | */ | ||
1681 | if (!mvm->restart_fw) | ||
1682 | ieee80211_sched_scan_stopped(mvm->hw); | ||
1683 | break; | ||
1684 | } | ||
1685 | } | ||
1686 | } | ||
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c index 50f9288368af..1845b79487c8 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/iwlwifi/mvm/sta.c | |||
@@ -209,9 +209,8 @@ static int iwl_mvm_tdls_sta_init(struct iwl_mvm *mvm, | |||
209 | { | 209 | { |
210 | unsigned long used_hw_queues; | 210 | unsigned long used_hw_queues; |
211 | struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); | 211 | struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); |
212 | unsigned int wdg_timeout = iwlmvm_mod_params.tfd_q_hang_detect ? | 212 | unsigned int wdg_timeout = |
213 | mvm->cfg->base_params->wd_timeout : | 213 | iwl_mvm_get_wd_timeout(mvm, NULL, true, false); |
214 | IWL_WATCHDOG_DISABLED; | ||
215 | u32 ac; | 214 | u32 ac; |
216 | 215 | ||
217 | lockdep_assert_held(&mvm->mutex); | 216 | lockdep_assert_held(&mvm->mutex); |
@@ -491,8 +490,18 @@ int iwl_mvm_rm_sta(struct iwl_mvm *mvm, | |||
491 | 490 | ||
492 | if (vif->type == NL80211_IFTYPE_STATION && | 491 | if (vif->type == NL80211_IFTYPE_STATION && |
493 | mvmvif->ap_sta_id == mvm_sta->sta_id) { | 492 | mvmvif->ap_sta_id == mvm_sta->sta_id) { |
493 | ret = iwl_mvm_drain_sta(mvm, mvm_sta, true); | ||
494 | if (ret) | ||
495 | return ret; | ||
494 | /* flush its queues here since we are freeing mvm_sta */ | 496 | /* flush its queues here since we are freeing mvm_sta */ |
495 | ret = iwl_mvm_flush_tx_path(mvm, mvm_sta->tfd_queue_msk, true); | 497 | ret = iwl_mvm_flush_tx_path(mvm, mvm_sta->tfd_queue_msk, true); |
498 | if (ret) | ||
499 | return ret; | ||
500 | ret = iwl_trans_wait_tx_queue_empty(mvm->trans, | ||
501 | mvm_sta->tfd_queue_msk); | ||
502 | if (ret) | ||
503 | return ret; | ||
504 | ret = iwl_mvm_drain_sta(mvm, mvm_sta, false); | ||
496 | 505 | ||
497 | /* if we are associated - we can't remove the AP STA now */ | 506 | /* if we are associated - we can't remove the AP STA now */ |
498 | if (vif->bss_conf.assoc) | 507 | if (vif->bss_conf.assoc) |
@@ -971,9 +980,8 @@ int iwl_mvm_sta_tx_agg_oper(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | |||
971 | { | 980 | { |
972 | struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); | 981 | struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); |
973 | struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid]; | 982 | struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid]; |
974 | unsigned int wdg_timeout = iwlmvm_mod_params.tfd_q_hang_detect ? | 983 | unsigned int wdg_timeout = |
975 | mvm->cfg->base_params->wd_timeout : | 984 | iwl_mvm_get_wd_timeout(mvm, vif, sta->tdls, false); |
976 | IWL_WATCHDOG_DISABLED; | ||
977 | int queue, fifo, ret; | 985 | int queue, fifo, ret; |
978 | u16 ssn; | 986 | u16 ssn; |
979 | 987 | ||
@@ -1120,8 +1128,12 @@ int iwl_mvm_sta_tx_agg_flush(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | |||
1120 | spin_unlock_bh(&mvmsta->lock); | 1128 | spin_unlock_bh(&mvmsta->lock); |
1121 | 1129 | ||
1122 | if (old_state >= IWL_AGG_ON) { | 1130 | if (old_state >= IWL_AGG_ON) { |
1131 | iwl_mvm_drain_sta(mvm, mvmsta, true); | ||
1123 | if (iwl_mvm_flush_tx_path(mvm, BIT(txq_id), true)) | 1132 | if (iwl_mvm_flush_tx_path(mvm, BIT(txq_id), true)) |
1124 | IWL_ERR(mvm, "Couldn't flush the AGG queue\n"); | 1133 | IWL_ERR(mvm, "Couldn't flush the AGG queue\n"); |
1134 | iwl_trans_wait_tx_queue_empty(mvm->trans, | ||
1135 | mvmsta->tfd_queue_msk); | ||
1136 | iwl_mvm_drain_sta(mvm, mvmsta, false); | ||
1125 | 1137 | ||
1126 | iwl_mvm_sta_tx_agg(mvm, sta, tid, txq_id, false); | 1138 | iwl_mvm_sta_tx_agg(mvm, sta, tid, txq_id, false); |
1127 | 1139 | ||
@@ -1702,8 +1714,8 @@ void iwl_mvm_sta_modify_disable_tx_ap(struct iwl_mvm *mvm, | |||
1702 | mvm_sta->disable_tx = disable; | 1714 | mvm_sta->disable_tx = disable; |
1703 | 1715 | ||
1704 | /* | 1716 | /* |
1705 | * Tell mac80211 to start/stop queueing tx for this station, | 1717 | * Tell mac80211 to start/stop queuing tx for this station, |
1706 | * but don't stop queueing if there are still pending frames | 1718 | * but don't stop queuing if there are still pending frames |
1707 | * for this station. | 1719 | * for this station. |
1708 | */ | 1720 | */ |
1709 | if (disable || !atomic_read(&mvm->pending_frames[mvm_sta->sta_id])) | 1721 | if (disable || !atomic_read(&mvm->pending_frames[mvm_sta->sta_id])) |
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.h b/drivers/net/wireless/iwlwifi/mvm/sta.h index d8f48975ad08..748f5dc3f9f4 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sta.h +++ b/drivers/net/wireless/iwlwifi/mvm/sta.h | |||
@@ -150,7 +150,7 @@ struct iwl_mvm_vif; | |||
150 | * DOC: station table - AP Station in STA mode | 150 | * DOC: station table - AP Station in STA mode |
151 | * | 151 | * |
152 | * %iwl_mvm_vif includes the index of the AP station in the fw's STA table: | 152 | * %iwl_mvm_vif includes the index of the AP station in the fw's STA table: |
153 | * %ap_sta_id. To get the point to the coresponsding %ieee80211_sta, | 153 | * %ap_sta_id. To get the point to the corresponding %ieee80211_sta, |
154 | * &fw_id_to_mac_id can be used. Due to the way the fw works, we must not remove | 154 | * &fw_id_to_mac_id can be used. Due to the way the fw works, we must not remove |
155 | * the AP station from the fw before setting the MAC context as unassociated. | 155 | * the AP station from the fw before setting the MAC context as unassociated. |
156 | * Hence, %fw_id_to_mac_id[%ap_sta_id] will be NULLed when the AP station is | 156 | * Hence, %fw_id_to_mac_id[%ap_sta_id] will be NULLed when the AP station is |
@@ -209,14 +209,14 @@ struct iwl_mvm_vif; | |||
209 | * When a trigger frame is received, mac80211 tells the driver to send frames | 209 | * When a trigger frame is received, mac80211 tells the driver to send frames |
210 | * from the AMPDU queues or sends frames to non-aggregation queues itself, | 210 | * from the AMPDU queues or sends frames to non-aggregation queues itself, |
211 | * depending on which ACs are delivery-enabled and what TID has frames to | 211 | * depending on which ACs are delivery-enabled and what TID has frames to |
212 | * transmit. Note that mac80211 has all the knowledege since all the non-agg | 212 | * transmit. Note that mac80211 has all the knowledge since all the non-agg |
213 | * frames are buffered / filtered, and the driver tells mac80211 about agg | 213 | * frames are buffered / filtered, and the driver tells mac80211 about agg |
214 | * frames). The driver needs to tell the fw to let frames out even if the | 214 | * frames). The driver needs to tell the fw to let frames out even if the |
215 | * station is asleep. This is done by %iwl_mvm_sta_modify_sleep_tx_count. | 215 | * station is asleep. This is done by %iwl_mvm_sta_modify_sleep_tx_count. |
216 | * | 216 | * |
217 | * When we receive a frame from that station with PM bit unset, the driver | 217 | * When we receive a frame from that station with PM bit unset, the driver |
218 | * needs to let the fw know that this station isn't asleep any more. This is | 218 | * needs to let the fw know that this station isn't asleep any more. This is |
219 | * done by %iwl_mvm_sta_modify_ps_wake in response to mac80211 signalling the | 219 | * done by %iwl_mvm_sta_modify_ps_wake in response to mac80211 signaling the |
220 | * station's wakeup. | 220 | * station's wakeup. |
221 | * | 221 | * |
222 | * For a GO, the Service Period might be cut short due to an absence period | 222 | * For a GO, the Service Period might be cut short due to an absence period |
diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.c b/drivers/net/wireless/iwlwifi/mvm/time-event.c index 8d179ab67cc2..fd7b0d36f9a6 100644 --- a/drivers/net/wireless/iwlwifi/mvm/time-event.c +++ b/drivers/net/wireless/iwlwifi/mvm/time-event.c | |||
@@ -119,7 +119,7 @@ void iwl_mvm_roc_done_wk(struct work_struct *wk) | |||
119 | 119 | ||
120 | /* | 120 | /* |
121 | * Flush the offchannel queue -- this is called when the time | 121 | * Flush the offchannel queue -- this is called when the time |
122 | * event finishes or is cancelled, so that frames queued for it | 122 | * event finishes or is canceled, so that frames queued for it |
123 | * won't get stuck on the queue and be transmitted in the next | 123 | * won't get stuck on the queue and be transmitted in the next |
124 | * time event. | 124 | * time event. |
125 | * We have to send the command asynchronously since this cannot | 125 | * We have to send the command asynchronously since this cannot |
@@ -187,7 +187,8 @@ static bool iwl_mvm_te_check_disconnect(struct iwl_mvm *mvm, | |||
187 | return false; | 187 | return false; |
188 | if (errmsg) | 188 | if (errmsg) |
189 | IWL_ERR(mvm, "%s\n", errmsg); | 189 | IWL_ERR(mvm, "%s\n", errmsg); |
190 | ieee80211_connection_loss(vif); | 190 | |
191 | iwl_mvm_connection_loss(mvm, vif, errmsg); | ||
191 | return true; | 192 | return true; |
192 | } | 193 | } |
193 | 194 | ||
@@ -196,19 +197,24 @@ iwl_mvm_te_handle_notify_csa(struct iwl_mvm *mvm, | |||
196 | struct iwl_mvm_time_event_data *te_data, | 197 | struct iwl_mvm_time_event_data *te_data, |
197 | struct iwl_time_event_notif *notif) | 198 | struct iwl_time_event_notif *notif) |
198 | { | 199 | { |
199 | if (!le32_to_cpu(notif->status)) { | 200 | struct ieee80211_vif *vif = te_data->vif; |
200 | if (te_data->vif->type == NL80211_IFTYPE_STATION) | 201 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); |
201 | ieee80211_connection_loss(te_data->vif); | 202 | |
203 | if (!notif->status) | ||
202 | IWL_DEBUG_TE(mvm, "CSA time event failed to start\n"); | 204 | IWL_DEBUG_TE(mvm, "CSA time event failed to start\n"); |
203 | iwl_mvm_te_clear_data(mvm, te_data); | ||
204 | return; | ||
205 | } | ||
206 | 205 | ||
207 | switch (te_data->vif->type) { | 206 | switch (te_data->vif->type) { |
208 | case NL80211_IFTYPE_AP: | 207 | case NL80211_IFTYPE_AP: |
208 | if (!notif->status) | ||
209 | mvmvif->csa_failed = true; | ||
209 | iwl_mvm_csa_noa_start(mvm); | 210 | iwl_mvm_csa_noa_start(mvm); |
210 | break; | 211 | break; |
211 | case NL80211_IFTYPE_STATION: | 212 | case NL80211_IFTYPE_STATION: |
213 | if (!notif->status) { | ||
214 | iwl_mvm_connection_loss(mvm, vif, | ||
215 | "CSA TE failed to start"); | ||
216 | break; | ||
217 | } | ||
212 | iwl_mvm_csa_client_absent(mvm, te_data->vif); | 218 | iwl_mvm_csa_client_absent(mvm, te_data->vif); |
213 | ieee80211_chswitch_done(te_data->vif, true); | 219 | ieee80211_chswitch_done(te_data->vif, true); |
214 | break; | 220 | break; |
@@ -222,6 +228,44 @@ iwl_mvm_te_handle_notify_csa(struct iwl_mvm *mvm, | |||
222 | iwl_mvm_te_clear_data(mvm, te_data); | 228 | iwl_mvm_te_clear_data(mvm, te_data); |
223 | } | 229 | } |
224 | 230 | ||
231 | static void iwl_mvm_te_check_trigger(struct iwl_mvm *mvm, | ||
232 | struct iwl_time_event_notif *notif, | ||
233 | struct iwl_mvm_time_event_data *te_data) | ||
234 | { | ||
235 | struct iwl_fw_dbg_trigger_tlv *trig; | ||
236 | struct iwl_fw_dbg_trigger_time_event *te_trig; | ||
237 | int i; | ||
238 | |||
239 | if (!iwl_fw_dbg_trigger_enabled(mvm->fw, FW_DBG_TRIGGER_TIME_EVENT)) | ||
240 | return; | ||
241 | |||
242 | trig = iwl_fw_dbg_get_trigger(mvm->fw, FW_DBG_TRIGGER_TIME_EVENT); | ||
243 | te_trig = (void *)trig->data; | ||
244 | |||
245 | if (!iwl_fw_dbg_trigger_check_stop(mvm, te_data->vif, trig)) | ||
246 | return; | ||
247 | |||
248 | for (i = 0; i < ARRAY_SIZE(te_trig->time_events); i++) { | ||
249 | u32 trig_te_id = le32_to_cpu(te_trig->time_events[i].id); | ||
250 | u32 trig_action_bitmap = | ||
251 | le32_to_cpu(te_trig->time_events[i].action_bitmap); | ||
252 | u32 trig_status_bitmap = | ||
253 | le32_to_cpu(te_trig->time_events[i].status_bitmap); | ||
254 | |||
255 | if (trig_te_id != te_data->id || | ||
256 | !(trig_action_bitmap & le32_to_cpu(notif->action)) || | ||
257 | !(trig_status_bitmap & BIT(le32_to_cpu(notif->status)))) | ||
258 | continue; | ||
259 | |||
260 | iwl_mvm_fw_dbg_collect_trig(mvm, trig, | ||
261 | "Time event %d Action 0x%x received status: %d", | ||
262 | te_data->id, | ||
263 | le32_to_cpu(notif->action), | ||
264 | le32_to_cpu(notif->status)); | ||
265 | break; | ||
266 | } | ||
267 | } | ||
268 | |||
225 | /* | 269 | /* |
226 | * Handles a FW notification for an event that is known to the driver. | 270 | * Handles a FW notification for an event that is known to the driver. |
227 | * | 271 | * |
@@ -239,6 +283,8 @@ static void iwl_mvm_te_handle_notif(struct iwl_mvm *mvm, | |||
239 | le32_to_cpu(notif->unique_id), | 283 | le32_to_cpu(notif->unique_id), |
240 | le32_to_cpu(notif->action)); | 284 | le32_to_cpu(notif->action)); |
241 | 285 | ||
286 | iwl_mvm_te_check_trigger(mvm, notif, te_data); | ||
287 | |||
242 | /* | 288 | /* |
243 | * The FW sends the start/end time event notifications even for events | 289 | * The FW sends the start/end time event notifications even for events |
244 | * that it fails to schedule. This is indicated in the status field of | 290 | * that it fails to schedule. This is indicated in the status field of |
@@ -248,11 +294,16 @@ static void iwl_mvm_te_handle_notif(struct iwl_mvm *mvm, | |||
248 | * events in the system). | 294 | * events in the system). |
249 | */ | 295 | */ |
250 | if (!le32_to_cpu(notif->status)) { | 296 | if (!le32_to_cpu(notif->status)) { |
251 | bool start = le32_to_cpu(notif->action) & | 297 | const char *msg; |
252 | TE_V2_NOTIF_HOST_EVENT_START; | 298 | |
253 | IWL_WARN(mvm, "Time Event %s notification failure\n", | 299 | if (notif->action & cpu_to_le32(TE_V2_NOTIF_HOST_EVENT_START)) |
254 | start ? "start" : "end"); | 300 | msg = "Time Event start notification failure"; |
255 | if (iwl_mvm_te_check_disconnect(mvm, te_data->vif, NULL)) { | 301 | else |
302 | msg = "Time Event end notification failure"; | ||
303 | |||
304 | IWL_DEBUG_TE(mvm, "%s\n", msg); | ||
305 | |||
306 | if (iwl_mvm_te_check_disconnect(mvm, te_data->vif, msg)) { | ||
256 | iwl_mvm_te_clear_data(mvm, te_data); | 307 | iwl_mvm_te_clear_data(mvm, te_data); |
257 | return; | 308 | return; |
258 | } | 309 | } |
@@ -315,6 +366,8 @@ static int iwl_mvm_aux_roc_te_handle_notif(struct iwl_mvm *mvm, | |||
315 | if (!aux_roc_te) /* Not a Aux ROC time event */ | 366 | if (!aux_roc_te) /* Not a Aux ROC time event */ |
316 | return -EINVAL; | 367 | return -EINVAL; |
317 | 368 | ||
369 | iwl_mvm_te_check_trigger(mvm, notif, te_data); | ||
370 | |||
318 | if (!le32_to_cpu(notif->status)) { | 371 | if (!le32_to_cpu(notif->status)) { |
319 | IWL_DEBUG_TE(mvm, | 372 | IWL_DEBUG_TE(mvm, |
320 | "ERROR: Aux ROC Time Event %s notification failure\n", | 373 | "ERROR: Aux ROC Time Event %s notification failure\n", |
@@ -769,7 +822,7 @@ void iwl_mvm_stop_roc(struct iwl_mvm *mvm) | |||
769 | * Iterate over the list of aux roc time events and find the time | 822 | * Iterate over the list of aux roc time events and find the time |
770 | * event that is associated with a BSS interface. | 823 | * event that is associated with a BSS interface. |
771 | * This assumes that a BSS interface can have only a single time | 824 | * This assumes that a BSS interface can have only a single time |
772 | * event at any given time and this time event coresponds to a ROC | 825 | * event at any given time and this time event corresponds to a ROC |
773 | * request | 826 | * request |
774 | */ | 827 | */ |
775 | list_for_each_entry(te_data, &mvm->aux_roc_te_list, list) { | 828 | list_for_each_entry(te_data, &mvm->aux_roc_te_list, list) { |
diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.h b/drivers/net/wireless/iwlwifi/mvm/time-event.h index 6f6b35db3ab8..de4fbc6d57f1 100644 --- a/drivers/net/wireless/iwlwifi/mvm/time-event.h +++ b/drivers/net/wireless/iwlwifi/mvm/time-event.h | |||
@@ -147,7 +147,7 @@ void iwl_mvm_protect_session(struct iwl_mvm *mvm, | |||
147 | * @vif: the virtual interface for which the session is issued | 147 | * @vif: the virtual interface for which the session is issued |
148 | * | 148 | * |
149 | * This functions cancels the session protection which is an act of good | 149 | * This functions cancels the session protection which is an act of good |
150 | * citizenship. If it is not needed any more it should be cancelled because | 150 | * citizenship. If it is not needed any more it should be canceled because |
151 | * the other bindings wait for the medium during that time. | 151 | * the other bindings wait for the medium during that time. |
152 | * This funtions doesn't sleep. | 152 | * This funtions doesn't sleep. |
153 | */ | 153 | */ |
@@ -162,7 +162,7 @@ int iwl_mvm_rx_time_event_notif(struct iwl_mvm *mvm, | |||
162 | struct iwl_device_cmd *cmd); | 162 | struct iwl_device_cmd *cmd); |
163 | 163 | ||
164 | /** | 164 | /** |
165 | * iwl_mvm_start_p2p_roc - start remain on channel for p2p device functionlity | 165 | * iwl_mvm_start_p2p_roc - start remain on channel for p2p device functionality |
166 | * @mvm: the mvm component | 166 | * @mvm: the mvm component |
167 | * @vif: the virtual interface for which the roc is requested. It is assumed | 167 | * @vif: the virtual interface for which the roc is requested. It is assumed |
168 | * that the vif type is NL80211_IFTYPE_P2P_DEVICE | 168 | * that the vif type is NL80211_IFTYPE_P2P_DEVICE |
diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c index ba34dda1ae36..ef32e177f662 100644 --- a/drivers/net/wireless/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/iwlwifi/mvm/tx.c | |||
@@ -1049,6 +1049,14 @@ out: | |||
1049 | return 0; | 1049 | return 0; |
1050 | } | 1050 | } |
1051 | 1051 | ||
1052 | /* | ||
1053 | * Note that there are transports that buffer frames before they reach | ||
1054 | * the firmware. This means that after flush_tx_path is called, the | ||
1055 | * queue might not be empty. The race-free way to handle this is to: | ||
1056 | * 1) set the station as draining | ||
1057 | * 2) flush the Tx path | ||
1058 | * 3) wait for the transport queues to be empty | ||
1059 | */ | ||
1052 | int iwl_mvm_flush_tx_path(struct iwl_mvm *mvm, u32 tfd_msk, bool sync) | 1060 | int iwl_mvm_flush_tx_path(struct iwl_mvm *mvm, u32 tfd_msk, bool sync) |
1053 | { | 1061 | { |
1054 | int ret; | 1062 | int ret; |
diff --git a/drivers/net/wireless/iwlwifi/mvm/utils.c b/drivers/net/wireless/iwlwifi/mvm/utils.c index 435faee0a28e..bc55a8b82db6 100644 --- a/drivers/net/wireless/iwlwifi/mvm/utils.c +++ b/drivers/net/wireless/iwlwifi/mvm/utils.c | |||
@@ -122,7 +122,7 @@ int iwl_mvm_send_cmd_pdu(struct iwl_mvm *mvm, u8 id, | |||
122 | } | 122 | } |
123 | 123 | ||
124 | /* | 124 | /* |
125 | * We assume that the caller set the status to the sucess value | 125 | * We assume that the caller set the status to the success value |
126 | */ | 126 | */ |
127 | int iwl_mvm_send_cmd_status(struct iwl_mvm *mvm, struct iwl_host_cmd *cmd, | 127 | int iwl_mvm_send_cmd_status(struct iwl_mvm *mvm, struct iwl_host_cmd *cmd, |
128 | u32 *status) | 128 | u32 *status) |
@@ -737,7 +737,7 @@ int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq, bool init) | |||
737 | } | 737 | } |
738 | 738 | ||
739 | /** | 739 | /** |
740 | * iwl_mvm_update_smps - Get a requst to change the SMPS mode | 740 | * iwl_mvm_update_smps - Get a request to change the SMPS mode |
741 | * @req_type: The part of the driver who call for a change. | 741 | * @req_type: The part of the driver who call for a change. |
742 | * @smps_requests: The request to change the SMPS mode. | 742 | * @smps_requests: The request to change the SMPS mode. |
743 | * | 743 | * |
@@ -921,3 +921,71 @@ struct ieee80211_vif *iwl_mvm_get_bss_vif(struct iwl_mvm *mvm) | |||
921 | 921 | ||
922 | return bss_iter_data.vif; | 922 | return bss_iter_data.vif; |
923 | } | 923 | } |
924 | |||
925 | unsigned int iwl_mvm_get_wd_timeout(struct iwl_mvm *mvm, | ||
926 | struct ieee80211_vif *vif, | ||
927 | bool tdls, bool cmd_q) | ||
928 | { | ||
929 | struct iwl_fw_dbg_trigger_tlv *trigger; | ||
930 | struct iwl_fw_dbg_trigger_txq_timer *txq_timer; | ||
931 | unsigned int default_timeout = | ||
932 | cmd_q ? IWL_DEF_WD_TIMEOUT : mvm->cfg->base_params->wd_timeout; | ||
933 | |||
934 | if (!iwl_fw_dbg_trigger_enabled(mvm->fw, FW_DBG_TRIGGER_TXQ_TIMERS)) | ||
935 | return iwlmvm_mod_params.tfd_q_hang_detect ? | ||
936 | default_timeout : IWL_WATCHDOG_DISABLED; | ||
937 | |||
938 | trigger = iwl_fw_dbg_get_trigger(mvm->fw, FW_DBG_TRIGGER_TXQ_TIMERS); | ||
939 | txq_timer = (void *)trigger->data; | ||
940 | |||
941 | if (tdls) | ||
942 | return le32_to_cpu(txq_timer->tdls); | ||
943 | |||
944 | if (cmd_q) | ||
945 | return le32_to_cpu(txq_timer->command_queue); | ||
946 | |||
947 | if (WARN_ON(!vif)) | ||
948 | return default_timeout; | ||
949 | |||
950 | switch (ieee80211_vif_type_p2p(vif)) { | ||
951 | case NL80211_IFTYPE_ADHOC: | ||
952 | return le32_to_cpu(txq_timer->ibss); | ||
953 | case NL80211_IFTYPE_STATION: | ||
954 | return le32_to_cpu(txq_timer->bss); | ||
955 | case NL80211_IFTYPE_AP: | ||
956 | return le32_to_cpu(txq_timer->softap); | ||
957 | case NL80211_IFTYPE_P2P_CLIENT: | ||
958 | return le32_to_cpu(txq_timer->p2p_client); | ||
959 | case NL80211_IFTYPE_P2P_GO: | ||
960 | return le32_to_cpu(txq_timer->p2p_go); | ||
961 | case NL80211_IFTYPE_P2P_DEVICE: | ||
962 | return le32_to_cpu(txq_timer->p2p_device); | ||
963 | default: | ||
964 | WARN_ON(1); | ||
965 | return mvm->cfg->base_params->wd_timeout; | ||
966 | } | ||
967 | } | ||
968 | |||
969 | void iwl_mvm_connection_loss(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | ||
970 | const char *errmsg) | ||
971 | { | ||
972 | struct iwl_fw_dbg_trigger_tlv *trig; | ||
973 | struct iwl_fw_dbg_trigger_mlme *trig_mlme; | ||
974 | |||
975 | if (!iwl_fw_dbg_trigger_enabled(mvm->fw, FW_DBG_TRIGGER_MLME)) | ||
976 | goto out; | ||
977 | |||
978 | trig = iwl_fw_dbg_get_trigger(mvm->fw, FW_DBG_TRIGGER_MLME); | ||
979 | trig_mlme = (void *)trig->data; | ||
980 | if (!iwl_fw_dbg_trigger_check_stop(mvm, vif, trig)) | ||
981 | goto out; | ||
982 | |||
983 | if (trig_mlme->stop_connection_loss && | ||
984 | --trig_mlme->stop_connection_loss) | ||
985 | goto out; | ||
986 | |||
987 | iwl_mvm_fw_dbg_collect_trig(mvm, trig, "%s", errmsg); | ||
988 | |||
989 | out: | ||
990 | ieee80211_connection_loss(vif); | ||
991 | } | ||
diff --git a/drivers/net/wireless/iwlwifi/pcie/rx.c b/drivers/net/wireless/iwlwifi/pcie/rx.c index 7b7e2f223fb2..7ff69c642103 100644 --- a/drivers/net/wireless/iwlwifi/pcie/rx.c +++ b/drivers/net/wireless/iwlwifi/pcie/rx.c | |||
@@ -600,9 +600,11 @@ static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans, | |||
600 | if (pkt->len_n_flags == cpu_to_le32(FH_RSCSR_FRAME_INVALID)) | 600 | if (pkt->len_n_flags == cpu_to_le32(FH_RSCSR_FRAME_INVALID)) |
601 | break; | 601 | break; |
602 | 602 | ||
603 | IWL_DEBUG_RX(trans, "cmd at offset %d: %s (0x%.2x)\n", | 603 | IWL_DEBUG_RX(trans, |
604 | rxcb._offset, get_cmd_string(trans_pcie, pkt->hdr.cmd), | 604 | "cmd at offset %d: %s (0x%.2x, seq 0x%x)\n", |
605 | pkt->hdr.cmd); | 605 | rxcb._offset, |
606 | get_cmd_string(trans_pcie, pkt->hdr.cmd), | ||
607 | pkt->hdr.cmd, le16_to_cpu(pkt->hdr.sequence)); | ||
606 | 608 | ||
607 | len = iwl_rx_packet_len(pkt); | 609 | len = iwl_rx_packet_len(pkt); |
608 | len += sizeof(u32); /* account for status word */ | 610 | len += sizeof(u32); /* account for status word */ |
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index dc247325d8d7..2de8fbfe4edf 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c | |||
@@ -691,11 +691,15 @@ static int iwl_pcie_rsa_race_bug_wa(struct iwl_trans *trans) | |||
691 | { | 691 | { |
692 | u32 val, loop = 1000; | 692 | u32 val, loop = 1000; |
693 | 693 | ||
694 | /* Check the RSA semaphore is accessible - if not, we are in trouble */ | 694 | /* |
695 | * Check the RSA semaphore is accessible. | ||
696 | * If the HW isn't locked and the rsa semaphore isn't accessible, | ||
697 | * we are in trouble. | ||
698 | */ | ||
695 | val = iwl_read_prph(trans, PREG_AUX_BUS_WPROT_0); | 699 | val = iwl_read_prph(trans, PREG_AUX_BUS_WPROT_0); |
696 | if (val & (BIT(1) | BIT(17))) { | 700 | if (val & (BIT(1) | BIT(17))) { |
697 | IWL_ERR(trans, | 701 | IWL_INFO(trans, |
698 | "can't access the RSA semaphore it is write protected\n"); | 702 | "can't access the RSA semaphore it is write protected\n"); |
699 | return 0; | 703 | return 0; |
700 | } | 704 | } |
701 | 705 | ||
@@ -719,10 +723,10 @@ static int iwl_pcie_rsa_race_bug_wa(struct iwl_trans *trans) | |||
719 | return -EIO; | 723 | return -EIO; |
720 | } | 724 | } |
721 | 725 | ||
722 | static int iwl_pcie_load_cpu_sections_8000b(struct iwl_trans *trans, | 726 | static int iwl_pcie_load_cpu_sections_8000(struct iwl_trans *trans, |
723 | const struct fw_img *image, | 727 | const struct fw_img *image, |
724 | int cpu, | 728 | int cpu, |
725 | int *first_ucode_section) | 729 | int *first_ucode_section) |
726 | { | 730 | { |
727 | int shift_param; | 731 | int shift_param; |
728 | int i, ret = 0, sec_num = 0x1; | 732 | int i, ret = 0, sec_num = 0x1; |
@@ -917,20 +921,16 @@ static int iwl_pcie_load_given_ucode(struct iwl_trans *trans, | |||
917 | } | 921 | } |
918 | 922 | ||
919 | /* release CPU reset */ | 923 | /* release CPU reset */ |
920 | if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000) | 924 | iwl_write32(trans, CSR_RESET, 0); |
921 | iwl_write_prph(trans, RELEASE_CPU_RESET, RELEASE_CPU_RESET_BIT); | ||
922 | else | ||
923 | iwl_write32(trans, CSR_RESET, 0); | ||
924 | 925 | ||
925 | return 0; | 926 | return 0; |
926 | } | 927 | } |
927 | 928 | ||
928 | static int iwl_pcie_load_given_ucode_8000b(struct iwl_trans *trans, | 929 | static int iwl_pcie_load_given_ucode_8000(struct iwl_trans *trans, |
929 | const struct fw_img *image) | 930 | const struct fw_img *image) |
930 | { | 931 | { |
931 | int ret = 0; | 932 | int ret = 0; |
932 | int first_ucode_section; | 933 | int first_ucode_section; |
933 | u32 reg; | ||
934 | 934 | ||
935 | IWL_DEBUG_FW(trans, "working with %s CPU\n", | 935 | IWL_DEBUG_FW(trans, "working with %s CPU\n", |
936 | image->is_dual_cpus ? "Dual" : "Single"); | 936 | image->is_dual_cpus ? "Dual" : "Single"); |
@@ -948,38 +948,23 @@ static int iwl_pcie_load_given_ucode_8000b(struct iwl_trans *trans, | |||
948 | iwl_write_prph(trans, RELEASE_CPU_RESET, RELEASE_CPU_RESET_BIT); | 948 | iwl_write_prph(trans, RELEASE_CPU_RESET, RELEASE_CPU_RESET_BIT); |
949 | 949 | ||
950 | /* load to FW the binary Secured sections of CPU1 */ | 950 | /* load to FW the binary Secured sections of CPU1 */ |
951 | ret = iwl_pcie_load_cpu_sections_8000b(trans, image, 1, | 951 | ret = iwl_pcie_load_cpu_sections_8000(trans, image, 1, |
952 | &first_ucode_section); | 952 | &first_ucode_section); |
953 | if (ret) | 953 | if (ret) |
954 | return ret; | 954 | return ret; |
955 | 955 | ||
956 | /* load to FW the binary sections of CPU2 */ | 956 | /* load to FW the binary sections of CPU2 */ |
957 | ret = iwl_pcie_load_cpu_sections_8000b(trans, image, 2, | 957 | ret = iwl_pcie_load_cpu_sections_8000(trans, image, 2, |
958 | &first_ucode_section); | 958 | &first_ucode_section); |
959 | if (ret) | 959 | if (ret) |
960 | return ret; | 960 | return ret; |
961 | 961 | ||
962 | /* wait for image verification to complete */ | ||
963 | ret = iwl_poll_prph_bit(trans, LMPM_SECURE_BOOT_CPU1_STATUS_ADDR_B0, | ||
964 | LMPM_SECURE_BOOT_STATUS_SUCCESS, | ||
965 | LMPM_SECURE_BOOT_STATUS_SUCCESS, | ||
966 | LMPM_SECURE_TIME_OUT); | ||
967 | if (ret < 0) { | ||
968 | reg = iwl_read_prph(trans, | ||
969 | LMPM_SECURE_BOOT_CPU1_STATUS_ADDR_B0); | ||
970 | |||
971 | IWL_ERR(trans, "Timeout on secure boot process, reg = %x\n", | ||
972 | reg); | ||
973 | return ret; | ||
974 | } | ||
975 | |||
976 | return 0; | 962 | return 0; |
977 | } | 963 | } |
978 | 964 | ||
979 | static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, | 965 | static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, |
980 | const struct fw_img *fw, bool run_in_rfkill) | 966 | const struct fw_img *fw, bool run_in_rfkill) |
981 | { | 967 | { |
982 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
983 | int ret; | 968 | int ret; |
984 | bool hw_rfkill; | 969 | bool hw_rfkill; |
985 | 970 | ||
@@ -1009,9 +994,6 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, | |||
1009 | return ret; | 994 | return ret; |
1010 | } | 995 | } |
1011 | 996 | ||
1012 | /* init ref_count to 1 (should be cleared when ucode is loaded) */ | ||
1013 | trans_pcie->ref_count = 1; | ||
1014 | |||
1015 | /* make sure rfkill handshake bits are cleared */ | 997 | /* make sure rfkill handshake bits are cleared */ |
1016 | iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); | 998 | iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); |
1017 | iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, | 999 | iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, |
@@ -1026,9 +1008,8 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, | |||
1026 | iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); | 1008 | iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); |
1027 | 1009 | ||
1028 | /* Load the given image to the HW */ | 1010 | /* Load the given image to the HW */ |
1029 | if ((trans->cfg->device_family == IWL_DEVICE_FAMILY_8000) && | 1011 | if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000) |
1030 | (CSR_HW_REV_STEP(trans->hw_rev) != SILICON_A_STEP)) | 1012 | return iwl_pcie_load_given_ucode_8000(trans, fw); |
1031 | return iwl_pcie_load_given_ucode_8000b(trans, fw); | ||
1032 | else | 1013 | else |
1033 | return iwl_pcie_load_given_ucode(trans, fw); | 1014 | return iwl_pcie_load_given_ucode(trans, fw); |
1034 | } | 1015 | } |
@@ -1330,6 +1311,9 @@ static void iwl_trans_pcie_configure(struct iwl_trans *trans, | |||
1330 | trans_pcie->bc_table_dword = trans_cfg->bc_table_dword; | 1311 | trans_pcie->bc_table_dword = trans_cfg->bc_table_dword; |
1331 | trans_pcie->scd_set_active = trans_cfg->scd_set_active; | 1312 | trans_pcie->scd_set_active = trans_cfg->scd_set_active; |
1332 | 1313 | ||
1314 | /* init ref_count to 1 (should be cleared when ucode is loaded) */ | ||
1315 | trans_pcie->ref_count = 1; | ||
1316 | |||
1333 | /* Initialize NAPI here - it should be before registering to mac80211 | 1317 | /* Initialize NAPI here - it should be before registering to mac80211 |
1334 | * in the opmode but after the HW struct is allocated. | 1318 | * in the opmode but after the HW struct is allocated. |
1335 | * As this function may be called again in some corner cases don't | 1319 | * As this function may be called again in some corner cases don't |
diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c index 074f716020aa..01f56c7df8b5 100644 --- a/drivers/net/wireless/rtlwifi/base.c +++ b/drivers/net/wireless/rtlwifi/base.c | |||
@@ -1315,7 +1315,8 @@ static void setup_arp_tx(struct rtl_priv *rtlpriv, struct rtl_ps_ctl *ppsc) | |||
1315 | } | 1315 | } |
1316 | 1316 | ||
1317 | /*should call before software enc*/ | 1317 | /*should call before software enc*/ |
1318 | u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx) | 1318 | u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx, |
1319 | bool is_enc) | ||
1319 | { | 1320 | { |
1320 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 1321 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
1321 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | 1322 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); |
@@ -1344,7 +1345,9 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx) | |||
1344 | break; | 1345 | break; |
1345 | } | 1346 | } |
1346 | 1347 | ||
1347 | offset = mac_hdr_len + SNAP_SIZE + encrypt_header_len; | 1348 | offset = mac_hdr_len + SNAP_SIZE; |
1349 | if (is_enc) | ||
1350 | offset += encrypt_header_len; | ||
1348 | ether_type = be16_to_cpup((__be16 *)(skb->data + offset)); | 1351 | ether_type = be16_to_cpup((__be16 *)(skb->data + offset)); |
1349 | 1352 | ||
1350 | if (ETH_P_IP == ether_type) { | 1353 | if (ETH_P_IP == ether_type) { |
diff --git a/drivers/net/wireless/rtlwifi/base.h b/drivers/net/wireless/rtlwifi/base.h index ff9a4bfd4515..74233d601a90 100644 --- a/drivers/net/wireless/rtlwifi/base.h +++ b/drivers/net/wireless/rtlwifi/base.h | |||
@@ -120,7 +120,8 @@ bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx); | |||
120 | int rtlwifi_rate_mapping(struct ieee80211_hw *hw, bool isht, | 120 | int rtlwifi_rate_mapping(struct ieee80211_hw *hw, bool isht, |
121 | bool isvht, u8 desc_rate); | 121 | bool isvht, u8 desc_rate); |
122 | bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb); | 122 | bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb); |
123 | u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx); | 123 | u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx, |
124 | bool is_enc); | ||
124 | 125 | ||
125 | void rtl_beacon_statistic(struct ieee80211_hw *hw, struct sk_buff *skb); | 126 | void rtl_beacon_statistic(struct ieee80211_hw *hw, struct sk_buff *skb); |
126 | int rtl_tx_agg_start(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | 127 | int rtl_tx_agg_start(struct ieee80211_hw *hw, struct ieee80211_vif *vif, |
diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index 8c45cf44ce24..f46c9d7f6528 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c | |||
@@ -887,7 +887,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) | |||
887 | unicast = true; | 887 | unicast = true; |
888 | rtlpriv->stats.rxbytesunicast += skb->len; | 888 | rtlpriv->stats.rxbytesunicast += skb->len; |
889 | } | 889 | } |
890 | rtl_is_special_data(hw, skb, false); | 890 | rtl_is_special_data(hw, skb, false, true); |
891 | 891 | ||
892 | if (ieee80211_is_data(fc)) { | 892 | if (ieee80211_is_data(fc)) { |
893 | rtlpriv->cfg->ops->led_control(hw, LED_CTL_RX); | 893 | rtlpriv->cfg->ops->led_control(hw, LED_CTL_RX); |
diff --git a/drivers/net/wireless/rtlwifi/rc.c b/drivers/net/wireless/rtlwifi/rc.c index 7863bd278b22..74c14ce28238 100644 --- a/drivers/net/wireless/rtlwifi/rc.c +++ b/drivers/net/wireless/rtlwifi/rc.c | |||
@@ -56,7 +56,8 @@ static u8 _rtl_rc_get_highest_rix(struct rtl_priv *rtlpriv, | |||
56 | wireless_mode = sta_entry->wireless_mode; | 56 | wireless_mode = sta_entry->wireless_mode; |
57 | } | 57 | } |
58 | 58 | ||
59 | if (rtl_is_special_data(rtlpriv->mac80211.hw, skb, true) || not_data) { | 59 | if (rtl_is_special_data(rtlpriv->mac80211.hw, skb, true, false) || |
60 | not_data) { | ||
60 | return 0; | 61 | return 0; |
61 | } else { | 62 | } else { |
62 | if (rtlhal->current_bandtype == BAND_ON_2_4G) { | 63 | if (rtlhal->current_bandtype == BAND_ON_2_4G) { |
@@ -201,7 +202,7 @@ static void rtl_tx_status(void *ppriv, | |||
201 | if (!priv_sta || !ieee80211_is_data(fc)) | 202 | if (!priv_sta || !ieee80211_is_data(fc)) |
202 | return; | 203 | return; |
203 | 204 | ||
204 | if (rtl_is_special_data(mac->hw, skb, true)) | 205 | if (rtl_is_special_data(mac->hw, skb, true, true)) |
205 | return; | 206 | return; |
206 | 207 | ||
207 | if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) || | 208 | if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) || |
diff --git a/drivers/net/wireless/ti/wl1251/main.c b/drivers/net/wireless/ti/wl1251/main.c index d1e9a13be910..5d54d16a59e7 100644 --- a/drivers/net/wireless/ti/wl1251/main.c +++ b/drivers/net/wireless/ti/wl1251/main.c | |||
@@ -1608,7 +1608,7 @@ int wl1251_free_hw(struct wl1251 *wl) | |||
1608 | } | 1608 | } |
1609 | EXPORT_SYMBOL_GPL(wl1251_free_hw); | 1609 | EXPORT_SYMBOL_GPL(wl1251_free_hw); |
1610 | 1610 | ||
1611 | MODULE_DESCRIPTION("TI wl1251 Wireles LAN Driver Core"); | 1611 | MODULE_DESCRIPTION("TI wl1251 Wireless LAN Driver Core"); |
1612 | MODULE_LICENSE("GPL"); | 1612 | MODULE_LICENSE("GPL"); |
1613 | MODULE_AUTHOR("Kalle Valo <kvalo@adurom.com>"); | 1613 | MODULE_AUTHOR("Kalle Valo <kvalo@adurom.com>"); |
1614 | MODULE_FIRMWARE(WL1251_FW_NAME); | 1614 | MODULE_FIRMWARE(WL1251_FW_NAME); |
diff --git a/drivers/ssb/driver_pcicore.c b/drivers/ssb/driver_pcicore.c index d75b72ba2672..15a7ee3859dd 100644 --- a/drivers/ssb/driver_pcicore.c +++ b/drivers/ssb/driver_pcicore.c | |||
@@ -357,6 +357,15 @@ static void ssb_pcicore_init_hostmode(struct ssb_pcicore *pc) | |||
357 | pcicore_write32(pc, SSB_PCICORE_SBTOPCI2, | 357 | pcicore_write32(pc, SSB_PCICORE_SBTOPCI2, |
358 | SSB_PCICORE_SBTOPCI_MEM | SSB_PCI_DMA); | 358 | SSB_PCICORE_SBTOPCI_MEM | SSB_PCI_DMA); |
359 | 359 | ||
360 | /* | ||
361 | * Accessing PCI config without a proper delay after devices reset (not | ||
362 | * GPIO reset) was causing reboots on WRT300N v1.0. | ||
363 | * Tested delay 850 us lowered reboot chance to 50-80%, 1000 us fixed it | ||
364 | * completely. Flushing all writes was also tested but with no luck. | ||
365 | */ | ||
366 | if (pc->dev->bus->chip_id == 0x4704) | ||
367 | usleep_range(1000, 2000); | ||
368 | |||
360 | /* Enable PCI bridge BAR0 prefetch and burst */ | 369 | /* Enable PCI bridge BAR0 prefetch and burst */ |
361 | val = PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; | 370 | val = PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; |
362 | ssb_extpci_write_config(pc, 0, 0, 0, PCI_COMMAND, &val, 2); | 371 | ssb_extpci_write_config(pc, 0, 0, 0, PCI_COMMAND, &val, 2); |