From bd1d395070cca4f42a93e520b0597274789274a4 Mon Sep 17 00:00:00 2001 From: Tamizh chelvam Date: Mon, 6 Aug 2018 12:39:01 +0300 Subject: [PATCH 001/276] ath10k: fix kernel panic by moving pci flush after napi_disable When continuously running wifi up/down sequence, the napi poll can be scheduled after the CE buffers being freed by ath10k_pci_flush Steps: In a certain condition, during wifi down below scenario might occur. ath10k_stop->ath10k_hif_stop->napi_schedule->ath10k_pci_flush->napi_poll(napi_synchronize). In the above scenario, CE buffer entries will be freed up and become NULL in ath10k_pci_flush. And the napi_poll has been invoked after the flush process and it will try to get the skb from the CE buffer entry and perform some action on that. Since the CE buffer already cleaned by pci flush this action will create NULL pointer dereference and trigger below kernel panic. Unable to handle kernel NULL pointer dereference at virtual address 0000005c PC is at ath10k_pci_htt_rx_cb+0x64/0x3ec [ath10k_pci] ath10k_pci_htt_rx_cb [ath10k_pci] ath10k_ce_per_engine_service+0x74/0xc4 [ath10k_pci] ath10k_ce_per_engine_service [ath10k_pci] ath10k_ce_per_engine_service_any+0x74/0x80 [ath10k_pci] ath10k_ce_per_engine_service_any [ath10k_pci] ath10k_pci_napi_poll+0x48/0xec [ath10k_pci] ath10k_pci_napi_poll [ath10k_pci] net_rx_action+0xac/0x160 net_rx_action __do_softirq+0xdc/0x208 __do_softirq irq_exit+0x84/0xe0 irq_exit __handle_domain_irq+0x80/0xa0 __handle_domain_irq gic_handle_irq+0x38/0x5c gic_handle_irq __irq_usr+0x44/0x60 Tested on QCA4019 and firmware version 10.4.3.2.1.1-00010 Signed-off-by: Tamizh chelvam Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/ahb.c | 4 ++-- drivers/net/wireless/ath/ath10k/pci.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/ahb.c b/drivers/net/wireless/ath/ath10k/ahb.c index c9bd0e2b5db7..be90c9e9e5bc 100644 --- a/drivers/net/wireless/ath/ath10k/ahb.c +++ b/drivers/net/wireless/ath/ath10k/ahb.c @@ -655,10 +655,10 @@ static void ath10k_ahb_hif_stop(struct ath10k *ar) ath10k_ahb_irq_disable(ar); synchronize_irq(ar_ahb->irq); - ath10k_pci_flush(ar); - napi_synchronize(&ar->napi); napi_disable(&ar->napi); + + ath10k_pci_flush(ar); } static int ath10k_ahb_hif_power_up(struct ath10k *ar) diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c index af2cf55c4c1e..97fa5c74f2fe 100644 --- a/drivers/net/wireless/ath/ath10k/pci.c +++ b/drivers/net/wireless/ath/ath10k/pci.c @@ -2068,9 +2068,9 @@ static void ath10k_pci_hif_stop(struct ath10k *ar) ath10k_pci_irq_disable(ar); ath10k_pci_irq_sync(ar); - ath10k_pci_flush(ar); napi_synchronize(&ar->napi); napi_disable(&ar->napi); + ath10k_pci_flush(ar); spin_lock_irqsave(&ar_pci->ps_lock, flags); WARN_ON(ar_pci->ps_wake_refcount > 0); From 3f96556f639e6cc507cc682406e83671f8e7c1ea Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Mon, 6 Aug 2018 12:39:07 +0300 Subject: [PATCH 002/276] wcn36xx: Use kmemdup instead of duplicating it in wcn36xx_smd_process_ptt_msg_rsp Replace calls to kmalloc followed by a memcpy with a direct call to kmemdup. Signed-off-by: YueHaibing Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/wcn36xx/smd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c b/drivers/net/wireless/ath/wcn36xx/smd.c index 00098f24116d..1d2d698fb779 100644 --- a/drivers/net/wireless/ath/wcn36xx/smd.c +++ b/drivers/net/wireless/ath/wcn36xx/smd.c @@ -792,10 +792,10 @@ static int wcn36xx_smd_process_ptt_msg_rsp(void *buf, size_t len, rsp->header.len - sizeof(rsp->ptt_msg_resp_status)); if (rsp->header.len > 0) { - *p_ptt_rsp_msg = kmalloc(rsp->header.len, GFP_ATOMIC); + *p_ptt_rsp_msg = kmemdup(rsp->ptt_msg, rsp->header.len, + GFP_ATOMIC); if (!*p_ptt_rsp_msg) return -ENOMEM; - memcpy(*p_ptt_rsp_msg, rsp->ptt_msg, rsp->header.len); } return ret; } From d410e28f3ae476e1572b8893c646ef44fae7bbbd Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Mon, 6 Aug 2018 12:39:16 +0300 Subject: [PATCH 003/276] wcn36xx: use dma_zalloc_coherent instead of allocator/memset Use dma_zalloc_coherent instead of dma_alloc_coherent followed by memset 0. Signed-off-by: YueHaibing Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/wcn36xx/dxe.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/ath/wcn36xx/dxe.c b/drivers/net/wireless/ath/wcn36xx/dxe.c index 06cfe8d311f3..5ab3e31c9ffa 100644 --- a/drivers/net/wireless/ath/wcn36xx/dxe.c +++ b/drivers/net/wireless/ath/wcn36xx/dxe.c @@ -174,13 +174,12 @@ static int wcn36xx_dxe_init_descs(struct device *dev, struct wcn36xx_dxe_ch *wcn int i; size = wcn_ch->desc_num * sizeof(struct wcn36xx_dxe_desc); - wcn_ch->cpu_addr = dma_alloc_coherent(dev, size, &wcn_ch->dma_addr, - GFP_KERNEL); + wcn_ch->cpu_addr = dma_zalloc_coherent(dev, size, + &wcn_ch->dma_addr, + GFP_KERNEL); if (!wcn_ch->cpu_addr) return -ENOMEM; - memset(wcn_ch->cpu_addr, 0, size); - cur_dxe = (struct wcn36xx_dxe_desc *)wcn_ch->cpu_addr; cur_ctl = wcn_ch->head_blk_ctl; @@ -628,13 +627,13 @@ int wcn36xx_dxe_allocate_mem_pools(struct wcn36xx *wcn) 16 - (WCN36XX_BD_CHUNK_SIZE % 8); s = wcn->mgmt_mem_pool.chunk_size * WCN36XX_DXE_CH_DESC_NUMB_TX_H; - cpu_addr = dma_alloc_coherent(wcn->dev, s, &wcn->mgmt_mem_pool.phy_addr, - GFP_KERNEL); + cpu_addr = dma_zalloc_coherent(wcn->dev, s, + &wcn->mgmt_mem_pool.phy_addr, + GFP_KERNEL); if (!cpu_addr) goto out_err; wcn->mgmt_mem_pool.virt_addr = cpu_addr; - memset(cpu_addr, 0, s); /* Allocate BD headers for DATA frames */ @@ -643,13 +642,13 @@ int wcn36xx_dxe_allocate_mem_pools(struct wcn36xx *wcn) 16 - (WCN36XX_BD_CHUNK_SIZE % 8); s = wcn->data_mem_pool.chunk_size * WCN36XX_DXE_CH_DESC_NUMB_TX_L; - cpu_addr = dma_alloc_coherent(wcn->dev, s, &wcn->data_mem_pool.phy_addr, - GFP_KERNEL); + cpu_addr = dma_zalloc_coherent(wcn->dev, s, + &wcn->data_mem_pool.phy_addr, + GFP_KERNEL); if (!cpu_addr) goto out_err; wcn->data_mem_pool.virt_addr = cpu_addr; - memset(cpu_addr, 0, s); return 0; From 58da3b42307061b71f2dcce2bd1185d578a3aa53 Mon Sep 17 00:00:00 2001 From: Rakesh Pillai Date: Mon, 6 Aug 2018 20:18:08 +0530 Subject: [PATCH 004/276] ath10k: skip resetting rx filter for WCN3990 WCN3990 has the MAC_PCU_ADDR1 configured properly and hence it will not send spurious ack frames during boot up. Hence the reset_rx_filter workaround is not needed for WCN3990. Add a hw_param to indicate if hardware rx filter reset is needed and skip the reset_rx_filter for WCN3990. Tested HW: WCN3990 Tested FW: WLAN.HL.2.0-01188-QCAHLSWMTPLZ-1 Signed-off-by: Rakesh Pillai Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/core.c | 17 ++++++++++++++++- drivers/net/wireless/ath/ath10k/hw.h | 5 +++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c index c40cd129afe7..ebc213884a9a 100644 --- a/drivers/net/wireless/ath/ath10k/core.c +++ b/drivers/net/wireless/ath/ath10k/core.c @@ -91,6 +91,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL, .shadow_reg_support = false, .rri_on_ddr = false, + .hw_filter_reset_required = true, }, { .id = QCA988X_HW_2_0_VERSION, @@ -124,6 +125,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .per_ce_irq = false, .shadow_reg_support = false, .rri_on_ddr = false, + .hw_filter_reset_required = true, }, { .id = QCA9887_HW_1_0_VERSION, @@ -157,6 +159,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .per_ce_irq = false, .shadow_reg_support = false, .rri_on_ddr = false, + .hw_filter_reset_required = true, }, { .id = QCA6174_HW_2_1_VERSION, @@ -189,6 +192,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .per_ce_irq = false, .shadow_reg_support = false, .rri_on_ddr = false, + .hw_filter_reset_required = true, }, { .id = QCA6174_HW_2_1_VERSION, @@ -221,6 +225,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .per_ce_irq = false, .shadow_reg_support = false, .rri_on_ddr = false, + .hw_filter_reset_required = true, }, { .id = QCA6174_HW_3_0_VERSION, @@ -253,6 +258,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .per_ce_irq = false, .shadow_reg_support = false, .rri_on_ddr = false, + .hw_filter_reset_required = true, }, { .id = QCA6174_HW_3_2_VERSION, @@ -288,6 +294,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .per_ce_irq = false, .shadow_reg_support = false, .rri_on_ddr = false, + .hw_filter_reset_required = true, }, { .id = QCA99X0_HW_2_0_DEV_VERSION, @@ -326,6 +333,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .per_ce_irq = false, .shadow_reg_support = false, .rri_on_ddr = false, + .hw_filter_reset_required = true, }, { .id = QCA9984_HW_1_0_DEV_VERSION, @@ -369,6 +377,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .per_ce_irq = false, .shadow_reg_support = false, .rri_on_ddr = false, + .hw_filter_reset_required = true, }, { .id = QCA9888_HW_2_0_DEV_VERSION, @@ -411,6 +420,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .per_ce_irq = false, .shadow_reg_support = false, .rri_on_ddr = false, + .hw_filter_reset_required = true, }, { .id = QCA9377_HW_1_0_DEV_VERSION, @@ -443,6 +453,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .per_ce_irq = false, .shadow_reg_support = false, .rri_on_ddr = false, + .hw_filter_reset_required = true, }, { .id = QCA9377_HW_1_1_DEV_VERSION, @@ -477,6 +488,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .per_ce_irq = false, .shadow_reg_support = false, .rri_on_ddr = false, + .hw_filter_reset_required = true, }, { .id = QCA4019_HW_1_0_DEV_VERSION, @@ -516,6 +528,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .per_ce_irq = false, .shadow_reg_support = false, .rri_on_ddr = false, + .hw_filter_reset_required = true, }, { .id = WCN3990_HW_1_0_DEV_VERSION, @@ -539,6 +552,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .per_ce_irq = true, .shadow_reg_support = true, .rri_on_ddr = true, + .hw_filter_reset_required = false, }, }; @@ -2405,7 +2419,8 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode, * possible to implicitly make it correct by creating a dummy vdev and * then deleting it. */ - if (mode == ATH10K_FIRMWARE_MODE_NORMAL) { + if (ar->hw_params.hw_filter_reset_required && + mode == ATH10K_FIRMWARE_MODE_NORMAL) { status = ath10k_core_reset_rx_filter(ar); if (status) { ath10k_err(ar, diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h index 977f79ebb4fd..fac58c3c576a 100644 --- a/drivers/net/wireless/ath/ath10k/hw.h +++ b/drivers/net/wireless/ath/ath10k/hw.h @@ -589,6 +589,11 @@ struct ath10k_hw_params { /* Number of bytes to be the offset for each FFT sample */ int spectral_bin_offset; + + /* targets which require hw filter reset during boot up, + * to avoid it sending spurious acks. + */ + bool hw_filter_reset_required; }; struct htt_rx_desc; From a9911937e7d332761e8c4fcbc7ba0426bdc3956f Mon Sep 17 00:00:00 2001 From: Martin Willi Date: Wed, 22 Aug 2018 09:39:52 +0200 Subject: [PATCH 005/276] ath10k: schedule hardware restart if WMI command times out When running in AP mode, ath10k sometimes suffers from TX credit starvation. The issue is hard to reproduce and shows up once in a few days, but has been repeatedly seen with QCA9882 and a large range of firmwares, including 10.2.4.70.67. Once the module is in this state, TX credits are never replenished, which results in "SWBA overrun" errors, as no beacons can be sent. Even worse, WMI commands run in a timeout while holding the conf mutex for three seconds each, making any further operations slow and the whole system unresponsive. The firmware/driver never recovers from that state automatically, and triggering TX flush or warm restarts won't work over WMI. So issue a hardware restart if a WMI command times out due to missing TX credits. This implies a connectivity outage of about 1.4s in AP mode, but brings back the interface and the whole system to a usable state. WMI command timeouts have not been seen in absent of this specific issue, so taking such drastic actions seems legitimate. Signed-off-by: Martin Willi Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/wmi.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index fd612d2905b0..40ce0e4006bc 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -1869,6 +1869,12 @@ int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id) if (ret) dev_kfree_skb_any(skb); + if (ret == -EAGAIN) { + ath10k_warn(ar, "wmi command %d timeout, restarting hardware\n", + cmd_id); + queue_work(ar->workqueue, &ar->restart_work); + } + return ret; } From 06ae8dc00433797555481ee3391cab6acaf1a5db Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Thu, 23 Aug 2018 20:12:47 -0500 Subject: [PATCH 006/276] ath10k: use struct_size() in kzalloc() One of the more common cases of allocation size calculations is finding the size of a structure that has a zero-sized array at the end, along with memory for some number of elements for that array. For example: struct foo { int stuff; void *entry[]; }; instance = kzalloc(sizeof(struct foo) + sizeof(void *) * count, GFP_KERNEL); Instead of leaving these open-coded and prone to type mistakes, we can now use the new struct_size() helper: instance = kzalloc(struct_size(instance, entry, count), GFP_KERNEL); This issue was detected with the help of Coccinelle. Signed-off-by: Gustavo A. R. Silva Reviewed-by: Kees Cook Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/ce.c | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/ce.c b/drivers/net/wireless/ath/ath10k/ce.c index 18c709c484e7..d0381aaad01c 100644 --- a/drivers/net/wireless/ath/ath10k/ce.c +++ b/drivers/net/wireless/ath/ath10k/ce.c @@ -1416,10 +1416,8 @@ ath10k_ce_alloc_src_ring(struct ath10k *ar, unsigned int ce_id, nentries = roundup_pow_of_two(nentries); - src_ring = kzalloc(sizeof(*src_ring) + - (nentries * - sizeof(*src_ring->per_transfer_context)), - GFP_KERNEL); + src_ring = kzalloc(struct_size(src_ring, per_transfer_context, + nentries), GFP_KERNEL); if (src_ring == NULL) return ERR_PTR(-ENOMEM); @@ -1476,10 +1474,8 @@ ath10k_ce_alloc_src_ring_64(struct ath10k *ar, unsigned int ce_id, nentries = roundup_pow_of_two(nentries); - src_ring = kzalloc(sizeof(*src_ring) + - (nentries * - sizeof(*src_ring->per_transfer_context)), - GFP_KERNEL); + src_ring = kzalloc(struct_size(src_ring, per_transfer_context, + nentries), GFP_KERNEL); if (!src_ring) return ERR_PTR(-ENOMEM); @@ -1534,10 +1530,8 @@ ath10k_ce_alloc_dest_ring(struct ath10k *ar, unsigned int ce_id, nentries = roundup_pow_of_two(attr->dest_nentries); - dest_ring = kzalloc(sizeof(*dest_ring) + - (nentries * - sizeof(*dest_ring->per_transfer_context)), - GFP_KERNEL); + dest_ring = kzalloc(struct_size(dest_ring, per_transfer_context, + nentries), GFP_KERNEL); if (dest_ring == NULL) return ERR_PTR(-ENOMEM); @@ -1580,10 +1574,8 @@ ath10k_ce_alloc_dest_ring_64(struct ath10k *ar, unsigned int ce_id, nentries = roundup_pow_of_two(attr->dest_nentries); - dest_ring = kzalloc(sizeof(*dest_ring) + - (nentries * - sizeof(*dest_ring->per_transfer_context)), - GFP_KERNEL); + dest_ring = kzalloc(struct_size(dest_ring, per_transfer_context, + nentries), GFP_KERNEL); if (!dest_ring) return ERR_PTR(-ENOMEM); From bf05e0fe7da443a518db883112d4485ae65ba9d7 Mon Sep 17 00:00:00 2001 From: Varsha Rao Date: Wed, 25 Jul 2018 20:53:03 +0200 Subject: [PATCH 007/276] ath9k: Remove unnecessary parentheses Remove extra parentheses to fix the clang warning of extraneous parentheses. Signed-off-by: Varsha Rao Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath9k/debug_sta.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/debug_sta.c b/drivers/net/wireless/ath/ath9k/debug_sta.c index a6f45f1bb5bb..ed8b77a74630 100644 --- a/drivers/net/wireless/ath/ath9k/debug_sta.c +++ b/drivers/net/wireless/ath/ath9k/debug_sta.c @@ -116,7 +116,7 @@ void ath_debug_rate_stats(struct ath_softc *sc, if (rxs->rate_idx >= ARRAY_SIZE(rstats->ht_stats)) goto exit; - if ((rxs->bw == RATE_INFO_BW_40)) + if (rxs->bw == RATE_INFO_BW_40) rstats->ht_stats[rxs->rate_idx].ht40_cnt++; else rstats->ht_stats[rxs->rate_idx].ht20_cnt++; From a2f73a167dc1d4940c59099c18d23c15ac9aee71 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Thu, 16 Aug 2018 13:50:30 +0100 Subject: [PATCH 008/276] ath9k: remove unused array firstep_table Array firstep_table is being assigned but is never used hence it is redundant and can be removed. Cleans up clang warning: warning: 'firstep_table' defined but not used [-Wunused-const-variable=] Signed-off-by: Colin Ian King Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath9k/ar5008_phy.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c index ef2dd68d3f77..11d6f975c87d 100644 --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c @@ -37,10 +37,6 @@ #define AR5008_11NG_HT_SS_SHIFT 12 #define AR5008_11NG_HT_DS_SHIFT 20 -static const int firstep_table[] = -/* level: 0 1 2 3 4 5 6 7 8 */ - { -4, -2, 0, 2, 4, 6, 8, 10, 12 }; /* lvl 0-8, default 2 */ - /* * register values to turn OFDM weak signal detection OFF */ From d9c52fd17cb483bd8a470398afcb79f86c1b77c8 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 20 Aug 2018 11:37:51 +0200 Subject: [PATCH 009/276] ath9k: fix tx99 with monitor mode interface Tx99 is typically configured via a monitor mode interface, which does not get added to the driver as a vif. Since the code currently expects a configured virtual interface for tx99, enabling tx99 via debugfs fails. Since the vif is not needed anyway, remove all checks for it. Signed-off-by: Felix Fietkau [kvalo@codeaurora.org: s/CPTCFG/CONFIG/] Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath9k/ath9k.h | 1 - drivers/net/wireless/ath/ath9k/main.c | 12 +++--------- drivers/net/wireless/ath/ath9k/tx99.c | 9 --------- drivers/net/wireless/ath/ath9k/xmit.c | 2 +- 4 files changed, 4 insertions(+), 20 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 21ba20981a80..003e9fb456ac 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -1074,7 +1074,6 @@ struct ath_softc { struct ath_spec_scan_priv spec_priv; - struct ieee80211_vif *tx99_vif; struct sk_buff *tx99_skb; bool tx99_state; s16 tx99_power; diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 1049773378f2..6ce4b9f1dcb4 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1251,15 +1251,10 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, struct ath_vif *avp = (void *)vif->drv_priv; struct ath_node *an = &avp->mcast_node; - mutex_lock(&sc->mutex); + if (IS_ENABLED(CONFIG_ATH9K_TX99)) + return -EOPNOTSUPP; - if (IS_ENABLED(CONFIG_ATH9K_TX99)) { - if (sc->cur_chan->nvifs >= 1) { - mutex_unlock(&sc->mutex); - return -EOPNOTSUPP; - } - sc->tx99_vif = vif; - } + mutex_lock(&sc->mutex); ath_dbg(common, CONFIG, "Attach a VIF of type: %d\n", vif->type); sc->cur_chan->nvifs++; @@ -1342,7 +1337,6 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, ath9k_p2p_remove_vif(sc, vif); sc->cur_chan->nvifs--; - sc->tx99_vif = NULL; if (!ath9k_is_chanctx_enabled()) list_del(&avp->list); diff --git a/drivers/net/wireless/ath/ath9k/tx99.c b/drivers/net/wireless/ath/ath9k/tx99.c index ce50d8f5835e..9b05ffb68c34 100644 --- a/drivers/net/wireless/ath/ath9k/tx99.c +++ b/drivers/net/wireless/ath/ath9k/tx99.c @@ -54,12 +54,6 @@ static struct sk_buff *ath9k_build_tx99_skb(struct ath_softc *sc) struct ieee80211_hdr *hdr; struct ieee80211_tx_info *tx_info; struct sk_buff *skb; - struct ath_vif *avp; - - if (!sc->tx99_vif) - return NULL; - - avp = (struct ath_vif *)sc->tx99_vif->drv_priv; skb = alloc_skb(len, GFP_KERNEL); if (!skb) @@ -77,14 +71,11 @@ static struct sk_buff *ath9k_build_tx99_skb(struct ath_softc *sc) memcpy(hdr->addr2, hw->wiphy->perm_addr, ETH_ALEN); memcpy(hdr->addr3, hw->wiphy->perm_addr, ETH_ALEN); - hdr->seq_ctrl |= cpu_to_le16(avp->seq_no); - tx_info = IEEE80211_SKB_CB(skb); memset(tx_info, 0, sizeof(*tx_info)); rate = &tx_info->control.rates[0]; tx_info->band = sc->cur_chan->chandef.chan->band; tx_info->flags = IEEE80211_TX_CTL_NO_ACK; - tx_info->control.vif = sc->tx99_vif; rate->count = 1; if (ah->curchan && IS_CHAN_HT(ah->curchan)) { rate->flags |= IEEE80211_TX_RC_MCS; diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 43b6c8508e49..66b6a8872c06 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -2973,7 +2973,7 @@ int ath9k_tx99_send(struct ath_softc *sc, struct sk_buff *skb, return -EINVAL; } - ath_set_rates(sc->tx99_vif, NULL, bf); + ath_set_rates(NULL, NULL, bf); ath9k_hw_set_desc_link(sc->sc_ah, bf->bf_desc, bf->bf_daddr); ath9k_hw_tx99_start(sc->sc_ah, txctl->txq->axq_qnum); From 4ac1f003e72ad46b0dfc22954bf012adb809d08e Mon Sep 17 00:00:00 2001 From: Varsha Rao Date: Wed, 25 Jul 2018 20:49:48 +0200 Subject: [PATCH 010/276] ath6kl: Remove unnecessary parentheses Remove extra parentheses to fix the clang warning of extraneous parentheses. Signed-off-by: Varsha Rao Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c index 0c61dbaa62a4..cb59016c723b 100644 --- a/drivers/net/wireless/ath/ath6kl/main.c +++ b/drivers/net/wireless/ath/ath6kl/main.c @@ -638,7 +638,7 @@ void ath6kl_connect_event(struct ath6kl_vif *vif, u16 channel, u8 *bssid, memcpy(vif->bssid, bssid, sizeof(vif->bssid)); vif->bss_ch = channel; - if ((vif->nw_type == INFRA_NETWORK)) { + if (vif->nw_type == INFRA_NETWORK) { ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx, vif->listen_intvl_t, 0); ath6kl_check_ch_switch(ar, channel); From 32dcfe8316cdbd885542967c0c85f5b9de78874b Mon Sep 17 00:00:00 2001 From: Karthick Gopalasubramanian Date: Thu, 23 Aug 2018 14:47:05 +0300 Subject: [PATCH 011/276] wil6210: remove reset file from debugfs Reset file is not used and may cause race conditions with operational driver if used. Signed-off-by: Karthick Gopalasubramanian Signed-off-by: Maya Erez Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/wil6210/debugfs.c | 27 ---------------------- 1 file changed, 27 deletions(-) diff --git a/drivers/net/wireless/ath/wil6210/debugfs.c b/drivers/net/wireless/ath/wil6210/debugfs.c index 51c3330bc316..4057f0685947 100644 --- a/drivers/net/wireless/ath/wil6210/debugfs.c +++ b/drivers/net/wireless/ath/wil6210/debugfs.c @@ -725,32 +725,6 @@ struct dentry *wil_debugfs_create_ioblob(const char *name, return debugfs_create_file(name, mode, parent, wil_blob, &fops_ioblob); } -/*---reset---*/ -static ssize_t wil_write_file_reset(struct file *file, const char __user *buf, - size_t len, loff_t *ppos) -{ - struct wil6210_priv *wil = file->private_data; - struct net_device *ndev = wil->main_ndev; - - /** - * BUG: - * this code does NOT sync device state with the rest of system - * use with care, debug only!!! - */ - rtnl_lock(); - dev_close(ndev); - ndev->flags &= ~IFF_UP; - rtnl_unlock(); - wil_reset(wil, true); - - return len; -} - -static const struct file_operations fops_reset = { - .write = wil_write_file_reset, - .open = simple_open, -}; - /*---write channel 1..4 to rxon for it, 0 to rxoff---*/ static ssize_t wil_write_file_rxon(struct file *file, const char __user *buf, size_t len, loff_t *ppos) @@ -2451,7 +2425,6 @@ static const struct { {"desc", 0444, &fops_txdesc}, {"bf", 0444, &fops_bf}, {"mem_val", 0644, &fops_memread}, - {"reset", 0244, &fops_reset}, {"rxon", 0244, &fops_rxon}, {"tx_mgmt", 0244, &fops_txmgmt}, {"wmi_send", 0244, &fops_wmi}, From 22b9610ec68716d664aac99cee6e65464cc6c922 Mon Sep 17 00:00:00 2001 From: Alexei Avshalom Lazar Date: Thu, 23 Aug 2018 14:47:06 +0300 Subject: [PATCH 012/276] wil6210: add support for channel 4 wil6210 supports channels 1-3 of the 60GHz band. New FW added support for channel 4. Add support for channel 4 also in wil6210 driver. Signed-off-by: Alexei Avshalom Lazar Signed-off-by: Maya Erez Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/wil6210/cfg80211.c | 22 ++++++++++++++++++++- drivers/net/wireless/ath/wil6210/main.c | 2 ++ drivers/net/wireless/ath/wil6210/wil6210.h | 2 ++ drivers/net/wireless/ath/wil6210/wmi.h | 1 + 4 files changed, 26 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c index f79c337105cb..1bdb026ae85c 100644 --- a/drivers/net/wireless/ath/wil6210/cfg80211.c +++ b/drivers/net/wireless/ath/wil6210/cfg80211.c @@ -48,9 +48,29 @@ static struct ieee80211_channel wil_60ghz_channels[] = { CHAN60G(1, 0), CHAN60G(2, 0), CHAN60G(3, 0), -/* channel 4 not supported yet */ + CHAN60G(4, 0), }; +static int wil_num_supported_channels(struct wil6210_priv *wil) +{ + int num_channels = ARRAY_SIZE(wil_60ghz_channels); + + if (!test_bit(WMI_FW_CAPABILITY_CHANNEL_4, wil->fw_capabilities)) + num_channels--; + + return num_channels; +} + +void update_supported_bands(struct wil6210_priv *wil) +{ + struct wiphy *wiphy = wil_to_wiphy(wil); + + wil_dbg_misc(wil, "update supported bands"); + + wiphy->bands[NL80211_BAND_60GHZ]->n_channels = + wil_num_supported_channels(wil); +} + /* Vendor id to be used in vendor specific command and events * to user space. * NOTE: The authoritative place for definition of QCA_NL80211_VENDOR_ID, diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c index 7debed6bec06..8820cee16a00 100644 --- a/drivers/net/wireless/ath/wil6210/main.c +++ b/drivers/net/wireless/ath/wil6210/main.c @@ -1154,6 +1154,8 @@ void wil_refresh_fw_capabilities(struct wil6210_priv *wil) wil->max_agg_wsize = WIL_MAX_AGG_WSIZE; wil->max_ampdu_size = WIL_MAX_AMPDU_SIZE; } + + update_supported_bands(wil); } void wil_mbox_ring_le2cpus(struct wil6210_mbox_ring *r) diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h index 17c294b1ead1..85565de05840 100644 --- a/drivers/net/wireless/ath/wil6210/wil6210.h +++ b/drivers/net/wireless/ath/wil6210/wil6210.h @@ -1370,4 +1370,6 @@ int wmi_addba_rx_resp_edma(struct wil6210_priv *wil, u8 mid, u8 cid, u8 tid, u8 token, u16 status, bool amsdu, u16 agg_wsize, u16 timeout); +void update_supported_bands(struct wil6210_priv *wil); + #endif /* __WIL6210_H__ */ diff --git a/drivers/net/wireless/ath/wil6210/wmi.h b/drivers/net/wireless/ath/wil6210/wmi.h index 139acb2caf92..f430e1d48e81 100644 --- a/drivers/net/wireless/ath/wil6210/wmi.h +++ b/drivers/net/wireless/ath/wil6210/wmi.h @@ -103,6 +103,7 @@ enum wmi_fw_capability { WMI_FW_CAPABILITY_AMSDU = 23, WMI_FW_CAPABILITY_RAW_MODE = 24, WMI_FW_CAPABILITY_TX_REQ_EXT = 25, + WMI_FW_CAPABILITY_CHANNEL_4 = 26, WMI_FW_CAPABILITY_MAX, }; From 9a65064abdf82934e0ed4744125f9f466f421f57 Mon Sep 17 00:00:00 2001 From: Dedy Lansky Date: Thu, 23 Aug 2018 14:47:07 +0300 Subject: [PATCH 013/276] wil6210: drop Rx multicast packets that are looped-back to STA Delivering a looped-back multicast packet to network stack can cause higher layer protocols to fail like for example IPv6 DAD. In STA mode, upon receiving Rx multicast packet, check if the source MAC address is equal to our own MAC address and if so drop the packet. Signed-off-by: Dedy Lansky Signed-off-by: Maya Erez Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/wil6210/txrx.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c index 6a7943e487fb..e7b003b38f45 100644 --- a/drivers/net/wireless/ath/wil6210/txrx.c +++ b/drivers/net/wireless/ath/wil6210/txrx.c @@ -765,7 +765,14 @@ void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev) return; } - if (wdev->iftype == NL80211_IFTYPE_AP && !vif->ap_isolate) { + if (wdev->iftype == NL80211_IFTYPE_STATION) { + if (mcast && ether_addr_equal(eth->h_source, ndev->dev_addr)) { + /* mcast packet looped back to us */ + rc = GRO_DROP; + dev_kfree_skb(skb); + goto stats; + } + } else if (wdev->iftype == NL80211_IFTYPE_AP && !vif->ap_isolate) { if (mcast) { /* send multicast frames both to higher layers in * local net stack and back to the wireless medium From 596bdbcce90fa93f43ebcb99cefea34bd2e27707 Mon Sep 17 00:00:00 2001 From: Maya Erez Date: Thu, 23 Aug 2018 14:47:08 +0300 Subject: [PATCH 014/276] wil6210: set edma variables only for Talyn-MB devices use_rx_hw_reordering is already set to true in wil_set_capabilities for Talyn-MB devices. Remove its setting from wil_priv_init to prevent its activation for older chips. Similarly, move the setting of use_compressed_rx_status to wil_set_capabilities. Signed-off-by: Maya Erez Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/wil6210/main.c | 2 -- drivers/net/wireless/ath/wil6210/pcie_bus.c | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c index 8820cee16a00..827df1cd9a62 100644 --- a/drivers/net/wireless/ath/wil6210/main.c +++ b/drivers/net/wireless/ath/wil6210/main.c @@ -653,8 +653,6 @@ int wil_priv_init(struct wil6210_priv *wil) /* edma configuration can be updated via debugfs before allocation */ wil->num_rx_status_rings = WIL_DEFAULT_NUM_RX_STATUS_RINGS; - wil->use_compressed_rx_status = true; - wil->use_rx_hw_reordering = true; wil->tx_status_ring_order = WIL_TX_SRING_SIZE_ORDER_DEFAULT; /* Rx status ring size should be bigger than the number of RX buffers diff --git a/drivers/net/wireless/ath/wil6210/pcie_bus.c b/drivers/net/wireless/ath/wil6210/pcie_bus.c index 89119e7facd0..c8c6613371d1 100644 --- a/drivers/net/wireless/ath/wil6210/pcie_bus.c +++ b/drivers/net/wireless/ath/wil6210/pcie_bus.c @@ -108,6 +108,7 @@ int wil_set_capabilities(struct wil6210_priv *wil) set_bit(hw_capa_no_flash, wil->hw_capa); wil->use_enhanced_dma_hw = true; wil->use_rx_hw_reordering = true; + wil->use_compressed_rx_status = true; wil_fw_name = ftm_mode ? WIL_FW_NAME_FTM_TALYN : WIL_FW_NAME_TALYN; if (wil_fw_verify_file_exists(wil, wil_fw_name)) From 686ab4f5bd8d696bfeef55ef761c7f7a6ad1b3ec Mon Sep 17 00:00:00 2001 From: Maya Erez Date: Thu, 23 Aug 2018 14:47:09 +0300 Subject: [PATCH 015/276] wil6210: allocate rx reorder buffer only if rx reorder is enabled wil_addba_rx_request allocates the rx reorder buffer regardless of use_rx_hw_reordering settings. Fix this by checking wil->use_rx_hw_reordering before allocating the reorder buffer. Signed-off-by: Maya Erez Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/wil6210/rx_reorder.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/ath/wil6210/rx_reorder.c b/drivers/net/wireless/ath/wil6210/rx_reorder.c index b608aa16b4f1..983bd001b53b 100644 --- a/drivers/net/wireless/ath/wil6210/rx_reorder.c +++ b/drivers/net/wireless/ath/wil6210/rx_reorder.c @@ -382,11 +382,13 @@ __acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock) } /* apply */ - r = wil_tid_ampdu_rx_alloc(wil, agg_wsize, ssn); - spin_lock_bh(&sta->tid_rx_lock); - wil_tid_ampdu_rx_free(wil, sta->tid_rx[tid]); - sta->tid_rx[tid] = r; - spin_unlock_bh(&sta->tid_rx_lock); + if (!wil->use_rx_hw_reordering) { + r = wil_tid_ampdu_rx_alloc(wil, agg_wsize, ssn); + spin_lock_bh(&sta->tid_rx_lock); + wil_tid_ampdu_rx_free(wil, sta->tid_rx[tid]); + sta->tid_rx[tid] = r; + spin_unlock_bh(&sta->tid_rx_lock); + } out: return rc; From df2b53884a5a454bf441ca78e5b57307262c73f4 Mon Sep 17 00:00:00 2001 From: Maya Erez Date: Thu, 23 Aug 2018 14:47:10 +0300 Subject: [PATCH 016/276] wil6210: prevent usage of tx ring 0 for eDMA In enhanced DMA ring 0 is used for RX ring, hence TX ring 0 is an unused element in ring_tx and ring2cid_tid arrays. Initialize ring2cid_tid CID to WIL6210_MAX_CID to prevent a false match of CID 0. Go over the ring_tx and ring2cid_tid from wil_get_min_tx_ring_id and on to prevent access to index 0 in eDMA. Signed-off-by: Maya Erez Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/wil6210/main.c | 7 +++++-- drivers/net/wireless/ath/wil6210/txrx.c | 6 ++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c index 827df1cd9a62..3fcf79924a4c 100644 --- a/drivers/net/wireless/ath/wil6210/main.c +++ b/drivers/net/wireless/ath/wil6210/main.c @@ -223,6 +223,7 @@ __acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock) struct net_device *ndev = vif_to_ndev(vif); struct wireless_dev *wdev = vif_to_wdev(vif); struct wil_sta_info *sta = &wil->sta[cid]; + int min_ring_id = wil_get_min_tx_ring_id(wil); might_sleep(); wil_dbg_misc(wil, "disconnect_cid: CID %d, MID %d, status %d\n", @@ -273,7 +274,7 @@ __acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock) memset(sta->tid_crypto_rx, 0, sizeof(sta->tid_crypto_rx)); memset(&sta->group_crypto_rx, 0, sizeof(sta->group_crypto_rx)); /* release vrings */ - for (i = 0; i < ARRAY_SIZE(wil->ring_tx); i++) { + for (i = min_ring_id; i < ARRAY_SIZE(wil->ring_tx); i++) { if (wil->ring2cid_tid[i][0] == cid) wil_ring_fini_tx(wil, i); } @@ -604,8 +605,10 @@ int wil_priv_init(struct wil6210_priv *wil) wil->sta[i].mid = U8_MAX; } - for (i = 0; i < WIL6210_MAX_TX_RINGS; i++) + for (i = 0; i < WIL6210_MAX_TX_RINGS; i++) { spin_lock_init(&wil->ring_tx_data[i].lock); + wil->ring2cid_tid[i][0] = WIL6210_MAX_CID; + } mutex_init(&wil->mutex); mutex_init(&wil->vif_mutex); diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c index e7b003b38f45..259e4a872623 100644 --- a/drivers/net/wireless/ath/wil6210/txrx.c +++ b/drivers/net/wireless/ath/wil6210/txrx.c @@ -77,8 +77,9 @@ bool wil_is_tx_idle(struct wil6210_priv *wil) { int i; unsigned long data_comp_to; + int min_ring_id = wil_get_min_tx_ring_id(wil); - for (i = 0; i < WIL6210_MAX_TX_RINGS; i++) { + for (i = min_ring_id; i < WIL6210_MAX_TX_RINGS; i++) { struct wil_ring *vring = &wil->ring_tx[i]; int vring_index = vring - wil->ring_tx; struct wil_ring_tx_data *txdata = @@ -1942,6 +1943,7 @@ static inline void __wil_update_net_queues(struct wil6210_priv *wil, bool check_stop) { int i; + int min_ring_id = wil_get_min_tx_ring_id(wil); if (unlikely(!vif)) return; @@ -1974,7 +1976,7 @@ static inline void __wil_update_net_queues(struct wil6210_priv *wil, return; /* check wake */ - for (i = 0; i < WIL6210_MAX_TX_RINGS; i++) { + for (i = min_ring_id; i < WIL6210_MAX_TX_RINGS; i++) { struct wil_ring *cur_ring = &wil->ring_tx[i]; struct wil_ring_tx_data *txdata = &wil->ring_tx_data[i]; From 84f16fbb62384fb209cd35741d94eb00b5ca2746 Mon Sep 17 00:00:00 2001 From: Maya Erez Date: Thu, 23 Aug 2018 14:47:11 +0300 Subject: [PATCH 017/276] wil6210: fix RX buffers release and unmap RX SKBs are released in both wil6210 rmmod and RX handle. As there is no lock to protect the buffers DMA unmap, the SKB pointer in buff_arr is used to check if the buffer memory was already released. Setting wil->rx_buff_mgmt.buff_arr[buff_id].skb to NULL before the DMA memory unmap will prevent duplicate unmapping of the same memory. Move the buffer ID to the free list also in case the SKB is NULL. Signed-off-by: Maya Erez Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/wil6210/txrx_edma.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/ath/wil6210/txrx_edma.c b/drivers/net/wireless/ath/wil6210/txrx_edma.c index bca61cb44c37..3e7fc2983cbb 100644 --- a/drivers/net/wireless/ath/wil6210/txrx_edma.c +++ b/drivers/net/wireless/ath/wil6210/txrx_edma.c @@ -279,9 +279,6 @@ static void wil_move_all_rx_buff_to_free_list(struct wil6210_priv *wil, u16 buff_id; *d = *_d; - pa = wil_rx_desc_get_addr_edma(&d->dma); - dmalen = le16_to_cpu(d->dma.length); - dma_unmap_single(dev, pa, dmalen, DMA_FROM_DEVICE); /* Extract the SKB from the rx_buff management array */ buff_id = __le16_to_cpu(d->mac.buff_id); @@ -291,10 +288,15 @@ static void wil_move_all_rx_buff_to_free_list(struct wil6210_priv *wil, } skb = wil->rx_buff_mgmt.buff_arr[buff_id].skb; wil->rx_buff_mgmt.buff_arr[buff_id].skb = NULL; - if (unlikely(!skb)) + if (unlikely(!skb)) { wil_err(wil, "No Rx skb at buff_id %d\n", buff_id); - else + } else { + pa = wil_rx_desc_get_addr_edma(&d->dma); + dmalen = le16_to_cpu(d->dma.length); + dma_unmap_single(dev, pa, dmalen, DMA_FROM_DEVICE); + kfree_skb(skb); + } /* Move the buffer from the active to the free list */ list_move(&wil->rx_buff_mgmt.buff_arr[buff_id].list, @@ -906,6 +908,9 @@ static struct sk_buff *wil_sring_reap_rx_edma(struct wil6210_priv *wil, wil->rx_buff_mgmt.buff_arr[buff_id].skb = NULL; if (!skb) { wil_err(wil, "No Rx skb at buff_id %d\n", buff_id); + /* Move the buffer from the active list to the free list */ + list_move(&wil->rx_buff_mgmt.buff_arr[buff_id].list, + &wil->rx_buff_mgmt.free); goto again; } From b9010f105f21788b2dbe0e9599677a27247a9092 Mon Sep 17 00:00:00 2001 From: Ahmad Masri Date: Thu, 23 Aug 2018 14:47:12 +0300 Subject: [PATCH 018/276] wil6210: add FT roam support for AP and station This feature is needed for enterprise APs and clients to enable fast roaming as defined in 802.11r between APs in the same ESS. On AP side, this feature is supported only when disable_ap_sme is enabled. Signed-off-by: Ahmad Masri Signed-off-by: Maya Erez Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/wil6210/cfg80211.c | 311 +++++++++++++--- drivers/net/wireless/ath/wil6210/debugfs.c | 17 +- drivers/net/wireless/ath/wil6210/main.c | 2 + drivers/net/wireless/ath/wil6210/txrx.c | 83 +++++ drivers/net/wireless/ath/wil6210/txrx_edma.c | 11 + drivers/net/wireless/ath/wil6210/wil6210.h | 17 + drivers/net/wireless/ath/wil6210/wmi.c | 350 ++++++++++++++++++- drivers/net/wireless/ath/wil6210/wmi.h | 1 + 8 files changed, 735 insertions(+), 57 deletions(-) diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c index 1bdb026ae85c..d18e81fae5f1 100644 --- a/drivers/net/wireless/ath/wil6210/cfg80211.c +++ b/drivers/net/wireless/ath/wil6210/cfg80211.c @@ -219,7 +219,9 @@ wil_mgmt_stypes[NUM_NL80211_IFTYPES] = { .tx = BIT(IEEE80211_STYPE_ACTION >> 4) | BIT(IEEE80211_STYPE_PROBE_RESP >> 4) | BIT(IEEE80211_STYPE_ASSOC_RESP >> 4) | - BIT(IEEE80211_STYPE_DISASSOC >> 4), + BIT(IEEE80211_STYPE_DISASSOC >> 4) | + BIT(IEEE80211_STYPE_AUTH >> 4) | + BIT(IEEE80211_STYPE_REASSOC_RESP >> 4), .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | @@ -891,6 +893,26 @@ static void wil_print_crypto(struct wil6210_priv *wil, c->control_port_no_encrypt); } +static const char * +wil_get_auth_type_name(enum nl80211_auth_type auth_type) +{ + switch (auth_type) { + case NL80211_AUTHTYPE_OPEN_SYSTEM: + return "OPEN_SYSTEM"; + case NL80211_AUTHTYPE_SHARED_KEY: + return "SHARED_KEY"; + case NL80211_AUTHTYPE_FT: + return "FT"; + case NL80211_AUTHTYPE_NETWORK_EAP: + return "NETWORK_EAP"; + case NL80211_AUTHTYPE_SAE: + return "SAE"; + case NL80211_AUTHTYPE_AUTOMATIC: + return "AUTOMATIC"; + default: + return "unknown"; + } +} static void wil_print_connect_params(struct wil6210_priv *wil, struct cfg80211_connect_params *sme) { @@ -904,11 +926,73 @@ static void wil_print_connect_params(struct wil6210_priv *wil, if (sme->ssid) print_hex_dump(KERN_INFO, " SSID: ", DUMP_PREFIX_OFFSET, 16, 1, sme->ssid, sme->ssid_len, true); + if (sme->prev_bssid) + wil_info(wil, " Previous BSSID=%pM\n", sme->prev_bssid); + wil_info(wil, " Auth Type: %s\n", + wil_get_auth_type_name(sme->auth_type)); wil_info(wil, " Privacy: %s\n", sme->privacy ? "secure" : "open"); wil_info(wil, " PBSS: %d\n", sme->pbss); wil_print_crypto(wil, &sme->crypto); } +static int wil_ft_connect(struct wiphy *wiphy, + struct net_device *ndev, + struct cfg80211_connect_params *sme) +{ + struct wil6210_priv *wil = wiphy_to_wil(wiphy); + struct wil6210_vif *vif = ndev_to_vif(ndev); + struct wmi_ft_auth_cmd auth_cmd; + int rc; + + if (!test_bit(WMI_FW_CAPABILITY_FT_ROAMING, wil->fw_capabilities)) { + wil_err(wil, "FT: FW does not support FT roaming\n"); + return -EOPNOTSUPP; + } + + if (!sme->prev_bssid) { + wil_err(wil, "FT: prev_bssid was not set\n"); + return -EINVAL; + } + + if (ether_addr_equal(sme->prev_bssid, sme->bssid)) { + wil_err(wil, "FT: can not roam to same AP\n"); + return -EINVAL; + } + + if (!test_bit(wil_vif_fwconnected, vif->status)) { + wil_err(wil, "FT: roam while not connected\n"); + return -EINVAL; + } + + if (vif->privacy != sme->privacy) { + wil_err(wil, "FT: privacy mismatch, current (%d) roam (%d)\n", + vif->privacy, sme->privacy); + return -EINVAL; + } + + if (sme->pbss) { + wil_err(wil, "FT: roam is not valid for PBSS\n"); + return -EINVAL; + } + + memset(&auth_cmd, 0, sizeof(auth_cmd)); + auth_cmd.channel = sme->channel->hw_value - 1; + ether_addr_copy(auth_cmd.bssid, sme->bssid); + + wil_info(wil, "FT: roaming\n"); + + set_bit(wil_vif_ft_roam, vif->status); + rc = wmi_send(wil, WMI_FT_AUTH_CMDID, vif->mid, + &auth_cmd, sizeof(auth_cmd)); + if (rc == 0) + mod_timer(&vif->connect_timer, + jiffies + msecs_to_jiffies(5000)); + else + clear_bit(wil_vif_ft_roam, vif->status); + + return rc; +} + static int wil_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_connect_params *sme) @@ -921,14 +1005,23 @@ static int wil_cfg80211_connect(struct wiphy *wiphy, const u8 *rsn_eid; int ch; int rc = 0; + bool is_ft_roam = false; + u8 network_type; enum ieee80211_bss_type bss_type = IEEE80211_BSS_TYPE_ESS; wil_dbg_misc(wil, "connect, mid=%d\n", vif->mid); wil_print_connect_params(wil, sme); - if (test_bit(wil_vif_fwconnecting, vif->status) || + if (sme->auth_type == NL80211_AUTHTYPE_FT) + is_ft_roam = true; + if (sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC && test_bit(wil_vif_fwconnected, vif->status)) - return -EALREADY; + is_ft_roam = true; + + if (!is_ft_roam) + if (test_bit(wil_vif_fwconnecting, vif->status) || + test_bit(wil_vif_fwconnected, vif->status)) + return -EALREADY; if (sme->ie_len > WMI_MAX_IE_LEN) { wil_err(wil, "IE too large (%td bytes)\n", sme->ie_len); @@ -938,8 +1031,13 @@ static int wil_cfg80211_connect(struct wiphy *wiphy, rsn_eid = sme->ie ? cfg80211_find_ie(WLAN_EID_RSN, sme->ie, sme->ie_len) : NULL; - if (sme->privacy && !rsn_eid) + if (sme->privacy && !rsn_eid) { wil_info(wil, "WSC connection\n"); + if (is_ft_roam) { + wil_err(wil, "No WSC with FT roam\n"); + return -EINVAL; + } + } if (sme->pbss) bss_type = IEEE80211_BSS_TYPE_PBSS; @@ -961,6 +1059,45 @@ static int wil_cfg80211_connect(struct wiphy *wiphy, vif->privacy = sme->privacy; vif->pbss = sme->pbss; + rc = wmi_set_ie(vif, WMI_FRAME_ASSOC_REQ, sme->ie_len, sme->ie); + if (rc) + goto out; + + switch (bss->capability & WLAN_CAPABILITY_DMG_TYPE_MASK) { + case WLAN_CAPABILITY_DMG_TYPE_AP: + network_type = WMI_NETTYPE_INFRA; + break; + case WLAN_CAPABILITY_DMG_TYPE_PBSS: + network_type = WMI_NETTYPE_P2P; + break; + default: + wil_err(wil, "Unsupported BSS type, capability= 0x%04x\n", + bss->capability); + rc = -EINVAL; + goto out; + } + + ch = bss->channel->hw_value; + if (ch == 0) { + wil_err(wil, "BSS at unknown frequency %dMhz\n", + bss->channel->center_freq); + rc = -EOPNOTSUPP; + goto out; + } + + if (is_ft_roam) { + if (network_type != WMI_NETTYPE_INFRA) { + wil_err(wil, "FT: Unsupported BSS type, capability= 0x%04x\n", + bss->capability); + rc = -EINVAL; + goto out; + } + rc = wil_ft_connect(wiphy, ndev, sme); + if (rc == 0) + vif->bss = bss; + goto out; + } + if (vif->privacy) { /* For secure assoc, remove old keys */ rc = wmi_del_cipher_key(vif, 0, bss->bssid, @@ -977,28 +1114,9 @@ static int wil_cfg80211_connect(struct wiphy *wiphy, } } - /* WMI_SET_APPIE_CMD. ie may contain rsn info as well as other info - * elements. Send it also in case it's empty, to erase previously set - * ies in FW. - */ - rc = wmi_set_ie(vif, WMI_FRAME_ASSOC_REQ, sme->ie_len, sme->ie); - if (rc) - goto out; - /* WMI_CONNECT_CMD */ memset(&conn, 0, sizeof(conn)); - switch (bss->capability & WLAN_CAPABILITY_DMG_TYPE_MASK) { - case WLAN_CAPABILITY_DMG_TYPE_AP: - conn.network_type = WMI_NETTYPE_INFRA; - break; - case WLAN_CAPABILITY_DMG_TYPE_PBSS: - conn.network_type = WMI_NETTYPE_P2P; - break; - default: - wil_err(wil, "Unsupported BSS type, capability= 0x%04x\n", - bss->capability); - goto out; - } + conn.network_type = network_type; if (vif->privacy) { if (rsn_eid) { /* regular secure connection */ conn.dot11_auth_mode = WMI_AUTH11_SHARED; @@ -1018,14 +1136,6 @@ static int wil_cfg80211_connect(struct wiphy *wiphy, conn.ssid_len = min_t(u8, ssid_eid[1], 32); memcpy(conn.ssid, ssid_eid+2, conn.ssid_len); - - ch = bss->channel->hw_value; - if (ch == 0) { - wil_err(wil, "BSS at unknown frequency %dMhz\n", - bss->channel->center_freq); - rc = -EOPNOTSUPP; - goto out; - } conn.channel = ch - 1; ether_addr_copy(conn.bssid, bss->bssid); @@ -1221,9 +1331,9 @@ wil_find_sta_by_key_usage(struct wil6210_priv *wil, u8 mid, return &wil->sta[cid]; } -static void wil_set_crypto_rx(u8 key_index, enum wmi_key_usage key_usage, - struct wil_sta_info *cs, - struct key_params *params) +void wil_set_crypto_rx(u8 key_index, enum wmi_key_usage key_usage, + struct wil_sta_info *cs, + struct key_params *params) { struct wil_tid_crypto_rx_single *cc; int tid; @@ -1306,13 +1416,19 @@ static int wil_cfg80211_add_key(struct wiphy *wiphy, params->seq_len, params->seq); if (IS_ERR(cs)) { - wil_err(wil, "Not connected, %pM %s[%d] PN %*phN\n", - mac_addr, key_usage_str[key_usage], key_index, - params->seq_len, params->seq); - return -EINVAL; + /* in FT, sta info may not be available as add_key may be + * sent by host before FW sends WMI_CONNECT_EVENT + */ + if (!test_bit(wil_vif_ft_roam, vif->status)) { + wil_err(wil, "Not connected, %pM %s[%d] PN %*phN\n", + mac_addr, key_usage_str[key_usage], key_index, + params->seq_len, params->seq); + return -EINVAL; + } } - wil_del_rx_key(key_index, key_usage, cs); + if (!IS_ERR(cs)) + wil_del_rx_key(key_index, key_usage, cs); if (params->seq && params->seq_len != IEEE80211_GCMP_PN_LEN) { wil_err(wil, @@ -1325,7 +1441,10 @@ static int wil_cfg80211_add_key(struct wiphy *wiphy, rc = wmi_add_cipher_key(vif, key_index, mac_addr, params->key_len, params->key, key_usage); - if (!rc) + if (!rc && !IS_ERR(cs)) + /* in FT set crypto will take place upon receiving + * WMI_RING_EN_EVENTID event + */ wil_set_crypto_rx(key_index, key_usage, cs, params); return rc; @@ -1488,21 +1607,36 @@ static void wil_print_bcon_data(struct cfg80211_beacon_data *b) } /* internal functions for device reset and starting AP */ +static u8 * +_wil_cfg80211_get_proberesp_ies(const u8 *proberesp, u16 proberesp_len, + u16 *ies_len) +{ + u8 *ies = NULL; + + if (proberesp) { + struct ieee80211_mgmt *f = + (struct ieee80211_mgmt *)proberesp; + size_t hlen = offsetof(struct ieee80211_mgmt, + u.probe_resp.variable); + + ies = f->u.probe_resp.variable; + if (ies_len) + *ies_len = proberesp_len - hlen; + } + + return ies; +} + static int _wil_cfg80211_set_ies(struct wil6210_vif *vif, struct cfg80211_beacon_data *bcon) { int rc; u16 len = 0, proberesp_len = 0; - u8 *ies = NULL, *proberesp = NULL; + u8 *ies = NULL, *proberesp; - if (bcon->probe_resp) { - struct ieee80211_mgmt *f = - (struct ieee80211_mgmt *)bcon->probe_resp; - size_t hlen = offsetof(struct ieee80211_mgmt, - u.probe_resp.variable); - proberesp = f->u.probe_resp.variable; - proberesp_len = bcon->probe_resp_len - hlen; - } + proberesp = _wil_cfg80211_get_proberesp_ies(bcon->probe_resp, + bcon->probe_resp_len, + &proberesp_len); rc = _wil_cfg80211_merge_extra_ies(proberesp, proberesp_len, bcon->proberesp_ies, @@ -1546,6 +1680,9 @@ static int _wil_cfg80211_start_ap(struct wiphy *wiphy, struct wireless_dev *wdev = ndev->ieee80211_ptr; u8 wmi_nettype = wil_iftype_nl2wmi(wdev->iftype); u8 is_go = (wdev->iftype == NL80211_IFTYPE_P2P_GO); + u16 proberesp_len = 0; + u8 *proberesp; + bool ft = false; if (pbss) wmi_nettype = WMI_NETTYPE_P2P; @@ -1558,6 +1695,25 @@ static int _wil_cfg80211_start_ap(struct wiphy *wiphy, wil_set_recovery_state(wil, fw_recovery_idle); + proberesp = _wil_cfg80211_get_proberesp_ies(bcon->probe_resp, + bcon->probe_resp_len, + &proberesp_len); + /* check that the probe response IEs has a MDE */ + if ((proberesp && proberesp_len > 0 && + cfg80211_find_ie(WLAN_EID_MOBILITY_DOMAIN, + proberesp, + proberesp_len))) + ft = true; + + if (ft) { + if (!test_bit(WMI_FW_CAPABILITY_FT_ROAMING, + wil->fw_capabilities)) { + wil_err(wil, "FW does not support FT roaming\n"); + return -ENOTSUPP; + } + set_bit(wil_vif_ft_roam, vif->status); + } + mutex_lock(&wil->mutex); if (!wil_has_other_active_ifaces(wil, ndev, true, false)) { @@ -1719,6 +1875,7 @@ static int wil_cfg80211_stop_ap(struct wiphy *wiphy, mutex_lock(&wil->mutex); wmi_pcp_stop(vif); + clear_bit(wil_vif_ft_roam, vif->status); if (last) __wil_down(wil); @@ -1738,8 +1895,9 @@ static int wil_cfg80211_add_station(struct wiphy *wiphy, struct wil6210_vif *vif = ndev_to_vif(dev); struct wil6210_priv *wil = wiphy_to_wil(wiphy); - wil_dbg_misc(wil, "add station %pM aid %d mid %d\n", - mac, params->aid, vif->mid); + wil_dbg_misc(wil, "add station %pM aid %d mid %d mask 0x%x set 0x%x\n", + mac, params->aid, vif->mid, + params->sta_flags_mask, params->sta_flags_set); if (!disable_ap_sme) { wil_err(wil, "not supported with AP SME enabled\n"); @@ -2060,6 +2218,54 @@ wil_cfg80211_sched_scan_stop(struct wiphy *wiphy, struct net_device *dev, return 0; } +static int +wil_cfg80211_update_ft_ies(struct wiphy *wiphy, struct net_device *dev, + struct cfg80211_update_ft_ies_params *ftie) +{ + struct wil6210_priv *wil = wiphy_to_wil(wiphy); + struct wil6210_vif *vif = ndev_to_vif(dev); + struct cfg80211_bss *bss; + struct wmi_ft_reassoc_cmd reassoc; + int rc = 0; + + wil_dbg_misc(wil, "update ft ies, mid=%d\n", vif->mid); + wil_hex_dump_misc("FT IE ", DUMP_PREFIX_OFFSET, 16, 1, + ftie->ie, ftie->ie_len, true); + + if (!test_bit(WMI_FW_CAPABILITY_FT_ROAMING, wil->fw_capabilities)) { + wil_err(wil, "FW does not support FT roaming\n"); + return -EOPNOTSUPP; + } + + rc = wmi_update_ft_ies(vif, ftie->ie_len, ftie->ie); + if (rc) + return rc; + + if (!test_bit(wil_vif_ft_roam, vif->status)) + /* vif is not roaming */ + return 0; + + /* wil_vif_ft_roam is set. wil_cfg80211_update_ft_ies is used as + * a trigger for reassoc + */ + + bss = vif->bss; + if (!bss) { + wil_err(wil, "FT: bss is NULL\n"); + return -EINVAL; + } + + memset(&reassoc, 0, sizeof(reassoc)); + ether_addr_copy(reassoc.bssid, bss->bssid); + + rc = wmi_send(wil, WMI_FT_REASSOC_CMDID, vif->mid, + &reassoc, sizeof(reassoc)); + if (rc) + wil_err(wil, "FT: reassoc failed (%d)\n", rc); + + return rc; +} + static const struct cfg80211_ops wil_cfg80211_ops = { .add_virtual_intf = wil_cfg80211_add_iface, .del_virtual_intf = wil_cfg80211_del_iface, @@ -2095,6 +2301,7 @@ static const struct cfg80211_ops wil_cfg80211_ops = { .resume = wil_cfg80211_resume, .sched_scan_start = wil_cfg80211_sched_scan_start, .sched_scan_stop = wil_cfg80211_sched_scan_stop, + .update_ft_ies = wil_cfg80211_update_ft_ies, }; static void wil_wiphy_init(struct wiphy *wiphy) diff --git a/drivers/net/wireless/ath/wil6210/debugfs.c b/drivers/net/wireless/ath/wil6210/debugfs.c index 4057f0685947..6973333497c1 100644 --- a/drivers/net/wireless/ath/wil6210/debugfs.c +++ b/drivers/net/wireless/ath/wil6210/debugfs.c @@ -1669,6 +1669,7 @@ __acquires(&p->tid_rx_lock) __releases(&p->tid_rx_lock) char *status = "unknown"; u8 aid = 0; u8 mid; + bool sta_connected = false; switch (p->status) { case wil_sta_unused: @@ -1683,8 +1684,20 @@ __acquires(&p->tid_rx_lock) __releases(&p->tid_rx_lock) break; } mid = (p->status != wil_sta_unused) ? p->mid : U8_MAX; - seq_printf(s, "[%d] %pM %s MID %d AID %d\n", i, p->addr, status, - mid, aid); + if (mid < wil->max_vifs) { + struct wil6210_vif *vif = wil->vifs[mid]; + + if (vif->wdev.iftype == NL80211_IFTYPE_STATION && + p->status == wil_sta_connected) + sta_connected = true; + } + /* print roam counter only for connected stations */ + if (sta_connected) + seq_printf(s, "[%d] %pM connected (roam counter %d) MID %d AID %d\n", + i, p->addr, p->stats.ft_roams, mid, aid); + else + seq_printf(s, "[%d] %pM %s MID %d AID %d\n", i, + p->addr, status, mid, aid); if (p->status == wil_sta_connected) { spin_lock_bh(&p->tid_rx_lock); diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c index 3fcf79924a4c..398900a1c29e 100644 --- a/drivers/net/wireless/ath/wil6210/main.c +++ b/drivers/net/wireless/ath/wil6210/main.c @@ -361,6 +361,8 @@ static void _wil6210_disconnect(struct wil6210_vif *vif, const u8 *bssid, vif->bss = NULL; } clear_bit(wil_vif_fwconnecting, vif->status); + clear_bit(wil_vif_ft_roam, vif->status); + break; case NL80211_IFTYPE_AP: case NL80211_IFTYPE_P2P_GO: diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c index 259e4a872623..cc5f263cc965 100644 --- a/drivers/net/wireless/ath/wil6210/txrx.c +++ b/drivers/net/wireless/ath/wil6210/txrx.c @@ -1059,6 +1059,88 @@ static int wil_vring_init_tx(struct wil6210_vif *vif, int id, int size, return rc; } +static int wil_tx_vring_modify(struct wil6210_vif *vif, int ring_id, int cid, + int tid) +{ + struct wil6210_priv *wil = vif_to_wil(vif); + int rc; + struct wmi_vring_cfg_cmd cmd = { + .action = cpu_to_le32(WMI_VRING_CMD_MODIFY), + .vring_cfg = { + .tx_sw_ring = { + .max_mpdu_size = + cpu_to_le16(wil_mtu2macbuf(mtu_max)), + .ring_size = 0, + }, + .ringid = ring_id, + .cidxtid = mk_cidxtid(cid, tid), + .encap_trans_type = WMI_VRING_ENC_TYPE_802_3, + .mac_ctrl = 0, + .to_resolution = 0, + .agg_max_wsize = 0, + .schd_params = { + .priority = cpu_to_le16(0), + .timeslot_us = cpu_to_le16(0xfff), + }, + }, + }; + struct { + struct wmi_cmd_hdr wmi; + struct wmi_vring_cfg_done_event cmd; + } __packed reply = { + .cmd = {.status = WMI_FW_STATUS_FAILURE}, + }; + struct wil_ring *vring = &wil->ring_tx[ring_id]; + struct wil_ring_tx_data *txdata = &wil->ring_tx_data[ring_id]; + + wil_dbg_misc(wil, "vring_modify: ring %d cid %d tid %d\n", ring_id, + cid, tid); + lockdep_assert_held(&wil->mutex); + + if (!vring->va) { + wil_err(wil, "Tx ring [%d] not allocated\n", ring_id); + return -EINVAL; + } + + if (wil->ring2cid_tid[ring_id][0] != cid || + wil->ring2cid_tid[ring_id][1] != tid) { + wil_err(wil, "ring info does not match cid=%u tid=%u\n", + wil->ring2cid_tid[ring_id][0], + wil->ring2cid_tid[ring_id][1]); + } + + cmd.vring_cfg.tx_sw_ring.ring_mem_base = cpu_to_le64(vring->pa); + + rc = wmi_call(wil, WMI_VRING_CFG_CMDID, vif->mid, &cmd, sizeof(cmd), + WMI_VRING_CFG_DONE_EVENTID, &reply, sizeof(reply), 100); + if (rc) + goto fail; + + if (reply.cmd.status != WMI_FW_STATUS_SUCCESS) { + wil_err(wil, "Tx modify failed, status 0x%02x\n", + reply.cmd.status); + rc = -EINVAL; + goto fail; + } + + /* set BA aggregation window size to 0 to force a new BA with the + * new AP + */ + txdata->agg_wsize = 0; + if (txdata->dot1x_open && agg_wsize >= 0) + wil_addba_tx_request(wil, ring_id, agg_wsize); + + return 0; +fail: + spin_lock_bh(&txdata->lock); + txdata->dot1x_open = false; + txdata->enabled = 0; + spin_unlock_bh(&txdata->lock); + wil->ring2cid_tid[ring_id][0] = WIL6210_MAX_CID; + wil->ring2cid_tid[ring_id][1] = 0; + return rc; +} + int wil_vring_init_bcast(struct wil6210_vif *vif, int id, int size) { struct wil6210_priv *wil = vif_to_wil(vif); @@ -2281,6 +2363,7 @@ void wil_init_txrx_ops_legacy_dma(struct wil6210_priv *wil) wil->txrx_ops.ring_init_bcast = wil_vring_init_bcast; wil->txrx_ops.tx_init = wil_tx_init; wil->txrx_ops.tx_fini = wil_tx_fini; + wil->txrx_ops.tx_ring_modify = wil_tx_vring_modify; /* RX ops */ wil->txrx_ops.rx_init = wil_rx_init; wil->txrx_ops.wmi_addba_rx_resp = wmi_addba_rx_resp; diff --git a/drivers/net/wireless/ath/wil6210/txrx_edma.c b/drivers/net/wireless/ath/wil6210/txrx_edma.c index 3e7fc2983cbb..2bbae75b9a84 100644 --- a/drivers/net/wireless/ath/wil6210/txrx_edma.c +++ b/drivers/net/wireless/ath/wil6210/txrx_edma.c @@ -747,6 +747,16 @@ static int wil_ring_init_tx_edma(struct wil6210_vif *vif, int ring_id, return rc; } +static int wil_tx_ring_modify_edma(struct wil6210_vif *vif, int ring_id, + int cid, int tid) +{ + struct wil6210_priv *wil = vif_to_wil(vif); + + wil_err(wil, "ring modify is not supported for EDMA\n"); + + return -EOPNOTSUPP; +} + /* This function is used only for RX SW reorder */ static int wil_check_bar(struct wil6210_priv *wil, void *msg, int cid, struct sk_buff *skb, struct wil_net_stats *stats) @@ -1600,6 +1610,7 @@ void wil_init_txrx_ops_edma(struct wil6210_priv *wil) wil->txrx_ops.tx_desc_map = wil_tx_desc_map_edma; wil->txrx_ops.tx_desc_unmap = wil_tx_desc_unmap_edma; wil->txrx_ops.tx_ring_tso = __wil_tx_ring_tso_edma; + wil->txrx_ops.tx_ring_modify = wil_tx_ring_modify_edma; /* RX ops */ wil->txrx_ops.rx_init = wil_rx_init_edma; wil->txrx_ops.wmi_addba_rx_resp = wmi_addba_rx_resp_edma; diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h index 85565de05840..cf6a69198b5d 100644 --- a/drivers/net/wireless/ath/wil6210/wil6210.h +++ b/drivers/net/wireless/ath/wil6210/wil6210.h @@ -449,6 +449,15 @@ static inline void parse_cidxtid(u8 cidxtid, u8 *cid, u8 *tid) *tid = (cidxtid >> 4) & 0xf; } +/** + * wil_cid_valid - check cid is valid + * @cid: CID value + */ +static inline bool wil_cid_valid(u8 cid) +{ + return (cid >= 0 && cid < WIL6210_MAX_CID); +} + struct wil6210_mbox_ring { u32 base; u16 entry_size; /* max. size of mbox entry, incl. all headers */ @@ -577,6 +586,7 @@ struct wil_net_stats { unsigned long rx_csum_err; u16 last_mcs_rx; u64 rx_per_mcs[WIL_MCS_MAX + 1]; + u32 ft_roams; /* relevant in STA mode */ }; /** @@ -599,6 +609,8 @@ struct wil_txrx_ops { struct wil_ctx *ctx); int (*tx_ring_tso)(struct wil6210_priv *wil, struct wil6210_vif *vif, struct wil_ring *ring, struct sk_buff *skb); + int (*tx_ring_modify)(struct wil6210_vif *vif, int ring_id, + int cid, int tid); irqreturn_t (*irq_tx)(int irq, void *cookie); /* RX ops */ int (*rx_init)(struct wil6210_priv *wil, u16 ring_size); @@ -821,6 +833,7 @@ extern u8 led_polarity; enum wil6210_vif_status { wil_vif_fwconnecting, wil_vif_fwconnected, + wil_vif_ft_roam, wil_vif_status_last /* keep last */ }; @@ -1204,6 +1217,7 @@ int wmi_add_cipher_key(struct wil6210_vif *vif, u8 key_index, int wmi_echo(struct wil6210_priv *wil); int wmi_set_ie(struct wil6210_vif *vif, u8 type, u16 ie_len, const void *ie); int wmi_rx_chain_add(struct wil6210_priv *wil, struct wil_ring *vring); +int wmi_update_ft_ies(struct wil6210_vif *vif, u16 ie_len, const void *ie); int wmi_rxon(struct wil6210_priv *wil, bool on); int wmi_get_temperature(struct wil6210_priv *wil, u32 *t_m, u32 *t_r); int wmi_disconnect_sta(struct wil6210_vif *vif, const u8 *mac, @@ -1319,6 +1333,9 @@ void wil6210_unmask_irq_tx_edma(struct wil6210_priv *wil); void wil_rx_handle(struct wil6210_priv *wil, int *quota); void wil6210_unmask_irq_rx(struct wil6210_priv *wil); void wil6210_unmask_irq_rx_edma(struct wil6210_priv *wil); +void wil_set_crypto_rx(u8 key_index, enum wmi_key_usage key_usage, + struct wil_sta_info *cs, + struct key_params *params); int wil_iftype_nl2wmi(enum nl80211_iftype type); diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c index 42c02a20ec97..c3ad8e4df3ec 100644 --- a/drivers/net/wireless/ath/wil6210/wmi.c +++ b/drivers/net/wireless/ath/wil6210/wmi.c @@ -227,6 +227,14 @@ struct blink_on_off_time led_blink_time[] = { {WIL_LED_BLINK_ON_FAST_MS, WIL_LED_BLINK_OFF_FAST_MS}, }; +struct auth_no_hdr { + __le16 auth_alg; + __le16 auth_transaction; + __le16 status_code; + /* possibly followed by Challenge text */ + u8 variable[0]; +} __packed; + u8 led_polarity = LED_POLARITY_LOW_ACTIVE; /** @@ -468,6 +476,12 @@ static const char *cmdid2name(u16 cmdid) return "WMI_LINK_STATS_CMD"; case WMI_SW_TX_REQ_EXT_CMDID: return "WMI_SW_TX_REQ_EXT_CMDID"; + case WMI_FT_AUTH_CMDID: + return "WMI_FT_AUTH_CMD"; + case WMI_FT_REASSOC_CMDID: + return "WMI_FT_REASSOC_CMD"; + case WMI_UPDATE_FT_IES_CMDID: + return "WMI_UPDATE_FT_IES_CMD"; default: return "Untracked CMD"; } @@ -606,6 +620,12 @@ static const char *eventid2name(u16 eventid) return "WMI_LINK_STATS_CONFIG_DONE_EVENT"; case WMI_LINK_STATS_EVENTID: return "WMI_LINK_STATS_EVENT"; + case WMI_COMMAND_NOT_SUPPORTED_EVENTID: + return "WMI_COMMAND_NOT_SUPPORTED_EVENT"; + case WMI_FT_AUTH_STATUS_EVENTID: + return "WMI_FT_AUTH_STATUS_EVENT"; + case WMI_FT_REASSOC_STATUS_EVENTID: + return "WMI_FT_REASSOC_STATUS_EVENT"; default: return "Untracked EVENT"; } @@ -1156,6 +1176,9 @@ static void wmi_evt_ring_en(struct wil6210_vif *vif, int id, void *d, int len) struct wmi_ring_en_event *evt = d; u8 vri = evt->ring_index; struct wireless_dev *wdev = vif_to_wdev(vif); + struct wil_sta_info *sta; + int cid; + struct key_params params; wil_dbg_wmi(wil, "Enable vring %d MID %d\n", vri, vif->mid); @@ -1164,13 +1187,33 @@ static void wmi_evt_ring_en(struct wil6210_vif *vif, int id, void *d, int len) return; } - if (wdev->iftype != NL80211_IFTYPE_AP || !disable_ap_sme) - /* in AP mode with disable_ap_sme, this is done by - * wil_cfg80211_change_station() + if (wdev->iftype != NL80211_IFTYPE_AP || !disable_ap_sme || + test_bit(wil_vif_ft_roam, vif->status)) + /* in AP mode with disable_ap_sme that is not FT, + * this is done by wil_cfg80211_change_station() */ wil->ring_tx_data[vri].dot1x_open = true; if (vri == vif->bcast_ring) /* no BA for bcast */ return; + + cid = wil->ring2cid_tid[vri][0]; + if (!wil_cid_valid(cid)) { + wil_err(wil, "invalid cid %d for vring %d\n", cid, vri); + return; + } + + /* In FT mode we get key but not store it as it is received + * before WMI_CONNECT_EVENT received from FW. + * wil_set_crypto_rx is called here to reset the security PN + */ + sta = &wil->sta[cid]; + if (test_bit(wil_vif_ft_roam, vif->status)) { + memset(¶ms, 0, sizeof(params)); + wil_set_crypto_rx(0, WMI_KEY_USE_PAIRWISE, sta, ¶ms); + if (wdev->iftype != NL80211_IFTYPE_AP) + clear_bit(wil_vif_ft_roam, vif->status); + } + if (agg_wsize >= 0) wil_addba_tx_request(wil, vri, agg_wsize); } @@ -1461,6 +1504,271 @@ wmi_evt_link_stats(struct wil6210_vif *vif, int id, void *d, int len) evt->payload, payload_size); } +/** + * find cid and ringid for the station vif + * + * return error, if other interfaces are used or ring was not found + */ +static int wil_find_cid_ringid_sta(struct wil6210_priv *wil, + struct wil6210_vif *vif, + int *cid, + int *ringid) +{ + struct wil_ring *ring; + struct wil_ring_tx_data *txdata; + int min_ring_id = wil_get_min_tx_ring_id(wil); + int i; + u8 lcid; + + if (!(vif->wdev.iftype == NL80211_IFTYPE_STATION || + vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT)) { + wil_err(wil, "invalid interface type %d\n", vif->wdev.iftype); + return -EINVAL; + } + + /* In the STA mode, it is expected to have only one ring + * for the AP we are connected to. + * find it and return the cid associated with it. + */ + for (i = min_ring_id; i < WIL6210_MAX_TX_RINGS; i++) { + ring = &wil->ring_tx[i]; + txdata = &wil->ring_tx_data[i]; + if (!ring->va || !txdata->enabled || txdata->mid != vif->mid) + continue; + + lcid = wil->ring2cid_tid[i][0]; + if (lcid >= WIL6210_MAX_CID) /* skip BCAST */ + continue; + + wil_dbg_wmi(wil, "find sta -> ringid %d cid %d\n", i, lcid); + *cid = lcid; + *ringid = i; + return 0; + } + + wil_dbg_wmi(wil, "find sta cid while no rings active?\n"); + + return -ENOENT; +} + +static void +wmi_evt_auth_status(struct wil6210_vif *vif, int id, void *d, int len) +{ + struct wil6210_priv *wil = vif_to_wil(vif); + struct net_device *ndev = vif_to_ndev(vif); + struct wmi_ft_auth_status_event *data = d; + int ie_len = len - offsetof(struct wmi_ft_auth_status_event, ie_info); + int rc, cid = 0, ringid = 0; + struct cfg80211_ft_event_params ft; + u16 d_len; + /* auth_alg(u16) + auth_transaction(u16) + status_code(u16) */ + const size_t auth_ie_offset = sizeof(u16) * 3; + struct auth_no_hdr *auth = (struct auth_no_hdr *)data->ie_info; + + /* check the status */ + if (ie_len >= 0 && data->status != WMI_FW_STATUS_SUCCESS) { + wil_err(wil, "FT: auth failed. status %d\n", data->status); + goto fail; + } + + if (ie_len < auth_ie_offset) { + wil_err(wil, "FT: auth event too short, len %d\n", len); + goto fail; + } + + d_len = le16_to_cpu(data->ie_len); + if (d_len != ie_len) { + wil_err(wil, + "FT: auth ie length mismatch, d_len %d should be %d\n", + d_len, ie_len); + goto fail; + } + + if (!test_bit(wil_vif_ft_roam, wil->status)) { + wil_err(wil, "FT: Not in roaming state\n"); + goto fail; + } + + if (le16_to_cpu(auth->auth_transaction) != 2) { + wil_err(wil, "FT: auth error. auth_transaction %d\n", + le16_to_cpu(auth->auth_transaction)); + goto fail; + } + + if (le16_to_cpu(auth->auth_alg) != WLAN_AUTH_FT) { + wil_err(wil, "FT: auth error. auth_alg %d\n", + le16_to_cpu(auth->auth_alg)); + goto fail; + } + + wil_dbg_wmi(wil, "FT: Auth to %pM successfully\n", data->mac_addr); + wil_hex_dump_wmi("FT Auth ies : ", DUMP_PREFIX_OFFSET, 16, 1, + data->ie_info, d_len, true); + + /* find cid and ringid */ + rc = wil_find_cid_ringid_sta(wil, vif, &cid, &ringid); + if (rc) { + wil_err(wil, "No valid cid found\n"); + goto fail; + } + + if (vif->privacy) { + /* For secure assoc, remove old keys */ + rc = wmi_del_cipher_key(vif, 0, wil->sta[cid].addr, + WMI_KEY_USE_PAIRWISE); + if (rc) { + wil_err(wil, "WMI_DELETE_CIPHER_KEY_CMD(PTK) failed\n"); + goto fail; + } + rc = wmi_del_cipher_key(vif, 0, wil->sta[cid].addr, + WMI_KEY_USE_RX_GROUP); + if (rc) { + wil_err(wil, "WMI_DELETE_CIPHER_KEY_CMD(GTK) failed\n"); + goto fail; + } + } + + memset(&ft, 0, sizeof(ft)); + ft.ies = data->ie_info + auth_ie_offset; + ft.ies_len = d_len - auth_ie_offset; + ft.target_ap = data->mac_addr; + cfg80211_ft_event(ndev, &ft); + + return; + +fail: + wil6210_disconnect(vif, NULL, WLAN_REASON_PREV_AUTH_NOT_VALID, false); +} + +static void +wmi_evt_reassoc_status(struct wil6210_vif *vif, int id, void *d, int len) +{ + struct wil6210_priv *wil = vif_to_wil(vif); + struct net_device *ndev = vif_to_ndev(vif); + struct wiphy *wiphy = wil_to_wiphy(wil); + struct wmi_ft_reassoc_status_event *data = d; + int ies_len = len - offsetof(struct wmi_ft_reassoc_status_event, + ie_info); + int rc = -ENOENT, cid = 0, ringid = 0; + int ch; /* channel number (primary) */ + size_t assoc_req_ie_len = 0, assoc_resp_ie_len = 0; + u8 *assoc_req_ie = NULL, *assoc_resp_ie = NULL; + /* capinfo(u16) + listen_interval(u16) + current_ap mac addr + IEs */ + const size_t assoc_req_ie_offset = sizeof(u16) * 2 + ETH_ALEN; + /* capinfo(u16) + status_code(u16) + associd(u16) + IEs */ + const size_t assoc_resp_ie_offset = sizeof(u16) * 3; + u16 d_len; + int freq; + struct cfg80211_roam_info info; + + if (ies_len < 0) { + wil_err(wil, "ft reassoc event too short, len %d\n", len); + goto fail; + } + + wil_dbg_wmi(wil, "Reasoc Status event: status=%d, aid=%d", + data->status, data->aid); + wil_dbg_wmi(wil, " mac_addr=%pM, beacon_ie_len=%d", + data->mac_addr, data->beacon_ie_len); + wil_dbg_wmi(wil, " reassoc_req_ie_len=%d, reassoc_resp_ie_len=%d", + le16_to_cpu(data->reassoc_req_ie_len), + le16_to_cpu(data->reassoc_resp_ie_len)); + + d_len = le16_to_cpu(data->beacon_ie_len) + + le16_to_cpu(data->reassoc_req_ie_len) + + le16_to_cpu(data->reassoc_resp_ie_len); + if (d_len != ies_len) { + wil_err(wil, + "ft reassoc ie length mismatch, d_len %d should be %d\n", + d_len, ies_len); + goto fail; + } + + /* check the status */ + if (data->status != WMI_FW_STATUS_SUCCESS) { + wil_err(wil, "ft reassoc failed. status %d\n", data->status); + goto fail; + } + + /* find cid and ringid */ + rc = wil_find_cid_ringid_sta(wil, vif, &cid, &ringid); + if (rc) { + wil_err(wil, "No valid cid found\n"); + goto fail; + } + + ch = data->channel + 1; + wil_info(wil, "FT: Roam %pM channel [%d] cid %d aid %d\n", + data->mac_addr, ch, cid, data->aid); + + wil_hex_dump_wmi("reassoc AI : ", DUMP_PREFIX_OFFSET, 16, 1, + data->ie_info, len - sizeof(*data), true); + + /* figure out IE's */ + if (le16_to_cpu(data->reassoc_req_ie_len) > assoc_req_ie_offset) { + assoc_req_ie = &data->ie_info[assoc_req_ie_offset]; + assoc_req_ie_len = le16_to_cpu(data->reassoc_req_ie_len) - + assoc_req_ie_offset; + } + if (le16_to_cpu(data->reassoc_resp_ie_len) <= assoc_resp_ie_offset) { + wil_err(wil, "FT: reassoc resp ie len is too short, len %d\n", + le16_to_cpu(data->reassoc_resp_ie_len)); + goto fail; + } + + assoc_resp_ie = &data->ie_info[le16_to_cpu(data->reassoc_req_ie_len) + + assoc_resp_ie_offset]; + assoc_resp_ie_len = le16_to_cpu(data->reassoc_resp_ie_len) - + assoc_resp_ie_offset; + + if (test_bit(wil_status_resetting, wil->status) || + !test_bit(wil_status_fwready, wil->status)) { + wil_err(wil, "FT: status_resetting, cancel reassoc event\n"); + /* no need for cleanup, wil_reset will do that */ + return; + } + + mutex_lock(&wil->mutex); + + /* ring modify to set the ring for the roamed AP settings */ + wil_dbg_wmi(wil, + "ft modify tx config for connection CID %d ring %d\n", + cid, ringid); + + rc = wil->txrx_ops.tx_ring_modify(vif, ringid, cid, 0); + if (rc) { + wil_err(wil, "modify TX for CID %d MID %d ring %d failed (%d)\n", + cid, vif->mid, ringid, rc); + mutex_unlock(&wil->mutex); + goto fail; + } + + /* Update the driver STA members with the new bss */ + wil->sta[cid].aid = data->aid; + wil->sta[cid].stats.ft_roams++; + ether_addr_copy(wil->sta[cid].addr, vif->bss->bssid); + mutex_unlock(&wil->mutex); + del_timer_sync(&vif->connect_timer); + + cfg80211_ref_bss(wiphy, vif->bss); + freq = ieee80211_channel_to_frequency(ch, NL80211_BAND_60GHZ); + + memset(&info, 0, sizeof(info)); + info.channel = ieee80211_get_channel(wiphy, freq); + info.bss = vif->bss; + info.req_ie = assoc_req_ie; + info.req_ie_len = assoc_req_ie_len; + info.resp_ie = assoc_resp_ie; + info.resp_ie_len = assoc_resp_ie_len; + cfg80211_roamed(ndev, &info, GFP_KERNEL); + vif->bss = NULL; + + return; + +fail: + wil6210_disconnect(vif, NULL, WLAN_REASON_PREV_AUTH_NOT_VALID, false); +} + /** * Some events are ignored for purpose; and need not be interpreted as * "unhandled events" @@ -1492,6 +1800,8 @@ static const struct { {WMI_DATA_PORT_OPEN_EVENTID, wmi_evt_ignore}, {WMI_SCHED_SCAN_RESULT_EVENTID, wmi_evt_sched_scan_result}, {WMI_LINK_STATS_EVENTID, wmi_evt_link_stats}, + {WMI_FT_AUTH_STATUS_EVENTID, wmi_evt_auth_status}, + {WMI_FT_REASSOC_STATUS_EVENTID, wmi_evt_reassoc_status}, }; /* @@ -2086,6 +2396,40 @@ int wmi_set_ie(struct wil6210_vif *vif, u8 type, u16 ie_len, const void *ie) return rc; } +int wmi_update_ft_ies(struct wil6210_vif *vif, u16 ie_len, const void *ie) +{ + struct wil6210_priv *wil = vif_to_wil(vif); + u16 len; + struct wmi_update_ft_ies_cmd *cmd; + int rc; + + if (!ie) + ie_len = 0; + + len = sizeof(struct wmi_update_ft_ies_cmd) + ie_len; + if (len < ie_len) { + wil_err(wil, "wraparound. ie len %d\n", ie_len); + return -EINVAL; + } + + cmd = kzalloc(len, GFP_KERNEL); + if (!cmd) { + rc = -ENOMEM; + goto out; + } + + cmd->ie_len = cpu_to_le16(ie_len); + memcpy(cmd->ie_info, ie, ie_len); + rc = wmi_send(wil, WMI_UPDATE_FT_IES_CMDID, vif->mid, cmd, len); + kfree(cmd); + +out: + if (rc) + wil_err(wil, "update ft ies failed : %d\n", rc); + + return rc; +} + /** * wmi_rxon - turn radio on/off * @on: turn on if true, off otherwise diff --git a/drivers/net/wireless/ath/wil6210/wmi.h b/drivers/net/wireless/ath/wil6210/wmi.h index f430e1d48e81..b668758da994 100644 --- a/drivers/net/wireless/ath/wil6210/wmi.h +++ b/drivers/net/wireless/ath/wil6210/wmi.h @@ -2370,6 +2370,7 @@ struct wmi_ft_reassoc_status_event { __le16 beacon_ie_len; __le16 reassoc_req_ie_len; __le16 reassoc_resp_ie_len; + u8 reserved[4]; u8 ie_info[0]; } __packed; From 4405b632e3da839defec966e4b0be44d0c5e3102 Mon Sep 17 00:00:00 2001 From: Dedy Lansky Date: Thu, 23 Aug 2018 14:47:13 +0300 Subject: [PATCH 019/276] wil6210: fix invalid memory access for rx_buff_mgmt debugfs Check rx_buff_mgmt is allocated before accessing its internal fields. Signed-off-by: Dedy Lansky Signed-off-by: Maya Erez Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/wil6210/debugfs.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/wireless/ath/wil6210/debugfs.c b/drivers/net/wireless/ath/wil6210/debugfs.c index 6973333497c1..965c61be8b79 100644 --- a/drivers/net/wireless/ath/wil6210/debugfs.c +++ b/drivers/net/wireless/ath/wil6210/debugfs.c @@ -1237,6 +1237,9 @@ static int wil_rx_buff_mgmt_debugfs_show(struct seq_file *s, void *data) int num_active; int num_free; + if (!rbm->buff_arr) + return -EINVAL; + seq_printf(s, " size = %zu\n", rbm->size); seq_printf(s, " free_list_empty_cnt = %lu\n", rbm->free_list_empty_cnt); From 34d5629d2ca89d847b7040762b87964c696c14da Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Fri, 24 Aug 2018 15:04:59 +0300 Subject: [PATCH 020/276] ath10k: limit available channels via DT ieee80211-freq-limit Tri-band devices (1x 2.4GHz + 2x 5GHz) often incorporate special filters in the RX and TX path. These filtered channel can in theory still be used by the hardware but the signal strength is reduced so much that it makes no sense. There is already a DT property to limit the available channels but ath10k has to manually call this functionality to limit the currrently set wiphy channels further. Signed-off-by: Sven Eckelmann Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/mac.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 90f9372dec25..496772d95d11 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -18,6 +18,7 @@ #include "mac.h" +#include #include #include #include @@ -8359,6 +8360,7 @@ int ath10k_mac_register(struct ath10k *ar) ar->hw->wiphy->bands[NL80211_BAND_5GHZ] = band; } + wiphy_read_of_freq_limits(ar->hw->wiphy); ath10k_mac_setup_ht_vht_cap(ar); ar->hw->wiphy->interface_modes = From b21e32dc348a6facd178306d9d8151aeb47b1535 Mon Sep 17 00:00:00 2001 From: Mordechay Goodstein Date: Sun, 11 Feb 2018 20:34:19 +0200 Subject: [PATCH 021/276] iwlwifi: turn timestamp marker cmd off by default Don't enable debugging timestamps by default, so we save power by not waking up the FW with timestamp commands. Signed-off-by: Mordechay Goodstein Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index a31a42e673c4..bab54c9889af 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -1133,9 +1133,6 @@ int iwl_fw_start_dbg_conf(struct iwl_fw_runtime *fwrt, u8 conf_id) IWL_WARN(fwrt, "FW already configured (%d) - re-configuring\n", fwrt->dump.conf); - /* start default config marker cmd for syncing logs */ - iwl_fw_trigger_timestamp(fwrt, 1); - /* Send all HCMDs for configuring the FW debug */ ptr = (void *)&fwrt->fw->dbg_conf_tlv[conf_id]->hcmd; for (i = 0; i < fwrt->fw->dbg_conf_tlv[conf_id]->num_of_hcmds; i++) { From fe997b00c5b5953e48e61956ced0e73c84e9d054 Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Sat, 18 Aug 2018 10:16:29 +0300 Subject: [PATCH 022/276] iwlwifi: remove unused TLC debugging commands The iwl_dhc_tlc_cmd struct is not used, so remove it, including the iwl_tcl_debug_flags enumeration. Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/fw/api/rs.h | 60 ------------------- 1 file changed, 60 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/rs.h b/drivers/net/wireless/intel/iwlwifi/fw/api/rs.h index 087fae91baef..fe2763cfc3b5 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/rs.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/rs.h @@ -217,66 +217,6 @@ struct iwl_tlc_update_notif { __le32 amsdu_enabled; } __packed; /* TLC_MNG_UPDATE_NTFY_API_S_VER_2 */ -/** - * enum iwl_tlc_debug_flags - debug options - * @IWL_TLC_DEBUG_FIXED_RATE: set fixed rate for rate scaling - * @IWL_TLC_DEBUG_STATS_TH: threshold for sending statistics to the driver, in - * frames - * @IWL_TLC_DEBUG_STATS_TIME_TH: threshold for sending statistics to the - * driver, in msec - * @IWL_TLC_DEBUG_AGG_TIME_LIM: time limit for a BA session - * @IWL_TLC_DEBUG_AGG_DIS_START_TH: frame with try-count greater than this - * threshold should not start an aggregation session - * @IWL_TLC_DEBUG_AGG_FRAME_CNT_LIM: set max number of frames in an aggregation - * @IWL_TLC_DEBUG_RENEW_ADDBA_DELAY: delay between retries of ADD BA - * @IWL_TLC_DEBUG_START_AC_RATE_IDX: frames per second to start a BA session - * @IWL_TLC_DEBUG_NO_FAR_RANGE_TWEAK: disable BW scaling - */ -enum iwl_tlc_debug_flags { - IWL_TLC_DEBUG_FIXED_RATE, - IWL_TLC_DEBUG_STATS_TH, - IWL_TLC_DEBUG_STATS_TIME_TH, - IWL_TLC_DEBUG_AGG_TIME_LIM, - IWL_TLC_DEBUG_AGG_DIS_START_TH, - IWL_TLC_DEBUG_AGG_FRAME_CNT_LIM, - IWL_TLC_DEBUG_RENEW_ADDBA_DELAY, - IWL_TLC_DEBUG_START_AC_RATE_IDX, - IWL_TLC_DEBUG_NO_FAR_RANGE_TWEAK, -}; /* TLC_MNG_DEBUG_FLAGS_API_E_VER_1 */ - -/** - * struct iwl_dhc_tlc_dbg - fixed debug config - * @sta_id: bit 0 - enable/disable, bits 1 - 7 hold station id - * @reserved1: reserved - * @flags: bitmap of %IWL_TLC_DEBUG_\* - * @fixed_rate: rate value - * @stats_threshold: if number of tx-ed frames is greater, send statistics - * @time_threshold: statistics threshold in usec - * @agg_time_lim: max agg time - * @agg_dis_start_threshold: frames with try-cont greater than this count will - * not be aggregated - * @agg_frame_count_lim: agg size - * @addba_retry_delay: delay between retries of ADD BA - * @start_ac_rate_idx: frames per second to start a BA session - * @no_far_range_tweak: disable BW scaling - * @reserved2: reserved - */ -struct iwl_dhc_tlc_cmd { - u8 sta_id; - u8 reserved1[3]; - __le32 flags; - __le32 fixed_rate; - __le16 stats_threshold; - __le16 time_threshold; - __le16 agg_time_lim; - __le16 agg_dis_start_threshold; - __le16 agg_frame_count_lim; - __le16 addba_retry_delay; - u8 start_ac_rate_idx[IEEE80211_NUM_ACS]; - u8 no_far_range_tweak; - u8 reserved2[3]; -} __packed; - /* * These serve as indexes into * struct iwl_rate_info fw_rate_idx_to_plcp[IWL_RATE_COUNT]; From dd2690579f5138e569440e5252e93d8634593190 Mon Sep 17 00:00:00 2001 From: Naftali Goldstein Date: Tue, 13 Mar 2018 20:00:35 +0200 Subject: [PATCH 023/276] iwlwifi: runtime: avoid calling debugfs read functions more than once Upon first calling read() on a debugfs file, invoke iwl_dbgfs_##name##_read and store the response buffer on the heap, so subsequent read() calls don't need to invoke said function again. This is done because cat etc will call read() repeatedly until EOF is reached (or read() returns 0), which in the current implementation will cause said function to be invoked multiple times. With the current implementation this can also cause buggy behavior in some weird edge cases where the first invocation returns a string of length n, and the second of length m>n: The last m-n characters of the second invocation will be printed to screen. Signed-off-by: Naftali Goldstein Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/fw/debugfs.c | 115 ++++++++++++++---- 1 file changed, 89 insertions(+), 26 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c b/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c index 8ba5a60ec9ed..2dd534b474b8 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c @@ -8,6 +8,7 @@ * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * Copyright(c) 2016 - 2017 Intel Deutschland GmbH + * Copyright (C) 2018 Intel Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -33,6 +34,7 @@ * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * Copyright(c) 2016 - 2017 Intel Deutschland GmbH + * Copyright (C) 2018 Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -66,55 +68,117 @@ #include "debugfs.h" #include "dbg.h" -#define FWRT_DEBUGFS_READ_FILE_OPS(name) \ -static ssize_t iwl_dbgfs_##name##_read(struct iwl_fw_runtime *fwrt, \ - char *buf, size_t count, \ - loff_t *ppos); \ -static const struct file_operations iwl_dbgfs_##name##_ops = { \ - .read = iwl_dbgfs_##name##_read, \ - .open = simple_open, \ - .llseek = generic_file_llseek, \ +#define FWRT_DEBUGFS_OPEN_WRAPPER(name, buflen, argtype) \ +struct dbgfs_##name##_data { \ + argtype *arg; \ + bool read_done; \ + ssize_t rlen; \ + char rbuf[buflen]; \ +}; \ +static int _iwl_dbgfs_##name##_open(struct inode *inode, \ + struct file *file) \ +{ \ + struct dbgfs_##name##_data *data; \ + \ + data = kzalloc(sizeof(*data), GFP_KERNEL); \ + if (!data) \ + return -ENOMEM; \ + \ + data->read_done = false; \ + data->arg = inode->i_private; \ + file->private_data = data; \ + \ + return 0; \ } -#define FWRT_DEBUGFS_WRITE_WRAPPER(name, buflen) \ -static ssize_t iwl_dbgfs_##name##_write(struct iwl_fw_runtime *fwrt, \ - char *buf, size_t count, \ - loff_t *ppos); \ +#define FWRT_DEBUGFS_READ_WRAPPER(name) \ +static ssize_t _iwl_dbgfs_##name##_read(struct file *file, \ + char __user *user_buf, \ + size_t count, loff_t *ppos) \ +{ \ + struct dbgfs_##name##_data *data = file->private_data; \ + \ + if (!data->read_done) { \ + data->read_done = true; \ + data->rlen = iwl_dbgfs_##name##_read(data->arg, \ + sizeof(data->rbuf),\ + data->rbuf); \ + } \ + \ + if (data->rlen < 0) \ + return data->rlen; \ + return simple_read_from_buffer(user_buf, count, ppos, \ + data->rbuf, data->rlen); \ +} + +static int _iwl_dbgfs_release(struct inode *inode, struct file *file) +{ + kfree(file->private_data); + + return 0; +} + +#define _FWRT_DEBUGFS_READ_FILE_OPS(name, buflen, argtype) \ +FWRT_DEBUGFS_OPEN_WRAPPER(name, buflen, argtype) \ +FWRT_DEBUGFS_READ_WRAPPER(name) \ +static const struct file_operations iwl_dbgfs_##name##_ops = { \ + .read = _iwl_dbgfs_##name##_read, \ + .open = _iwl_dbgfs_##name##_open, \ + .llseek = generic_file_llseek, \ + .release = _iwl_dbgfs_release, \ +} + +#define FWRT_DEBUGFS_WRITE_WRAPPER(name, buflen, argtype) \ static ssize_t _iwl_dbgfs_##name##_write(struct file *file, \ const char __user *user_buf, \ size_t count, loff_t *ppos) \ { \ - struct iwl_fw_runtime *fwrt = file->private_data; \ + argtype *arg = \ + ((struct dbgfs_##name##_data *)file->private_data)->arg;\ char buf[buflen] = {}; \ size_t buf_size = min(count, sizeof(buf) - 1); \ \ if (copy_from_user(buf, user_buf, buf_size)) \ return -EFAULT; \ \ - return iwl_dbgfs_##name##_write(fwrt, buf, buf_size, ppos); \ + return iwl_dbgfs_##name##_write(arg, buf, buf_size); \ } -#define FWRT_DEBUGFS_READ_WRITE_FILE_OPS(name, buflen) \ -FWRT_DEBUGFS_WRITE_WRAPPER(name, buflen) \ +#define _FWRT_DEBUGFS_READ_WRITE_FILE_OPS(name, buflen, argtype) \ +FWRT_DEBUGFS_OPEN_WRAPPER(name, buflen, argtype) \ +FWRT_DEBUGFS_WRITE_WRAPPER(name, buflen, argtype) \ +FWRT_DEBUGFS_READ_WRAPPER(name) \ static const struct file_operations iwl_dbgfs_##name##_ops = { \ .write = _iwl_dbgfs_##name##_write, \ - .read = iwl_dbgfs_##name##_read, \ - .open = simple_open, \ + .read = _iwl_dbgfs_##name##_read, \ + .open = _iwl_dbgfs_##name##_open, \ .llseek = generic_file_llseek, \ + .release = _iwl_dbgfs_release, \ } -#define FWRT_DEBUGFS_WRITE_FILE_OPS(name, buflen) \ -FWRT_DEBUGFS_WRITE_WRAPPER(name, buflen) \ +#define _FWRT_DEBUGFS_WRITE_FILE_OPS(name, buflen, argtype) \ +FWRT_DEBUGFS_OPEN_WRAPPER(name, buflen, argtype) \ +FWRT_DEBUGFS_WRITE_WRAPPER(name, buflen, argtype) \ static const struct file_operations iwl_dbgfs_##name##_ops = { \ .write = _iwl_dbgfs_##name##_write, \ - .open = simple_open, \ + .open = _iwl_dbgfs_##name##_open, \ .llseek = generic_file_llseek, \ + .release = _iwl_dbgfs_release, \ } +#define FWRT_DEBUGFS_READ_FILE_OPS(name, bufsz) \ + _FWRT_DEBUGFS_READ_FILE_OPS(name, bufsz, struct iwl_fw_runtime) + +#define FWRT_DEBUGFS_WRITE_FILE_OPS(name, bufsz) \ + _FWRT_DEBUGFS_WRITE_FILE_OPS(name, bufsz, struct iwl_fw_runtime) + +#define FWRT_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz) \ + _FWRT_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz, struct iwl_fw_runtime) + #define FWRT_DEBUGFS_ADD_FILE_ALIAS(alias, name, parent, mode) do { \ - if (!debugfs_create_file(alias, mode, parent, fwrt, \ - &iwl_dbgfs_##name##_ops)) \ - goto err; \ + if (!debugfs_create_file(alias, mode, parent, fwrt, \ + &iwl_dbgfs_##name##_ops)) \ + goto err; \ } while (0) #define FWRT_DEBUGFS_ADD_FILE(name, parent, mode) \ FWRT_DEBUGFS_ADD_FILE_ALIAS(#name, name, parent, mode) @@ -173,8 +237,7 @@ void iwl_fw_trigger_timestamp(struct iwl_fw_runtime *fwrt, u32 delay) } static ssize_t iwl_dbgfs_timestamp_marker_write(struct iwl_fw_runtime *fwrt, - char *buf, size_t count, - loff_t *ppos) + char *buf, size_t count) { int ret; u32 delay; From 2210f6959dfa754d2a191f3db6ac7592d1bebc9c Mon Sep 17 00:00:00 2001 From: Avraham Stern Date: Tue, 20 Mar 2018 17:05:06 +0200 Subject: [PATCH 024/276] iwlwifi: set the tid for non-QOS frames to zero The tid for Non-QOS frames is set to IWL_MAX_TID_COUNT. This value is also used for configuring the queue for non-QOS data. However, this tid is used by the FW for management queues. As a result, the FW does not encrypt non-QOS data frames. Fix this by setting the tid for non-QOS data frames to zero, which is a valid value for data frames in the FW. This also fixes a bug in sending multicast frames, where the queues are allocated with tid == 0, but are sent with tid == 8, which may lead to unexpected behavior. Signed-off-by: Avraham Stern Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/fw/api/tx.h | 2 +- drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 24 ++++++++++++++----- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h b/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h index 514b86123d3d..135135d80d4d 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h @@ -186,7 +186,7 @@ enum iwl_tx_cmd_sec_ctrl { /* * TID for non QoS frames - to be written in tid_tspec */ -#define IWL_TID_NON_QOS IWL_MAX_TID_COUNT +#define IWL_TID_NON_QOS 0 /* * Limits on the retransmissions - to be written in {data,rts}_retry_limit diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c index ff193dca2020..83f3e74337db 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c @@ -8,6 +8,7 @@ * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * Copyright(c) 2016 - 2017 Intel Deutschland GmbH + * Copyright(c) 2018 Intel Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -35,6 +36,7 @@ * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * Copyright(c) 2016 - 2017 Intel Deutschland GmbH + * Copyright(c) 2018 Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -245,14 +247,18 @@ void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb, iwl_mvm_bar_check_trigger(mvm, bar->ra, tx_cmd->tid_tspec, ssn); } else { - tx_cmd->tid_tspec = IWL_TID_NON_QOS; + if (ieee80211_is_data(fc)) + tx_cmd->tid_tspec = IWL_TID_NON_QOS; + else + tx_cmd->tid_tspec = IWL_MAX_TID_COUNT; + if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) tx_flags |= TX_CMD_FLG_SEQ_CTL; else tx_flags &= ~TX_CMD_FLG_SEQ_CTL; } - /* Default to 0 (BE) when tid_spec is set to IWL_TID_NON_QOS */ + /* Default to 0 (BE) when tid_spec is set to IWL_MAX_TID_COUNT */ if (tx_cmd->tid_tspec < IWL_MAX_TID_COUNT) ac = tid_to_mac80211_ac[tx_cmd->tid_tspec]; else @@ -1049,6 +1055,8 @@ static int iwl_mvm_tx_mpdu(struct iwl_mvm *mvm, struct sk_buff *skb, /* update the tx_cmd hdr as it was already copied */ tx_cmd->hdr->seq_ctrl = hdr->seq_ctrl; } + } else if (ieee80211_is_data(fc) && !ieee80211_is_data_qos(fc)) { + tid = IWL_TID_NON_QOS; } txq_id = mvmsta->tid_data[tid].txq_id; @@ -1525,7 +1533,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm, iwl_mvm_tx_airtime(mvm, mvmsta, le16_to_cpu(tx_resp->wireless_media_time)); - if (tid != IWL_TID_NON_QOS && tid != IWL_MGMT_TID) { + if (sta->wme && tid != IWL_MGMT_TID) { struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid]; bool send_eosp_ndp = false; @@ -1645,20 +1653,24 @@ static void iwl_mvm_rx_tx_cmd_agg(struct iwl_mvm *mvm, u16 sequence = le16_to_cpu(pkt->hdr.sequence); struct iwl_mvm_sta *mvmsta; int queue = SEQ_TO_QUEUE(sequence); + struct ieee80211_sta *sta; if (WARN_ON_ONCE(queue < IWL_MVM_DQA_MIN_DATA_QUEUE && (queue != IWL_MVM_DQA_BSS_CLIENT_QUEUE))) return; - if (WARN_ON_ONCE(tid == IWL_TID_NON_QOS)) - return; - iwl_mvm_rx_tx_cmd_agg_dbg(mvm, pkt); rcu_read_lock(); mvmsta = iwl_mvm_sta_from_staid_rcu(mvm, sta_id); + sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]); + if (WARN_ON_ONCE(!sta || !sta->wme)) { + rcu_read_unlock(); + return; + } + if (!WARN_ON_ONCE(!mvmsta)) { mvmsta->tid_data[tid].rate_n_flags = le32_to_cpu(tx_resp->initial_rate); From 2d8c261511abfebd705d2163500d6b3049f0dec6 Mon Sep 17 00:00:00 2001 From: Shahar S Matityahu Date: Mon, 29 Jan 2018 11:05:37 +0200 Subject: [PATCH 025/276] iwlwifi: add d3 debug data support During d3, the firmware records debug data into internal buffer if debug data collection occurs, collect the data that was written to the buffer Signed-off-by: Shahar S Matityahu Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/cfg/22000.c | 4 +- drivers/net/wireless/intel/iwlwifi/cfg/9000.c | 4 +- drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 48 +++++++++++++++++++ drivers/net/wireless/intel/iwlwifi/fw/dbg.h | 10 ++++ .../wireless/intel/iwlwifi/fw/error-dump.h | 8 ++-- drivers/net/wireless/intel/iwlwifi/fw/file.h | 2 + .../net/wireless/intel/iwlwifi/fw/runtime.h | 1 + .../net/wireless/intel/iwlwifi/iwl-config.h | 4 ++ drivers/net/wireless/intel/iwlwifi/iwl-csr.h | 1 + drivers/net/wireless/intel/iwlwifi/iwl-drv.c | 4 +- drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 3 ++ drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 6 ++- 12 files changed, 85 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c index 91ca77c7571c..c6b738c8fd84 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c @@ -155,7 +155,9 @@ static const struct iwl_ht_params iwl_22000_ht_params = { .gen2 = true, \ .nvm_type = IWL_NVM_EXT, \ .dbgc_supported = true, \ - .min_umac_error_event_table = 0x400000 + .min_umac_error_event_table = 0x400000, \ + .d3_debug_data_base_addr = 0x401000, \ + .d3_debug_data_length = 60 * 1024 #define IWL_DEVICE_22500 \ IWL_DEVICE_22000_COMMON, \ diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/9000.c b/drivers/net/wireless/intel/iwlwifi/cfg/9000.c index 24b2f7cbb308..37deaf4fd7b3 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/9000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/9000.c @@ -155,7 +155,9 @@ static const struct iwl_tt_params iwl9000_tt_params = { .nvm_type = IWL_NVM_EXT, \ .dbgc_supported = true, \ .min_umac_error_event_table = 0x800000, \ - .csr = &iwl_csr_v1 + .csr = &iwl_csr_v1, \ + .d3_debug_data_base_addr = 0x401000, \ + .d3_debug_data_length = 92 * 1024 const struct iwl_cfg iwl9160_2ac_cfg = { .name = "Intel(R) Dual Band Wireless AC 9160", diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index bab54c9889af..70173ad11050 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -746,6 +746,11 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt) sizeof(struct iwl_fw_error_dump_paging) + PAGING_BLOCK_SIZE); + if (iwl_fw_dbg_is_d3_debug_enabled(fwrt) && fwrt->dump.d3_debug_data) { + file_len += sizeof(*dump_data) + + fwrt->trans->cfg->d3_debug_data_length * 2; + } + /* If we only want a monitor dump, reset the file length */ if (monitor_dump_only) { file_len = sizeof(*dump_file) + sizeof(*dump_data) * 2 + @@ -858,6 +863,26 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt) dump_data = iwl_fw_error_next_data(dump_data); } + if (iwl_fw_dbg_is_d3_debug_enabled(fwrt) && fwrt->dump.d3_debug_data) { + u32 addr = fwrt->trans->cfg->d3_debug_data_base_addr; + size_t data_size = fwrt->trans->cfg->d3_debug_data_length; + + dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_D3_DEBUG_DATA); + dump_data->len = cpu_to_le32(data_size * 2); + + memcpy(dump_data->data, fwrt->dump.d3_debug_data, + data_size); + + kfree(fwrt->dump.d3_debug_data); + fwrt->dump.d3_debug_data = NULL; + + iwl_trans_read_mem_bytes(fwrt->trans, addr, + dump_data->data + data_size, + data_size); + + dump_data = iwl_fw_error_next_data(dump_data); + } + for (i = 0; i < fwrt->fw->n_dbg_mem_tlv; i++) { u32 len = le32_to_cpu(fw_dbg_mem[i].len); u32 ofs = le32_to_cpu(fw_dbg_mem[i].ofs); @@ -1212,3 +1237,26 @@ void iwl_fw_error_dump_wk(struct work_struct *work) fwrt->ops->dump_end(fwrt->ops_ctx); } +void iwl_fw_dbg_read_d3_debug_data(struct iwl_fw_runtime *fwrt) +{ + const struct iwl_cfg *cfg = fwrt->trans->cfg; + + if (!iwl_fw_dbg_is_d3_debug_enabled(fwrt)) + return; + + if (!fwrt->dump.d3_debug_data) { + fwrt->dump.d3_debug_data = kmalloc(cfg->d3_debug_data_length, + GFP_KERNEL); + if (!fwrt->dump.d3_debug_data) { + IWL_ERR(fwrt, + "failed to allocate memory for D3 debug data\n"); + return; + } + } + + /* if the buffer holds previous debug data it is overwritten */ + iwl_trans_read_mem_bytes(fwrt->trans, cfg->d3_debug_data_base_addr, + fwrt->dump.d3_debug_data, + cfg->d3_debug_data_length); +} +IWL_EXPORT_SYMBOL(iwl_fw_dbg_read_d3_debug_data); diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h index 507d9a49fa97..2c6df7756927 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h @@ -217,6 +217,16 @@ static inline void iwl_fw_dump_conf_clear(struct iwl_fw_runtime *fwrt) void iwl_fw_error_dump_wk(struct work_struct *work); +static inline bool iwl_fw_dbg_is_d3_debug_enabled(struct iwl_fw_runtime *fwrt) +{ + return fw_has_capa(&fwrt->fw->ucode_capa, + IWL_UCODE_TLV_CAPA_D3_DEBUG) && + fwrt->trans->cfg->d3_debug_data_length && + fwrt->fw->dbg_dump_mask & BIT(IWL_FW_ERROR_DUMP_D3_DEBUG_DATA); +} + +void iwl_fw_dbg_read_d3_debug_data(struct iwl_fw_runtime *fwrt); + static inline void iwl_fw_flush_dump(struct iwl_fw_runtime *fwrt) { flush_delayed_work(&fwrt->dump.wk); diff --git a/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h b/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h index ed7beca8817e..6d3ef331b7d5 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h @@ -8,6 +8,7 @@ * Copyright(c) 2014 Intel Corporation. All rights reserved. * Copyright(c) 2014 - 2015 Intel Mobile Communications GmbH * Copyright(c) 2016 - 2017 Intel Deutschland GmbH + * Copyright (C) 2018 Intel Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -18,11 +19,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * @@ -35,6 +31,7 @@ * Copyright(c) 2014 Intel Corporation. All rights reserved. * Copyright(c) 2014 - 2015 Intel Mobile Communications GmbH * Copyright(c) 2016 - 2017 Intel Deutschland GmbH + * Copyright (C) 2018 Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -116,6 +113,7 @@ enum iwl_fw_error_dump_type { IWL_FW_ERROR_DUMP_INTERNAL_TXF = 14, IWL_FW_ERROR_DUMP_EXTERNAL = 15, /* Do not move */ IWL_FW_ERROR_DUMP_MEM_CFG = 16, + IWL_FW_ERROR_DUMP_D3_DEBUG_DATA = 17, IWL_FW_ERROR_DUMP_MAX, }; diff --git a/drivers/net/wireless/intel/iwlwifi/fw/file.h b/drivers/net/wireless/intel/iwlwifi/fw/file.h index bbf2b265a06a..257ef70f8a1e 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/file.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/file.h @@ -349,6 +349,7 @@ typedef unsigned int __bitwise iwl_ucode_tlv_capa_t; * command size (command version 4) that supports toggling ACK TX * power reduction. * @IWL_UCODE_TLV_CAPA_MLME_OFFLOAD: supports MLME offload + * @IWL_UCODE_TLV_CAPA_D3_DEBUG: supports debug recording during D3 * * @NUM_IWL_UCODE_TLV_CAPA: number of bits used */ @@ -397,6 +398,7 @@ enum iwl_ucode_tlv_capa { IWL_UCODE_TLV_CAPA_LQM_SUPPORT = (__force iwl_ucode_tlv_capa_t)81, IWL_UCODE_TLV_CAPA_TX_POWER_ACK = (__force iwl_ucode_tlv_capa_t)84, IWL_UCODE_TLV_CAPA_LED_CMD_SUPPORT = (__force iwl_ucode_tlv_capa_t)86, + IWL_UCODE_TLV_CAPA_D3_DEBUG = (__force iwl_ucode_tlv_capa_t)87, IWL_UCODE_TLV_CAPA_MLME_OFFLOAD = (__force iwl_ucode_tlv_capa_t)96, NUM_IWL_UCODE_TLV_CAPA diff --git a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h index ed23367f7088..9ed5819defaf 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h @@ -136,6 +136,7 @@ struct iwl_fw_runtime { /* ts of the beginning of a non-collect fw dbg data period */ unsigned long non_collect_ts_start[FW_DBG_TRIGGER_MAX - 1]; + u32 *d3_debug_data; } dump; #ifdef CONFIG_IWLWIFI_DEBUGFS struct { diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h b/drivers/net/wireless/intel/iwlwifi/iwl-config.h index 12fddcf15bab..4d16ac545269 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h @@ -388,6 +388,8 @@ struct iwl_csr_params { * @gen2: 22000 and on transport operation * @cdb: CDB support * @nvm_type: see &enum iwl_nvm_type + * @d3_debug_data_base_addr: base address where D3 debug data is stored + * @d3_debug_data_length: length of the D3 debug data * * We enable the driver to be backward compatible wrt. hardware features. * API differences in uCode shouldn't be handled here but through TLVs @@ -452,6 +454,8 @@ struct iwl_cfg { u8 ucode_api_min; u32 min_umac_error_event_table; u32 extra_phy_cfg_flags; + u32 d3_debug_data_base_addr; + u32 d3_debug_data_length; }; static const struct iwl_csr_params iwl_csr_v1 = { diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-csr.h b/drivers/net/wireless/intel/iwlwifi/iwl-csr.h index 9019de99f077..e2b29b844c3a 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-csr.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-csr.h @@ -188,6 +188,7 @@ #define CSR_HW_IF_CONFIG_REG_MSK_BOARD_VER (0x000000C0) #define CSR_HW_IF_CONFIG_REG_BIT_MAC_SI (0x00000100) #define CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI (0x00000200) +#define CSR_HW_IF_CONFIG_REG_D3_DEBUG (0x00000200) #define CSR_HW_IF_CONFIG_REG_MSK_PHY_TYPE (0x00000C00) #define CSR_HW_IF_CONFIG_REG_MSK_PHY_DASH (0x00003000) #define CSR_HW_IF_CONFIG_REG_MSK_PHY_STEP (0x0000C000) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c index c0631255aee7..39a1eadfc4b7 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c @@ -1275,8 +1275,8 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context) fw->ucode_capa.standard_phy_calibration_size = IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE; fw->ucode_capa.n_scan_channels = IWL_DEFAULT_SCAN_CHANNELS; - /* dump all fw memory areas by default */ - fw->dbg_dump_mask = 0xffffffff; + /* dump all fw memory areas by default except d3 debug data */ + fw->dbg_dump_mask = 0xfffdffff; pieces = kzalloc(sizeof(*pieces), GFP_KERNEL); if (!pieces) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c index 79bdae994822..47ceffbfd9af 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c @@ -1883,6 +1883,7 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test) goto err; } + iwl_fw_dbg_read_d3_debug_data(&mvm->fwrt); /* query SRAM first in case we want event logging */ iwl_mvm_read_d3_sram(mvm); @@ -2117,6 +2118,8 @@ static int iwl_mvm_d3_test_release(struct inode *inode, struct file *file) mvm->d3_test_active = false; + iwl_fw_dbg_read_d3_debug_data(&mvm->fwrt); + rtnl_lock(); __iwl_mvm_resume(mvm, true); rtnl_unlock(); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index 0e26619fb330..bce5d150eb58 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -182,6 +182,9 @@ static void iwl_mvm_nic_config(struct iwl_op_mode *op_mode) if (mvm->trans->cfg->device_family < IWL_DEVICE_FAMILY_8000) reg_val |= CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI; + if (iwl_fw_dbg_is_d3_debug_enabled(&mvm->fwrt)) + reg_val |= CSR_HW_IF_CONFIG_REG_D3_DEBUG; + iwl_trans_set_bits_mask(mvm->trans, CSR_HW_IF_CONFIG_REG, CSR_HW_IF_CONFIG_REG_MSK_MAC_DASH | CSR_HW_IF_CONFIG_REG_MSK_MAC_STEP | @@ -189,7 +192,8 @@ static void iwl_mvm_nic_config(struct iwl_op_mode *op_mode) CSR_HW_IF_CONFIG_REG_MSK_PHY_STEP | CSR_HW_IF_CONFIG_REG_MSK_PHY_DASH | CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI | - CSR_HW_IF_CONFIG_REG_BIT_MAC_SI, + CSR_HW_IF_CONFIG_REG_BIT_MAC_SI | + CSR_HW_IF_CONFIG_REG_D3_DEBUG, reg_val); IWL_DEBUG_INFO(mvm, "Radio type=0x%x-0x%x-0x%x\n", radio_cfg_type, From 11a0513cac8afb0c78280a10db72bcd671a8841f Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Tue, 27 Feb 2018 16:37:56 +0200 Subject: [PATCH 026/276] iwlwifi: mvm: remove duplicate if in iwl_mvm_setup_connection_keep() We repeated the same if twice in a row. Remove the second one and move the code block into the previous one. Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c index 47ceffbfd9af..799ee015ef84 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c @@ -1503,6 +1503,7 @@ static bool iwl_mvm_setup_connection_keep(struct iwl_mvm *mvm, .conf.cipher = gtkdata.cipher, .conf.keyidx = status->gtk.key_index, }; + __be64 replay_ctr; switch (gtkdata.cipher) { case WLAN_CIPHER_SUITE_CCMP: @@ -1524,11 +1525,9 @@ static bool iwl_mvm_setup_connection_keep(struct iwl_mvm *mvm, if (IS_ERR(key)) return false; iwl_mvm_set_key_rx_seq(mvm, key, status); - } - if (status->num_of_gtk_rekeys) { - __be64 replay_ctr = - cpu_to_be64(le64_to_cpu(status->replay_ctr)); + replay_ctr = cpu_to_be64(le64_to_cpu(status->replay_ctr)); + ieee80211_gtk_rekey_notify(vif, vif->bss_conf.bssid, (void *)&replay_ctr, GFP_KERNEL); } From a75b9b333aeb045fdb7f610b85f8b5305a2d706d Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Tue, 21 Aug 2018 07:24:18 +0300 Subject: [PATCH 027/276] iwlwifi: mvm: protect D0i3 code behind CONFIG_PM Runtime PM can only be used if CONFIG_PM is set. Move all the d0i3 code (which is essentially runtime PM) behind the CONFIG_PM flag. This prevents undefined usage of some functions when CONFIG_PM is not defined. Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 4 ++++ drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 3 +++ drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 15 +++++++++++++-- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index b15b0d84bb7e..0426cc614bfe 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -1124,7 +1124,9 @@ int __iwl_mvm_mac_start(struct iwl_mvm *mvm) * would do. */ clear_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status); +#ifdef CONFIG_PM iwl_mvm_d0i3_enable_tx(mvm, NULL); +#endif } return ret; @@ -1162,7 +1164,9 @@ static void iwl_mvm_restart_complete(struct iwl_mvm *mvm) mutex_lock(&mvm->mutex); clear_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status); +#ifdef CONFIG_PM iwl_mvm_d0i3_enable_tx(mvm, NULL); +#endif ret = iwl_mvm_update_quotas(mvm, true, NULL); if (ret) IWL_ERR(mvm, "Failed to update quotas after restart (%d)\n", diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index b3987a0a7018..35faeeef2484 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -1776,10 +1776,13 @@ void iwl_mvm_ref(struct iwl_mvm *mvm, enum iwl_mvm_ref_type ref_type); void iwl_mvm_unref(struct iwl_mvm *mvm, enum iwl_mvm_ref_type ref_type); int iwl_mvm_ref_sync(struct iwl_mvm *mvm, enum iwl_mvm_ref_type ref_type); bool iwl_mvm_ref_taken(struct iwl_mvm *mvm); + +#ifdef CONFIG_PM void iwl_mvm_d0i3_enable_tx(struct iwl_mvm *mvm, __le16 *qos_seq); int iwl_mvm_enter_d0i3(struct iwl_op_mode *op_mode); int iwl_mvm_exit_d0i3(struct iwl_op_mode *op_mode); int _iwl_mvm_exit_d0i3(struct iwl_mvm *mvm); +#endif /* BT Coex */ int iwl_mvm_send_bt_init_conf(struct iwl_mvm *mvm); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index bce5d150eb58..421509c63f23 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -495,7 +495,9 @@ static const struct iwl_hcmd_arr iwl_mvm_groups[] = { /* this forward declaration can avoid to export the function */ static void iwl_mvm_async_handlers_wk(struct work_struct *wk); +#ifdef CONFIG_PM static void iwl_mvm_d0i3_exit_work(struct work_struct *wk); +#endif static u32 iwl_mvm_min_backoff(struct iwl_mvm *mvm) { @@ -665,7 +667,9 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, INIT_WORK(&mvm->async_handlers_wk, iwl_mvm_async_handlers_wk); INIT_WORK(&mvm->roc_done_wk, iwl_mvm_roc_done_wk); +#ifdef CONFIG_PM INIT_WORK(&mvm->d0i3_exit_work, iwl_mvm_d0i3_exit_work); +#endif INIT_DELAYED_WORK(&mvm->tdls_cs.dwork, iwl_mvm_tdls_ch_switch_work); INIT_DELAYED_WORK(&mvm->scan_timeout_dwork, iwl_mvm_scan_timeout_wk); INIT_WORK(&mvm->add_stream_wk, iwl_mvm_add_new_dqa_stream_wk); @@ -1278,6 +1282,7 @@ static void iwl_mvm_cmd_queue_full(struct iwl_op_mode *op_mode) iwl_mvm_nic_restart(mvm, true); } +#ifdef CONFIG_PM struct iwl_d0i3_iter_data { struct iwl_mvm *mvm; struct ieee80211_vif *connected_vif; @@ -1689,6 +1694,13 @@ int iwl_mvm_exit_d0i3(struct iwl_op_mode *op_mode) return _iwl_mvm_exit_d0i3(mvm); } +#define IWL_MVM_D0I3_OPS \ + .enter_d0i3 = iwl_mvm_enter_d0i3, \ + .exit_d0i3 = iwl_mvm_exit_d0i3, +#else /* CONFIG_PM */ +#define IWL_MVM_D0I3_OPS +#endif /* CONFIG_PM */ + #define IWL_MVM_COMMON_OPS \ /* these could be differentiated */ \ .async_cb = iwl_mvm_async_cb, \ @@ -1699,8 +1711,7 @@ int iwl_mvm_exit_d0i3(struct iwl_op_mode *op_mode) .nic_error = iwl_mvm_nic_error, \ .cmd_queue_full = iwl_mvm_cmd_queue_full, \ .nic_config = iwl_mvm_nic_config, \ - .enter_d0i3 = iwl_mvm_enter_d0i3, \ - .exit_d0i3 = iwl_mvm_exit_d0i3, \ + IWL_MVM_D0I3_OPS \ /* as we only register one, these MUST be common! */ \ .start = iwl_op_mode_mvm_start, \ .stop = iwl_op_mode_mvm_stop From 2afa6a7311f5727c5a3984419d11b863cae69712 Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Mon, 26 Mar 2018 10:24:18 +0300 Subject: [PATCH 028/276] iwlwifi: mvm: support new WoWLAN status FW API A new FW API has been added for WOWLAN_GET_STATUSES to support multiple GTK keys and IGTK keys. Check the respective TLV and use the new API when it is set. Let most of the code use the new version (v7) and convert the old version (v6) to the new one when needed. Also refactor some functions a bit so that they can be reused more easily. Particularly the part that calls WOWLAN_GET_STATUSES which is reused in D3 and D0i3. Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/fw/api/d3.h | 91 ++++++++++- drivers/net/wireless/intel/iwlwifi/fw/file.h | 1 + drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 154 +++++++++++++----- drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 1 + drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 19 +-- 5 files changed, 210 insertions(+), 56 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h b/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h index 57f4bc242023..6fae02fa4cad 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h @@ -8,6 +8,7 @@ * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH * Copyright(c) 2015 - 2017 Intel Deutschland GmbH + * Copyright(c) 2018 Intel Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -30,6 +31,7 @@ * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH * Copyright(c) 2015 - 2017 Intel Deutschland GmbH + * Copyright(c) 2018 Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -374,7 +376,7 @@ enum iwl_wowlan_wakeup_reason { }; /* WOWLAN_WAKE_UP_REASON_API_E_VER_2 */ -struct iwl_wowlan_gtk_status { +struct iwl_wowlan_gtk_status_v1 { u8 key_index; u8 reserved[3]; u8 decrypt_key[16]; @@ -382,8 +384,52 @@ struct iwl_wowlan_gtk_status { struct iwl_wowlan_rsc_tsc_params_cmd rsc; } __packed; /* WOWLAN_GTK_MATERIAL_VER_1 */ +#define WOWLAN_KEY_MAX_SIZE 32 +#define WOWLAN_GTK_KEYS_NUM 2 +#define WOWLAN_IGTK_KEYS_NUM 2 + /** - * struct iwl_wowlan_status - WoWLAN status + * struct iwl_wowlan_gtk_status - GTK status + * @key: GTK material + * @key_len: GTK legth, if set to 0, the key is not available + * @key_flags: information about the key: + * bits[0:1]: key index assigned by the AP + * bits[2:6]: GTK index of the key in the internal DB + * bit[7]: Set iff this is the currently used GTK + * @reserved: padding + * @tkip_mic_key: TKIP RX MIC key + * @rsc: TSC RSC counters + */ +struct iwl_wowlan_gtk_status { + u8 key[WOWLAN_KEY_MAX_SIZE]; + u8 key_len; + u8 key_flags; + u8 reserved[2]; + u8 tkip_mic_key[8]; + struct iwl_wowlan_rsc_tsc_params_cmd rsc; +} __packed; /* WOWLAN_GTK_MATERIAL_VER_2 */ + +#define IWL_WOWLAN_GTK_IDX_MASK (BIT(0) | BIT(1)) + +/** + * struct iwl_wowlan_igtk_status - IGTK status + * @key: IGTK material + * @ipn: the IGTK packet number (replay counter) + * @key_len: IGTK length, if set to 0, the key is not available + * @key_flags: information about the key: + * bits[0]: key index assigned by the AP (0: index 4, 1: index 5) + * bits[1:5]: IGTK index of the key in the internal DB + * bit[6]: Set iff this is the currently used IGTK + */ +struct iwl_wowlan_igtk_status { + u8 key[WOWLAN_KEY_MAX_SIZE]; + u8 ipn[6]; + u8 key_len; + u8 key_flags; +} __packed; /* WOWLAN_IGTK_MATERIAL_VER_1 */ + +/** + * struct iwl_wowlan_status_v6 - WoWLAN status * @gtk: GTK data * @replay_ctr: GTK rekey replay counter * @pattern_number: number of the matched pattern @@ -397,8 +443,8 @@ struct iwl_wowlan_gtk_status { * @wake_packet_bufsize: wakeup packet buffer size * @wake_packet: wakeup packet */ -struct iwl_wowlan_status { - struct iwl_wowlan_gtk_status gtk; +struct iwl_wowlan_status_v6 { + struct iwl_wowlan_gtk_status_v1 gtk; __le64 replay_ctr; __le16 pattern_number; __le16 non_qos_seq_ctr; @@ -412,6 +458,43 @@ struct iwl_wowlan_status { u8 wake_packet[]; /* can be truncated from _length to _bufsize */ } __packed; /* WOWLAN_STATUSES_API_S_VER_6 */ +/** + * struct iwl_wowlan_status - WoWLAN status + * @gtk: GTK data + * @igtk: IGTK data + * @replay_ctr: GTK rekey replay counter + * @pattern_number: number of the matched pattern + * @non_qos_seq_ctr: non-QoS sequence counter to use next + * @qos_seq_ctr: QoS sequence counters to use next + * @wakeup_reasons: wakeup reasons, see &enum iwl_wowlan_wakeup_reason + * @num_of_gtk_rekeys: number of GTK rekeys + * @transmitted_ndps: number of transmitted neighbor discovery packets + * @received_beacons: number of received beacons + * @wake_packet_length: wakeup packet length + * @wake_packet_bufsize: wakeup packet buffer size + * @wake_packet: wakeup packet + */ +struct iwl_wowlan_status { + struct iwl_wowlan_gtk_status gtk[WOWLAN_GTK_KEYS_NUM]; + struct iwl_wowlan_igtk_status igtk[WOWLAN_IGTK_KEYS_NUM]; + __le64 replay_ctr; + __le16 pattern_number; + __le16 non_qos_seq_ctr; + __le16 qos_seq_ctr[8]; + __le32 wakeup_reasons; + __le32 num_of_gtk_rekeys; + __le32 transmitted_ndps; + __le32 received_beacons; + __le32 wake_packet_length; + __le32 wake_packet_bufsize; + u8 wake_packet[]; /* can be truncated from _length to _bufsize */ +} __packed; /* WOWLAN_STATUSES_API_S_VER_7 */ + +static inline u8 iwlmvm_wowlan_gtk_idx(struct iwl_wowlan_gtk_status *gtk) +{ + return gtk->key_flags & IWL_WOWLAN_GTK_IDX_MASK; +} + #define IWL_WOWLAN_TCP_MAX_PACKET_LEN 64 #define IWL_WOWLAN_REMOTE_WAKE_MAX_PACKET_LEN 128 #define IWL_WOWLAN_REMOTE_WAKE_MAX_TOKENS 2048 diff --git a/drivers/net/wireless/intel/iwlwifi/fw/file.h b/drivers/net/wireless/intel/iwlwifi/fw/file.h index 257ef70f8a1e..c116dc3fbffe 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/file.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/file.h @@ -276,6 +276,7 @@ enum iwl_ucode_tlv_api { IWL_UCODE_TLV_API_OCE = (__force iwl_ucode_tlv_api_t)33, IWL_UCODE_TLV_API_NEW_BEACON_TEMPLATE = (__force iwl_ucode_tlv_api_t)34, IWL_UCODE_TLV_API_NEW_RX_STATS = (__force iwl_ucode_tlv_api_t)35, + IWL_UCODE_TLV_API_WOWLAN_KEY_MATERIAL = (__force iwl_ucode_tlv_api_t)36, IWL_UCODE_TLV_API_QUOTA_LOW_LATENCY = (__force iwl_ucode_tlv_api_t)38, IWL_UCODE_TLV_API_DEPRECATE_TTAK = (__force iwl_ucode_tlv_api_t)41, IWL_UCODE_TLV_API_ADAPTIVE_DWELL_V2 = (__force iwl_ucode_tlv_api_t)42, diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c index 799ee015ef84..58531dd40c45 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c @@ -1362,7 +1362,7 @@ static void iwl_mvm_set_key_rx_seq(struct iwl_mvm *mvm, struct ieee80211_key_conf *key, struct iwl_wowlan_status *status) { - union iwl_all_tsc_rsc *rsc = &status->gtk.rsc.all_tsc_rsc; + union iwl_all_tsc_rsc *rsc = &status->gtk[0].rsc.all_tsc_rsc; switch (key->cipher) { case WLAN_CIPHER_SUITE_CCMP: @@ -1419,7 +1419,8 @@ static void iwl_mvm_d3_update_keys(struct ieee80211_hw *hw, */ if (sta) { struct ieee80211_key_seq seq = {}; - union iwl_all_tsc_rsc *sc = &data->status->gtk.rsc.all_tsc_rsc; + union iwl_all_tsc_rsc *sc = + &data->status->gtk[0].rsc.all_tsc_rsc; if (data->find_phase) return; @@ -1501,23 +1502,24 @@ static bool iwl_mvm_setup_connection_keep(struct iwl_mvm *mvm, u8 key[32]; } conf = { .conf.cipher = gtkdata.cipher, - .conf.keyidx = status->gtk.key_index, + .conf.keyidx = + iwlmvm_wowlan_gtk_idx(&status->gtk[0]), }; __be64 replay_ctr; switch (gtkdata.cipher) { case WLAN_CIPHER_SUITE_CCMP: conf.conf.keylen = WLAN_KEY_LEN_CCMP; - memcpy(conf.conf.key, status->gtk.decrypt_key, + memcpy(conf.conf.key, status->gtk[0].key, WLAN_KEY_LEN_CCMP); break; case WLAN_CIPHER_SUITE_TKIP: conf.conf.keylen = WLAN_KEY_LEN_TKIP; - memcpy(conf.conf.key, status->gtk.decrypt_key, 16); + memcpy(conf.conf.key, status->gtk[0].key, 16); /* leave TX MIC key zeroed, we don't use it anyway */ memcpy(conf.conf.key + NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY, - status->gtk.tkip_mic_key, 8); + status->gtk[0].tkip_mic_key, 8); break; } @@ -1526,7 +1528,8 @@ static bool iwl_mvm_setup_connection_keep(struct iwl_mvm *mvm, return false; iwl_mvm_set_key_rx_seq(mvm, key, status); - replay_ctr = cpu_to_be64(le64_to_cpu(status->replay_ctr)); + replay_ctr = + cpu_to_be64(le64_to_cpu(status->replay_ctr)); ieee80211_gtk_rekey_notify(vif, vif->bss_conf.bssid, (void *)&replay_ctr, GFP_KERNEL); @@ -1540,6 +1543,107 @@ static bool iwl_mvm_setup_connection_keep(struct iwl_mvm *mvm, return true; } +struct iwl_wowlan_status *iwl_mvm_send_wowlan_get_status(struct iwl_mvm *mvm) +{ + struct iwl_wowlan_status *v7, *status; + struct iwl_host_cmd cmd = { + .id = WOWLAN_GET_STATUSES, + .flags = CMD_WANT_SKB, + }; + int ret, len, status_size; + + lockdep_assert_held(&mvm->mutex); + + ret = iwl_mvm_send_cmd(mvm, &cmd); + if (ret) { + IWL_ERR(mvm, "failed to query wakeup status (%d)\n", ret); + return ERR_PTR(ret); + } + + if (!fw_has_api(&mvm->fw->ucode_capa, + IWL_UCODE_TLV_API_WOWLAN_KEY_MATERIAL)) { + struct iwl_wowlan_status_v6 *v6 = (void *)cmd.resp_pkt->data; + int data_size; + + status_size = sizeof(*v6); + len = iwl_rx_packet_payload_len(cmd.resp_pkt); + + if (len < status_size) { + IWL_ERR(mvm, "Invalid WoWLAN status response!\n"); + status = ERR_PTR(-EIO); + goto out_free_resp; + } + + data_size = ALIGN(le32_to_cpu(v6->wake_packet_bufsize), 4); + + if (len != (status_size + data_size)) { + IWL_ERR(mvm, "Invalid WoWLAN status response!\n"); + status = ERR_PTR(-EIO); + goto out_free_resp; + } + + status = kzalloc(sizeof(*status) + data_size, GFP_KERNEL); + if (!status) + goto out_free_resp; + + BUILD_BUG_ON(sizeof(v6->gtk.decrypt_key) > + sizeof(status->gtk[0].key)); + BUILD_BUG_ON(sizeof(v6->gtk.tkip_mic_key) > + sizeof(status->gtk[0].tkip_mic_key)); + + /* copy GTK info to the right place */ + memcpy(status->gtk[0].key, v6->gtk.decrypt_key, + sizeof(v6->gtk.decrypt_key)); + memcpy(status->gtk[0].tkip_mic_key, v6->gtk.tkip_mic_key, + sizeof(v6->gtk.tkip_mic_key)); + memcpy(&status->gtk[0].rsc, &v6->gtk.rsc, + sizeof(status->gtk[0].rsc)); + + /* hardcode the key length to 16 since v6 only supports 16 */ + status->gtk[0].key_len = 16; + + /* + * The key index only uses 2 bits (values 0 to 3) and + * we always set bit 7 which means this is the + * currently used key. + */ + status->gtk[0].key_flags = v6->gtk.key_index | BIT(7); + + status->replay_ctr = v6->replay_ctr; + + /* everything starting from pattern_number is identical */ + memcpy(&status->pattern_number, &v6->pattern_number, + offsetof(struct iwl_wowlan_status, wake_packet) - + offsetof(struct iwl_wowlan_status, pattern_number) + + data_size); + + goto out_free_resp; + } + + v7 = (void *)cmd.resp_pkt->data; + status_size = sizeof(*v7); + len = iwl_rx_packet_payload_len(cmd.resp_pkt); + + if (len < status_size) { + IWL_ERR(mvm, "Invalid WoWLAN status response!\n"); + status = ERR_PTR(-EIO); + goto out_free_resp; + } + + if (len != (status_size + + ALIGN(le32_to_cpu(v7->wake_packet_bufsize), 4))) { + IWL_ERR(mvm, "Invalid WoWLAN status response!\n"); + status = ERR_PTR(-EIO); + goto out_free_resp; + } + + status = kmemdup(v7, len, GFP_KERNEL); + +out_free_resp: + iwl_free_resp(&cmd); + return status; +} + static struct iwl_wowlan_status * iwl_mvm_get_wakeup_status(struct iwl_mvm *mvm, struct ieee80211_vif *vif) { @@ -1549,12 +1653,7 @@ iwl_mvm_get_wakeup_status(struct iwl_mvm *mvm, struct ieee80211_vif *vif) u32 valid; u32 error_id; } err_info; - struct iwl_host_cmd cmd = { - .id = WOWLAN_GET_STATUSES, - .flags = CMD_WANT_SKB, - }; - struct iwl_wowlan_status *status, *fw_status; - int ret, len, status_size; + int ret; iwl_trans_read_mem_bytes(mvm->trans, base, &err_info, sizeof(err_info)); @@ -1577,34 +1676,7 @@ iwl_mvm_get_wakeup_status(struct iwl_mvm *mvm, struct ieee80211_vif *vif) if (ret) IWL_ERR(mvm, "failed to query offload statistics (%d)\n", ret); - ret = iwl_mvm_send_cmd(mvm, &cmd); - if (ret) { - IWL_ERR(mvm, "failed to query status (%d)\n", ret); - return ERR_PTR(ret); - } - - status_size = sizeof(*fw_status); - - len = iwl_rx_packet_payload_len(cmd.resp_pkt); - if (len < status_size) { - IWL_ERR(mvm, "Invalid WoWLAN status response!\n"); - fw_status = ERR_PTR(-EIO); - goto out_free_resp; - } - - status = (void *)cmd.resp_pkt->data; - if (len != (status_size + - ALIGN(le32_to_cpu(status->wake_packet_bufsize), 4))) { - IWL_ERR(mvm, "Invalid WoWLAN status response!\n"); - fw_status = ERR_PTR(-EIO); - goto out_free_resp; - } - - fw_status = kmemdup(status, len, GFP_KERNEL); - -out_free_resp: - iwl_free_resp(&cmd); - return fw_status; + return iwl_mvm_send_wowlan_get_status(mvm); } /* releases the MVM mutex */ diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index 35faeeef2484..a0d694ea0182 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -1733,6 +1733,7 @@ void iwl_mvm_ipv6_addr_change(struct ieee80211_hw *hw, void iwl_mvm_set_default_unicast_key(struct ieee80211_hw *hw, struct ieee80211_vif *vif, int idx); extern const struct file_operations iwl_dbgfs_d3_test_ops; +struct iwl_wowlan_status *iwl_mvm_send_wowlan_get_status(struct iwl_mvm *mvm); #ifdef CONFIG_PM int iwl_mvm_wowlan_config_key_params(struct iwl_mvm *mvm, struct ieee80211_vif *vif, diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index 421509c63f23..d275832dbb14 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -1605,25 +1605,23 @@ void iwl_mvm_d0i3_enable_tx(struct iwl_mvm *mvm, __le16 *qos_seq) static void iwl_mvm_d0i3_exit_work(struct work_struct *wk) { struct iwl_mvm *mvm = container_of(wk, struct iwl_mvm, d0i3_exit_work); - struct iwl_host_cmd get_status_cmd = { - .id = WOWLAN_GET_STATUSES, - .flags = CMD_HIGH_PRIO | CMD_WANT_SKB, - }; struct iwl_mvm_d0i3_exit_work_iter_data iter_data = { .mvm = mvm, }; struct iwl_wowlan_status *status; - int ret; u32 wakeup_reasons = 0; __le16 *qos_seq = NULL; mutex_lock(&mvm->mutex); - ret = iwl_mvm_send_cmd(mvm, &get_status_cmd); - if (ret) - goto out; - status = (void *)get_status_cmd.resp_pkt->data; + status = iwl_mvm_send_wowlan_get_status(mvm); + if (IS_ERR_OR_NULL(status)) { + /* set to NULL so we don't need to check before kfree'ing */ + status = NULL; + goto out; + } + wakeup_reasons = le32_to_cpu(status->wakeup_reasons); qos_seq = status->qos_seq_ctr; @@ -1642,8 +1640,7 @@ static void iwl_mvm_d0i3_exit_work(struct work_struct *wk) wakeup_reasons); /* qos_seq might point inside resp_pkt, so free it only now */ - if (get_status_cmd.resp_pkt) - iwl_free_resp(&get_status_cmd); + kfree(status); /* the FW might have updated the regdomain */ iwl_mvm_update_changed_regdom(mvm); From 86e177d80ff7b127138e69e03a3ba7a4c090f57b Mon Sep 17 00:00:00 2001 From: Gregory Greenman Date: Mon, 22 Jan 2018 07:38:12 +0200 Subject: [PATCH 029/276] iwlwifi: mvm: add NOA and CSA to a probe response A probe response built by a P2P GO should contain: 1. CSA/eCSA IE when relevant 2. If the corresponding probe request had P2P IE, then need to add P2P IE with NOA attributes. However, the NOA attributes and the updated channel switch counter are known only to the FW. The solution is that FW will send a notification with the relevant probe response data and the driver will save it and update the probe response accordingly. Signed-off-by: Gregory Greenman Signed-off-by: Luca Coelho --- .../wireless/intel/iwlwifi/fw/api/mac-cfg.h | 49 ++++++++++++++ .../net/wireless/intel/iwlwifi/mvm/mac-ctxt.c | 61 +++++++++++++++++ .../net/wireless/intel/iwlwifi/mvm/mac80211.c | 9 +++ drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 18 +++++ drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 67 +++++++++++++++++++ 5 files changed, 204 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/mac-cfg.h b/drivers/net/wireless/intel/iwlwifi/fw/api/mac-cfg.h index 17c7ef1662a9..ca49db786ed6 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/mac-cfg.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/mac-cfg.h @@ -8,6 +8,7 @@ * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * Copyright(c) 2016 - 2017 Intel Deutschland GmbH + * Copyright(c) 2018 Intel Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -30,6 +31,7 @@ * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * Copyright(c) 2016 - 2017 Intel Deutschland GmbH + * Copyright(c) 2018 Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -71,12 +73,59 @@ enum iwl_mac_conf_subcmd_ids { * @LOW_LATENCY_CMD: &struct iwl_mac_low_latency_cmd */ LOW_LATENCY_CMD = 0x3, + /** + * @PROBE_RESPONSE_DATA_NOTIF: &struct iwl_probe_resp_data_notif + */ + PROBE_RESPONSE_DATA_NOTIF = 0xFC, + /** * @CHANNEL_SWITCH_NOA_NOTIF: &struct iwl_channel_switch_noa_notif */ CHANNEL_SWITCH_NOA_NOTIF = 0xFF, }; +#define IWL_P2P_NOA_DESC_COUNT (2) + +/** + * struct iwl_p2p_noa_attr - NOA attr contained in probe resp FW notification + * + * @id: attribute id + * @len_low: length low half + * @len_high: length high half + * @idx: instance of NoA timing + * @ctwin: GO's ct window and pwer save capability + * @desc: NoA descriptor + * @reserved: reserved for alignment purposes + */ +struct iwl_p2p_noa_attr { + u8 id; + u8 len_low; + u8 len_high; + u8 idx; + u8 ctwin; + struct ieee80211_p2p_noa_desc desc[IWL_P2P_NOA_DESC_COUNT]; + u8 reserved; +} __packed; + +#define IWL_PROBE_RESP_DATA_NO_CSA (0xff) + +/** + * struct iwl_probe_resp_data_notif - notification with NOA and CSA counter + * + * @mac_id: the mac which should send the probe response + * @noa_active: notifies if the noa attribute should be handled + * @noa_attr: P2P NOA attribute + * @csa_counter: current csa counter + * @reserved: reserved for alignment purposes + */ +struct iwl_probe_resp_data_notif { + __le32 mac_id; + __le32 noa_active; + struct iwl_p2p_noa_attr noa_attr; + u8 csa_counter; + u8 reserved[3]; +} __packed; /* PROBE_RESPONSE_DATA_NTFY_API_S_VER_1 */ + /** * struct iwl_channel_switch_noa_notif - Channel switch NOA notification * diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c index b3fd20502abb..6a38a3ee4db0 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c @@ -8,6 +8,7 @@ * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH * Copyright(c) 2015 - 2017 Intel Deutschland GmbH + * Copyright(c) 2018 Intel Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -35,6 +36,7 @@ * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH * Copyright(c) 2015 - 2017 Intel Deutschland GmbH + * Copyright(c) 2018 Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -1568,6 +1570,65 @@ void iwl_mvm_rx_stored_beacon_notif(struct iwl_mvm *mvm, ieee80211_rx_napi(mvm->hw, NULL, skb, NULL); } +static void iwl_mvm_probe_resp_data_iter(void *_data, u8 *mac, + struct ieee80211_vif *vif) +{ + struct iwl_probe_resp_data_notif *notif = _data; + struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); + struct iwl_probe_resp_data *old_data, *new_data; + + if (mvmvif->id != (u16)le32_to_cpu(notif->mac_id)) + return; + + new_data = kzalloc(sizeof(*new_data), GFP_KERNEL); + if (!new_data) + return; + + memcpy(&new_data->notif, notif, sizeof(new_data->notif)); + + /* noa_attr contains 1 reserved byte, need to substruct it */ + new_data->noa_len = sizeof(struct ieee80211_vendor_ie) + + sizeof(new_data->notif.noa_attr) - 1; + + /* + * If it's a one time NoA, only one descriptor is needed, + * adjust the length according to len_low. + */ + if (new_data->notif.noa_attr.len_low == + sizeof(struct ieee80211_p2p_noa_desc) + 2) + new_data->noa_len -= sizeof(struct ieee80211_p2p_noa_desc); + + old_data = rcu_dereference_protected(mvmvif->probe_resp_data, + lockdep_is_held(&mvmvif->mvm->mutex)); + rcu_assign_pointer(mvmvif->probe_resp_data, new_data); + + if (old_data) + kfree_rcu(old_data, rcu_head); + + if (notif->csa_counter != IWL_PROBE_RESP_DATA_NO_CSA && + notif->csa_counter >= 1) + ieee80211_csa_set_counter(vif, notif->csa_counter); +} + +void iwl_mvm_probe_resp_data_notif(struct iwl_mvm *mvm, + struct iwl_rx_cmd_buffer *rxb) +{ + struct iwl_rx_packet *pkt = rxb_addr(rxb); + struct iwl_probe_resp_data_notif *notif = (void *)pkt->data; + int len = iwl_rx_packet_payload_len(pkt); + + if (WARN_ON_ONCE(len < sizeof(*notif))) + return; + + IWL_DEBUG_INFO(mvm, "Probe response data notif: noa %d, csa %d\n", + notif->noa_active, notif->csa_counter); + + ieee80211_iterate_active_interfaces(mvm->hw, + IEEE80211_IFACE_ITER_ACTIVE, + iwl_mvm_probe_resp_data_iter, + notif); +} + void iwl_mvm_channel_switch_noa_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb) { diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index 0426cc614bfe..3a502eada774 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -1035,6 +1035,7 @@ static void iwl_mvm_cleanup_iterator(void *data, u8 *mac, mvmvif->phy_ctxt = NULL; memset(&mvmvif->bf_data, 0, sizeof(mvmvif->bf_data)); + memset(&mvmvif->probe_resp_data, 0, sizeof(mvmvif->probe_resp_data)); } static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm) @@ -1337,6 +1338,7 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw, int ret; mvmvif->mvm = mvm; + RCU_INIT_POINTER(mvmvif->probe_resp_data, NULL); /* * make sure D0i3 exit is completed, otherwise a target access @@ -1501,6 +1503,7 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw, { struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); + struct iwl_probe_resp_data *probe_data; iwl_mvm_prepare_mac_removal(mvm, vif); @@ -1510,6 +1513,12 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw, mutex_lock(&mvm->mutex); + probe_data = rcu_dereference_protected(mvmvif->probe_resp_data, + lockdep_is_held(&mvm->mutex)); + RCU_INIT_POINTER(mvmvif->probe_resp_data, NULL); + if (probe_data) + kfree_rcu(probe_data, rcu_head); + if (mvm->bf_allowed_vif == mvmvif) { mvm->bf_allowed_vif = NULL; vif->driver_flags &= ~(IEEE80211_VIF_BEACON_FILTER | diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index a0d694ea0182..e5a717ade628 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -335,6 +335,18 @@ struct iwl_mvm_vif_bf_data { int last_bt_coex_event; }; +/** + * struct iwl_probe_resp_data - data for NoA/CSA updates + * @rcu_head: used for freeing the data on update + * @notif: notification data + * @noa_len: length of NoA attribute, calculated from the notification + */ +struct iwl_probe_resp_data { + struct rcu_head rcu_head; + struct iwl_probe_resp_data_notif notif; + int noa_len; +}; + /** * struct iwl_mvm_vif - data per Virtual Interface, it is a MAC context * @id: between 0 and 3 @@ -365,6 +377,8 @@ struct iwl_mvm_vif_bf_data { * average signal of beacons retrieved from the firmware * @csa_failed: CSA failed to schedule time event, report an error later * @features: hw features active for this vif + * @probe_resp_data: data from FW notification to store NOA and CSA related + * data to be inserted into probe response. */ struct iwl_mvm_vif { struct iwl_mvm *mvm; @@ -460,6 +474,8 @@ struct iwl_mvm_vif { /* TCP Checksum Offload */ netdev_features_t features; + + struct iwl_probe_resp_data __rcu *probe_resp_data; }; static inline struct iwl_mvm_vif * @@ -1602,6 +1618,8 @@ void iwl_mvm_mac_ctxt_recalc_tsf_id(struct iwl_mvm *mvm, struct ieee80211_vif *vif); unsigned long iwl_mvm_get_used_hw_queues(struct iwl_mvm *mvm, struct ieee80211_vif *exclude_vif); +void iwl_mvm_probe_resp_data_notif(struct iwl_mvm *mvm, + struct iwl_rx_cmd_buffer *rxb); void iwl_mvm_channel_switch_noa_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb); /* Bindings */ diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c index 83f3e74337db..796f010204d5 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c @@ -626,6 +626,66 @@ static int iwl_mvm_get_ctrl_vif_queue(struct iwl_mvm *mvm, } } +static void iwl_mvm_probe_resp_set_noa(struct iwl_mvm *mvm, + struct sk_buff *skb) +{ + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct iwl_mvm_vif *mvmvif = + iwl_mvm_vif_from_mac80211(info->control.vif); + struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; + int base_len = (u8 *)mgmt->u.probe_resp.variable - (u8 *)mgmt; + struct iwl_probe_resp_data *resp_data; + u8 *ie, *pos; + u8 match[] = { + (WLAN_OUI_WFA >> 16) & 0xff, + (WLAN_OUI_WFA >> 8) & 0xff, + WLAN_OUI_WFA & 0xff, + WLAN_OUI_TYPE_WFA_P2P, + }; + + rcu_read_lock(); + + resp_data = rcu_dereference(mvmvif->probe_resp_data); + if (!resp_data) + goto out; + + if (!resp_data->notif.noa_active) + goto out; + + ie = (u8 *)cfg80211_find_ie_match(WLAN_EID_VENDOR_SPECIFIC, + mgmt->u.probe_resp.variable, + skb->len - base_len, + match, 4, 2); + if (!ie) { + IWL_DEBUG_TX(mvm, "probe resp doesn't have P2P IE\n"); + goto out; + } + + if (skb_tailroom(skb) < resp_data->noa_len) { + if (pskb_expand_head(skb, 0, resp_data->noa_len, GFP_ATOMIC)) { + IWL_ERR(mvm, + "Failed to reallocate probe resp\n"); + goto out; + } + } + + pos = skb_put(skb, resp_data->noa_len); + + *pos++ = WLAN_EID_VENDOR_SPECIFIC; + /* Set length of IE body (not including ID and length itself) */ + *pos++ = resp_data->noa_len - 2; + *pos++ = (WLAN_OUI_WFA >> 16) & 0xff; + *pos++ = (WLAN_OUI_WFA >> 8) & 0xff; + *pos++ = WLAN_OUI_WFA & 0xff; + *pos++ = WLAN_OUI_TYPE_WFA_P2P; + + memcpy(pos, &resp_data->notif.noa_attr, + resp_data->noa_len - sizeof(struct ieee80211_vendor_ie)); + +out: + rcu_read_unlock(); +} + int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct sk_buff *skb) { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; @@ -634,6 +694,7 @@ int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct sk_buff *skb) struct iwl_device_cmd *dev_cmd; u8 sta_id; int hdrlen = ieee80211_hdrlen(hdr->frame_control); + __le16 fc = hdr->frame_control; int queue; /* IWL_MVM_OFFCHANNEL_QUEUE is used for ROC packets that can be used @@ -695,6 +756,9 @@ int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct sk_buff *skb) } } + if (unlikely(ieee80211_is_probe_resp(fc))) + iwl_mvm_probe_resp_set_noa(mvm, skb); + IWL_DEBUG_TX(mvm, "station Id %d, queue=%d\n", sta_id, queue); dev_cmd = iwl_mvm_set_tx_params(mvm, skb, &info, hdrlen, NULL, sta_id); @@ -1016,6 +1080,9 @@ static int iwl_mvm_tx_mpdu(struct iwl_mvm *mvm, struct sk_buff *skb, if (WARN_ON_ONCE(mvmsta->sta_id == IWL_MVM_INVALID_STA)) return -1; + if (unlikely(ieee80211_is_probe_resp(fc))) + iwl_mvm_probe_resp_set_noa(mvm, skb); + dev_cmd = iwl_mvm_set_tx_params(mvm, skb, info, hdrlen, sta, mvmsta->sta_id); if (!dev_cmd) From 7d2bcc22cd16dd3997df2c8417a2cd31b79c3bae Mon Sep 17 00:00:00 2001 From: Golan Ben Ami Date: Tue, 3 Apr 2018 16:39:18 +0300 Subject: [PATCH 030/276] iwlwifi: add required include to iwl-fh.h Some variables are used in iwl-fh.h, but their type's definition isn't included. This may break compilation when using the file without including the necessary dependencies first. Add the required include to iwl-fh.h. Signed-off-by: Golan Ben Ami Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/iwl-fh.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-fh.h b/drivers/net/wireless/intel/iwlwifi/iwl-fh.h index df0e9ffff706..4f7254303853 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-fh.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-fh.h @@ -68,6 +68,8 @@ #include #include +#include "iwl-trans.h" + /****************************/ /* Flow Handler Definitions */ /****************************/ From bd6fc6552b053fcb7bef8c1665adb8011d2b7eaa Mon Sep 17 00:00:00 2001 From: Liad Kaufman Date: Sun, 4 Mar 2018 14:21:49 +0200 Subject: [PATCH 031/276] iwlwifi: mvm: add bss color to radiotap Add BSS color to the HE radiotap. Signed-off-by: Liad Kaufman Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c index b53148f972a4..4af3ab2ee1a8 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c @@ -1042,6 +1042,20 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, he_phy_data), IEEE80211_RADIOTAP_HE_MU_FLAGS2_PUNC_FROM_SIG_A_BW); } + + if (he_phy_data != HE_PHY_DATA_INVAL && + (he_type == RATE_MCS_HE_TYPE_SU || + he_type == RATE_MCS_HE_TYPE_MU)) { + u8 bss_color = FIELD_GET(IWL_RX_HE_PHY_BSS_COLOR_MASK, + he_phy_data); + + if (bss_color) { + he->data1 |= + cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_BSS_COLOR_KNOWN); + he->data3 |= cpu_to_le16(bss_color); + } + } + rx_status->device_timestamp = gp2_on_air_rise; rx_status->band = channel > 14 ? NL80211_BAND_5GHZ : NL80211_BAND_2GHZ; From 621f3f57050a71b05411f3665ef6b105a25af672 Mon Sep 17 00:00:00 2001 From: Liad Kaufman Date: Sun, 1 Apr 2018 17:35:43 +0300 Subject: [PATCH 032/276] iwlwifi: mvm: add support for RX_AMPDU_EOF bit for HE SU Current implementation turns this bit on only for HE MU. Signed-off-by: Liad Kaufman Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c index 4af3ab2ee1a8..311c639e23de 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c @@ -1082,7 +1082,8 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, mvm->ampdu_toggle = toggle_bit; if (he_phy_data != HE_PHY_DATA_INVAL && - he_type == RATE_MCS_HE_TYPE_MU) { + (he_type == RATE_MCS_HE_TYPE_MU || + he_type == RATE_MCS_HE_TYPE_SU)) { rx_status->flag |= RX_FLAG_AMPDU_EOF_BIT_KNOWN; if (FIELD_GET(IWL_RX_HE_PHY_DELIM_EOF, he_phy_data)) From c630b477caf78998cdcd5766956817d8721c23c9 Mon Sep 17 00:00:00 2001 From: Sara Sharon Date: Mon, 9 Apr 2018 11:20:09 +0300 Subject: [PATCH 033/276] iwlwifi: mvm: move he RX handling to a separate function The HE code is bloating the RX handling, and makes it too big. Signed-off-by: Sara Sharon Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 582 +++++++++--------- 1 file changed, 286 insertions(+), 296 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c index 311c639e23de..968f1c372f1c 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c @@ -856,6 +856,289 @@ static void iwl_mvm_flip_address(u8 *addr) ether_addr_copy(addr, mac_addr); } +static void iwl_mvm_rx_he(struct iwl_mvm *mvm, struct sk_buff *skb, + struct iwl_rx_mpdu_desc *desc, + u32 rate_n_flags, u16 phy_info, int queue) +{ + struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb); + /* this is invalid e.g. because puncture type doesn't allow 0b11 */ +#define HE_PHY_DATA_INVAL ((u64)-1) + u64 he_phy_data = HE_PHY_DATA_INVAL; + struct ieee80211_radiotap_he *he = NULL; + struct ieee80211_radiotap_he_mu *he_mu = NULL; + u32 he_type = 0xffffffff; + u8 stbc; + + static const struct ieee80211_radiotap_he known = { + .data1 = cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_DATA_MCS_KNOWN | + IEEE80211_RADIOTAP_HE_DATA1_DATA_DCM_KNOWN | + IEEE80211_RADIOTAP_HE_DATA1_STBC_KNOWN | + IEEE80211_RADIOTAP_HE_DATA1_CODING_KNOWN), + .data2 = cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_GI_KNOWN | + IEEE80211_RADIOTAP_HE_DATA2_TXBF_KNOWN), + }; + static const struct ieee80211_radiotap_he_mu mu_known = { + .flags1 = cpu_to_le16(IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_MCS_KNOWN | + IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_DCM_KNOWN | + IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_SYMS_USERS_KNOWN | + IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_COMP_KNOWN), + .flags2 = cpu_to_le16(IEEE80211_RADIOTAP_HE_MU_FLAGS2_PUNC_FROM_SIG_A_BW_KNOWN), + }; + unsigned int radiotap_len = 0; + bool overload = phy_info & IWL_RX_MPDU_PHY_TSF_OVERLOAD; + + he = skb_put_data(skb, &known, sizeof(known)); + radiotap_len += sizeof(known); + rx_status->flag |= RX_FLAG_RADIOTAP_HE; + + he_type = rate_n_flags & RATE_MCS_HE_TYPE_MSK; + + if (phy_info & IWL_RX_MPDU_PHY_TSF_OVERLOAD) { + if (mvm->trans->cfg->device_family >= + IWL_DEVICE_FAMILY_22560) + he_phy_data = le64_to_cpu(desc->v3.he_phy_data); + else + he_phy_data = le64_to_cpu(desc->v1.he_phy_data); + + if (he_type == RATE_MCS_HE_TYPE_MU) { + he_mu = skb_put_data(skb, &mu_known, + sizeof(mu_known)); + radiotap_len += sizeof(mu_known); + rx_status->flag |= RX_FLAG_RADIOTAP_HE_MU; + } + } + + /* temporarily hide the radiotap data */ + __skb_pull(skb, radiotap_len); + + if (overload && he_type == RATE_MCS_HE_TYPE_SU) { + he->data1 |= + cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_UL_DL_KNOWN); + if (FIELD_GET(IWL_RX_HE_PHY_UPLINK, he_phy_data)) + he->data3 |= + cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA3_UL_DL); + + if (!queue && !(phy_info & IWL_RX_MPDU_PHY_AMPDU)) { + rx_status->flag |= RX_FLAG_AMPDU_DETAILS; + rx_status->flag |= RX_FLAG_AMPDU_EOF_BIT_KNOWN; + if (FIELD_GET(IWL_RX_HE_PHY_DELIM_EOF, he_phy_data)) + rx_status->flag |= RX_FLAG_AMPDU_EOF_BIT; + } + } else if (overload && he_mu && he_phy_data != HE_PHY_DATA_INVAL) { + he_mu->flags1 |= + le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_SIBG_SYM_OR_USER_NUM_MASK, + he_phy_data), + IEEE80211_RADIOTAP_HE_MU_FLAGS2_SIG_B_SYMS_USERS); + he_mu->flags1 |= + le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_SIGB_DCM, + he_phy_data), + IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_DCM); + he_mu->flags1 |= + le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_SIGB_MCS_MASK, + he_phy_data), + IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_MCS); + he_mu->flags2 |= + le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_SIGB_COMPRESSION, + he_phy_data), + IEEE80211_RADIOTAP_HE_MU_FLAGS2_SIG_B_COMP); + he_mu->flags2 |= + le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_PREAMBLE_PUNC_TYPE_MASK, + he_phy_data), + IEEE80211_RADIOTAP_HE_MU_FLAGS2_PUNC_FROM_SIG_A_BW); + } + + if (he_phy_data != HE_PHY_DATA_INVAL) { + he->data1 |= + cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_BSS_COLOR_KNOWN); + he->data3 |= + le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_BSS_COLOR_MASK, + he_phy_data), + IEEE80211_RADIOTAP_HE_DATA3_BSS_COLOR); + } + + /* update aggregation data for monitor sake on default queue */ + if (!queue && (phy_info & IWL_RX_MPDU_PHY_AMPDU)) { + bool toggle_bit = phy_info & IWL_RX_MPDU_PHY_AMPDU_TOGGLE; + + /* toggle is switched whenever new aggregation starts */ + if (toggle_bit != mvm->ampdu_toggle && + he_phy_data != HE_PHY_DATA_INVAL && + (he_type == RATE_MCS_HE_TYPE_MU || + he_type == RATE_MCS_HE_TYPE_SU)) { + rx_status->flag |= RX_FLAG_AMPDU_EOF_BIT_KNOWN; + if (FIELD_GET(IWL_RX_HE_PHY_DELIM_EOF, + he_phy_data)) + rx_status->flag |= RX_FLAG_AMPDU_EOF_BIT; + } + } + + if (he_type == RATE_MCS_HE_TYPE_EXT_SU && + rate_n_flags & RATE_MCS_HE_106T_MSK) { + rx_status->bw = RATE_INFO_BW_HE_RU; + rx_status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_106; + } + if (he_mu) { + /* + * Unfortunately, we have to leave the mac80211 data + * incorrect for the case that we receive an HE-MU + * transmission and *don't* have the he_mu pointer, + * i.e. we don't have the phy data (due to the bits + * being used for TSF). This shouldn't happen though + * as management frames where we need the TSF/timers + * are not be transmitted in HE-MU, I think. + */ + u8 ru = FIELD_GET(IWL_RX_HE_PHY_RU_ALLOC_MASK, he_phy_data); + u8 offs = 0; + + rx_status->bw = RATE_INFO_BW_HE_RU; + + switch (ru) { + case 0 ... 36: + rx_status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_26; + offs = ru; + break; + case 37 ... 52: + rx_status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_52; + offs = ru - 37; + break; + case 53 ... 60: + rx_status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_106; + offs = ru - 53; + break; + case 61 ... 64: + rx_status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_242; + offs = ru - 61; + break; + case 65 ... 66: + rx_status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_484; + offs = ru - 65; + break; + case 67: + rx_status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_996; + break; + case 68: + rx_status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_2x996; + break; + } + he->data2 |= + le16_encode_bits(offs, + IEEE80211_RADIOTAP_HE_DATA2_RU_OFFSET); + he->data2 |= + cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_PRISEC_80_KNOWN); + if (he_phy_data & IWL_RX_HE_PHY_RU_ALLOC_SEC80) + he->data2 |= + cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_PRISEC_80_SEC); + } else if (he) { + he->data1 |= + cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_BW_RU_ALLOC_KNOWN); + } + + stbc = (rate_n_flags & RATE_MCS_STBC_MSK) >> RATE_MCS_STBC_POS; + rx_status->nss = + ((rate_n_flags & RATE_VHT_MCS_NSS_MSK) >> + RATE_VHT_MCS_NSS_POS) + 1; + rx_status->rate_idx = rate_n_flags & RATE_VHT_MCS_RATE_CODE_MSK; + rx_status->encoding = RX_ENC_HE; + rx_status->enc_flags |= stbc << RX_ENC_FLAG_STBC_SHIFT; + if (rate_n_flags & RATE_MCS_BF_MSK) + rx_status->enc_flags |= RX_ENC_FLAG_BF; + + rx_status->he_dcm = + !!(rate_n_flags & RATE_HE_DUAL_CARRIER_MODE_MSK); + +#define CHECK_TYPE(F) \ + BUILD_BUG_ON(IEEE80211_RADIOTAP_HE_DATA1_FORMAT_ ## F != \ + (RATE_MCS_HE_TYPE_ ## F >> RATE_MCS_HE_TYPE_POS)) + + CHECK_TYPE(SU); + CHECK_TYPE(EXT_SU); + CHECK_TYPE(MU); + CHECK_TYPE(TRIG); + + he->data1 |= cpu_to_le16(he_type >> RATE_MCS_HE_TYPE_POS); + + if (rate_n_flags & RATE_MCS_BF_POS) + he->data5 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA5_TXBF); + + switch ((rate_n_flags & RATE_MCS_HE_GI_LTF_MSK) >> + RATE_MCS_HE_GI_LTF_POS) { + case 0: + rx_status->he_gi = NL80211_RATE_INFO_HE_GI_0_8; + break; + case 1: + rx_status->he_gi = NL80211_RATE_INFO_HE_GI_0_8; + break; + case 2: + rx_status->he_gi = NL80211_RATE_INFO_HE_GI_1_6; + break; + case 3: + if (rate_n_flags & RATE_MCS_SGI_MSK) + rx_status->he_gi = NL80211_RATE_INFO_HE_GI_0_8; + else + rx_status->he_gi = NL80211_RATE_INFO_HE_GI_3_2; + break; + } + + switch (he_type) { + case RATE_MCS_HE_TYPE_SU: { + u16 val; + + /* LTF syms correspond to streams */ + he->data2 |= + cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_NUM_LTF_SYMS_KNOWN); + switch (rx_status->nss) { + case 1: + val = 0; + break; + case 2: + val = 1; + break; + case 3: + case 4: + val = 2; + break; + case 5: + case 6: + val = 3; + break; + case 7: + case 8: + val = 4; + break; + default: + WARN_ONCE(1, "invalid nss: %d\n", + rx_status->nss); + val = 0; + } + he->data5 |= + le16_encode_bits(val, + IEEE80211_RADIOTAP_HE_DATA5_NUM_LTF_SYMS); + } + break; + case RATE_MCS_HE_TYPE_MU: { + u16 val; + + if (he_phy_data == HE_PHY_DATA_INVAL) + break; + + val = FIELD_GET(IWL_RX_HE_PHY_HE_LTF_NUM_MASK, + he_phy_data); + + he->data2 |= + cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_NUM_LTF_SYMS_KNOWN); + he->data5 |= + cpu_to_le16(FIELD_PREP( + IEEE80211_RADIOTAP_HE_DATA5_NUM_LTF_SYMS, + val)); + } + break; + case RATE_MCS_HE_TYPE_EXT_SU: + case RATE_MCS_HE_TYPE_TRIG: + /* not supported */ + break; + } +} + void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, struct iwl_rx_cmd_buffer *rxb, int queue) { @@ -869,12 +1152,6 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, struct ieee80211_sta *sta = NULL; struct sk_buff *skb; u8 crypt_len = 0, channel, energy_a, energy_b; - struct ieee80211_radiotap_he *he = NULL; - struct ieee80211_radiotap_he_mu *he_mu = NULL; - u32 he_type = 0xffffffff; - /* this is invalid e.g. because puncture type doesn't allow 0b11 */ -#define HE_PHY_DATA_INVAL ((u64)-1) - u64 he_phy_data = HE_PHY_DATA_INVAL; size_t desc_size; if (unlikely(test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status))) @@ -918,48 +1195,8 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, rx_status = IEEE80211_SKB_RXCB(skb); - if (rate_n_flags & RATE_MCS_HE_MSK) { - static const struct ieee80211_radiotap_he known = { - .data1 = cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_DATA_MCS_KNOWN | - IEEE80211_RADIOTAP_HE_DATA1_DATA_DCM_KNOWN | - IEEE80211_RADIOTAP_HE_DATA1_STBC_KNOWN | - IEEE80211_RADIOTAP_HE_DATA1_CODING_KNOWN), - .data2 = cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_GI_KNOWN | - IEEE80211_RADIOTAP_HE_DATA2_TXBF_KNOWN), - }; - static const struct ieee80211_radiotap_he_mu mu_known = { - .flags1 = cpu_to_le16(IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_MCS_KNOWN | - IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_DCM_KNOWN | - IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_SYMS_USERS_KNOWN | - IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_COMP_KNOWN), - .flags2 = cpu_to_le16(IEEE80211_RADIOTAP_HE_MU_FLAGS2_PUNC_FROM_SIG_A_BW_KNOWN), - }; - unsigned int radiotap_len = 0; - - he = skb_put_data(skb, &known, sizeof(known)); - radiotap_len += sizeof(known); - rx_status->flag |= RX_FLAG_RADIOTAP_HE; - - he_type = rate_n_flags & RATE_MCS_HE_TYPE_MSK; - - if (phy_info & IWL_RX_MPDU_PHY_TSF_OVERLOAD) { - if (mvm->trans->cfg->device_family >= - IWL_DEVICE_FAMILY_22560) - he_phy_data = le64_to_cpu(desc->v3.he_phy_data); - else - he_phy_data = le64_to_cpu(desc->v1.he_phy_data); - - if (he_type == RATE_MCS_HE_TYPE_MU) { - he_mu = skb_put_data(skb, &mu_known, - sizeof(mu_known)); - radiotap_len += sizeof(mu_known); - rx_status->flag |= RX_FLAG_RADIOTAP_HE_MU; - } - } - - /* temporarily hide the radiotap data */ - __skb_pull(skb, radiotap_len); - } + if (rate_n_flags & RATE_MCS_HE_MSK) + iwl_mvm_rx_he(mvm, skb, desc, rate_n_flags, phy_info, queue); rx_status = IEEE80211_SKB_RXCB(skb); @@ -995,65 +1232,6 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, rx_status->mactime = tsf_on_air_rise; /* TSF as indicated by the firmware is at INA time */ rx_status->flag |= RX_FLAG_MACTIME_PLCP_START; - } else if (he_type == RATE_MCS_HE_TYPE_SU) { - u64 he_phy_data; - - if (mvm->trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) - he_phy_data = le64_to_cpu(desc->v3.he_phy_data); - else - he_phy_data = le64_to_cpu(desc->v1.he_phy_data); - - he->data1 |= - cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_UL_DL_KNOWN); - if (FIELD_GET(IWL_RX_HE_PHY_UPLINK, - he_phy_data)) - he->data3 |= - cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA3_UL_DL); - - if (!queue && !(phy_info & IWL_RX_MPDU_PHY_AMPDU)) { - rx_status->ampdu_reference = mvm->ampdu_ref; - mvm->ampdu_ref++; - - rx_status->flag |= RX_FLAG_AMPDU_DETAILS; - rx_status->flag |= RX_FLAG_AMPDU_EOF_BIT_KNOWN; - if (FIELD_GET(IWL_RX_HE_PHY_DELIM_EOF, - he_phy_data)) - rx_status->flag |= RX_FLAG_AMPDU_EOF_BIT; - } - } else if (he_mu && he_phy_data != HE_PHY_DATA_INVAL) { - he_mu->flags1 |= - le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_SIBG_SYM_OR_USER_NUM_MASK, - he_phy_data), - IEEE80211_RADIOTAP_HE_MU_FLAGS2_SIG_B_SYMS_USERS); - he_mu->flags1 |= - le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_SIGB_DCM, - he_phy_data), - IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_DCM); - he_mu->flags1 |= - le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_SIGB_MCS_MASK, - he_phy_data), - IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_MCS); - he_mu->flags2 |= - le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_SIGB_COMPRESSION, - he_phy_data), - IEEE80211_RADIOTAP_HE_MU_FLAGS2_SIG_B_COMP); - he_mu->flags2 |= - le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_PREAMBLE_PUNC_TYPE_MASK, - he_phy_data), - IEEE80211_RADIOTAP_HE_MU_FLAGS2_PUNC_FROM_SIG_A_BW); - } - - if (he_phy_data != HE_PHY_DATA_INVAL && - (he_type == RATE_MCS_HE_TYPE_SU || - he_type == RATE_MCS_HE_TYPE_MU)) { - u8 bss_color = FIELD_GET(IWL_RX_HE_PHY_BSS_COLOR_MASK, - he_phy_data); - - if (bss_color) { - he->data1 |= - cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_BSS_COLOR_KNOWN); - he->data3 |= cpu_to_le16(bss_color); - } } rx_status->device_timestamp = gp2_on_air_rise; @@ -1080,16 +1258,6 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, if (toggle_bit != mvm->ampdu_toggle) { mvm->ampdu_ref++; mvm->ampdu_toggle = toggle_bit; - - if (he_phy_data != HE_PHY_DATA_INVAL && - (he_type == RATE_MCS_HE_TYPE_MU || - he_type == RATE_MCS_HE_TYPE_SU)) { - rx_status->flag |= RX_FLAG_AMPDU_EOF_BIT_KNOWN; - if (FIELD_GET(IWL_RX_HE_PHY_DELIM_EOF, - he_phy_data)) - rx_status->flag |= - RX_FLAG_AMPDU_EOF_BIT; - } } } @@ -1212,70 +1380,6 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, break; } - if (he_type == RATE_MCS_HE_TYPE_EXT_SU && - rate_n_flags & RATE_MCS_HE_106T_MSK) { - rx_status->bw = RATE_INFO_BW_HE_RU; - rx_status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_106; - } - - if (rate_n_flags & RATE_MCS_HE_MSK && - phy_info & IWL_RX_MPDU_PHY_TSF_OVERLOAD && - he_type == RATE_MCS_HE_TYPE_MU) { - /* - * Unfortunately, we have to leave the mac80211 data - * incorrect for the case that we receive an HE-MU - * transmission and *don't* have the he_mu pointer, - * i.e. we don't have the phy data (due to the bits - * being used for TSF). This shouldn't happen though - * as management frames where we need the TSF/timers - * are not be transmitted in HE-MU, I think. - */ - u8 ru = FIELD_GET(IWL_RX_HE_PHY_RU_ALLOC_MASK, he_phy_data); - u8 offs = 0; - - rx_status->bw = RATE_INFO_BW_HE_RU; - - switch (ru) { - case 0 ... 36: - rx_status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_26; - offs = ru; - break; - case 37 ... 52: - rx_status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_52; - offs = ru - 37; - break; - case 53 ... 60: - rx_status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_106; - offs = ru - 53; - break; - case 61 ... 64: - rx_status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_242; - offs = ru - 61; - break; - case 65 ... 66: - rx_status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_484; - offs = ru - 65; - break; - case 67: - rx_status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_996; - break; - case 68: - rx_status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_2x996; - break; - } - he->data2 |= - le16_encode_bits(offs, - IEEE80211_RADIOTAP_HE_DATA2_RU_OFFSET); - he->data2 |= - cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_PRISEC_80_KNOWN); - if (he_phy_data & IWL_RX_HE_PHY_RU_ALLOC_SEC80) - he->data2 |= - cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_PRISEC_80_SEC); - } else if (he) { - he->data1 |= - cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_BW_RU_ALLOC_KNOWN); - } - if (!(rate_n_flags & RATE_MCS_CCK_MSK) && rate_n_flags & RATE_MCS_SGI_MSK) rx_status->enc_flags |= RX_ENC_FLAG_SHORT_GI; @@ -1300,120 +1404,7 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, rx_status->enc_flags |= stbc << RX_ENC_FLAG_STBC_SHIFT; if (rate_n_flags & RATE_MCS_BF_MSK) rx_status->enc_flags |= RX_ENC_FLAG_BF; - } else if (he) { - u8 stbc = (rate_n_flags & RATE_MCS_STBC_MSK) >> - RATE_MCS_STBC_POS; - rx_status->nss = - ((rate_n_flags & RATE_VHT_MCS_NSS_MSK) >> - RATE_VHT_MCS_NSS_POS) + 1; - rx_status->rate_idx = rate_n_flags & RATE_VHT_MCS_RATE_CODE_MSK; - rx_status->encoding = RX_ENC_HE; - rx_status->enc_flags |= stbc << RX_ENC_FLAG_STBC_SHIFT; - if (rate_n_flags & RATE_MCS_BF_MSK) - rx_status->enc_flags |= RX_ENC_FLAG_BF; - - rx_status->he_dcm = - !!(rate_n_flags & RATE_HE_DUAL_CARRIER_MODE_MSK); - -#define CHECK_TYPE(F) \ - BUILD_BUG_ON(IEEE80211_RADIOTAP_HE_DATA1_FORMAT_ ## F != \ - (RATE_MCS_HE_TYPE_ ## F >> RATE_MCS_HE_TYPE_POS)) - - CHECK_TYPE(SU); - CHECK_TYPE(EXT_SU); - CHECK_TYPE(MU); - CHECK_TYPE(TRIG); - - he->data1 |= cpu_to_le16(he_type >> RATE_MCS_HE_TYPE_POS); - - if (rate_n_flags & RATE_MCS_BF_POS) - he->data5 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA5_TXBF); - - switch ((rate_n_flags & RATE_MCS_HE_GI_LTF_MSK) >> - RATE_MCS_HE_GI_LTF_POS) { - case 0: - rx_status->he_gi = NL80211_RATE_INFO_HE_GI_0_8; - break; - case 1: - rx_status->he_gi = NL80211_RATE_INFO_HE_GI_0_8; - break; - case 2: - rx_status->he_gi = NL80211_RATE_INFO_HE_GI_1_6; - break; - case 3: - if (rate_n_flags & RATE_MCS_SGI_MSK) - rx_status->he_gi = NL80211_RATE_INFO_HE_GI_0_8; - else - rx_status->he_gi = NL80211_RATE_INFO_HE_GI_3_2; - break; - } - - switch (he_type) { - case RATE_MCS_HE_TYPE_SU: { - u16 val; - - /* LTF syms correspond to streams */ - he->data2 |= - cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_NUM_LTF_SYMS_KNOWN); - switch (rx_status->nss) { - case 1: - val = 0; - break; - case 2: - val = 1; - break; - case 3: - case 4: - val = 2; - break; - case 5: - case 6: - val = 3; - break; - case 7: - case 8: - val = 4; - break; - default: - WARN_ONCE(1, "invalid nss: %d\n", - rx_status->nss); - val = 0; - } - he->data5 |= - le16_encode_bits(val, - IEEE80211_RADIOTAP_HE_DATA5_NUM_LTF_SYMS); - } - break; - case RATE_MCS_HE_TYPE_MU: { - u16 val; - u64 he_phy_data; - - if (mvm->trans->cfg->device_family >= - IWL_DEVICE_FAMILY_22560) - he_phy_data = le64_to_cpu(desc->v3.he_phy_data); - else - he_phy_data = le64_to_cpu(desc->v1.he_phy_data); - - if (he_phy_data == HE_PHY_DATA_INVAL) - break; - - val = FIELD_GET(IWL_RX_HE_PHY_HE_LTF_NUM_MASK, - he_phy_data); - - he->data2 |= - cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_NUM_LTF_SYMS_KNOWN); - he->data5 |= - cpu_to_le16(FIELD_PREP( - IEEE80211_RADIOTAP_HE_DATA5_NUM_LTF_SYMS, - val)); - } - break; - case RATE_MCS_HE_TYPE_EXT_SU: - case RATE_MCS_HE_TYPE_TRIG: - /* not supported yet */ - break; - } - } else { + } else if (!(rate_n_flags & RATE_MCS_HE_MSK)) { int rate = iwl_mvm_legacy_rate_to_mac80211_idx(rate_n_flags, rx_status->band); @@ -1424,7 +1415,6 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, goto out; } rx_status->rate_idx = rate; - } /* management stuff on default queue */ From 4799ea53a57854b0b35f73703d9bfabf15bfd4f7 Mon Sep 17 00:00:00 2001 From: Sara Sharon Date: Mon, 9 Apr 2018 11:20:09 +0300 Subject: [PATCH 034/276] iwlwifi: mvm: move he RX handling to a separate function The HE code is bloating the RX handling, and makes it too big. Signed-off-by: Sara Sharon Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c index 968f1c372f1c..a5e3a47f4a98 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c @@ -1028,7 +1028,7 @@ static void iwl_mvm_rx_he(struct iwl_mvm *mvm, struct sk_buff *skb, if (he_phy_data & IWL_RX_HE_PHY_RU_ALLOC_SEC80) he->data2 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_PRISEC_80_SEC); - } else if (he) { + } else { he->data1 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_BW_RU_ALLOC_KNOWN); } From 75e9947ea42de92ab330a9761bc6f5862720260d Mon Sep 17 00:00:00 2001 From: Mordechay Goodstein Date: Mon, 9 Apr 2018 15:52:16 +0300 Subject: [PATCH 035/276] iwlwifi: enable reading the value of delay in timestamp_marker cmd The user can validate what was written to the file by reading it, and check what is the default value before changing it. Signed-off-by: Mordechay Goodstein Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/debugfs.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c b/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c index 2dd534b474b8..c1f087c50cc9 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c @@ -251,7 +251,15 @@ static ssize_t iwl_dbgfs_timestamp_marker_write(struct iwl_fw_runtime *fwrt, return count; } -FWRT_DEBUGFS_WRITE_FILE_OPS(timestamp_marker, 10); +static ssize_t iwl_dbgfs_timestamp_marker_read(struct iwl_fw_runtime *fwrt, + size_t size, char *buf) +{ + u32 delay_secs = jiffies_to_msecs(fwrt->timestamp.delay) / 1000; + + return scnprintf(buf, size, "%d\n", delay_secs); +} + +FWRT_DEBUGFS_READ_WRITE_FILE_OPS(timestamp_marker, 16); int iwl_fwrt_dbgfs_register(struct iwl_fw_runtime *fwrt, struct dentry *dbgfs_dir) From 7891965d74bc48fb42b5068033192f97c9aa2090 Mon Sep 17 00:00:00 2001 From: Sara Sharon Date: Mon, 9 Apr 2018 14:00:27 +0300 Subject: [PATCH 036/276] iwlwifi: drop packets with bad status in CD We need to drop packets with errors (such as replay, MIC, ICV, conversion, duplicate and so on). Drop invalid packets, put the status bits in the metadata and move the enum definition to the correct place (FW API header). Signed-off-by: Sara Sharon Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/fw/api/rx.h | 63 +++++++++++++++++++ .../net/wireless/intel/iwlwifi/iwl-trans.h | 1 + .../wireless/intel/iwlwifi/pcie/internal.h | 60 ------------------ drivers/net/wireless/intel/iwlwifi/pcie/rx.c | 8 ++- 4 files changed, 70 insertions(+), 62 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h b/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h index 2f599353c885..2ba1401e5c0d 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h @@ -574,6 +574,69 @@ struct iwl_rx_mpdu_desc { #define IWL_RX_DESC_SIZE_V1 offsetofend(struct iwl_rx_mpdu_desc, v1) +#define IWL_CD_STTS_OPTIMIZED_POS 0 +#define IWL_CD_STTS_OPTIMIZED_MSK 0x01 +#define IWL_CD_STTS_TRANSFER_STATUS_POS 1 +#define IWL_CD_STTS_TRANSFER_STATUS_MSK 0x0E +#define IWL_CD_STTS_WIFI_STATUS_POS 4 +#define IWL_CD_STTS_WIFI_STATUS_MSK 0xF0 + +/** + * enum iwl_completion_desc_transfer_status - transfer status (bits 1-3) + * @IWL_CD_STTS_UNUSED: unused + * @IWL_CD_STTS_UNUSED_2: unused + * @IWL_CD_STTS_END_TRANSFER: successful transfer complete. + * In sniffer mode, when split is used, set in last CD completion. (RX) + * @IWL_CD_STTS_OVERFLOW: In sniffer mode, when using split - used for + * all CD completion. (RX) + * @IWL_CD_STTS_ABORTED: CR abort / close flow. (RX) + * @IWL_CD_STTS_ERROR: general error (RX) + */ +enum iwl_completion_desc_transfer_status { + IWL_CD_STTS_UNUSED, + IWL_CD_STTS_UNUSED_2, + IWL_CD_STTS_END_TRANSFER, + IWL_CD_STTS_OVERFLOW, + IWL_CD_STTS_ABORTED, + IWL_CD_STTS_ERROR, +}; + +/** + * enum iwl_completion_desc_wifi_status - wifi status (bits 4-7) + * @IWL_CD_STTS_VALID: the packet is valid (RX) + * @IWL_CD_STTS_FCS_ERR: frame check sequence error (RX) + * @IWL_CD_STTS_SEC_KEY_ERR: error handling the security key of rx (RX) + * @IWL_CD_STTS_DECRYPTION_ERR: error decrypting the frame (RX) + * @IWL_CD_STTS_DUP: duplicate packet (RX) + * @IWL_CD_STTS_ICV_MIC_ERR: MIC error (RX) + * @IWL_CD_STTS_INTERNAL_SNAP_ERR: problems removing the snap (RX) + * @IWL_CD_STTS_SEC_PORT_FAIL: security port fail (RX) + * @IWL_CD_STTS_BA_OLD_SN: block ack received old SN (RX) + * @IWL_CD_STTS_QOS_NULL: QoS null packet (RX) + * @IWL_CD_STTS_MAC_HDR_ERR: MAC header conversion error (RX) + * @IWL_CD_STTS_MAX_RETRANS: reached max number of retransmissions (TX) + * @IWL_CD_STTS_EX_LIFETIME: exceeded lifetime (TX) + * @IWL_CD_STTS_NOT_USED: completed but not used (RX) + * @IWL_CD_STTS_REPLAY_ERR: pn check failed, replay error (RX) + */ +enum iwl_completion_desc_wifi_status { + IWL_CD_STTS_VALID, + IWL_CD_STTS_FCS_ERR, + IWL_CD_STTS_SEC_KEY_ERR, + IWL_CD_STTS_DECRYPTION_ERR, + IWL_CD_STTS_DUP, + IWL_CD_STTS_ICV_MIC_ERR, + IWL_CD_STTS_INTERNAL_SNAP_ERR, + IWL_CD_STTS_SEC_PORT_FAIL, + IWL_CD_STTS_BA_OLD_SN, + IWL_CD_STTS_QOS_NULL, + IWL_CD_STTS_MAC_HDR_ERR, + IWL_CD_STTS_MAX_RETRANS, + IWL_CD_STTS_EX_LIFETIME, + IWL_CD_STTS_NOT_USED, + IWL_CD_STTS_REPLAY_ERR, +}; + struct iwl_frame_release { u8 baid; u8 reserved; diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h index 279dd7b7a3fb..0b8cf7f3af93 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h @@ -269,6 +269,7 @@ struct iwl_rx_cmd_buffer { bool _page_stolen; u32 _rx_page_order; unsigned int truesize; + u8 status; }; static inline void *rxb_addr(struct iwl_rx_cmd_buffer *r) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h index b63d44b7cd7c..0127386de6c6 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h +++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h @@ -102,66 +102,6 @@ struct isr_statistics { u32 unhandled; }; -#define IWL_CD_STTS_OPTIMIZED_POS 0 -#define IWL_CD_STTS_OPTIMIZED_MSK 0x01 -#define IWL_CD_STTS_TRANSFER_STATUS_POS 1 -#define IWL_CD_STTS_TRANSFER_STATUS_MSK 0x0E -#define IWL_CD_STTS_WIFI_STATUS_POS 4 -#define IWL_CD_STTS_WIFI_STATUS_MSK 0xF0 - -/** - * enum iwl_completion_desc_transfer_status - transfer status (bits 1-3) - * @IWL_CD_STTS_END_TRANSFER: successful transfer complete. - * In sniffer mode, when split is used, set in last CD completion. (RX) - * @IWL_CD_STTS_OVERFLOW: In sniffer mode, when using split - used for - * all CD completion. (RX) - * @IWL_CD_STTS_ABORTED: CR abort / close flow. (RX) - */ -enum iwl_completion_desc_transfer_status { - IWL_CD_STTS_UNUSED, - IWL_CD_STTS_UNUSED_2, - IWL_CD_STTS_END_TRANSFER, - IWL_CD_STTS_OVERFLOW, - IWL_CD_STTS_ABORTED, - IWL_CD_STTS_ERROR, -}; - -/** - * enum iwl_completion_desc_wifi_status - wifi status (bits 4-7) - * @IWL_CD_STTS_VALID: the packet is valid (RX) - * @IWL_CD_STTS_FCS_ERR: frame check sequence error (RX) - * @IWL_CD_STTS_SEC_KEY_ERR: error handling the security key of rx (RX) - * @IWL_CD_STTS_DECRYPTION_ERR: error decrypting the frame (RX) - * @IWL_CD_STTS_DUP: duplicate packet (RX) - * @IWL_CD_STTS_ICV_MIC_ERR: MIC error (RX) - * @IWL_CD_STTS_INTERNAL_SNAP_ERR: problems removing the snap (RX) - * @IWL_CD_STTS_SEC_PORT_FAIL: security port fail (RX) - * @IWL_CD_STTS_BA_OLD_SN: block ack received old SN (RX) - * @IWL_CD_STTS_QOS_NULL: QoS null packet (RX) - * @IWL_CD_STTS_MAC_HDR_ERR: MAC header conversion error (RX) - * @IWL_CD_STTS_MAX_RETRANS: reached max number of retransmissions (TX) - * @IWL_CD_STTS_EX_LIFETIME: exceeded lifetime (TX) - * @IWL_CD_STTS_NOT_USED: completed but not used (RX) - * @IWL_CD_STTS_REPLAY_ERR: pn check failed, replay error (RX) - */ -enum iwl_completion_desc_wifi_status { - IWL_CD_STTS_VALID, - IWL_CD_STTS_FCS_ERR, - IWL_CD_STTS_SEC_KEY_ERR, - IWL_CD_STTS_DECRYPTION_ERR, - IWL_CD_STTS_DUP, - IWL_CD_STTS_ICV_MIC_ERR, - IWL_CD_STTS_INTERNAL_SNAP_ERR, - IWL_CD_STTS_SEC_PORT_FAIL, - IWL_CD_STTS_BA_OLD_SN, - IWL_CD_STTS_QOS_NULL, - IWL_CD_STTS_MAC_HDR_ERR, - IWL_CD_STTS_MAX_RETRANS, - IWL_CD_STTS_EX_LIFETIME, - IWL_CD_STTS_NOT_USED, - IWL_CD_STTS_REPLAY_ERR, -}; - #define IWL_RX_TD_TYPE_MSK 0xff000000 #define IWL_RX_TD_SIZE_MSK 0x00ffffff #define IWL_RX_TD_SIZE_2K BIT(11) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c index d017aa2a0a8b..b82f7a0509ec 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c @@ -1187,7 +1187,8 @@ static void iwl_pcie_rx_reuse_rbd(struct iwl_trans *trans, static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans, struct iwl_rxq *rxq, struct iwl_rx_mem_buffer *rxb, - bool emergency) + bool emergency, + int i) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_txq *txq = trans_pcie->txq[trans_pcie->cmd_queue]; @@ -1213,6 +1214,9 @@ static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans, .truesize = max_len, }; + if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) + rxcb.status = rxq->cd[i].status; + pkt = rxb_addr(&rxcb); if (pkt->len_n_flags == cpu_to_le32(FH_RSCSR_FRAME_INVALID)) { @@ -1406,7 +1410,7 @@ static void iwl_pcie_rx_handle(struct iwl_trans *trans, int queue) goto out; IWL_DEBUG_RX(trans, "Q %d: HW = %d, SW = %d\n", rxq->id, r, i); - iwl_pcie_rx_handle_rb(trans, rxq, rxb, emergency); + iwl_pcie_rx_handle_rb(trans, rxq, rxb, emergency, i); i = (i + 1) & (rxq->queue_size - 1); From 9b3089bd820d16c9bc27acbd0a68a575e1df9290 Mon Sep 17 00:00:00 2001 From: Golan Ben Ami Date: Sun, 25 Mar 2018 16:57:42 +0300 Subject: [PATCH 037/276] iwlwifi: pcie: allow using tx init for other queues but the command queue We would like to allow using tx init code for other queues but the command queue - for newer devices. Signed-off-by: Golan Ben Ami Signed-off-by: Luca Coelho --- .../wireless/intel/iwlwifi/pcie/internal.h | 3 ++- .../wireless/intel/iwlwifi/pcie/trans-gen2.c | 2 +- .../net/wireless/intel/iwlwifi/pcie/tx-gen2.c | 23 ++++++++++--------- 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h index 0127386de6c6..da6d367de76e 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h +++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h @@ -640,7 +640,8 @@ void iwl_pcie_disable_ict(struct iwl_trans *trans); * TX / HCMD ******************************************************/ int iwl_pcie_tx_init(struct iwl_trans *trans); -int iwl_pcie_gen2_tx_init(struct iwl_trans *trans); +int iwl_pcie_gen2_tx_init(struct iwl_trans *trans, int txq_id, + int queue_size); void iwl_pcie_tx_start(struct iwl_trans *trans, u32 scd_base_addr); int iwl_pcie_tx_stop(struct iwl_trans *trans); void iwl_pcie_tx_free(struct iwl_trans *trans); diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c index 2bc67219ed3e..3e5c732a89db 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c @@ -265,7 +265,7 @@ static int iwl_pcie_gen2_nic_init(struct iwl_trans *trans) return -ENOMEM; /* Allocate or reset and init all Tx and Command queues */ - if (iwl_pcie_gen2_tx_init(trans)) + if (iwl_pcie_gen2_tx_init(trans, trans_pcie->cmd_queue, TFD_CMD_SLOTS)) return -ENOMEM; /* enable shadow regs in HW */ diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c index b99f33ff9123..9ce7b2072613 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c @@ -1251,30 +1251,31 @@ void iwl_pcie_gen2_tx_free(struct iwl_trans *trans) } } -int iwl_pcie_gen2_tx_init(struct iwl_trans *trans) +int iwl_pcie_gen2_tx_init(struct iwl_trans *trans, int txq_id, int queue_size) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - struct iwl_txq *cmd_queue; - int txq_id = trans_pcie->cmd_queue, ret; + struct iwl_txq *queue; + int ret; - /* alloc and init the command queue */ + /* alloc and init the tx queue */ if (!trans_pcie->txq[txq_id]) { - cmd_queue = kzalloc(sizeof(*cmd_queue), GFP_KERNEL); - if (!cmd_queue) { - IWL_ERR(trans, "Not enough memory for command queue\n"); + queue = kzalloc(sizeof(*queue), GFP_KERNEL); + if (!queue) { + IWL_ERR(trans, "Not enough memory for tx queue\n"); return -ENOMEM; } - trans_pcie->txq[txq_id] = cmd_queue; - ret = iwl_pcie_txq_alloc(trans, cmd_queue, TFD_CMD_SLOTS, true); + trans_pcie->txq[txq_id] = queue; + ret = iwl_pcie_txq_alloc(trans, queue, queue_size, true); if (ret) { IWL_ERR(trans, "Tx %d queue init failed\n", txq_id); goto error; } } else { - cmd_queue = trans_pcie->txq[txq_id]; + queue = trans_pcie->txq[txq_id]; } - ret = iwl_pcie_txq_init(trans, cmd_queue, TFD_CMD_SLOTS, true); + ret = iwl_pcie_txq_init(trans, queue, queue_size, + (txq_id == trans_pcie->cmd_queue)); if (ret) { IWL_ERR(trans, "Tx %d queue alloc failed\n", txq_id); goto error; From 89d5e833534bfdbcf2d25f93c780883f530847c9 Mon Sep 17 00:00:00 2001 From: Golan Ben Ami Date: Sun, 25 Mar 2018 09:57:08 +0300 Subject: [PATCH 038/276] iwlwifi: pcie: make non-static hcmd and rx code Allow other device generations to use the utilities that are used to send and reclaim host commands and to allocate rx, by making it non-static. Signed-off-by: Golan Ben Ami Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/pcie/internal.h | 8 ++++++++ drivers/net/wireless/intel/iwlwifi/pcie/rx.c | 4 ++-- drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c | 10 +++++----- drivers/net/wireless/intel/iwlwifi/pcie/tx.c | 2 +- 4 files changed, 16 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h index da6d367de76e..cb43b194dc05 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h +++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h @@ -613,6 +613,7 @@ void iwl_trans_pcie_free(struct iwl_trans *trans); /***************************************************** * RX ******************************************************/ +int _iwl_pcie_rx_init(struct iwl_trans *trans); int iwl_pcie_rx_init(struct iwl_trans *trans); int iwl_pcie_gen2_rx_init(struct iwl_trans *trans); irqreturn_t iwl_pcie_msix_isr(int irq, void *data); @@ -626,6 +627,7 @@ void iwl_pcie_rx_init_rxb_lists(struct iwl_rxq *rxq); int iwl_pcie_dummy_napi_poll(struct napi_struct *napi, int budget); void iwl_pcie_rxq_alloc_rbs(struct iwl_trans *trans, gfp_t priority, struct iwl_rxq *rxq); +int iwl_pcie_rx_alloc(struct iwl_trans *trans); /***************************************************** * ICT - interrupt handling @@ -658,11 +660,17 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, struct iwl_device_cmd *dev_cmd, int txq_id); void iwl_pcie_txq_check_wrptrs(struct iwl_trans *trans); int iwl_trans_pcie_send_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd); +void iwl_pcie_cmdq_reclaim(struct iwl_trans *trans, int txq_id, int idx); +void iwl_pcie_gen2_txq_inc_wr_ptr(struct iwl_trans *trans, + struct iwl_txq *txq); void iwl_pcie_hcmd_complete(struct iwl_trans *trans, struct iwl_rx_cmd_buffer *rxb); void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn, struct sk_buff_head *skbs); void iwl_trans_pcie_tx_reset(struct iwl_trans *trans); +void iwl_pcie_gen2_update_byte_tbl(struct iwl_trans_pcie *trans_pcie, + struct iwl_txq *txq, u16 byte_cnt, + int num_tbs); static inline u16 iwl_pcie_tfd_tb_get_len(struct iwl_trans *trans, void *_tfd, u8 idx) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c index b82f7a0509ec..acae8f967912 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c @@ -776,7 +776,7 @@ static int iwl_pcie_alloc_rxq_dma(struct iwl_trans *trans, return -ENOMEM; } -static int iwl_pcie_rx_alloc(struct iwl_trans *trans) +int iwl_pcie_rx_alloc(struct iwl_trans *trans) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_rb_allocator *rba = &trans_pcie->rba; @@ -1002,7 +1002,7 @@ int iwl_pcie_dummy_napi_poll(struct napi_struct *napi, int budget) return 0; } -static int _iwl_pcie_rx_init(struct iwl_trans *trans) +int _iwl_pcie_rx_init(struct iwl_trans *trans) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_rxq *def_rxq; diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c index 9ce7b2072613..4a08f4eab1a5 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c @@ -87,9 +87,9 @@ void iwl_pcie_gen2_tx_stop(struct iwl_trans *trans) /* * iwl_pcie_txq_update_byte_tbl - Set up entry in Tx byte-count array */ -static void iwl_pcie_gen2_update_byte_tbl(struct iwl_trans_pcie *trans_pcie, - struct iwl_txq *txq, u16 byte_cnt, - int num_tbs) +void iwl_pcie_gen2_update_byte_tbl(struct iwl_trans_pcie *trans_pcie, + struct iwl_txq *txq, u16 byte_cnt, + int num_tbs) { struct iwlagn_scd_bc_tbl *scd_bc_tbl = txq->bc_tbl.addr; struct iwl_trans *trans = iwl_trans_pcie_get_trans(trans_pcie); @@ -127,8 +127,8 @@ static void iwl_pcie_gen2_update_byte_tbl(struct iwl_trans_pcie *trans_pcie, /* * iwl_pcie_gen2_txq_inc_wr_ptr - Send new write index to hardware */ -static void iwl_pcie_gen2_txq_inc_wr_ptr(struct iwl_trans *trans, - struct iwl_txq *txq) +void iwl_pcie_gen2_txq_inc_wr_ptr(struct iwl_trans *trans, + struct iwl_txq *txq) { lockdep_assert_held(&txq->lock); diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c index 93f0d387688a..da8e0e7c7844 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c @@ -1230,7 +1230,7 @@ static int iwl_pcie_set_cmd_in_flight(struct iwl_trans *trans, * need to be reclaimed. As result, some free space forms. If there is * enough free space (> low mark), wake the stack that feeds us. */ -static void iwl_pcie_cmdq_reclaim(struct iwl_trans *trans, int txq_id, int idx) +void iwl_pcie_cmdq_reclaim(struct iwl_trans *trans, int txq_id, int idx) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_txq *txq = trans_pcie->txq[txq_id]; From 4290eaad7a8a7168c8f675d54503d7203b2db5ea Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 11 Apr 2018 16:17:00 +0200 Subject: [PATCH 039/276] iwlwifi: remove dump_regs() from transport ops This is used only within PCIe, and there's no reason to go through the transport methods for a function call within PCIe itself. Remove the dump_regs() method and call the function directly. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/iwl-trans.h | 11 ----------- drivers/net/wireless/intel/iwlwifi/pcie/internal.h | 1 + drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 3 +-- drivers/net/wireless/intel/iwlwifi/pcie/tx.c | 2 +- 4 files changed, 3 insertions(+), 14 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h index 0b8cf7f3af93..dbac9ac80ce9 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h @@ -539,9 +539,6 @@ struct iwl_trans_rxq_dma_data { * @dump_data: return a vmalloc'ed buffer with debug data, maybe containing last * TX'ed commands and similar. The buffer will be vfree'd by the caller. * Note that the transport must fill in the proper file headers. - * @dump_regs: dump using IWL_ERR configuration space and memory mapped - * registers of the device to diagnose failure, e.g., when HW becomes - * inaccessible. */ struct iwl_trans_ops { @@ -612,8 +609,6 @@ struct iwl_trans_ops { struct iwl_trans_dump_data *(*dump_data)(struct iwl_trans *trans, const struct iwl_fw_dbg_trigger_tlv *trigger); - - void (*dump_regs)(struct iwl_trans *trans); }; /** @@ -898,12 +893,6 @@ iwl_trans_dump_data(struct iwl_trans *trans, return trans->ops->dump_data(trans, trigger); } -static inline void iwl_trans_dump_regs(struct iwl_trans *trans) -{ - if (trans->ops->dump_regs) - trans->ops->dump_regs(trans); -} - static inline struct iwl_device_cmd * iwl_trans_alloc_tx_cmd(struct iwl_trans *trans) { diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h index cb43b194dc05..74442189d639 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h +++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h @@ -988,6 +988,7 @@ static inline void __iwl_trans_pcie_set_bit(struct iwl_trans *trans, } void iwl_trans_pcie_rf_kill(struct iwl_trans *trans, bool state); +void iwl_trans_pcie_dump_regs(struct iwl_trans *trans); #ifdef CONFIG_IWLWIFI_DEBUGFS int iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans); diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index 7d319b6863fe..7cc438f31154 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -92,7 +92,7 @@ #define IWL_FW_MEM_EXTENDED_START 0x40000 #define IWL_FW_MEM_EXTENDED_END 0x57FFF -static void iwl_trans_pcie_dump_regs(struct iwl_trans *trans) +void iwl_trans_pcie_dump_regs(struct iwl_trans *trans) { #define PCI_DUMP_SIZE 64 #define PREFIX_LEN 32 @@ -3175,7 +3175,6 @@ static void iwl_trans_pcie_resume(struct iwl_trans *trans) .ref = iwl_trans_pcie_ref, \ .unref = iwl_trans_pcie_unref, \ .dump_data = iwl_trans_pcie_dump_data, \ - .dump_regs = iwl_trans_pcie_dump_regs, \ .d3_suspend = iwl_trans_pcie_d3_suspend, \ .d3_resume = iwl_trans_pcie_d3_resume diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c index da8e0e7c7844..debff193016e 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c @@ -1912,7 +1912,7 @@ static int iwl_pcie_send_hcmd_sync(struct iwl_trans *trans, } if (test_bit(STATUS_FW_ERROR, &trans->status)) { - iwl_trans_dump_regs(trans); + iwl_trans_pcie_dump_regs(trans); IWL_ERR(trans, "FW error in SYNC CMD %s\n", iwl_get_cmd_string(trans, cmd->id)); dump_stack(); From 33bdccb71aa697c0e2051fe5dd03c7b291bfef7e Mon Sep 17 00:00:00 2001 From: Golan Ben Ami Date: Wed, 4 Apr 2018 08:56:05 +0300 Subject: [PATCH 040/276] iwlwifi: remove FSF's address from the license notice The Free Software Foundation's address shouldn't be in the license notice anymore, and some of our check scripts complain about it (via checkpatch.pl). Remove the address to silence it. Signed-off-by: Golan Ben Ami Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/iwl-op-mode.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-op-mode.h b/drivers/net/wireless/intel/iwlwifi/iwl-op-mode.h index b49eda8150bb..cbbdede2e01b 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-op-mode.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-op-mode.h @@ -8,6 +8,7 @@ * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH * Copyright(c) 2015 Intel Deutschland GmbH + * Copyright(c) 2018 Intel Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -19,9 +20,7 @@ * General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA + * along with this program. * * The full GNU General Public License is included in this distribution * in the file called COPYING. @@ -35,6 +34,7 @@ * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH * Copyright(c) 2015 Intel Deutschland GmbH + * Copyright(c) 2018 Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without From 4c2f445c0f49bfd9d28f31df3919e5d88ecff6c6 Mon Sep 17 00:00:00 2001 From: Ayala Beker Date: Thu, 8 Mar 2018 12:20:46 +0200 Subject: [PATCH 041/276] iwlwifi: mvm: skip EBS in low latency mode while fragmented scan isn't supported While associated in low latency mode, or when traffic load is high, don't enable EBS in scan request if fragmented EBS is not supported by the FW. Signed-off-by: Ayala Beker Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/file.h | 2 ++ drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 5 +++++ drivers/net/wireless/intel/iwlwifi/mvm/scan.c | 11 ++++++++++- 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/file.h b/drivers/net/wireless/intel/iwlwifi/fw/file.h index c116dc3fbffe..c7e296a5dda9 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/file.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/file.h @@ -258,6 +258,7 @@ typedef unsigned int __bitwise iwl_ucode_tlv_api_t; * deprecated. * @IWL_UCODE_TLV_API_ADAPTIVE_DWELL_V2: This ucode supports version 8 * of scan request: SCAN_REQUEST_CMD_UMAC_API_S_VER_8 + * @IWL_UCODE_TLV_API_FRAG_EBS: This ucode supports fragmented EBS * * @NUM_IWL_UCODE_TLV_API: number of bits used */ @@ -280,6 +281,7 @@ enum iwl_ucode_tlv_api { IWL_UCODE_TLV_API_QUOTA_LOW_LATENCY = (__force iwl_ucode_tlv_api_t)38, IWL_UCODE_TLV_API_DEPRECATE_TTAK = (__force iwl_ucode_tlv_api_t)41, IWL_UCODE_TLV_API_ADAPTIVE_DWELL_V2 = (__force iwl_ucode_tlv_api_t)42, + IWL_UCODE_TLV_API_FRAG_EBS = (__force iwl_ucode_tlv_api_t)44, NUM_IWL_UCODE_TLV_API #ifdef __CHECKER__ diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index e5a717ade628..780b920ee619 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -1245,6 +1245,11 @@ static inline bool iwl_mvm_is_oce_supported(struct iwl_mvm *mvm) return fw_has_api(&mvm->fw->ucode_capa, IWL_UCODE_TLV_API_OCE); } +static inline bool iwl_mvm_is_frag_ebs_supported(struct iwl_mvm *mvm) +{ + return fw_has_api(&mvm->fw->ucode_capa, IWL_UCODE_TLV_API_FRAG_EBS); +} + static inline bool iwl_mvm_enter_d0i3_on_suspend(struct iwl_mvm *mvm) { /* For now we only use this mode to differentiate between diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c index 11ecdf63b732..8a89989f59fd 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c @@ -836,16 +836,25 @@ static inline bool iwl_mvm_scan_use_ebs(struct iwl_mvm *mvm, struct ieee80211_vif *vif) { const struct iwl_ucode_capabilities *capa = &mvm->fw->ucode_capa; + bool low_latency; + + if (iwl_mvm_is_cdb_supported(mvm)) + low_latency = iwl_mvm_low_latency_band(mvm, NL80211_BAND_5GHZ); + else + low_latency = iwl_mvm_low_latency(mvm); /* We can only use EBS if: * 1. the feature is supported; * 2. the last EBS was successful; * 3. if only single scan, the single scan EBS API is supported; * 4. it's not a p2p find operation. + * 5. we are not in low latency mode, + * or if fragmented ebs is supported by the FW */ return ((capa->flags & IWL_UCODE_TLV_FLAGS_EBS_SUPPORT) && mvm->last_ebs_successful && IWL_MVM_ENABLE_EBS && - vif->type != NL80211_IFTYPE_P2P_DEVICE); + vif->type != NL80211_IFTYPE_P2P_DEVICE && + (!low_latency || iwl_mvm_is_frag_ebs_supported(mvm))); } static inline bool iwl_mvm_is_regular_scan(struct iwl_mvm_scan_params *params) From 0791c2fce3c8b719db14c57fe3fac689743cd399 Mon Sep 17 00:00:00 2001 From: Haim Dreyfuss Date: Thu, 29 Mar 2018 14:13:54 +0300 Subject: [PATCH 042/276] iwlwifi: mvm: support new reduce tx power FW API. Update reduce tx power command API to be compatible with new FW API. Signed-off-by: Haim Dreyfuss Signed-off-by: Luca Coelho --- .../wireless/intel/iwlwifi/fw/api/commands.h | 3 +- .../net/wireless/intel/iwlwifi/fw/api/power.h | 30 +++++++++++++++++-- drivers/net/wireless/intel/iwlwifi/fw/file.h | 3 ++ drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 23 +++++++++----- .../net/wireless/intel/iwlwifi/mvm/mac80211.c | 25 +++++++++++----- 5 files changed, 66 insertions(+), 18 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h b/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h index 6dad748e5cdc..8b4922bbe139 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h @@ -436,7 +436,8 @@ enum iwl_legacy_cmds { /** * @REDUCE_TX_POWER_CMD: - * &struct iwl_dev_tx_power_cmd_v3 or &struct iwl_dev_tx_power_cmd + * &struct iwl_dev_tx_power_cmd_v3 or &struct iwl_dev_tx_power_cmd_v4 + * or &struct iwl_dev_tx_power_cmd */ REDUCE_TX_POWER_CMD = 0x9f, diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/power.h b/drivers/net/wireless/intel/iwlwifi/fw/api/power.h index a3c77e01863b..286a22da232d 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/power.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/power.h @@ -8,6 +8,7 @@ * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH * Copyright(c) 2015 - 2017 Intel Deutschland GmbH + * Copyright (C) 2018 Intel Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -30,6 +31,7 @@ * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH * Copyright(c) 2015 - 2017 Intel Deutschland GmbH + * Copyright (C) 2018 Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -316,7 +318,9 @@ enum iwl_dev_tx_power_cmd_mode { IWL_TX_POWER_MODE_SET_DEVICE = 1, IWL_TX_POWER_MODE_SET_CHAINS = 2, IWL_TX_POWER_MODE_SET_ACK = 3, -}; /* TX_POWER_REDUCED_FLAGS_TYPE_API_E_VER_4 */; + IWL_TX_POWER_MODE_SET_SAR_TIMER = 4, + IWL_TX_POWER_MODE_SET_SAR_TIMER_DEFAULT_TABLE = 5, +}; /* TX_POWER_REDUCED_FLAGS_TYPE_API_E_VER_5 */; #define IWL_NUM_CHAIN_LIMITS 2 #define IWL_NUM_SUB_BANDS 5 @@ -350,13 +354,35 @@ struct iwl_dev_tx_power_cmd_v3 { * reduction. * @reserved: reserved (padding) */ -struct iwl_dev_tx_power_cmd { +struct iwl_dev_tx_power_cmd_v4 { /* v4 is just an extension of v3 - keep this here */ struct iwl_dev_tx_power_cmd_v3 v3; u8 enable_ack_reduction; u8 reserved[3]; } __packed; /* TX_REDUCED_POWER_API_S_VER_4 */ +/** + * struct iwl_dev_tx_power_cmd - TX power reduction command + * @v3: version 3 of the command, embedded here for easier software handling + * @enable_ack_reduction: enable or disable close range ack TX power + * reduction. + * @per_chain_restriction_changed: is per_chain_restriction has changed + * from last command. used if set_mode is + * IWL_TX_POWER_MODE_SET_SAR_TIMER. + * note: if not changed, the command is used for keep alive only. + * @reserved: reserved (padding) + * @timer_period: timer in milliseconds. if expires FW will change to default + * BIOS values. relevant if setMode is IWL_TX_POWER_MODE_SET_SAR_TIMER + */ +struct iwl_dev_tx_power_cmd { + /* v5 is just an extension of v3 - keep this here */ + struct iwl_dev_tx_power_cmd_v3 v3; + u8 enable_ack_reduction; + u8 per_chain_restriction_changed; + u8 reserved[2]; + __le32 timer_period; +} __packed; /* TX_REDUCED_POWER_API_S_VER_5 */ + #define IWL_NUM_GEO_PROFILES 3 /** diff --git a/drivers/net/wireless/intel/iwlwifi/fw/file.h b/drivers/net/wireless/intel/iwlwifi/fw/file.h index c7e296a5dda9..fce52ee4caec 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/file.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/file.h @@ -259,6 +259,8 @@ typedef unsigned int __bitwise iwl_ucode_tlv_api_t; * @IWL_UCODE_TLV_API_ADAPTIVE_DWELL_V2: This ucode supports version 8 * of scan request: SCAN_REQUEST_CMD_UMAC_API_S_VER_8 * @IWL_UCODE_TLV_API_FRAG_EBS: This ucode supports fragmented EBS + * @IWL_UCODE_TLV_API_REDUCE_TX_POWER: This ucode supports v5 of + * the REDUCE_TX_POWER_CMD. * * @NUM_IWL_UCODE_TLV_API: number of bits used */ @@ -282,6 +284,7 @@ enum iwl_ucode_tlv_api { IWL_UCODE_TLV_API_DEPRECATE_TTAK = (__force iwl_ucode_tlv_api_t)41, IWL_UCODE_TLV_API_ADAPTIVE_DWELL_V2 = (__force iwl_ucode_tlv_api_t)42, IWL_UCODE_TLV_API_FRAG_EBS = (__force iwl_ucode_tlv_api_t)44, + IWL_UCODE_TLV_API_REDUCE_TX_POWER = (__force iwl_ucode_tlv_api_t)45, NUM_IWL_UCODE_TLV_API #ifdef __CHECKER__ diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c index 6bb1a99a197a..878dc29c2010 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c @@ -773,19 +773,28 @@ static int iwl_mvm_sar_get_wgds_table(struct iwl_mvm *mvm) int iwl_mvm_sar_select_profile(struct iwl_mvm *mvm, int prof_a, int prof_b) { - struct iwl_dev_tx_power_cmd cmd = { - .v3.set_mode = cpu_to_le32(IWL_TX_POWER_MODE_SET_CHAINS), - }; + union { + struct iwl_dev_tx_power_cmd v5; + struct iwl_dev_tx_power_cmd_v4 v4; + } cmd; int i, j, idx; int profs[ACPI_SAR_NUM_CHAIN_LIMITS] = { prof_a, prof_b }; - int len = sizeof(cmd); + int len; BUILD_BUG_ON(ACPI_SAR_NUM_CHAIN_LIMITS < 2); BUILD_BUG_ON(ACPI_SAR_NUM_CHAIN_LIMITS * ACPI_SAR_NUM_SUB_BANDS != ACPI_SAR_TABLE_SIZE); - if (!fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_TX_POWER_ACK)) - len = sizeof(cmd.v3); + cmd.v5.v3.set_mode = cpu_to_le32(IWL_TX_POWER_MODE_SET_CHAINS); + + if (fw_has_api(&mvm->fw->ucode_capa, + IWL_UCODE_TLV_API_REDUCE_TX_POWER)) + len = sizeof(cmd.v5); + else if (fw_has_capa(&mvm->fw->ucode_capa, + IWL_UCODE_TLV_CAPA_TX_POWER_ACK)) + len = sizeof(cmd.v4); + else + len = sizeof(cmd.v4.v3); for (i = 0; i < ACPI_SAR_NUM_CHAIN_LIMITS; i++) { struct iwl_mvm_sar_profile *prof; @@ -812,7 +821,7 @@ int iwl_mvm_sar_select_profile(struct iwl_mvm *mvm, int prof_a, int prof_b) IWL_DEBUG_RADIO(mvm, " Chain[%d]:\n", i); for (j = 0; j < ACPI_SAR_NUM_SUB_BANDS; j++) { idx = (i * ACPI_SAR_NUM_SUB_BANDS) + j; - cmd.v3.per_chain_restriction[i][j] = + cmd.v5.v3.per_chain_restriction[i][j] = cpu_to_le16(prof->table[idx]); IWL_DEBUG_RADIO(mvm, " Band[%d] = %d * .125dBm\n", j, prof->table[idx]); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index 3a502eada774..d1bbafea595a 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -1313,19 +1313,28 @@ static struct iwl_mvm_phy_ctxt *iwl_mvm_get_free_phy_ctxt(struct iwl_mvm *mvm) static int iwl_mvm_set_tx_power(struct iwl_mvm *mvm, struct ieee80211_vif *vif, s16 tx_power) { - struct iwl_dev_tx_power_cmd cmd = { - .v3.set_mode = cpu_to_le32(IWL_TX_POWER_MODE_SET_MAC), - .v3.mac_context_id = + int len; + union { + struct iwl_dev_tx_power_cmd v5; + struct iwl_dev_tx_power_cmd_v4 v4; + } cmd = { + .v5.v3.set_mode = cpu_to_le32(IWL_TX_POWER_MODE_SET_MAC), + .v5.v3.mac_context_id = cpu_to_le32(iwl_mvm_vif_from_mac80211(vif)->id), - .v3.pwr_restriction = cpu_to_le16(8 * tx_power), + .v5.v3.pwr_restriction = cpu_to_le16(8 * tx_power), }; - int len = sizeof(cmd); if (tx_power == IWL_DEFAULT_MAX_TX_POWER) - cmd.v3.pwr_restriction = cpu_to_le16(IWL_DEV_MAX_TX_POWER); + cmd.v5.v3.pwr_restriction = cpu_to_le16(IWL_DEV_MAX_TX_POWER); - if (!fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_TX_POWER_ACK)) - len = sizeof(cmd.v3); + if (fw_has_api(&mvm->fw->ucode_capa, + IWL_UCODE_TLV_API_REDUCE_TX_POWER)) + len = sizeof(cmd.v5); + else if (fw_has_capa(&mvm->fw->ucode_capa, + IWL_UCODE_TLV_CAPA_TX_POWER_ACK)) + len = sizeof(cmd.v4); + else + len = sizeof(cmd.v4.v3); return iwl_mvm_send_cmd_pdu(mvm, REDUCE_TX_POWER_CMD, 0, len, &cmd); } From 9416560e41537a3f3be19b7ae757e517991900cd Mon Sep 17 00:00:00 2001 From: Golan Ben Ami Date: Sun, 25 Mar 2018 11:28:33 +0300 Subject: [PATCH 043/276] iwlwifi: pcie: store the default rxq number Store the default rxq number in a variable, so we won't need to use the actual number in the code. Signed-off-by: Golan Ben Ami Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/pcie/internal.h | 2 ++ drivers/net/wireless/intel/iwlwifi/pcie/rx.c | 2 +- drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 2 ++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h index 74442189d639..c03de2bc5739 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h +++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h @@ -456,6 +456,7 @@ struct iwl_self_init_dram { * @ucode_write_complete: indicates that the ucode has been copied. * @ucode_write_waitq: wait queue for uCode load * @cmd_queue - command queue number + * @def_rx_queue - default rx queue number * @rx_buf_size: Rx buffer size * @bc_table_dword: true if the BC table expects DWORD (as opposed to bytes) * @scd_set_active: should the transport configure the SCD for HCMD queue @@ -536,6 +537,7 @@ struct iwl_trans_pcie { u8 page_offs, dev_cmd_offs; u8 cmd_queue; + u8 def_rx_queue; u8 cmd_fifo; unsigned int cmd_q_wdg_timeout; u8 n_no_reclaim_cmds; diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c index acae8f967912..8075466aa4c4 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c @@ -1271,7 +1271,7 @@ static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans, index = SEQ_TO_INDEX(sequence); cmd_index = iwl_pcie_get_cmd_index(txq, index); - if (rxq->id == 0) + if (rxq->id == trans_pcie->def_rx_queue) iwl_op_mode_rx(trans->op_mode, &rxq->napi, &rxcb); else diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index 7cc438f31154..631f0015102b 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -3276,6 +3276,8 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, PCIE_LINK_STATE_CLKPM); } + trans_pcie->def_rx_queue = 0; + if (cfg->use_tfh) { addr_size = 64; trans_pcie->max_tbs = IWL_TFH_NUM_TBS; From b6fe27575a041267347d5b6cbc4447b4be049de3 Mon Sep 17 00:00:00 2001 From: Golan Ben Ami Date: Thu, 22 Mar 2018 14:57:11 +0200 Subject: [PATCH 044/276] iwlwifi: pcie: make gen2 of apm_init non-static This will allow using the same init in future generations. Signed-off-by: Golan Ben Ami Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/pcie/internal.h | 1 + drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h index c03de2bc5739..8fdef4a26db4 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h +++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h @@ -1009,6 +1009,7 @@ void iwl_pcie_enable_rx_wake(struct iwl_trans *trans, bool enable); void iwl_pcie_rx_allocator_work(struct work_struct *data); /* common functions that are used by gen2 transport */ +int iwl_pcie_gen2_apm_init(struct iwl_trans *trans); void iwl_pcie_apm_config(struct iwl_trans *trans); int iwl_pcie_prepare_card_hw(struct iwl_trans *trans); void iwl_pcie_synchronize_irqs(struct iwl_trans *trans); diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c index 3e5c732a89db..9b2a248e88b0 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c @@ -61,7 +61,7 @@ * (e.g. after platform boot, or shutdown via iwl_pcie_apm_stop()) * NOTE: This does not load uCode nor start the embedded processor */ -static int iwl_pcie_gen2_apm_init(struct iwl_trans *trans) +int iwl_pcie_gen2_apm_init(struct iwl_trans *trans) { int ret = 0; From 38bd7e58cf414d364df8c024314e2db0ce083918 Mon Sep 17 00:00:00 2001 From: Mordechay Goodstein Date: Tue, 10 Apr 2018 18:19:49 +0300 Subject: [PATCH 045/276] iwlwifi: add 80211 hdr offset to trace data Every rx mpdu cmd is built from cmd_hdr | 80211_hdr. The problem is that the size of cmd_hdr changes with API changes and we don't know where the 80211_hdr starts. By adding the size of cmd_hdr dynamically, we can ensure that we always know how to parse mpdu frames, without dependending on the API changes. Signed-off-by: Mordechay Goodstein Signed-off-by: Luca Coelho --- .../intel/iwlwifi/iwl-devtrace-data.h | 10 +++------ .../intel/iwlwifi/iwl-devtrace-iwlwifi.h | 14 +++++++----- .../net/wireless/intel/iwlwifi/iwl-devtrace.h | 22 +++++++++++-------- 3 files changed, 24 insertions(+), 22 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-data.h b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-data.h index a80e4202cd03..2cc6c019d0e1 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-data.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-data.h @@ -2,6 +2,7 @@ * * Copyright(c) 2009 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2015 Intel Deutschland GmbH + * Copyright(c) 2018 Intel Corporation * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -12,10 +13,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * * The full GNU General Public License is included in this distribution in the * file called LICENSE. * @@ -76,12 +73,11 @@ TRACE_EVENT(iwlwifi_dev_rx_data, TP_ARGS(dev, trans, rxbuf, len), TP_STRUCT__entry( DEV_ENTRY - __dynamic_array(u8, data, - len - iwl_rx_trace_len(trans, rxbuf, len)) + len - iwl_rx_trace_len(trans, rxbuf, len, NULL)) ), TP_fast_assign( - size_t offs = iwl_rx_trace_len(trans, rxbuf, len); + size_t offs = iwl_rx_trace_len(trans, rxbuf, len, NULL); DEV_ASSIGN; if (offs < len) memcpy(__get_dynamic_array(data), diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-iwlwifi.h b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-iwlwifi.h index 27e3e4e96aa2..82cfbfa0795d 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-iwlwifi.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-iwlwifi.h @@ -3,6 +3,7 @@ * Copyright(c) 2009 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2015 Intel Mobile Communications GmbH * Copyright(c) 2016 - 2017 Intel Deutschland GmbH + * Copyright(c) 2018 Intel Corporation * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -13,10 +14,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * * The full GNU General Public License is included in this distribution in the * file called LICENSE. * @@ -75,13 +72,18 @@ TRACE_EVENT(iwlwifi_dev_rx, TP_STRUCT__entry( DEV_ENTRY __field(u16, cmd) - __dynamic_array(u8, rxbuf, iwl_rx_trace_len(trans, pkt, len)) + __field(u8, hdr_offset) + __dynamic_array(u8, rxbuf, + iwl_rx_trace_len(trans, pkt, len, NULL)) ), TP_fast_assign( + size_t hdr_offset = 0; + DEV_ASSIGN; __entry->cmd = WIDE_ID(pkt->hdr.group_id, pkt->hdr.cmd); memcpy(__get_dynamic_array(rxbuf), pkt, - iwl_rx_trace_len(trans, pkt, len)); + iwl_rx_trace_len(trans, pkt, len, &hdr_offset)); + __entry->hdr_offset = hdr_offset; ), TP_printk("[%s] RX cmd %#.2x", __get_str(dev), __entry->cmd) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.h index f5c1127253cb..fc649b2bc017 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.h @@ -1,7 +1,8 @@ /****************************************************************************** * * Copyright(c) 2009 - 2014 Intel Corporation. All rights reserved. - * Copyright(C) 2016 Intel Deutschland GmbH + * Copyright(C) 2016 Intel Deutschland GmbH + * Copyright(c) 2018 Intel Corporation * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -12,10 +13,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * * The full GNU General Public License is included in this distribution in the * file called LICENSE. * @@ -60,16 +57,23 @@ static inline bool iwl_trace_data(struct sk_buff *skb) } static inline size_t iwl_rx_trace_len(const struct iwl_trans *trans, - void *rxbuf, size_t len) + void *rxbuf, size_t len, + size_t *out_hdr_offset) { struct iwl_cmd_header *cmd = (void *)((u8 *)rxbuf + sizeof(__le32)); - struct ieee80211_hdr *hdr; + struct ieee80211_hdr *hdr = NULL; + size_t hdr_offset; if (cmd->cmd != trans->rx_mpdu_cmd) return len; - hdr = (void *)((u8 *)cmd + sizeof(struct iwl_cmd_header) + - trans->rx_mpdu_cmd_hdr_size); + hdr_offset = sizeof(struct iwl_cmd_header) + + trans->rx_mpdu_cmd_hdr_size; + + if (out_hdr_offset) + *out_hdr_offset = hdr_offset; + + hdr = (void *)((u8 *)cmd + hdr_offset); if (!ieee80211_is_data(hdr->frame_control)) return len; /* maybe try to identify EAPOL frames? */ From 84f260251ed8153e84c64eb2c5278ab18d3ddef6 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 19 Apr 2018 10:57:08 +0200 Subject: [PATCH 046/276] iwlwifi: don't WARN on trying to dump dead firmware There's no point in warning here, the user will just get an error back to the debugfs file write, and warning just makes it seem like there's an internal consistency problem when in reality the user just happened to hit this at a bad time. Remove the warning. Fixes: f45f979dc208 ("iwlwifi: mvm: disable dbg data collect when fw isn't alive") Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index 70173ad11050..9c1d13e6bad3 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -1041,7 +1041,7 @@ int iwl_fw_dbg_collect_desc(struct iwl_fw_runtime *fwrt, * If the loading of the FW completed successfully, the next step is to * get the SMEM config data. Thus, if fwrt->smem_cfg.num_lmacs is non * zero, the FW was already loaded successully. If the state is "NO_FW" - * in such a case - WARN and exit, since FW may be dead. Otherwise, we + * in such a case - exit, since FW may be dead. Otherwise, we * can try to collect the data, since FW might just not be fully * loaded (no "ALIVE" yet), and the debug data is accessible. * @@ -1049,9 +1049,8 @@ int iwl_fw_dbg_collect_desc(struct iwl_fw_runtime *fwrt, * config. In such a case, due to HW access problems, we might * collect garbage. */ - if (WARN((fwrt->trans->state == IWL_TRANS_NO_FW) && - fwrt->smem_cfg.num_lmacs, - "Can't collect dbg data when FW isn't alive\n")) + if (fwrt->trans->state == IWL_TRANS_NO_FW && + fwrt->smem_cfg.num_lmacs) return -EIO; if (test_and_set_bit(IWL_FWRT_STATUS_DUMPING, &fwrt->status)) From 2b3fae668c66b21d42583583619fa1ba23bd2885 Mon Sep 17 00:00:00 2001 From: Matt Chen Date: Thu, 19 Apr 2018 15:18:00 +0800 Subject: [PATCH 047/276] iwlwifi: pcie: avoid unnecessary work if NIC is disconnected When the NIC is disconnected from PCI bus, we are not able to access it anymore. Check the status to avoid some unnecessary work so can improve the performance. It will help to make PCI bus rescan to bring back the device much faster. The real test is able to improve 7 seconds. [w/o patch] It takes around 9 seconds .. 2018-04-20T01:22:39.691929-07:00 WARNING kernel: [ 66.335881] Timeout waiting for hardware access (CSR_GP_CNTRL 0xffffffff) .. 2018-04-20T01:22:48.101094-07:00 INFO kernel: [ 74.747364] iwlwifi 0000:01:00.0: loaded firmware version 29.610311.0 op_mode iwlmvm [w/a patch] It takes about 2 seconds. .. 2018-04-20T01:18:16.454087-07:00 WARNING kernel: [ 75.966860] Timeout waiting for hardware access (CSR_GP_CNTRL 0xffffffff) .. 2018-04-20T01:18:18.602717-07:00 INFO kernel: [ 78.116132] iwlwifi 0000:01:00.0: loaded firmware version 29.610311.0 op_mode iwlmvm .. Fixes: 49564a806fc5 ("iwlwifi: pcie: remove non-responsive device") Signed-off-by: Matt Chen Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 4 ++++ drivers/net/wireless/intel/iwlwifi/pcie/tx.c | 10 ++++++++++ 2 files changed, 14 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index 631f0015102b..cf7d1acc8e7a 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -2266,6 +2266,10 @@ static int iwl_trans_pcie_wait_txq_empty(struct iwl_trans *trans, int txq_idx) unsigned long now = jiffies; u8 wr_ptr; + /* Make sure the NIC is still alive in the bus */ + if (trans_pcie->scheduled_for_removal) + return -EIO; + if (!test_bit(txq_idx, trans_pcie->queue_used)) return -EINVAL; diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c index debff193016e..d5aba9ebd84a 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c @@ -1188,6 +1188,10 @@ static int iwl_pcie_set_cmd_in_flight(struct iwl_trans *trans, lockdep_assert_held(&trans_pcie->reg_lock); + /* Make sure the NIC is still alive in the bus */ + if (trans_pcie->scheduled_for_removal) + return -EIO; + if (!(cmd->flags & CMD_SEND_IN_IDLE) && !trans_pcie->ref_cmd_in_flight) { trans_pcie->ref_cmd_in_flight = true; @@ -1957,6 +1961,12 @@ static int iwl_pcie_send_hcmd_sync(struct iwl_trans *trans, int iwl_trans_pcie_send_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) { + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + + /* Make sure the NIC is still alive in the bus */ + if (trans_pcie->scheduled_for_removal) + return -EIO; + if (!(cmd->flags & CMD_SEND_IN_RFKILL) && test_bit(STATUS_RFKILL_OPMODE, &trans->status)) { IWL_DEBUG_RF_KILL(trans, "Dropping CMD 0x%x: RF KILL\n", From 50f067b35684dbc5dfe81683c6e381e8eb7da3fb Mon Sep 17 00:00:00 2001 From: Erel Geron Date: Mon, 23 Apr 2018 11:43:02 +0300 Subject: [PATCH 048/276] iwlwifi: mvm: support Coex Schema 2 The new coex schema requires moving to SISO only when BT AG is 4. Adjust the SISO criteria according to the coex schema version reported by firmware. Signed-off-by: Erel Geron Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/api/coex.h | 3 +++ drivers/net/wireless/intel/iwlwifi/fw/file.h | 2 ++ drivers/net/wireless/intel/iwlwifi/mvm/coex.c | 9 +++++++-- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/coex.h b/drivers/net/wireless/intel/iwlwifi/fw/api/coex.h index 87c1ddea75ae..68060085010f 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/coex.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/coex.h @@ -8,6 +8,7 @@ * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH * Copyright(c) 2017 Intel Deutschland GmbH + * Copyright(c) 2018 Intel Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -30,6 +31,7 @@ * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH * Copyright(c) 2017 Intel Deutschland GmbH + * Copyright(c) 2018 Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -203,6 +205,7 @@ enum iwl_bt_activity_grading { BT_ON_NO_CONNECTION = 1, BT_LOW_TRAFFIC = 2, BT_HIGH_TRAFFIC = 3, + BT_VERY_HIGH_TRAFFIC = 4, BT_MAX_AG, }; /* BT_COEX_BT_ACTIVITY_GRADING_API_E_VER_1 */ diff --git a/drivers/net/wireless/intel/iwlwifi/fw/file.h b/drivers/net/wireless/intel/iwlwifi/fw/file.h index fce52ee4caec..7638d0bb1e11 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/file.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/file.h @@ -331,6 +331,7 @@ typedef unsigned int __bitwise iwl_ucode_tlv_capa_t; * @IWL_UCODE_TLV_CAPA_STA_PM_NOTIF: firmware will send STA PM notification * @IWL_UCODE_TLV_CAPA_TLC_OFFLOAD: firmware implements rate scaling algorithm * @IWL_UCODE_TLV_CAPA_DYNAMIC_QUOTA: firmware implements quota related + * @IWL_UCODE_TLV_CAPA_COEX_SCHEMA_2: firmware implements Coex Schema 2 * @IWL_UCODE_TLV_CAPA_EXTENDED_DTS_MEASURE: extended DTS measurement * @IWL_UCODE_TLV_CAPA_SHORT_PM_TIMEOUTS: supports short PM timeouts * @IWL_UCODE_TLV_CAPA_BT_MPLUT_SUPPORT: supports bt-coex Multi-priority LUT @@ -388,6 +389,7 @@ enum iwl_ucode_tlv_capa { IWL_UCODE_TLV_CAPA_D0I3_END_FIRST = (__force iwl_ucode_tlv_capa_t)41, IWL_UCODE_TLV_CAPA_TLC_OFFLOAD = (__force iwl_ucode_tlv_capa_t)43, IWL_UCODE_TLV_CAPA_DYNAMIC_QUOTA = (__force iwl_ucode_tlv_capa_t)44, + IWL_UCODE_TLV_CAPA_COEX_SCHEMA_2 = (__force iwl_ucode_tlv_capa_t)45, IWL_UCODE_TLV_CAPA_EXTENDED_DTS_MEASURE = (__force iwl_ucode_tlv_capa_t)64, IWL_UCODE_TLV_CAPA_SHORT_PM_TIMEOUTS = (__force iwl_ucode_tlv_capa_t)65, IWL_UCODE_TLV_CAPA_BT_MPLUT_SUPPORT = (__force iwl_ucode_tlv_capa_t)67, diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/coex.c b/drivers/net/wireless/intel/iwlwifi/mvm/coex.c index 016e03a5034f..9707f455086b 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/coex.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/coex.c @@ -331,7 +331,7 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac, struct ieee80211_chanctx_conf *chanctx_conf; /* default smps_mode is AUTOMATIC - only used for client modes */ enum ieee80211_smps_mode smps_mode = IEEE80211_SMPS_AUTOMATIC; - u32 bt_activity_grading; + u32 bt_activity_grading, min_ag_for_static_smps; int ave_rssi; lockdep_assert_held(&mvm->mutex); @@ -363,8 +363,13 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac, return; } + if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_COEX_SCHEMA_2)) + min_ag_for_static_smps = BT_VERY_HIGH_TRAFFIC; + else + min_ag_for_static_smps = BT_HIGH_TRAFFIC; + bt_activity_grading = le32_to_cpu(data->notif->bt_activity_grading); - if (bt_activity_grading >= BT_HIGH_TRAFFIC) + if (bt_activity_grading >= min_ag_for_static_smps) smps_mode = IEEE80211_SMPS_STATIC; else if (bt_activity_grading >= BT_LOW_TRAFFIC) smps_mode = IEEE80211_SMPS_DYNAMIC; From f60c9e591b058af18b45f8e222d7b40cf3c001cb Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 1 May 2018 14:23:56 +0300 Subject: [PATCH 049/276] iwlwifi: improve the flow when a NIC is disconnected When the NIC is disconnected, we just can't do anything besides seeking for help from the bus driver. Dumping the device's memory is not necessary and just bloats the logs with unusable data. Moreover, asking mac80211 to restart the hardware is also useless. Bypass all this. Also, use the STATUS_TRANS_DEAD status bit instead of a bool inside the transport layer. The advantage of this is that now, the transport and the op_mode can know what is the situation and bypass the useless recovery steps mentioned above. Signed-off-by: Emmanuel Grumbach Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 6 ++++-- drivers/net/wireless/intel/iwlwifi/pcie/internal.h | 2 -- drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 8 ++++---- drivers/net/wireless/intel/iwlwifi/pcie/tx.c | 10 ++++------ 4 files changed, 12 insertions(+), 14 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index d275832dbb14..da1aafb71298 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -1254,7 +1254,8 @@ void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error) INIT_WORK(&reprobe->work, iwl_mvm_reprobe_wk); schedule_work(&reprobe->work); } else if (mvm->fwrt.cur_fw_img == IWL_UCODE_REGULAR && - mvm->hw_registered) { + mvm->hw_registered && + !test_bit(STATUS_TRANS_DEAD, &mvm->trans->status)) { /* don't let the transport/FW power down */ iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN); @@ -1269,7 +1270,8 @@ static void iwl_mvm_nic_error(struct iwl_op_mode *op_mode) { struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode); - iwl_mvm_dump_nic_error_log(mvm); + if (!test_bit(STATUS_TRANS_DEAD, &mvm->trans->status)) + iwl_mvm_dump_nic_error_log(mvm); iwl_mvm_nic_restart(mvm, true); } diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h index 8fdef4a26db4..1089e6b216aa 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h +++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h @@ -480,7 +480,6 @@ struct iwl_self_init_dram { * @fh_mask: current unmasked fh causes * @hw_mask: current unmasked hw causes * @in_rescan: true if we have triggered a device rescan - * @scheduled_for_removal: true if we have scheduled a device removal */ struct iwl_trans_pcie { struct iwl_rxq *rxq; @@ -573,7 +572,6 @@ struct iwl_trans_pcie { cpumask_t affinity_mask[IWL_MAX_RX_HW_QUEUES]; u16 tx_cmd_queue_size; bool in_rescan; - bool scheduled_for_removal; }; static inline struct iwl_trans_pcie * diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index cf7d1acc8e7a..2a20999d4c15 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -2013,7 +2013,7 @@ static bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans, if (iwlwifi_mod_params.remove_when_gone && cntrl == ~0U) { struct iwl_trans_pcie_removal *removal; - if (trans_pcie->scheduled_for_removal) + if (test_bit(STATUS_TRANS_DEAD, &trans->status)) goto err; IWL_ERR(trans, "Device gone - scheduling removal!\n"); @@ -2039,7 +2039,7 @@ static bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans, * we don't need to clear this flag, because * the trans will be freed and reallocated. */ - trans_pcie->scheduled_for_removal = true; + set_bit(STATUS_TRANS_DEAD, &trans->status); removal->pdev = to_pci_dev(trans->dev); INIT_WORK(&removal->work, iwl_trans_pcie_removal_wk); @@ -2267,8 +2267,8 @@ static int iwl_trans_pcie_wait_txq_empty(struct iwl_trans *trans, int txq_idx) u8 wr_ptr; /* Make sure the NIC is still alive in the bus */ - if (trans_pcie->scheduled_for_removal) - return -EIO; + if (test_bit(STATUS_TRANS_DEAD, &trans->status)) + return -ENODEV; if (!test_bit(txq_idx, trans_pcie->queue_used)) return -EINVAL; diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c index d5aba9ebd84a..b89e976ecfcd 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c @@ -1189,8 +1189,8 @@ static int iwl_pcie_set_cmd_in_flight(struct iwl_trans *trans, lockdep_assert_held(&trans_pcie->reg_lock); /* Make sure the NIC is still alive in the bus */ - if (trans_pcie->scheduled_for_removal) - return -EIO; + if (test_bit(STATUS_TRANS_DEAD, &trans->status)) + return -ENODEV; if (!(cmd->flags & CMD_SEND_IN_IDLE) && !trans_pcie->ref_cmd_in_flight) { @@ -1961,11 +1961,9 @@ static int iwl_pcie_send_hcmd_sync(struct iwl_trans *trans, int iwl_trans_pcie_send_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) { - struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - /* Make sure the NIC is still alive in the bus */ - if (trans_pcie->scheduled_for_removal) - return -EIO; + if (test_bit(STATUS_TRANS_DEAD, &trans->status)) + return -ENODEV; if (!(cmd->flags & CMD_SEND_IN_RFKILL) && test_bit(STATUS_RFKILL_OPMODE, &trans->status)) { From 941ab4eb66c10bc5c7234e83a7a858b2806ed151 Mon Sep 17 00:00:00 2001 From: Sara Sharon Date: Tue, 1 May 2018 14:54:22 +0300 Subject: [PATCH 050/276] iwlwifi: mvm: fix BAR seq ctrl reporting There is a bug in FW where the sequence control may be incorrect, and the driver overrides it with the value of the ieee80211 header. However, in BAR there is no sequence control in the header, which result with arbitrary sequence. This access to an unknown location is bad and it makes the logs very confusing - so fix it. Signed-off-by: Sara Sharon Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c index 796f010204d5..31a81a4c6e78 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c @@ -1480,6 +1480,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm, while (!skb_queue_empty(&skbs)) { struct sk_buff *skb = __skb_dequeue(&skbs); struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ieee80211_hdr *hdr = (void *)skb->data; bool flushed = false; skb_freed++; @@ -1524,11 +1525,11 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm, info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; info->flags &= ~IEEE80211_TX_CTL_AMPDU; - /* W/A FW bug: seq_ctl is wrong when the status isn't success */ - if (status != TX_STATUS_SUCCESS) { - struct ieee80211_hdr *hdr = (void *)skb->data; + /* W/A FW bug: seq_ctl is wrong upon failure / BAR frame */ + if (ieee80211_is_back_req(hdr->frame_control)) + seq_ctl = 0; + else if (status != TX_STATUS_SUCCESS) seq_ctl = le16_to_cpu(hdr->seq_ctrl); - } if (unlikely(!seq_ctl)) { struct ieee80211_hdr *hdr = (void *)skb->data; From 1a19c139be18ed4d6d681049cc48586fae070120 Mon Sep 17 00:00:00 2001 From: Sara Sharon Date: Tue, 1 May 2018 15:12:08 +0300 Subject: [PATCH 051/276] iwlwifi: mvm: avoid sending too many BARs When we receive TX response, we may release a few packets due to a hole that was closed in the transmission window. However, if that frame failed, we will mark all the released frames as failed and will send multiple BARs. This affects statistics badly, and cause unnecessary frames transmission. Instead, mark all the following packets as success, with the desired result of sending a bar for the failed frame only. Signed-off-by: Sara Sharon Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c index 31a81a4c6e78..b33b8357a8f7 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c @@ -1510,6 +1510,14 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm, break; } + /* + * If we are freeing multiple frames, mark all the frames + * but the first one as acked, since they were acknowledged + * before + * */ + if (skb_freed > 1) + info->flags |= IEEE80211_TX_STAT_ACK; + iwl_mvm_tx_status_check_trigger(mvm, status); info->status.rates[0].count = tx_resp->failure_frame + 1; From 3baf7528d6f832b28622d1ddadd2e47f6c2b5e08 Mon Sep 17 00:00:00 2001 From: Avraham Stern Date: Thu, 3 May 2018 15:02:16 +0300 Subject: [PATCH 052/276] iwlwifi: mvm: Send LQ command as async when necessary The parameter that indicated whether the LQ command should be sent as sync or async was removed, causing the LQ command to be sent as sync from interrupt context (e.g. from the RX path). This resulted in a kernel warning: "scheduling while atomic" and failing to send the LQ command, which ultimately leads to a queue hang. Fix it by adding back the required parameter to send the command as sync only when it is allowed. Fixes: d94c5a820d10 ("iwlwifi: mvm: open BA session only when sta is authorized") Signed-off-by: Avraham Stern Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/mvm/mac80211.c | 6 ++++-- drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 2 +- drivers/net/wireless/intel/iwlwifi/mvm/rs.c | 18 ++++++++---------- drivers/net/wireless/intel/iwlwifi/mvm/rs.h | 2 +- drivers/net/wireless/intel/iwlwifi/mvm/utils.c | 7 +++---- 5 files changed, 17 insertions(+), 18 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index d1bbafea595a..a0382f9efeb1 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -2953,7 +2953,8 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw, iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL); } - iwl_mvm_rs_rate_init(mvm, sta, mvmvif->phy_ctxt->channel->band); + iwl_mvm_rs_rate_init(mvm, sta, mvmvif->phy_ctxt->channel->band, + false); ret = iwl_mvm_update_sta(mvm, vif, sta); } else if (old_state == IEEE80211_STA_ASSOC && new_state == IEEE80211_STA_AUTHORIZED) { @@ -2969,7 +2970,8 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw, /* enable beacon filtering */ WARN_ON(iwl_mvm_enable_beacon_filter(mvm, vif, 0)); - iwl_mvm_rs_rate_init(mvm, sta, mvmvif->phy_ctxt->channel->band); + iwl_mvm_rs_rate_init(mvm, sta, mvmvif->phy_ctxt->channel->band, + true); ret = 0; } else if (old_state == IEEE80211_STA_AUTHORIZED && diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index 780b920ee619..c6c09d377b1d 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -1708,7 +1708,7 @@ iwl_mvm_vif_dbgfs_clean(struct iwl_mvm *mvm, struct ieee80211_vif *vif) #endif /* CONFIG_IWLWIFI_DEBUGFS */ /* rate scaling */ -int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq, bool init); +int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq, bool sync); void iwl_mvm_update_frame_stats(struct iwl_mvm *mvm, u32 rate, bool agg); int rs_pretty_print_rate(char *buf, int bufsz, const u32 rate); void rs_update_last_rssi(struct iwl_mvm *mvm, diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c index 30cfd7d50bc9..d3e389a99a8a 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c @@ -1276,7 +1276,7 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta, (unsigned long)(lq_sta->last_tx + (IWL_MVM_RS_IDLE_TIMEOUT * HZ)))) { IWL_DEBUG_RATE(mvm, "Tx idle for too long. reinit rs\n"); - iwl_mvm_rs_rate_init(mvm, sta, info->band); + iwl_mvm_rs_rate_init(mvm, sta, info->band, true); return; } lq_sta->last_tx = jiffies; @@ -2859,9 +2859,8 @@ void rs_update_last_rssi(struct iwl_mvm *mvm, static void rs_initialize_lq(struct iwl_mvm *mvm, struct ieee80211_sta *sta, struct iwl_lq_sta *lq_sta, - enum nl80211_band band) + enum nl80211_band band, bool update) { - struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); struct iwl_scale_tbl_info *tbl; struct rs_rate *rate; u8 active_tbl = 0; @@ -2890,8 +2889,7 @@ static void rs_initialize_lq(struct iwl_mvm *mvm, rs_set_expected_tpt_table(lq_sta, tbl); rs_fill_lq_cmd(mvm, sta, lq_sta, rate); /* TODO restore station should remember the lq cmd */ - iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, - mvmsta->sta_state < IEEE80211_STA_AUTHORIZED); + iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, !update); } static void rs_drv_get_rate(void *mvm_r, struct ieee80211_sta *sta, @@ -3144,7 +3142,7 @@ void iwl_mvm_update_frame_stats(struct iwl_mvm *mvm, u32 rate, bool agg) * Called after adding a new station to initialize rate scaling */ static void rs_drv_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, - enum nl80211_band band) + enum nl80211_band band, bool update) { int i, j; struct ieee80211_hw *hw = mvm->hw; @@ -3224,7 +3222,7 @@ static void rs_drv_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, #ifdef CONFIG_IWLWIFI_DEBUGFS iwl_mvm_reset_frame_stats(mvm); #endif - rs_initialize_lq(mvm, sta, lq_sta, band); + rs_initialize_lq(mvm, sta, lq_sta, band, update); } static void rs_drv_rate_update(void *mvm_r, @@ -3244,7 +3242,7 @@ static void rs_drv_rate_update(void *mvm_r, for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++) ieee80211_stop_tx_ba_session(sta, tid); - iwl_mvm_rs_rate_init(mvm, sta, sband->band); + iwl_mvm_rs_rate_init(mvm, sta, sband->band, true); } #ifdef CONFIG_MAC80211_DEBUGFS @@ -4098,12 +4096,12 @@ static const struct rate_control_ops rs_mvm_ops_drv = { }; void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, - enum nl80211_band band) + enum nl80211_band band, bool update) { if (iwl_mvm_has_tlc_offload(mvm)) rs_fw_rate_init(mvm, sta, band); else - rs_drv_rate_init(mvm, sta, band); + rs_drv_rate_init(mvm, sta, band, update); } int iwl_mvm_rate_control_register(void) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.h b/drivers/net/wireless/intel/iwlwifi/mvm/rs.h index d2cf484e2b73..8e7f993e2911 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.h @@ -420,7 +420,7 @@ struct iwl_lq_sta { /* Initialize station's rate scaling information after adding station */ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, - enum nl80211_band band); + enum nl80211_band band, bool init); /* Notify RS about Tx status */ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta, diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c index b002a7afb5f5..6a5349401aa9 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c @@ -900,20 +900,19 @@ int iwl_mvm_disable_txq(struct iwl_mvm *mvm, int queue, int mac80211_queue, /** * iwl_mvm_send_lq_cmd() - Send link quality command - * @init: This command is sent as part of station initialization right - * after station has been added. + * @sync: This command can be sent synchronously. * * The link quality command is sent as the last step of station creation. * This is the special case in which init is set and we call a callback in * this case to clear the state indicating that station creation is in * progress. */ -int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq, bool init) +int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq, bool sync) { struct iwl_host_cmd cmd = { .id = LQ_CMD, .len = { sizeof(struct iwl_lq_cmd), }, - .flags = init ? 0 : CMD_ASYNC, + .flags = sync ? 0 : CMD_ASYNC, .data = { lq, }, }; From e506b481642a9e8d71e82f0facd250a917f24aa1 Mon Sep 17 00:00:00 2001 From: Sara Sharon Date: Mon, 23 Apr 2018 09:38:41 +0300 Subject: [PATCH 053/276] iwlwifi: pcie: set interrupt coalescing also for gen2 We offloaded all the RX configuration of init to firmware. However, the configuration of interrupt coalescing was left hanging - it wasn't offloaded nor was it written by host. This write to the CSR is allowed in gen2, so the host can do it. Without it we have various issues with RX fullness. Signed-off-by: Sara Sharon Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/pcie/rx.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c index 8075466aa4c4..7d9a4e5d4926 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c @@ -1107,6 +1107,9 @@ int iwl_pcie_rx_init(struct iwl_trans *trans) int iwl_pcie_gen2_rx_init(struct iwl_trans *trans) { + /* Set interrupt coalescing timer to default (2048 usecs) */ + iwl_write8(trans, CSR_INT_COALESCING, IWL_HOST_INT_TIMEOUT_DEF); + /* * We don't configure the RFH. * Restock will be done at alive, after firmware configured the RFH. From 754f890a3aef8211903d314cd9e1fbebe30283cc Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Fri, 24 Aug 2018 10:50:45 +0300 Subject: [PATCH 054/276] iwlwifi: remove all occurrences of the FSF address paragraph The Free Software Foundation address is superfluous and causes checkpatch to issue a warning when present. Remove all paragraphs with FSF's address to prevent that. Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/cfg/1000.c | 4 ---- drivers/net/wireless/intel/iwlwifi/cfg/2000.c | 4 ---- drivers/net/wireless/intel/iwlwifi/cfg/5000.c | 4 ---- drivers/net/wireless/intel/iwlwifi/cfg/6000.c | 4 ---- drivers/net/wireless/intel/iwlwifi/cfg/7000.c | 5 ----- drivers/net/wireless/intel/iwlwifi/cfg/8000.c | 5 ----- drivers/net/wireless/intel/iwlwifi/dvm/agn.h | 5 ----- drivers/net/wireless/intel/iwlwifi/dvm/calib.c | 5 ----- drivers/net/wireless/intel/iwlwifi/dvm/calib.h | 5 ----- drivers/net/wireless/intel/iwlwifi/dvm/commands.h | 5 ----- drivers/net/wireless/intel/iwlwifi/dvm/debugfs.c | 5 ----- drivers/net/wireless/intel/iwlwifi/dvm/dev.h | 4 ---- drivers/net/wireless/intel/iwlwifi/dvm/devices.c | 4 ---- drivers/net/wireless/intel/iwlwifi/dvm/led.c | 4 ---- drivers/net/wireless/intel/iwlwifi/dvm/led.h | 4 ---- drivers/net/wireless/intel/iwlwifi/dvm/lib.c | 5 ----- drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c | 4 ---- drivers/net/wireless/intel/iwlwifi/dvm/main.c | 4 ---- drivers/net/wireless/intel/iwlwifi/dvm/power.c | 4 ---- drivers/net/wireless/intel/iwlwifi/dvm/power.h | 4 ---- drivers/net/wireless/intel/iwlwifi/dvm/rs.c | 4 ---- drivers/net/wireless/intel/iwlwifi/dvm/rs.h | 4 ---- drivers/net/wireless/intel/iwlwifi/dvm/rx.c | 4 ---- drivers/net/wireless/intel/iwlwifi/dvm/rxon.c | 4 ---- drivers/net/wireless/intel/iwlwifi/dvm/scan.c | 5 ----- drivers/net/wireless/intel/iwlwifi/dvm/sta.c | 4 ---- drivers/net/wireless/intel/iwlwifi/dvm/tt.c | 4 ---- drivers/net/wireless/intel/iwlwifi/dvm/tt.h | 4 ---- drivers/net/wireless/intel/iwlwifi/dvm/tx.c | 5 ----- drivers/net/wireless/intel/iwlwifi/dvm/ucode.c | 5 ----- drivers/net/wireless/intel/iwlwifi/fw/acpi.c | 3 --- drivers/net/wireless/intel/iwlwifi/fw/acpi.h | 3 --- drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 3 --- drivers/net/wireless/intel/iwlwifi/fw/dbg.h | 3 --- drivers/net/wireless/intel/iwlwifi/fw/debugfs.c | 3 --- drivers/net/wireless/intel/iwlwifi/fw/debugfs.h | 3 --- drivers/net/wireless/intel/iwlwifi/fw/file.h | 5 ----- drivers/net/wireless/intel/iwlwifi/fw/img.h | 5 ----- drivers/net/wireless/intel/iwlwifi/fw/notif-wait.c | 5 ----- drivers/net/wireless/intel/iwlwifi/fw/notif-wait.h | 5 ----- drivers/net/wireless/intel/iwlwifi/iwl-agn-hw.h | 5 ----- drivers/net/wireless/intel/iwlwifi/iwl-config.h | 5 ----- drivers/net/wireless/intel/iwlwifi/iwl-csr.h | 5 ----- drivers/net/wireless/intel/iwlwifi/iwl-debug.c | 5 ----- drivers/net/wireless/intel/iwlwifi/iwl-debug.h | 4 ---- drivers/net/wireless/intel/iwlwifi/iwl-devtrace-io.h | 4 ---- drivers/net/wireless/intel/iwlwifi/iwl-devtrace-msg.h | 4 ---- drivers/net/wireless/intel/iwlwifi/iwl-devtrace-ucode.h | 4 ---- drivers/net/wireless/intel/iwlwifi/iwl-devtrace.c | 4 ---- drivers/net/wireless/intel/iwlwifi/iwl-drv.c | 5 ----- drivers/net/wireless/intel/iwlwifi/iwl-drv.h | 5 ----- drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.c | 3 --- drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.h | 5 ----- drivers/net/wireless/intel/iwlwifi/iwl-eeprom-read.c | 5 ----- drivers/net/wireless/intel/iwlwifi/iwl-eeprom-read.h | 5 ----- drivers/net/wireless/intel/iwlwifi/iwl-fh.h | 3 --- drivers/net/wireless/intel/iwlwifi/iwl-io.c | 4 ---- drivers/net/wireless/intel/iwlwifi/iwl-io.h | 4 ---- drivers/net/wireless/intel/iwlwifi/iwl-modparams.h | 3 --- drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c | 5 ----- drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.h | 5 ----- drivers/net/wireless/intel/iwlwifi/iwl-op-mode.h | 3 --- drivers/net/wireless/intel/iwlwifi/iwl-phy-db.c | 5 ----- drivers/net/wireless/intel/iwlwifi/iwl-phy-db.h | 5 ----- drivers/net/wireless/intel/iwlwifi/iwl-prph.h | 5 ----- drivers/net/wireless/intel/iwlwifi/iwl-scd.h | 5 ----- drivers/net/wireless/intel/iwlwifi/iwl-trans.c | 5 ----- drivers/net/wireless/intel/iwlwifi/iwl-trans.h | 5 ----- drivers/net/wireless/intel/iwlwifi/mvm/binding.c | 5 ----- drivers/net/wireless/intel/iwlwifi/mvm/coex.c | 5 ----- drivers/net/wireless/intel/iwlwifi/mvm/constants.h | 5 ----- drivers/net/wireless/intel/iwlwifi/mvm/debugfs-vif.c | 5 ----- drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c | 5 ----- drivers/net/wireless/intel/iwlwifi/mvm/debugfs.h | 5 ----- drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h | 5 ----- drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 5 ----- drivers/net/wireless/intel/iwlwifi/mvm/led.c | 5 ----- drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c | 5 ----- drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 5 ----- drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 5 ----- drivers/net/wireless/intel/iwlwifi/mvm/nvm.c | 5 ----- drivers/net/wireless/intel/iwlwifi/mvm/offloading.c | 5 ----- drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 5 ----- drivers/net/wireless/intel/iwlwifi/mvm/power.c | 5 ----- drivers/net/wireless/intel/iwlwifi/mvm/quota.c | 5 ----- drivers/net/wireless/intel/iwlwifi/mvm/rx.c | 5 ----- drivers/net/wireless/intel/iwlwifi/mvm/scan.c | 3 --- drivers/net/wireless/intel/iwlwifi/mvm/sf.c | 5 ----- drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 5 ----- drivers/net/wireless/intel/iwlwifi/mvm/tdls.c | 3 --- drivers/net/wireless/intel/iwlwifi/mvm/testmode.h | 5 ----- drivers/net/wireless/intel/iwlwifi/mvm/time-event.h | 5 ----- drivers/net/wireless/intel/iwlwifi/mvm/tof.c | 5 ----- drivers/net/wireless/intel/iwlwifi/mvm/tof.h | 5 ----- drivers/net/wireless/intel/iwlwifi/mvm/tt.c | 5 ----- drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 5 ----- drivers/net/wireless/intel/iwlwifi/mvm/utils.c | 5 ----- drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 5 ----- drivers/net/wireless/intel/iwlwifi/pcie/internal.h | 3 --- drivers/net/wireless/intel/iwlwifi/pcie/rx.c | 3 --- drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 5 ----- drivers/net/wireless/intel/iwlwifi/pcie/tx.c | 4 ---- 102 files changed, 455 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/1000.c b/drivers/net/wireless/intel/iwlwifi/cfg/1000.c index 591687984962..46686ee88ff4 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/1000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/1000.c @@ -12,10 +12,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * * The full GNU General Public License is included in this distribution in the * file called LICENSE. * diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/2000.c b/drivers/net/wireless/intel/iwlwifi/cfg/2000.c index fedb108db68f..e7e45846dd07 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/2000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/2000.c @@ -12,10 +12,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * * The full GNU General Public License is included in this distribution in the * file called LICENSE. * diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/5000.c b/drivers/net/wireless/intel/iwlwifi/cfg/5000.c index 36151e61a26f..575a7022d045 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/5000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/5000.c @@ -12,10 +12,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * * The full GNU General Public License is included in this distribution in the * file called LICENSE. * diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/6000.c b/drivers/net/wireless/intel/iwlwifi/cfg/6000.c index b5d8274761d8..30e62a7c9d52 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/6000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/6000.c @@ -12,10 +12,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * * The full GNU General Public License is included in this distribution in the * file called LICENSE. * diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/7000.c b/drivers/net/wireless/intel/iwlwifi/cfg/7000.c index a62c8346f13a..c973bfaa3414 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/7000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/7000.c @@ -19,11 +19,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/8000.c b/drivers/net/wireless/intel/iwlwifi/cfg/8000.c index c46fa712985b..348c40fcddcb 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/8000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/8000.c @@ -19,11 +19,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/agn.h b/drivers/net/wireless/intel/iwlwifi/dvm/agn.h index b79e38734f2f..431e13c6ee35 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/agn.h +++ b/drivers/net/wireless/intel/iwlwifi/dvm/agn.h @@ -16,11 +16,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/calib.c b/drivers/net/wireless/intel/iwlwifi/dvm/calib.c index c96f9b1d948a..588b15697710 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/calib.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/calib.c @@ -16,11 +16,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/calib.h b/drivers/net/wireless/intel/iwlwifi/dvm/calib.h index 099e3ce80ffc..c43ba94bfa8b 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/calib.h +++ b/drivers/net/wireless/intel/iwlwifi/dvm/calib.h @@ -16,11 +16,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/commands.h b/drivers/net/wireless/intel/iwlwifi/dvm/commands.h index f89736d60a3d..0f4be4be181c 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/commands.h +++ b/drivers/net/wireless/intel/iwlwifi/dvm/commands.h @@ -16,11 +16,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/debugfs.c b/drivers/net/wireless/intel/iwlwifi/dvm/debugfs.c index 096a07c5a33f..3d2e44a642de 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/debugfs.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/debugfs.c @@ -13,11 +13,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/dev.h b/drivers/net/wireless/intel/iwlwifi/dvm/dev.h index cceb4cd8e501..c5b8376d827f 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/dev.h +++ b/drivers/net/wireless/intel/iwlwifi/dvm/dev.h @@ -11,10 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * * The full GNU General Public License is included in this distribution in the * file called LICENSE. * diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/devices.c b/drivers/net/wireless/intel/iwlwifi/dvm/devices.c index f21732ec3b25..3dd7d8c45dab 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/devices.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/devices.c @@ -11,10 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * * The full GNU General Public License is included in this distribution in the * file called LICENSE. * diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/led.c b/drivers/net/wireless/intel/iwlwifi/dvm/led.c index 1bbd17ada974..04c236e9399b 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/led.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/led.c @@ -11,10 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * * The full GNU General Public License is included in this distribution in the * file called LICENSE. * diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/led.h b/drivers/net/wireless/intel/iwlwifi/dvm/led.h index 75f74edd018f..8f93a3246dee 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/led.h +++ b/drivers/net/wireless/intel/iwlwifi/dvm/led.h @@ -11,10 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * * The full GNU General Public License is included in this distribution in the * file called LICENSE. * diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/lib.c b/drivers/net/wireless/intel/iwlwifi/dvm/lib.c index 2b6ffbc46fa5..b2f172d4f78a 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/lib.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/lib.c @@ -13,11 +13,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c index 82caae02dd09..49b71dbf8490 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c @@ -14,10 +14,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * * The full GNU General Public License is included in this distribution in the * file called LICENSE. * diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/main.c b/drivers/net/wireless/intel/iwlwifi/dvm/main.c index 030482b357a3..1ef072071b0b 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/main.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/main.c @@ -15,10 +15,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * * The full GNU General Public License is included in this distribution in the * file called LICENSE. * diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/power.c b/drivers/net/wireless/intel/iwlwifi/dvm/power.c index 0ad557c89514..8c25e3aefb2b 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/power.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/power.c @@ -14,10 +14,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * * The full GNU General Public License is included in this distribution in the * file called LICENSE. * diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/power.h b/drivers/net/wireless/intel/iwlwifi/dvm/power.h index 2fd9b43adafd..a04fd4d375c6 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/power.h +++ b/drivers/net/wireless/intel/iwlwifi/dvm/power.h @@ -14,10 +14,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * * The full GNU General Public License is included in this distribution in the * file called LICENSE. * diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/rs.c b/drivers/net/wireless/intel/iwlwifi/dvm/rs.c index 98050d7be411..ef4b9de256f7 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/rs.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/rs.c @@ -11,10 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * * The full GNU General Public License is included in this distribution in the * file called LICENSE. * diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/rs.h b/drivers/net/wireless/intel/iwlwifi/dvm/rs.h index 50c1e951dd2d..b2df3a8cc464 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/rs.h +++ b/drivers/net/wireless/intel/iwlwifi/dvm/rs.h @@ -11,10 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * * The full GNU General Public License is included in this distribution in the * file called LICENSE. * diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/rx.c b/drivers/net/wireless/intel/iwlwifi/dvm/rx.c index c942830af2b5..6f17a5e24e82 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/rx.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/rx.c @@ -15,10 +15,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * * The full GNU General Public License is included in this distribution in the * file called LICENSE. * diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/rxon.c b/drivers/net/wireless/intel/iwlwifi/dvm/rxon.c index 8f3e5586eda9..eee1d48d453a 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/rxon.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/rxon.c @@ -12,10 +12,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * * The full GNU General Public License is included in this distribution in the * file called LICENSE. * diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/scan.c b/drivers/net/wireless/intel/iwlwifi/dvm/scan.c index 17e6a32384d3..8d7aafb4d9e9 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/scan.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/scan.c @@ -13,11 +13,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/sta.c b/drivers/net/wireless/intel/iwlwifi/dvm/sta.c index de6ec9b7ace4..b1792de09594 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/sta.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/sta.c @@ -14,10 +14,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * * The full GNU General Public License is included in this distribution in the * file called LICENSE. * diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/tt.c b/drivers/net/wireless/intel/iwlwifi/dvm/tt.c index 6524533d723c..4de2727ac63e 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/tt.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/tt.c @@ -14,10 +14,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * * The full GNU General Public License is included in this distribution in the * file called LICENSE. * diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/tt.h b/drivers/net/wireless/intel/iwlwifi/dvm/tt.h index d324e9be9cbf..6388c09603c6 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/tt.h +++ b/drivers/net/wireless/intel/iwlwifi/dvm/tt.h @@ -14,10 +14,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * * The full GNU General Public License is included in this distribution in the * file called LICENSE. * diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/tx.c b/drivers/net/wireless/intel/iwlwifi/dvm/tx.c index fb40ddfced99..4ff323a3a4e5 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/tx.c @@ -13,11 +13,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/ucode.c b/drivers/net/wireless/intel/iwlwifi/dvm/ucode.c index d6013bfe991c..3bf57085b976 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/ucode.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/ucode.c @@ -14,11 +14,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c index 75cae54ea7de..32d000cffe9f 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c @@ -16,9 +16,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/fw/acpi.h b/drivers/net/wireless/intel/iwlwifi/fw/acpi.h index cb5f32c1d705..2439e98431ee 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/acpi.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/acpi.h @@ -16,9 +16,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index 9c1d13e6bad3..37b1e1f13621 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -19,9 +19,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h index 2c6df7756927..5eba0e7ca760 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h @@ -19,9 +19,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c b/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c index c1f087c50cc9..1049bdfe1e69 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c @@ -19,9 +19,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program. - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/fw/debugfs.h b/drivers/net/wireless/intel/iwlwifi/fw/debugfs.h index cbbfa8e9e66d..88255035e8ef 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/debugfs.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/debugfs.h @@ -18,9 +18,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program. - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/fw/file.h b/drivers/net/wireless/intel/iwlwifi/fw/file.h index 7638d0bb1e11..858af103e6fd 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/file.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/file.h @@ -19,11 +19,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/fw/img.h b/drivers/net/wireless/intel/iwlwifi/fw/img.h index 0861b97c4233..9cc8fe8908ac 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/img.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/img.h @@ -19,11 +19,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/fw/notif-wait.c b/drivers/net/wireless/intel/iwlwifi/fw/notif-wait.c index 1096c945a68b..379735e086dc 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/notif-wait.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/notif-wait.c @@ -17,11 +17,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/fw/notif-wait.h b/drivers/net/wireless/intel/iwlwifi/fw/notif-wait.h index 368884be4e7c..61b067eeeac9 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/notif-wait.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/notif-wait.h @@ -17,11 +17,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-agn-hw.h b/drivers/net/wireless/intel/iwlwifi/iwl-agn-hw.h index ee9347a54cdc..359537620c93 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-agn-hw.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-agn-hw.h @@ -16,11 +16,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h b/drivers/net/wireless/intel/iwlwifi/iwl-config.h index 4d16ac545269..5e1280783376 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h @@ -18,11 +18,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-csr.h b/drivers/net/wireless/intel/iwlwifi/iwl-csr.h index e2b29b844c3a..caa5806acd81 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-csr.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-csr.h @@ -19,11 +19,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-debug.c b/drivers/net/wireless/intel/iwlwifi/iwl-debug.c index b1c3b0d0fcc6..e1a41fd503a8 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-debug.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-debug.c @@ -16,11 +16,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-debug.h b/drivers/net/wireless/intel/iwlwifi/iwl-debug.h index c023fcf5d452..a2af68a0d34b 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-debug.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-debug.h @@ -13,10 +13,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * * The full GNU General Public License is included in this distribution in the * file called LICENSE. * diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-io.h b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-io.h index 4164dc1745ed..7bb4e0e9bb69 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-io.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-io.h @@ -12,10 +12,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * * The full GNU General Public License is included in this distribution in the * file called LICENSE. * diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-msg.h b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-msg.h index 5dfc9295a7e0..32984c1f39a1 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-msg.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-msg.h @@ -11,10 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * * The full GNU General Public License is included in this distribution in the * file called LICENSE. * diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-ucode.h b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-ucode.h index e9b8673dd245..53842226ef1b 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-ucode.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-ucode.h @@ -11,10 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * * The full GNU General Public License is included in this distribution in the * file called LICENSE. * diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.c b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.c index 6aa719865a58..27b4dd409a0e 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.c @@ -11,10 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * * The full GNU General Public License is included in this distribution in the * file called LICENSE. * diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c index 39a1eadfc4b7..76f50b99af2a 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c @@ -18,11 +18,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.h b/drivers/net/wireless/intel/iwlwifi/iwl-drv.h index 1f8a2eeb7dff..2be30af7bdc3 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.h @@ -17,11 +17,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.c b/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.c index a4c96215933b..2fee4392be7f 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.c @@ -18,9 +18,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.h b/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.h index 8be50ed12300..d910bda087f7 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.h @@ -17,11 +17,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-read.c b/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-read.c index ac965c34a2f8..a6db6a814257 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-read.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-read.c @@ -17,11 +17,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-read.h b/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-read.h index 1ed78be06c23..47fced159800 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-read.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-read.h @@ -16,11 +16,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-fh.h b/drivers/net/wireless/intel/iwlwifi/iwl-fh.h index 4f7254303853..c6a534303936 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-fh.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-fh.h @@ -18,9 +18,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program. - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-io.c b/drivers/net/wireless/intel/iwlwifi/iwl-io.c index efb1998dcabd..4f10914f6048 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-io.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-io.c @@ -14,10 +14,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * * The full GNU General Public License is included in this distribution in the * file called LICENSE. * diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-io.h b/drivers/net/wireless/intel/iwlwifi/iwl-io.h index 5c8c0e130194..38085850a2d3 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-io.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-io.h @@ -13,10 +13,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * * The full GNU General Public License is included in this distribution in the * file called LICENSE. * diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-modparams.h b/drivers/net/wireless/intel/iwlwifi/iwl-modparams.h index 97072cf75bca..6fc8dac4aab7 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-modparams.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-modparams.h @@ -17,9 +17,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c index b4c3a957c102..137dedc844ad 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c @@ -19,11 +19,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.h b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.h index 234d1009a9de..b7e1ddf8f177 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.h @@ -18,11 +18,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-op-mode.h b/drivers/net/wireless/intel/iwlwifi/iwl-op-mode.h index cbbdede2e01b..cbd1a8eed620 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-op-mode.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-op-mode.h @@ -19,9 +19,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program. - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-phy-db.c b/drivers/net/wireless/intel/iwlwifi/iwl-phy-db.c index b7cd813ba70f..ae83cfdb750e 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-phy-db.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-phy-db.c @@ -17,11 +17,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-phy-db.h b/drivers/net/wireless/intel/iwlwifi/iwl-phy-db.h index d34de3f71db6..7020dca05221 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-phy-db.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-phy-db.h @@ -16,11 +16,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-prph.h b/drivers/net/wireless/intel/iwlwifi/iwl-prph.h index 421a869633a3..0f51c7bea8d0 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-prph.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-prph.h @@ -18,11 +18,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-scd.h b/drivers/net/wireless/intel/iwlwifi/iwl-scd.h index 99b43da32adf..9f11f3912816 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-scd.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-scd.h @@ -16,11 +16,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.c b/drivers/net/wireless/intel/iwlwifi/iwl-trans.c index 7e9c924e1220..727f73e0b3f1 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.c @@ -17,11 +17,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h index dbac9ac80ce9..0a6c8759b911 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h @@ -18,11 +18,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/binding.c b/drivers/net/wireless/intel/iwlwifi/mvm/binding.c index 75d35f6b041e..4094a4158032 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/binding.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/binding.c @@ -17,11 +17,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/coex.c b/drivers/net/wireless/intel/iwlwifi/mvm/coex.c index 9707f455086b..ec3b60cdcf18 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/coex.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/coex.c @@ -17,11 +17,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/constants.h b/drivers/net/wireless/intel/iwlwifi/mvm/constants.h index d61ff66ce07b..d96ada3c06fc 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/constants.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/constants.h @@ -18,11 +18,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs-vif.c b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs-vif.c index 798605c4f122..1aa6c7e93088 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs-vif.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs-vif.c @@ -18,11 +18,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c index 05b77419953c..202158d03d36 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c @@ -19,11 +19,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.h b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.h index ede6ef8d390e..a83d252c0602 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.h @@ -17,11 +17,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h index e8e74dd558f7..143c7fcaea41 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h @@ -18,11 +18,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c index 878dc29c2010..96d26b749952 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c @@ -19,11 +19,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/led.c b/drivers/net/wireless/intel/iwlwifi/mvm/led.c index b27269504a62..9bb1de1cad64 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/led.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/led.c @@ -17,11 +17,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c index 6a38a3ee4db0..56871aff1698 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c @@ -19,11 +19,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index a0382f9efeb1..134bb9fd21a4 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -19,11 +19,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index c6c09d377b1d..087e8a454ac2 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -19,11 +19,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c b/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c index cf48517944ec..fff98fed35ed 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c @@ -19,11 +19,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/offloading.c b/drivers/net/wireless/intel/iwlwifi/mvm/offloading.c index 6338d9cf7070..6d71e05626ad 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/offloading.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/offloading.c @@ -18,11 +18,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index da1aafb71298..e2463e8e486b 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -19,11 +19,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/power.c b/drivers/net/wireless/intel/iwlwifi/mvm/power.c index c11fe2621d51..5a0a28fd762d 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/power.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/power.c @@ -18,11 +18,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/quota.c b/drivers/net/wireless/intel/iwlwifi/mvm/quota.c index 690559bdf421..5e62b97af48b 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/quota.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/quota.c @@ -18,11 +18,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rx.c b/drivers/net/wireless/intel/iwlwifi/mvm/rx.c index bfb163419c67..a050220da678 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rx.c @@ -18,11 +18,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c index 8a89989f59fd..003bf0848386 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c @@ -19,9 +19,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sf.c b/drivers/net/wireless/intel/iwlwifi/mvm/sf.c index 539b06bf0803..d1d76bb9a750 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/sf.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/sf.c @@ -17,11 +17,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c index 18db1ed92d9b..6ebc715d90df 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c @@ -19,11 +19,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tdls.c b/drivers/net/wireless/intel/iwlwifi/mvm/tdls.c index 67f360c0d17e..e02f4eb20359 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tdls.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tdls.c @@ -18,9 +18,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program. - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/testmode.h b/drivers/net/wireless/intel/iwlwifi/mvm/testmode.h index cbbc16fd006a..ff82af11de8d 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/testmode.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/testmode.h @@ -17,11 +17,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/time-event.h b/drivers/net/wireless/intel/iwlwifi/mvm/time-event.h index 3d2e8b6159bb..1dd3d01245ea 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/time-event.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/time-event.h @@ -17,11 +17,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tof.c b/drivers/net/wireless/intel/iwlwifi/mvm/tof.c index 2d0b8a391308..01e0a999063b 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tof.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tof.c @@ -16,11 +16,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tof.h b/drivers/net/wireless/intel/iwlwifi/mvm/tof.h index 2ff560aa1a82..8138d0606c52 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tof.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tof.h @@ -16,11 +16,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tt.c b/drivers/net/wireless/intel/iwlwifi/mvm/tt.c index 1232f63278eb..0b3e5c99d316 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tt.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tt.c @@ -18,11 +18,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c index b33b8357a8f7..c99b79d686d0 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c @@ -19,11 +19,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c index 6a5349401aa9..f5a9e4026094 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c @@ -19,11 +19,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c index b150da4c6721..0d40864ac90f 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -19,11 +19,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h index 1089e6b216aa..a7896fcc44cf 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h +++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h @@ -17,9 +17,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program. - * * The full GNU General Public License is included in this distribution in the * file called LICENSE. * diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c index 7d9a4e5d4926..d519e7ebdbe8 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c @@ -17,9 +17,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program. - * * The full GNU General Public License is included in this distribution in the * file called LICENSE. * diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index 2a20999d4c15..8925b10217d7 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -19,11 +19,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * * The full GNU General Public License is included in this distribution * in the file called COPYING. * diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c index b89e976ecfcd..5091cd567b63 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c @@ -17,10 +17,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * * The full GNU General Public License is included in this distribution in the * file called LICENSE. * From dabf9844385885e50c05a08ebc312d46017eb261 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 26 Apr 2018 13:14:26 +0200 Subject: [PATCH 055/276] iwlwifi: mvm: implement extended HE-MU sniffer API Implement the extended HE-MU info type decoding to show the HE-SIG-B common contents in the HE-MU radiotap field. The DW4 data is partially overwritten by the hardware in all cases, so only the higher 16 bits can be used. To be able to use it for the HE SIG-B common data anyway, move the bits around in the following way: SIG-B common 0: DW 4 -> DW 7 SIG-B common 1: DW 7 -> DW 8 SIG-B common 2: DW 8 -> DW 4 (upper half) Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/fw/api/rx.h | 117 +++++++++++---- drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 140 ++++++++++++++---- 2 files changed, 206 insertions(+), 51 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h b/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h index 2ba1401e5c0d..e966679a964e 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h @@ -373,7 +373,33 @@ enum iwl_rx_he_phy { /* 1 bit reserved */ IWL_RX_HE_PHY_SIGB_DCM = BIT_ULL(32 + 21), IWL_RX_HE_PHY_PREAMBLE_PUNC_TYPE_MASK = 0xc0000000000000ULL, - /* 8 bits reserved */ + /* 4 bits reserved */ + IWL_RX_HE_PHY_INFO_TYPE_MASK = 0xf000000000000000ULL, + IWL_RX_HE_PHY_INFO_TYPE_SU = 0x0, + IWL_RX_HE_PHY_INFO_TYPE_MU = 0x1, + IWL_RX_HE_PHY_INFO_TYPE_MU_EXT_INFO = 0x2, +}; + +enum iwl_rx_he_sigb_common0 { + /* the a1/a2/... is what the PHY/firmware calls the values */ + IWL_RX_HE_SIGB_COMMON0_CH1_RU0 = 0x000000ff, /* a1 */ + IWL_RX_HE_SIGB_COMMON0_CH1_RU2 = 0x0000ff00, /* a2 */ + IWL_RX_HE_SIGB_COMMON0_CH2_RU0 = 0x00ff0000, /* b1 */ + IWL_RX_HE_SIGB_COMMON0_CH2_RU2 = 0xff000000, /* b2 */ +}; + +enum iwl_rx_he_sigb_common1 { + IWL_RX_HE_SIGB_COMMON1_CH1_RU1 = 0x000000ff, /* c1 */ + IWL_RX_HE_SIGB_COMMON1_CH1_RU3 = 0x0000ff00, /* c2 */ + IWL_RX_HE_SIGB_COMMON1_CH2_RU1 = 0x00ff0000, /* d1 */ + IWL_RX_HE_SIGB_COMMON1_CH2_RU3 = 0xff000000, /* d2 */ +}; + +enum iwl_rx_he_sigb_common2 { + IWL_RX_HE_SIGB_COMMON2_CH1_CTR_RU = 0x0001, + IWL_RX_HE_SIGB_COMMON2_CH2_CTR_RU = 0x0002, + IWL_RX_HE_SIGB_COMMON2_CH1_CRC_OK = 0x0004, + IWL_RX_HE_SIGB_COMMON2_CH2_CRC_OK = 0x0008, }; /** @@ -381,15 +407,31 @@ enum iwl_rx_he_phy { */ struct iwl_rx_mpdu_desc_v1 { /* DW7 - carries rss_hash only when rpa_en == 1 */ - /** - * @rss_hash: RSS hash value - */ - __le32 rss_hash; + union { + /** + * @rss_hash: RSS hash value + */ + __le32 rss_hash; + + /** + * @sigb_common0: for HE sniffer, HE-SIG-B common part 0 + */ + __le32 sigb_common0; + }; + /* DW8 - carries filter_match only when rpa_en == 1 */ - /** - * @filter_match: filter match value - */ - __le32 filter_match; + union { + /** + * @filter_match: filter match value + */ + __le32 filter_match; + + /** + * @sigb_common1: for HE sniffer, HE-SIG-B common part 1 + */ + __le32 sigb_common1; + }; + /* DW9 */ /** * @rate_n_flags: RX rate/flags encoding @@ -439,15 +481,30 @@ struct iwl_rx_mpdu_desc_v1 { */ struct iwl_rx_mpdu_desc_v3 { /* DW7 - carries filter_match only when rpa_en == 1 */ - /** - * @filter_match: filter match value - */ - __le32 filter_match; + union { + /** + * @filter_match: filter match value + */ + __le32 filter_match; + + /** + * @sigb_common0: for HE sniffer, HE-SIG-B common part 0 + */ + __le32 sigb_common0; + }; + /* DW8 - carries rss_hash only when rpa_en == 1 */ - /** - * @rss_hash: RSS hash value - */ - __le32 rss_hash; + union { + /** + * @rss_hash: RSS hash value + */ + __le32 rss_hash; + + /** + * @sigb_common1: for HE sniffer, HE-SIG-B common part 1 + */ + __le32 sigb_common1; + }; /* DW9 */ /** * @partial_hash: 31:0 ip/tcp header hash @@ -539,14 +596,24 @@ struct iwl_rx_mpdu_desc { */ u8 mac_phy_idx; /* DW4 - carries csum data only when rpa_en == 1 */ - /** - * @raw_csum: raw checksum (alledgedly unreliable) - */ - __le16 raw_csum; - /** - * @l3l4_flags: &enum iwl_rx_l3l4_flags - */ - __le16 l3l4_flags; + struct { + /** + * @raw_csum: raw checksum (alledgedly unreliable) + */ + __le16 raw_csum; + + union { + /** + * @l3l4_flags: &enum iwl_rx_l3l4_flags + */ + __le16 l3l4_flags; + + /** + * @sigb_common2: for HE sniffer, HE-SIG-B common part 2 + */ + __le16 sigb_common2; + }; + }; /* DW5 */ /** * @status: &enum iwl_rx_mpdu_status diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c index a5e3a47f4a98..fd66ea7c4b66 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c @@ -856,6 +856,64 @@ static void iwl_mvm_flip_address(u8 *addr) ether_addr_copy(addr, mac_addr); } +static void iwl_mvm_decode_he_sigb(struct iwl_mvm *mvm, + struct iwl_rx_mpdu_desc *desc, + struct ieee80211_radiotap_he_mu *he_mu) +{ + u32 sigb0, sigb1; + u16 sigb2; + + if (mvm->trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) { + sigb0 = le32_to_cpu(desc->v3.sigb_common0); + sigb1 = le32_to_cpu(desc->v3.sigb_common1); + } else { + sigb0 = le32_to_cpu(desc->v1.sigb_common0); + sigb1 = le32_to_cpu(desc->v1.sigb_common1); + } + + sigb2 = le16_to_cpu(desc->sigb_common2); + + if (FIELD_GET(IWL_RX_HE_SIGB_COMMON2_CH1_CRC_OK, sigb2)) { + he_mu->flags1 |= + cpu_to_le16(IEEE80211_RADIOTAP_HE_MU_FLAGS1_CH1_RU_KNOWN | + IEEE80211_RADIOTAP_HE_MU_FLAGS1_CH1_CTR_26T_RU_KNOWN); + + he_mu->flags1 |= + le16_encode_bits(FIELD_GET(IWL_RX_HE_SIGB_COMMON2_CH1_CTR_RU, + sigb2), + IEEE80211_RADIOTAP_HE_MU_FLAGS1_CH1_CTR_26T_RU); + + he_mu->ru_ch1[0] = FIELD_GET(IWL_RX_HE_SIGB_COMMON0_CH1_RU0, + sigb0); + he_mu->ru_ch1[1] = FIELD_GET(IWL_RX_HE_SIGB_COMMON1_CH1_RU1, + sigb1); + he_mu->ru_ch1[2] = FIELD_GET(IWL_RX_HE_SIGB_COMMON0_CH1_RU2, + sigb0); + he_mu->ru_ch1[3] = FIELD_GET(IWL_RX_HE_SIGB_COMMON1_CH1_RU3, + sigb1); + } + + if (FIELD_GET(IWL_RX_HE_SIGB_COMMON2_CH2_CRC_OK, sigb2)) { + he_mu->flags1 |= + cpu_to_le16(IEEE80211_RADIOTAP_HE_MU_FLAGS1_CH2_RU_KNOWN | + IEEE80211_RADIOTAP_HE_MU_FLAGS1_CH2_CTR_26T_RU_KNOWN); + + he_mu->flags2 |= + le16_encode_bits(FIELD_GET(IWL_RX_HE_SIGB_COMMON2_CH2_CTR_RU, + sigb2), + IEEE80211_RADIOTAP_HE_MU_FLAGS2_CH2_CTR_26T_RU); + + he_mu->ru_ch2[0] = FIELD_GET(IWL_RX_HE_SIGB_COMMON0_CH2_RU0, + sigb0); + he_mu->ru_ch2[1] = FIELD_GET(IWL_RX_HE_SIGB_COMMON1_CH2_RU1, + sigb1); + he_mu->ru_ch2[2] = FIELD_GET(IWL_RX_HE_SIGB_COMMON0_CH2_RU2, + sigb0); + he_mu->ru_ch2[3] = FIELD_GET(IWL_RX_HE_SIGB_COMMON1_CH2_RU3, + sigb1); + } +} + static void iwl_mvm_rx_he(struct iwl_mvm *mvm, struct sk_buff *skb, struct iwl_rx_mpdu_desc *desc, u32 rate_n_flags, u16 phy_info, int queue) @@ -882,10 +940,12 @@ static void iwl_mvm_rx_he(struct iwl_mvm *mvm, struct sk_buff *skb, IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_DCM_KNOWN | IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_SYMS_USERS_KNOWN | IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_COMP_KNOWN), - .flags2 = cpu_to_le16(IEEE80211_RADIOTAP_HE_MU_FLAGS2_PUNC_FROM_SIG_A_BW_KNOWN), + .flags2 = cpu_to_le16(IEEE80211_RADIOTAP_HE_MU_FLAGS2_PUNC_FROM_SIG_A_BW_KNOWN | + IEEE80211_RADIOTAP_HE_MU_FLAGS2_BW_FROM_SIG_A_BW_KNOWN), }; unsigned int radiotap_len = 0; bool overload = phy_info & IWL_RX_MPDU_PHY_TSF_OVERLOAD; + bool sigb_data = false; he = skb_put_data(skb, &known, sizeof(known)); radiotap_len += sizeof(known); @@ -943,17 +1003,26 @@ static void iwl_mvm_rx_he(struct iwl_mvm *mvm, struct sk_buff *skb, IEEE80211_RADIOTAP_HE_MU_FLAGS2_SIG_B_COMP); he_mu->flags2 |= le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_PREAMBLE_PUNC_TYPE_MASK, - he_phy_data), + he_phy_data), IEEE80211_RADIOTAP_HE_MU_FLAGS2_PUNC_FROM_SIG_A_BW); - } - if (he_phy_data != HE_PHY_DATA_INVAL) { - he->data1 |= - cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_BSS_COLOR_KNOWN); - he->data3 |= - le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_BSS_COLOR_MASK, - he_phy_data), - IEEE80211_RADIOTAP_HE_DATA3_BSS_COLOR); + sigb_data = FIELD_GET(IWL_RX_HE_PHY_INFO_TYPE_MASK, + he_phy_data) == + IWL_RX_HE_PHY_INFO_TYPE_MU_EXT_INFO; + if (sigb_data) + iwl_mvm_decode_he_sigb(mvm, desc, he_mu); + } + if (he_phy_data != HE_PHY_DATA_INVAL && + (he_type == RATE_MCS_HE_TYPE_SU || + he_type == RATE_MCS_HE_TYPE_MU)) { + u8 bss_color = FIELD_GET(IWL_RX_HE_PHY_BSS_COLOR_MASK, + he_phy_data); + + if (bss_color) { + he->data1 |= + cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_BSS_COLOR_KNOWN); + he->data3 |= cpu_to_le16(bss_color); + } } /* update aggregation data for monitor sake on default queue */ @@ -977,6 +1046,7 @@ static void iwl_mvm_rx_he(struct iwl_mvm *mvm, struct sk_buff *skb, rx_status->bw = RATE_INFO_BW_HE_RU; rx_status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_106; } + if (he_mu) { /* * Unfortunately, we have to leave the mac80211 data @@ -992,6 +1062,9 @@ static void iwl_mvm_rx_he(struct iwl_mvm *mvm, struct sk_buff *skb, rx_status->bw = RATE_INFO_BW_HE_RU; + he->data1 |= + cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_BW_RU_ALLOC_KNOWN); + switch (ru) { case 0 ... 36: rx_status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_26; @@ -1025,10 +1098,24 @@ static void iwl_mvm_rx_he(struct iwl_mvm *mvm, struct sk_buff *skb, IEEE80211_RADIOTAP_HE_DATA2_RU_OFFSET); he->data2 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_PRISEC_80_KNOWN); - if (he_phy_data & IWL_RX_HE_PHY_RU_ALLOC_SEC80) + if (he_phy_data & IWL_RX_HE_PHY_RU_ALLOC_SEC80) { he->data2 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_PRISEC_80_SEC); - } else { + +#define CHECK_BW(bw) \ + BUILD_BUG_ON(IEEE80211_RADIOTAP_HE_MU_FLAGS2_BW_FROM_SIG_A_BW_ ## bw ## MHZ != \ + RATE_MCS_CHAN_WIDTH_##bw >> RATE_MCS_CHAN_WIDTH_POS) + CHECK_BW(20); + CHECK_BW(40); + CHECK_BW(80); + CHECK_BW(160); + he_mu->flags2 |= + le16_encode_bits(FIELD_GET(RATE_MCS_CHAN_WIDTH_MSK, + rate_n_flags), + IEEE80211_RADIOTAP_HE_MU_FLAGS2_BW_FROM_SIG_A_BW); + } + } else if (he_type == RATE_MCS_HE_TYPE_SU || + he_type == RATE_MCS_HE_TYPE_EXT_SU) { he->data1 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_BW_RU_ALLOC_KNOWN); } @@ -1195,6 +1282,21 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, rx_status = IEEE80211_SKB_RXCB(skb); + /* This may be overridden by iwl_mvm_rx_he() to HE_RU */ + switch (rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK) { + case RATE_MCS_CHAN_WIDTH_20: + break; + case RATE_MCS_CHAN_WIDTH_40: + rx_status->bw = RATE_INFO_BW_40; + break; + case RATE_MCS_CHAN_WIDTH_80: + rx_status->bw = RATE_INFO_BW_80; + break; + case RATE_MCS_CHAN_WIDTH_160: + rx_status->bw = RATE_INFO_BW_160; + break; + } + if (rate_n_flags & RATE_MCS_HE_MSK) iwl_mvm_rx_he(mvm, skb, desc, rate_n_flags, phy_info, queue); @@ -1366,20 +1468,6 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, } } - switch (rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK) { - case RATE_MCS_CHAN_WIDTH_20: - break; - case RATE_MCS_CHAN_WIDTH_40: - rx_status->bw = RATE_INFO_BW_40; - break; - case RATE_MCS_CHAN_WIDTH_80: - rx_status->bw = RATE_INFO_BW_80; - break; - case RATE_MCS_CHAN_WIDTH_160: - rx_status->bw = RATE_INFO_BW_160; - break; - } - if (!(rate_n_flags & RATE_MCS_CCK_MSK) && rate_n_flags & RATE_MCS_SGI_MSK) rx_status->enc_flags |= RX_ENC_FLAG_SHORT_GI; From de8da23060843b07ad291ad3bdea173b58d86a3d Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 2 May 2018 11:20:00 +0200 Subject: [PATCH 056/276] iwlwifi: mvm: put LTF symbol size into HE radiotap I evidently completely confused "number of LTF symbols" and "LTF size". Radiotap was reporting the former, while I thought it was the latter, and we really need both. Add the LTF symbol size into the newly defined field in radiotap. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c index fd66ea7c4b66..f644bcf7e048 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c @@ -925,7 +925,7 @@ static void iwl_mvm_rx_he(struct iwl_mvm *mvm, struct sk_buff *skb, struct ieee80211_radiotap_he *he = NULL; struct ieee80211_radiotap_he_mu *he_mu = NULL; u32 he_type = 0xffffffff; - u8 stbc; + u8 stbc, ltf; static const struct ieee80211_radiotap_he known = { .data1 = cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_DATA_MCS_KNOWN | @@ -1151,21 +1151,33 @@ static void iwl_mvm_rx_he(struct iwl_mvm *mvm, struct sk_buff *skb, RATE_MCS_HE_GI_LTF_POS) { case 0: rx_status->he_gi = NL80211_RATE_INFO_HE_GI_0_8; + if (he_type == RATE_MCS_HE_TYPE_MU) + ltf = IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE_4X; + else + ltf = IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE_1X; break; case 1: rx_status->he_gi = NL80211_RATE_INFO_HE_GI_0_8; + ltf = IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE_2X; break; case 2: rx_status->he_gi = NL80211_RATE_INFO_HE_GI_1_6; + if (he_type == RATE_MCS_HE_TYPE_TRIG) + ltf = IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE_4X; + else + ltf = IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE_2X; break; case 3: if (rate_n_flags & RATE_MCS_SGI_MSK) rx_status->he_gi = NL80211_RATE_INFO_HE_GI_0_8; else rx_status->he_gi = NL80211_RATE_INFO_HE_GI_3_2; + ltf = IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE_4X; break; } + he->data5 |= le16_encode_bits(ltf, IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE); + switch (he_type) { case RATE_MCS_HE_TYPE_SU: { u16 val; From 93cc712a7993194c5682978d46f859b8d288ed53 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 2 May 2018 22:53:34 +0200 Subject: [PATCH 057/276] iwlwifi: mvm: properly decode HE GI duration The GI duration depends on the frame type in some cases, take that into account when decoding for radiotap. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c index f644bcf7e048..314012ed7a29 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c @@ -1150,25 +1150,35 @@ static void iwl_mvm_rx_he(struct iwl_mvm *mvm, struct sk_buff *skb, switch ((rate_n_flags & RATE_MCS_HE_GI_LTF_MSK) >> RATE_MCS_HE_GI_LTF_POS) { case 0: - rx_status->he_gi = NL80211_RATE_INFO_HE_GI_0_8; + if (he_type == RATE_MCS_HE_TYPE_TRIG) + rx_status->he_gi = NL80211_RATE_INFO_HE_GI_1_6; + else + rx_status->he_gi = NL80211_RATE_INFO_HE_GI_0_8; if (he_type == RATE_MCS_HE_TYPE_MU) ltf = IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE_4X; else ltf = IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE_1X; break; case 1: - rx_status->he_gi = NL80211_RATE_INFO_HE_GI_0_8; + if (he_type == RATE_MCS_HE_TYPE_TRIG) + rx_status->he_gi = NL80211_RATE_INFO_HE_GI_1_6; + else + rx_status->he_gi = NL80211_RATE_INFO_HE_GI_0_8; ltf = IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE_2X; break; case 2: - rx_status->he_gi = NL80211_RATE_INFO_HE_GI_1_6; - if (he_type == RATE_MCS_HE_TYPE_TRIG) + if (he_type == RATE_MCS_HE_TYPE_TRIG) { + rx_status->he_gi = NL80211_RATE_INFO_HE_GI_3_2; ltf = IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE_4X; - else + } else { + rx_status->he_gi = NL80211_RATE_INFO_HE_GI_1_6; ltf = IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE_2X; + } break; case 3: - if (rate_n_flags & RATE_MCS_SGI_MSK) + if ((he_type == RATE_MCS_HE_TYPE_SU || + he_type == RATE_MCS_HE_TYPE_EXT_SU) && + rate_n_flags & RATE_MCS_SGI_MSK) rx_status->he_gi = NL80211_RATE_INFO_HE_GI_0_8; else rx_status->he_gi = NL80211_RATE_INFO_HE_GI_3_2; From 925bc2b189ec05a2993d3870f4c9c7edaf60d088 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 3 May 2018 12:52:16 +0200 Subject: [PATCH 058/276] iwlwifi: mvm: report # of LTF symbols for extended range SU PPDUs This is the same as for SU PPDUs, so it's easy to do. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c index 314012ed7a29..05ce253b8c30 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c @@ -1189,7 +1189,8 @@ static void iwl_mvm_rx_he(struct iwl_mvm *mvm, struct sk_buff *skb, he->data5 |= le16_encode_bits(ltf, IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE); switch (he_type) { - case RATE_MCS_HE_TYPE_SU: { + case RATE_MCS_HE_TYPE_SU: + case RATE_MCS_HE_TYPE_EXT_SU: { u16 val; /* LTF syms correspond to streams */ @@ -1241,7 +1242,6 @@ static void iwl_mvm_rx_he(struct iwl_mvm *mvm, struct sk_buff *skb, val)); } break; - case RATE_MCS_HE_TYPE_EXT_SU: case RATE_MCS_HE_TYPE_TRIG: /* not supported */ break; From 317bc55fa82fbb7f1fe20170e50e0553af1bd69c Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 3 May 2018 13:35:08 +0200 Subject: [PATCH 059/276] iwlwifi: mvm: remove channel 2 from HE radiotap if not applicable If the bandwidth is only 20 MHz, then the second channel doesn't exist, but the hardware reports the CRC was OK. Suppress the data of the second channel in the HE radiotap in this case, by marking it as not known. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c index 05ce253b8c30..2eae657b16b6 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c @@ -858,6 +858,7 @@ static void iwl_mvm_flip_address(u8 *addr) static void iwl_mvm_decode_he_sigb(struct iwl_mvm *mvm, struct iwl_rx_mpdu_desc *desc, + u32 rate_n_flags, struct ieee80211_radiotap_he_mu *he_mu) { u32 sigb0, sigb1; @@ -893,7 +894,8 @@ static void iwl_mvm_decode_he_sigb(struct iwl_mvm *mvm, sigb1); } - if (FIELD_GET(IWL_RX_HE_SIGB_COMMON2_CH2_CRC_OK, sigb2)) { + if (FIELD_GET(IWL_RX_HE_SIGB_COMMON2_CH2_CRC_OK, sigb2) && + (rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK) != RATE_MCS_CHAN_WIDTH_20) { he_mu->flags1 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_MU_FLAGS1_CH2_RU_KNOWN | IEEE80211_RADIOTAP_HE_MU_FLAGS1_CH2_CTR_26T_RU_KNOWN); @@ -1010,7 +1012,7 @@ static void iwl_mvm_rx_he(struct iwl_mvm *mvm, struct sk_buff *skb, he_phy_data) == IWL_RX_HE_PHY_INFO_TYPE_MU_EXT_INFO; if (sigb_data) - iwl_mvm_decode_he_sigb(mvm, desc, he_mu); + iwl_mvm_decode_he_sigb(mvm, desc, rate_n_flags, he_mu); } if (he_phy_data != HE_PHY_DATA_INVAL && (he_type == RATE_MCS_HE_TYPE_SU || From 06c34dee07c7de4f679267321c914db4b3c2a56f Mon Sep 17 00:00:00 2001 From: Ido Yariv Date: Mon, 30 Apr 2018 21:21:19 -0400 Subject: [PATCH 060/276] iwlwifi: Add missing 11n disable module parameter check In the new method of parsing the NVM the disable_11n module parameter isn't consulted when setting up HT capabilities. Fix this. Signed-off-by: Ido Yariv Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.c b/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.c index 2fee4392be7f..4e3422a1c7bb 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.c @@ -742,7 +742,9 @@ void iwl_init_ht_hw_capab(const struct iwl_cfg *cfg, else rx_chains = hweight8(rx_chains); - if (!(data->sku_cap_11n_enable) || !cfg->ht_params) { + if (!(data->sku_cap_11n_enable) || + (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_ALL) || + !cfg->ht_params) { ht_info->ht_supported = false; return; } From 65c3b582ecab7a403efdf08babbf87fdbe27369c Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Mon, 7 May 2018 16:46:35 +0300 Subject: [PATCH 061/276] iwlwifi: mvm: send BCAST management frames to the right station Probe responses were sent to the multicast station while they should be routed to the broadcast station. This has no negative effect since the frame was still routed to the right queue, but it looked very fishy to send a frame to a (queue, station) tuple where 'queue' is not mapped to 'station'. Fixes: 7c305de2b954 ("iwlwifi: mvm: Direct multicast frames to the correct station") Signed-off-by: Emmanuel Grumbach Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c index c99b79d686d0..ffc0ad1eef15 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c @@ -730,7 +730,7 @@ int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct sk_buff *skb) if (info.control.vif->type == NL80211_IFTYPE_P2P_DEVICE || info.control.vif->type == NL80211_IFTYPE_AP || info.control.vif->type == NL80211_IFTYPE_ADHOC) { - if (info.control.vif->type == NL80211_IFTYPE_P2P_DEVICE) + if (!ieee80211_is_data(hdr->frame_control)) sta_id = mvmvif->bcast_sta.sta_id; else sta_id = mvmvif->mcast_sta.sta_id; From 2859de7637b541dc7191f4d3fce4a1adba80fb3e Mon Sep 17 00:00:00 2001 From: Naftali Goldstein Date: Thu, 10 May 2018 20:32:36 +0300 Subject: [PATCH 062/276] iwlwifi: mvm: always init rs_fw with 20MHz bandwidth rates As with the non-offloaded rs case, during assoc on the ap side the phy context is set to 20MHz until authorization of a client that supports wider channel-widths. Support this by sending the initial tlc_config_cmd with max supported channel width of 20MHz until authorization succeeds. Fixes: 6b7a5aea71b3 ("iwlwifi: mvm: always init rs with 20mhz bandwidth rates") Signed-off-by: Naftali Goldstein Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c | 5 +++-- drivers/net/wireless/intel/iwlwifi/mvm/rs.c | 2 +- drivers/net/wireless/intel/iwlwifi/mvm/rs.h | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c index 8169d1450b3b..1a7a158890cb 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c @@ -311,7 +311,7 @@ void iwl_mvm_tlc_update_notif(struct iwl_mvm *mvm, } void rs_fw_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, - enum nl80211_band band) + enum nl80211_band band, bool update) { struct ieee80211_hw *hw = mvm->hw; struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); @@ -320,7 +320,8 @@ void rs_fw_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, struct ieee80211_supported_band *sband; struct iwl_tlc_config_cmd cfg_cmd = { .sta_id = mvmsta->sta_id, - .max_ch_width = rs_fw_bw_from_sta_bw(sta), + .max_ch_width = update ? + rs_fw_bw_from_sta_bw(sta) : RATE_MCS_CHAN_WIDTH_20, .flags = cpu_to_le16(rs_fw_set_config_flags(mvm, sta)), .chains = rs_fw_set_active_chains(iwl_mvm_get_valid_tx_ant(mvm)), .max_mpdu_len = cpu_to_le16(sta->max_amsdu_len), diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c index d3e389a99a8a..c3282f1d77ba 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c @@ -4099,7 +4099,7 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, enum nl80211_band band, bool update) { if (iwl_mvm_has_tlc_offload(mvm)) - rs_fw_rate_init(mvm, sta, band); + rs_fw_rate_init(mvm, sta, band, update); else rs_drv_rate_init(mvm, sta, band, update); } diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.h b/drivers/net/wireless/intel/iwlwifi/mvm/rs.h index 8e7f993e2911..d0f47899f284 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.h @@ -461,7 +461,7 @@ void rs_remove_sta_debugfs(void *mvm, void *mvm_sta); void iwl_mvm_rs_add_sta(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta); void rs_fw_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, - enum nl80211_band band); + enum nl80211_band band, bool update); int rs_fw_tx_protection(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta, bool enable); void iwl_mvm_tlc_update_notif(struct iwl_mvm *mvm, From c5f97542aa06bd6ef34a87f0c8bcb924899cf861 Mon Sep 17 00:00:00 2001 From: Shahar S Matityahu Date: Thu, 3 May 2018 09:41:11 +0300 Subject: [PATCH 063/276] iwlwifi: change monitor DMA to be coherent Allow access to the memory by the host and the device simultaneously. This will be needed in some future patches. Signed-off-by: Shahar S Matityahu Signed-off-by: Luca Coelho --- .../wireless/intel/iwlwifi/pcie/internal.h | 4 +- .../net/wireless/intel/iwlwifi/pcie/trans.c | 62 ++++++------------- 2 files changed, 21 insertions(+), 45 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h index a7896fcc44cf..98d8da03ccfc 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h +++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h @@ -464,7 +464,7 @@ struct iwl_self_init_dram { * @mutex: to protect stop_device / start_fw / start_hw * @cmd_in_flight: true when we have a host command in flight * @fw_mon_phys: physical address of the buffer for the firmware monitor - * @fw_mon_page: points to the first page of the buffer for the firmware monitor + * @fw_mon_cpu_addr: address of the buffer for the firmware monitor * @fw_mon_size: size of the buffer for the firmware monitor * @msix_entries: array of MSI-X entries * @msix_enabled: true if managed to enable MSI-X @@ -554,7 +554,7 @@ struct iwl_trans_pcie { bool ref_cmd_in_flight; dma_addr_t fw_mon_phys; - struct page *fw_mon_page; + void *fw_mon_cpu_addr; u32 fw_mon_size; struct msix_entry msix_entries[IWL_MAX_RX_HW_QUEUES]; diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index 8925b10217d7..d8aca7291614 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -187,14 +187,13 @@ static void iwl_pcie_free_fw_monitor(struct iwl_trans *trans) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - if (!trans_pcie->fw_mon_page) + if (!trans_pcie->fw_mon_cpu_addr) return; - dma_unmap_page(trans->dev, trans_pcie->fw_mon_phys, - trans_pcie->fw_mon_size, DMA_FROM_DEVICE); - __free_pages(trans_pcie->fw_mon_page, - get_order(trans_pcie->fw_mon_size)); - trans_pcie->fw_mon_page = NULL; + dma_free_coherent(trans->dev, trans_pcie->fw_mon_size, + trans_pcie->fw_mon_cpu_addr, + trans_pcie->fw_mon_phys); + trans_pcie->fw_mon_cpu_addr = NULL; trans_pcie->fw_mon_phys = 0; trans_pcie->fw_mon_size = 0; } @@ -202,7 +201,7 @@ static void iwl_pcie_free_fw_monitor(struct iwl_trans *trans) void iwl_pcie_alloc_fw_monitor(struct iwl_trans *trans, u8 max_power) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - struct page *page = NULL; + void *cpu_addr = NULL; dma_addr_t phys; u32 size = 0; u8 power; @@ -219,38 +218,25 @@ void iwl_pcie_alloc_fw_monitor(struct iwl_trans *trans, u8 max_power) max_power)) return; - if (trans_pcie->fw_mon_page) { - dma_sync_single_for_device(trans->dev, trans_pcie->fw_mon_phys, - trans_pcie->fw_mon_size, - DMA_FROM_DEVICE); + if (trans_pcie->fw_mon_cpu_addr) return; - } phys = 0; for (power = max_power; power >= 11; power--) { - int order; - size = BIT(power); - order = get_order(size); - page = alloc_pages(__GFP_COMP | __GFP_NOWARN | __GFP_ZERO, - order); - if (!page) + cpu_addr = dma_alloc_coherent(trans->dev, size, &phys, + GFP_KERNEL | __GFP_NOWARN | + __GFP_ZERO | __GFP_COMP); + if (!cpu_addr) continue; - phys = dma_map_page(trans->dev, page, 0, PAGE_SIZE << order, - DMA_FROM_DEVICE); - if (dma_mapping_error(trans->dev, phys)) { - __free_pages(page, order); - page = NULL; - continue; - } IWL_INFO(trans, - "Allocated 0x%08x bytes (order %d) for firmware monitor.\n", - size, order); + "Allocated 0x%08x bytes for firmware monitor.\n", + size); break; } - if (WARN_ON_ONCE(!page)) + if (WARN_ON_ONCE(!cpu_addr)) return; if (power != max_power) @@ -259,7 +245,7 @@ void iwl_pcie_alloc_fw_monitor(struct iwl_trans *trans, u8 max_power) (unsigned long)BIT(power - 10), (unsigned long)BIT(max_power - 10)); - trans_pcie->fw_mon_page = page; + trans_pcie->fw_mon_cpu_addr = cpu_addr; trans_pcie->fw_mon_phys = phys; trans_pcie->fw_mon_size = size; } @@ -2863,7 +2849,7 @@ iwl_trans_pcie_dump_monitor(struct iwl_trans *trans, struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); u32 len = 0; - if ((trans_pcie->fw_mon_page && + if ((trans_pcie->fw_mon_cpu_addr && trans->cfg->device_family == IWL_DEVICE_FAMILY_7000) || trans->dbg_dest_tlv) { struct iwl_fw_error_dump_fw_mon *fw_mon_data; @@ -2891,19 +2877,9 @@ iwl_trans_pcie_dump_monitor(struct iwl_trans *trans, cpu_to_le32(iwl_read_prph(trans, base)); len += sizeof(**data) + sizeof(*fw_mon_data); - if (trans_pcie->fw_mon_page) { - /* - * The firmware is now asserted, it won't write anything - * to the buffer. CPU can take ownership to fetch the - * data. The buffer will be handed back to the device - * before the firmware will be restarted. - */ - dma_sync_single_for_cpu(trans->dev, - trans_pcie->fw_mon_phys, - trans_pcie->fw_mon_size, - DMA_FROM_DEVICE); + if (trans_pcie->fw_mon_cpu_addr) { memcpy(fw_mon_data->data, - page_address(trans_pcie->fw_mon_page), + trans_pcie->fw_mon_cpu_addr, trans_pcie->fw_mon_size); monitor_len = trans_pcie->fw_mon_size; @@ -2966,7 +2942,7 @@ static struct iwl_trans_dump_data cmdq->n_window * (sizeof(*txcmd) + TFD_MAX_PAYLOAD_SIZE); /* FW monitor */ - if (trans_pcie->fw_mon_page) { + if (trans_pcie->fw_mon_cpu_addr) { len += sizeof(*data) + sizeof(struct iwl_fw_error_dump_fw_mon) + trans_pcie->fw_mon_size; monitor_len = trans_pcie->fw_mon_size; From ae17404e38601856036836a8082ad57102dd097e Mon Sep 17 00:00:00 2001 From: Shahar S Matityahu Date: Thu, 3 May 2018 09:52:12 +0300 Subject: [PATCH 064/276] iwlwifi: avoid code duplication in stopping fw debug data recording Make all FW debug data stop recording flows to use iwl_fw_dbg_stop_recording function instead of writing to FW registers directly. Signed-off-by: Shahar S Matityahu Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 4 ++-- drivers/net/wireless/intel/iwlwifi/fw/dbg.h | 10 +++++----- drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 2 +- drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c | 5 ++--- drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 8 +------- 5 files changed, 11 insertions(+), 18 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index 37b1e1f13621..3435a83e4d18 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -1197,7 +1197,7 @@ void iwl_fw_error_dump_wk(struct work_struct *work) if (fwrt->trans->cfg->device_family == IWL_DEVICE_FAMILY_7000) { /* stop recording */ - iwl_fw_dbg_stop_recording(fwrt); + iwl_fw_dbg_stop_recording(fwrt->trans); iwl_fw_error_dump(fwrt); @@ -1215,7 +1215,7 @@ void iwl_fw_error_dump_wk(struct work_struct *work) u32 in_sample = iwl_read_prph(fwrt->trans, DBGC_IN_SAMPLE); u32 out_ctrl = iwl_read_prph(fwrt->trans, DBGC_OUT_CTRL); - iwl_fw_dbg_stop_recording(fwrt); + iwl_fw_dbg_stop_recording(fwrt->trans); /* wait before we collect the data till the DBGC stop */ udelay(500); diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h index 5eba0e7ca760..d04e68104ded 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h @@ -196,14 +196,14 @@ _iwl_fw_dbg_trigger_simple_stop(struct iwl_fw_runtime *fwrt, iwl_fw_dbg_get_trigger((fwrt)->fw,\ (trig))) -static inline void iwl_fw_dbg_stop_recording(struct iwl_fw_runtime *fwrt) +static inline void iwl_fw_dbg_stop_recording(struct iwl_trans *trans) { - if (fwrt->trans->cfg->device_family == IWL_DEVICE_FAMILY_7000) { - iwl_set_bits_prph(fwrt->trans, MON_BUFF_SAMPLE_CTL, 0x100); + if (trans->cfg->device_family == IWL_DEVICE_FAMILY_7000) { + iwl_set_bits_prph(trans, MON_BUFF_SAMPLE_CTL, 0x100); } else { - iwl_write_prph(fwrt->trans, DBGC_IN_SAMPLE, 0); + iwl_write_prph(trans, DBGC_IN_SAMPLE, 0); udelay(100); - iwl_write_prph(fwrt->trans, DBGC_OUT_CTRL, 0); + iwl_write_prph(trans, DBGC_OUT_CTRL, 0); } } diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c index 58531dd40c45..99050c8dd432 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c @@ -1042,7 +1042,7 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw, * the recording automatically before entering D3. This can * be removed once the FW starts doing that. */ - iwl_fw_dbg_stop_recording(&mvm->fwrt); + iwl_fw_dbg_stop_recording(mvm->fwrt.trans); /* must be last -- this switches firmware state */ ret = iwl_mvm_send_cmd(mvm, &d3_cfg_cmd); diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c index 9b2a248e88b0..5f61b02e651e 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c @@ -55,6 +55,7 @@ #include "iwl-context-info.h" #include "iwl-context-info-gen3.h" #include "internal.h" +#include "fw/dbg.h" /* * Start up NIC's basic functionality after it has been reset @@ -164,9 +165,7 @@ void _iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans, bool low_power) trans_pcie->is_down = true; /* Stop dbgc before stopping device */ - iwl_write_prph(trans, DBGC_IN_SAMPLE, 0); - udelay(100); - iwl_write_prph(trans, DBGC_OUT_CTRL, 0); + iwl_fw_dbg_stop_recording(trans); /* tell the device to stop sending interrupts */ iwl_disable_interrupts(trans); diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index d8aca7291614..cc8c53dc0ab6 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -1243,13 +1243,7 @@ static void _iwl_trans_pcie_stop_device(struct iwl_trans *trans, bool low_power) trans_pcie->is_down = true; /* Stop dbgc before stopping device */ - if (trans->cfg->device_family == IWL_DEVICE_FAMILY_7000) { - iwl_set_bits_prph(trans, MON_BUFF_SAMPLE_CTL, 0x100); - } else { - iwl_write_prph(trans, DBGC_IN_SAMPLE, 0); - udelay(100); - iwl_write_prph(trans, DBGC_OUT_CTRL, 0); - } + iwl_fw_dbg_stop_recording(trans); /* tell the device to stop sending interrupts */ iwl_disable_interrupts(trans); From 3e467b8e4cf4d56244f92b1fb26a25e405e7d3aa Mon Sep 17 00:00:00 2001 From: Naftali Goldstein Date: Tue, 1 May 2018 14:36:23 +0300 Subject: [PATCH 065/276] iwlwifi: rs-fw: enable STBC in he correctly In the HE phy capabilities IE there are 2 bits to signal support for STBC in bandwidths of 80Mhz or less, and of 160Mhz. Use these bits to determine STBC support if this IE exists. Signed-off-by: Naftali Goldstein Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/fw/api/rs.h | 10 +++++++--- .../net/wireless/intel/iwlwifi/mvm/rs-fw.c | 20 +++++++++++++++---- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/rs.h b/drivers/net/wireless/intel/iwlwifi/fw/api/rs.h index fe2763cfc3b5..955f2c3718e5 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/rs.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/rs.h @@ -66,12 +66,16 @@ /** * enum iwl_tlc_mng_cfg_flags_enum - options for TLC config flags - * @IWL_TLC_MNG_CFG_FLAGS_STBC_MSK: enable STBC + * @IWL_TLC_MNG_CFG_FLAGS_STBC_MSK: enable STBC. For HE this enables STBC for + * bandwidths <= 80MHz * @IWL_TLC_MNG_CFG_FLAGS_LDPC_MSK: enable LDPC + * @IWL_TLC_MNG_CFG_FLAGS_HE_STBC_160MHZ_MSK: enable STBC in HE at 160MHz + * bandwidth */ enum iwl_tlc_mng_cfg_flags { - IWL_TLC_MNG_CFG_FLAGS_STBC_MSK = BIT(0), - IWL_TLC_MNG_CFG_FLAGS_LDPC_MSK = BIT(1), + IWL_TLC_MNG_CFG_FLAGS_STBC_MSK = BIT(0), + IWL_TLC_MNG_CFG_FLAGS_LDPC_MSK = BIT(1), + IWL_TLC_MNG_CFG_FLAGS_HE_STBC_160MHZ_MSK = BIT(2), }; /** diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c index 1a7a158890cb..f00ff466ec1b 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c @@ -117,14 +117,26 @@ static u16 rs_fw_set_config_flags(struct iwl_mvm *mvm, { struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap; + struct ieee80211_sta_he_cap *he_cap = &sta->he_cap; bool vht_ena = vht_cap && vht_cap->vht_supported; u16 flags = 0; if (mvm->cfg->ht_params->stbc && - (num_of_ant(iwl_mvm_get_valid_tx_ant(mvm)) > 1) && - ((ht_cap && (ht_cap->cap & IEEE80211_HT_CAP_RX_STBC)) || - (vht_ena && (vht_cap->cap & IEEE80211_VHT_CAP_RXSTBC_MASK)))) - flags |= IWL_TLC_MNG_CFG_FLAGS_STBC_MSK; + (num_of_ant(iwl_mvm_get_valid_tx_ant(mvm)) > 1)) { + if (he_cap && he_cap->has_he) { + if (he_cap->he_cap_elem.phy_cap_info[2] & + IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ) + flags |= IWL_TLC_MNG_CFG_FLAGS_STBC_MSK; + + if (he_cap->he_cap_elem.phy_cap_info[7] & + IEEE80211_HE_PHY_CAP7_STBC_RX_ABOVE_80MHZ) + flags |= IWL_TLC_MNG_CFG_FLAGS_HE_STBC_160MHZ_MSK; + } else if ((ht_cap && + (ht_cap->cap & IEEE80211_HT_CAP_RX_STBC)) || + (vht_ena && + (vht_cap->cap & IEEE80211_VHT_CAP_RXSTBC_MASK))) + flags |= IWL_TLC_MNG_CFG_FLAGS_STBC_MSK; + } if (mvm->cfg->ht_params->ldpc && ((ht_cap && (ht_cap->cap & IEEE80211_HT_CAP_LDPC_CODING)) || From 423584dd8060a6d7e1b2fb71ad11025a64aa0bec Mon Sep 17 00:00:00 2001 From: Naftali Goldstein Date: Tue, 1 May 2018 14:40:44 +0300 Subject: [PATCH 066/276] iwlwifi: rs-fw: support dcm Add flags to the tlc_cfg_cmd for signaling peer support for receiving Dual Carrier Modulation at BPSK (MCS 0), and set them according to peer capabilities. Signed-off-by: Naftali Goldstein Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/api/rs.h | 8 ++++++++ drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c | 10 ++++++++++ 2 files changed, 18 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/rs.h b/drivers/net/wireless/intel/iwlwifi/fw/api/rs.h index 955f2c3718e5..9eddc4dc2ae6 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/rs.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/rs.h @@ -71,11 +71,19 @@ * @IWL_TLC_MNG_CFG_FLAGS_LDPC_MSK: enable LDPC * @IWL_TLC_MNG_CFG_FLAGS_HE_STBC_160MHZ_MSK: enable STBC in HE at 160MHz * bandwidth + * @IWL_TLC_MNG_CFG_FLAGS_HE_DCM_NSS_1_MSK: enable HE Dual Carrier Modulation + * for BPSK (MCS 0) with 1 spatial + * stream + * @IWL_TLC_MNG_CFG_FLAGS_HE_DCM_NSS_2_MSK: enable HE Dual Carrier Modulation + * for BPSK (MCS 0) with 2 spatial + * streams */ enum iwl_tlc_mng_cfg_flags { IWL_TLC_MNG_CFG_FLAGS_STBC_MSK = BIT(0), IWL_TLC_MNG_CFG_FLAGS_LDPC_MSK = BIT(1), IWL_TLC_MNG_CFG_FLAGS_HE_STBC_160MHZ_MSK = BIT(2), + IWL_TLC_MNG_CFG_FLAGS_HE_DCM_NSS_1_MSK = BIT(3), + IWL_TLC_MNG_CFG_FLAGS_HE_DCM_NSS_2_MSK = BIT(4), }; /** diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c index f00ff466ec1b..7a98e1a1dc40 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c @@ -143,6 +143,16 @@ static u16 rs_fw_set_config_flags(struct iwl_mvm *mvm, (vht_ena && (vht_cap->cap & IEEE80211_VHT_CAP_RXLDPC)))) flags |= IWL_TLC_MNG_CFG_FLAGS_LDPC_MSK; + if (he_cap && he_cap->has_he && + (he_cap->he_cap_elem.phy_cap_info[3] & + IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_TX_MASK)) { + flags |= IWL_TLC_MNG_CFG_FLAGS_HE_DCM_NSS_1_MSK; + + if (he_cap->he_cap_elem.phy_cap_info[3] & + IEEE80211_HE_PHY_CAP3_DCM_MAX_TX_NSS_2) + flags |= IWL_TLC_MNG_CFG_FLAGS_HE_DCM_NSS_2_MSK; + } + return flags; } From 764f9de5027149518b1633e5846b21b9fb882363 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 9 May 2018 11:53:04 +0200 Subject: [PATCH 067/276] iwlwifi: mvm: decode HE TB PPDU data Decode the HE TB PPDU data that we get in sniffer mode and use it to populate the HE radiotap information. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/fw/api/rx.h | 21 ++++++---- drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 38 ++++++++++--------- 2 files changed, 34 insertions(+), 25 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h b/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h index e966679a964e..2078ef425f8c 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h @@ -362,22 +362,27 @@ enum iwl_rx_he_phy { /* 6 bits reserved */ IWL_RX_HE_PHY_DELIM_EOF = BIT(31), - /* second dword - MU data */ - IWL_RX_HE_PHY_SIGB_COMPRESSION = BIT_ULL(32 + 0), - IWL_RX_HE_PHY_SIBG_SYM_OR_USER_NUM_MASK = 0x1e00000000ULL, + /* second dword - common data */ IWL_RX_HE_PHY_HE_LTF_NUM_MASK = 0xe000000000ULL, IWL_RX_HE_PHY_RU_ALLOC_SEC80 = BIT_ULL(32 + 8), /* trigger encoded */ IWL_RX_HE_PHY_RU_ALLOC_MASK = 0xfe0000000000ULL, - IWL_RX_HE_PHY_SIGB_MCS_MASK = 0xf000000000000ULL, - /* 1 bit reserved */ - IWL_RX_HE_PHY_SIGB_DCM = BIT_ULL(32 + 21), - IWL_RX_HE_PHY_PREAMBLE_PUNC_TYPE_MASK = 0xc0000000000000ULL, - /* 4 bits reserved */ IWL_RX_HE_PHY_INFO_TYPE_MASK = 0xf000000000000000ULL, IWL_RX_HE_PHY_INFO_TYPE_SU = 0x0, IWL_RX_HE_PHY_INFO_TYPE_MU = 0x1, IWL_RX_HE_PHY_INFO_TYPE_MU_EXT_INFO = 0x2, + IWL_RX_HE_PHY_INFO_TYPE_TB_EXT_INFO = 0x3, + + /* second dword - MU data */ + IWL_RX_HE_PHY_MU_SIGB_COMPRESSION = BIT_ULL(32 + 0), + IWL_RX_HE_PHY_MU_SIBG_SYM_OR_USER_NUM_MASK = 0x1e00000000ULL, + IWL_RX_HE_PHY_MU_SIGB_MCS_MASK = 0xf000000000000ULL, + IWL_RX_HE_PHY_MU_SIGB_DCM = BIT_ULL(32 + 21), + IWL_RX_HE_PHY_MU_PREAMBLE_PUNC_TYPE_MASK = 0xc0000000000000ULL, + + /* second dword - TB data */ + IWL_RX_HE_PHY_TB_PILOT_TYPE = BIT_ULL(32 + 0), + IWL_RX_HE_PHY_TB_LOW_SS_MASK = 0xe00000000ULL }; enum iwl_rx_he_sigb_common0 { diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c index 2eae657b16b6..f415c72394ee 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c @@ -988,23 +988,23 @@ static void iwl_mvm_rx_he(struct iwl_mvm *mvm, struct sk_buff *skb, } } else if (overload && he_mu && he_phy_data != HE_PHY_DATA_INVAL) { he_mu->flags1 |= - le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_SIBG_SYM_OR_USER_NUM_MASK, - he_phy_data), + le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_MU_SIBG_SYM_OR_USER_NUM_MASK, + he_phy_data), IEEE80211_RADIOTAP_HE_MU_FLAGS2_SIG_B_SYMS_USERS); he_mu->flags1 |= - le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_SIGB_DCM, - he_phy_data), + le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_MU_SIGB_DCM, + he_phy_data), IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_DCM); he_mu->flags1 |= - le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_SIGB_MCS_MASK, - he_phy_data), + le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_MU_SIGB_MCS_MASK, + he_phy_data), IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_MCS); he_mu->flags2 |= - le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_SIGB_COMPRESSION, - he_phy_data), + le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_MU_SIGB_COMPRESSION, + he_phy_data), IEEE80211_RADIOTAP_HE_MU_FLAGS2_SIG_B_COMP); he_mu->flags2 |= - le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_PREAMBLE_PUNC_TYPE_MASK, + le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_MU_PREAMBLE_PUNC_TYPE_MASK, he_phy_data), IEEE80211_RADIOTAP_HE_MU_FLAGS2_PUNC_FROM_SIG_A_BW); @@ -1049,15 +1049,18 @@ static void iwl_mvm_rx_he(struct iwl_mvm *mvm, struct sk_buff *skb, rx_status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_106; } - if (he_mu) { + if (he_phy_data != HE_PHY_DATA_INVAL && + (FIELD_GET(IWL_RX_HE_PHY_INFO_TYPE_MASK, he_phy_data) == + IWL_RX_HE_PHY_INFO_TYPE_MU_EXT_INFO || + FIELD_GET(IWL_RX_HE_PHY_INFO_TYPE_MASK, he_phy_data) == + IWL_RX_HE_PHY_INFO_TYPE_TB_EXT_INFO)) { /* * Unfortunately, we have to leave the mac80211 data * incorrect for the case that we receive an HE-MU - * transmission and *don't* have the he_mu pointer, - * i.e. we don't have the phy data (due to the bits - * being used for TSF). This shouldn't happen though - * as management frames where we need the TSF/timers - * are not be transmitted in HE-MU, I think. + * transmission and *don't* have the HE phy data (due + * to the bits being used for TSF). This shouldn't + * happen though as management frames where we need + * the TSF/timers are not be transmitted in HE-MU. */ u8 ru = FIELD_GET(IWL_RX_HE_PHY_RU_ALLOC_MASK, he_phy_data); u8 offs = 0; @@ -1100,10 +1103,11 @@ static void iwl_mvm_rx_he(struct iwl_mvm *mvm, struct sk_buff *skb, IEEE80211_RADIOTAP_HE_DATA2_RU_OFFSET); he->data2 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_PRISEC_80_KNOWN); - if (he_phy_data & IWL_RX_HE_PHY_RU_ALLOC_SEC80) { + if (he_phy_data & IWL_RX_HE_PHY_RU_ALLOC_SEC80) he->data2 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_PRISEC_80_SEC); + if (he_mu) { #define CHECK_BW(bw) \ BUILD_BUG_ON(IEEE80211_RADIOTAP_HE_MU_FLAGS2_BW_FROM_SIG_A_BW_ ## bw ## MHZ != \ RATE_MCS_CHAN_WIDTH_##bw >> RATE_MCS_CHAN_WIDTH_POS) @@ -1111,7 +1115,7 @@ static void iwl_mvm_rx_he(struct iwl_mvm *mvm, struct sk_buff *skb, CHECK_BW(40); CHECK_BW(80); CHECK_BW(160); - he_mu->flags2 |= + he->data2 |= le16_encode_bits(FIELD_GET(RATE_MCS_CHAN_WIDTH_MSK, rate_n_flags), IEEE80211_RADIOTAP_HE_MU_FLAGS2_BW_FROM_SIG_A_BW); From 1169310fa9a8d8a1fc94e406643444cac30ad8b1 Mon Sep 17 00:00:00 2001 From: Golan Ben Ami Date: Tue, 3 Apr 2018 18:37:51 +0300 Subject: [PATCH 068/276] iwlwifi: refactor txq_alloc for supporting more command type Support more txq_alloc command types by moving the command declaration to the gen specific area. While at it, move some of the code segments to a common place for re-use. Signed-off-by: Golan Ben Ami Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/iwl-trans.h | 7 +- .../net/wireless/intel/iwlwifi/mvm/utils.c | 14 +-- .../wireless/intel/iwlwifi/pcie/internal.h | 10 +- .../net/wireless/intel/iwlwifi/pcie/tx-gen2.c | 91 +++++++++++++------ 4 files changed, 82 insertions(+), 40 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h index 0a6c8759b911..388793b89856 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h @@ -562,7 +562,7 @@ struct iwl_trans_ops { bool configure_scd); /* 22000 functions */ int (*txq_alloc)(struct iwl_trans *trans, - struct iwl_tx_queue_cfg_cmd *cmd, + __le16 flags, u8 sta_id, u8 tid, int cmd_id, int size, unsigned int queue_wdg_timeout); void (*txq_free)(struct iwl_trans *trans, int queue); @@ -970,7 +970,7 @@ iwl_trans_txq_free(struct iwl_trans *trans, int queue) static inline int iwl_trans_txq_alloc(struct iwl_trans *trans, - struct iwl_tx_queue_cfg_cmd *cmd, + __le16 flags, u8 sta_id, u8 tid, int cmd_id, int size, unsigned int wdg_timeout) { @@ -984,7 +984,8 @@ iwl_trans_txq_alloc(struct iwl_trans *trans, return -EIO; } - return trans->ops->txq_alloc(trans, cmd, cmd_id, size, wdg_timeout); + return trans->ops->txq_alloc(trans, flags, sta_id, tid, + cmd_id, size, wdg_timeout); } static inline void iwl_trans_txq_set_shared_mode(struct iwl_trans *trans, diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c index f5a9e4026094..99a872769e90 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c @@ -720,19 +720,15 @@ static bool iwl_mvm_update_txq_mapping(struct iwl_mvm *mvm, int queue, int iwl_mvm_tvqm_enable_txq(struct iwl_mvm *mvm, int mac80211_queue, u8 sta_id, u8 tid, unsigned int timeout) { - struct iwl_tx_queue_cfg_cmd cmd = { - .flags = cpu_to_le16(TX_QUEUE_CFG_ENABLE_QUEUE), - .sta_id = sta_id, - .tid = tid, - }; int queue, size = IWL_DEFAULT_QUEUE_SIZE; - if (cmd.tid == IWL_MAX_TID_COUNT) { - cmd.tid = IWL_MGMT_TID; + if (tid == IWL_MAX_TID_COUNT) { + tid = IWL_MGMT_TID; size = IWL_MGMT_QUEUE_SIZE; } - queue = iwl_trans_txq_alloc(mvm->trans, (void *)&cmd, - SCD_QUEUE_CFG, size, timeout); + queue = iwl_trans_txq_alloc(mvm->trans, + cpu_to_le16(TX_QUEUE_CFG_ENABLE_QUEUE), + sta_id, tid, SCD_QUEUE_CFG, size, timeout); if (queue < 0) { IWL_DEBUG_TX_QUEUES(mvm, diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h index 98d8da03ccfc..769b7354fabe 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h +++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h @@ -1036,8 +1036,16 @@ void iwl_pcie_alloc_fw_monitor(struct iwl_trans *trans, u8 max_power); int iwl_trans_pcie_gen2_start_fw(struct iwl_trans *trans, const struct fw_img *fw, bool run_in_rfkill); void iwl_trans_pcie_gen2_fw_alive(struct iwl_trans *trans, u32 scd_addr); +void iwl_pcie_gen2_txq_free_memory(struct iwl_trans *trans, + struct iwl_txq *txq); +int iwl_trans_pcie_dyn_txq_alloc_dma(struct iwl_trans *trans, + struct iwl_txq **intxq, int size, + unsigned int timeout); +int iwl_trans_pcie_txq_alloc_response(struct iwl_trans *trans, + struct iwl_txq *txq, + struct iwl_host_cmd *hcmd); int iwl_trans_pcie_dyn_txq_alloc(struct iwl_trans *trans, - struct iwl_tx_queue_cfg_cmd *cmd, + __le16 flags, u8 sta_id, u8 tid, int cmd_id, int size, unsigned int timeout); void iwl_trans_pcie_dyn_txq_free(struct iwl_trans *trans, int queue); diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c index 4a08f4eab1a5..a33fb335849e 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c @@ -1065,8 +1065,8 @@ void iwl_pcie_gen2_txq_unmap(struct iwl_trans *trans, int txq_id) iwl_wake_queue(trans, txq); } -static void iwl_pcie_gen2_txq_free_memory(struct iwl_trans *trans, - struct iwl_txq *txq) +void iwl_pcie_gen2_txq_free_memory(struct iwl_trans *trans, + struct iwl_txq *txq) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct device *dev = trans->dev; @@ -1120,23 +1120,13 @@ static void iwl_pcie_gen2_txq_free(struct iwl_trans *trans, int txq_id) clear_bit(txq_id, trans_pcie->queue_used); } -int iwl_trans_pcie_dyn_txq_alloc(struct iwl_trans *trans, - struct iwl_tx_queue_cfg_cmd *cmd, - int cmd_id, int size, - unsigned int timeout) +int iwl_trans_pcie_dyn_txq_alloc_dma(struct iwl_trans *trans, + struct iwl_txq **intxq, int size, + unsigned int timeout) { - struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - struct iwl_tx_queue_cfg_rsp *rsp; - struct iwl_txq *txq; - struct iwl_host_cmd hcmd = { - .id = cmd_id, - .len = { sizeof(*cmd) }, - .data = { cmd, }, - .flags = CMD_WANT_SKB, - }; - int ret, qid; - u32 wr_ptr; + int ret; + struct iwl_txq *txq; txq = kzalloc(sizeof(*txq), GFP_KERNEL); if (!txq) return -ENOMEM; @@ -1164,20 +1154,30 @@ int iwl_trans_pcie_dyn_txq_alloc(struct iwl_trans *trans, txq->wd_timeout = msecs_to_jiffies(timeout); - cmd->tfdq_addr = cpu_to_le64(txq->dma_addr); - cmd->byte_cnt_addr = cpu_to_le64(txq->bc_tbl.dma); - cmd->cb_size = cpu_to_le32(TFD_QUEUE_CB_SIZE(size)); + *intxq = txq; + return 0; - ret = iwl_trans_send_cmd(trans, &hcmd); - if (ret) - goto error; +error: + iwl_pcie_gen2_txq_free_memory(trans, txq); + return ret; +} - if (WARN_ON(iwl_rx_packet_payload_len(hcmd.resp_pkt) != sizeof(*rsp))) { +int iwl_trans_pcie_txq_alloc_response(struct iwl_trans *trans, + struct iwl_txq *txq, + struct iwl_host_cmd *hcmd) +{ + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + struct iwl_tx_queue_cfg_rsp *rsp; + int ret, qid; + u32 wr_ptr; + + if (WARN_ON(iwl_rx_packet_payload_len(hcmd->resp_pkt) != + sizeof(*rsp))) { ret = -EINVAL; goto error_free_resp; } - rsp = (void *)hcmd.resp_pkt->data; + rsp = (void *)hcmd->resp_pkt->data; qid = le16_to_cpu(rsp->queue_number); wr_ptr = le16_to_cpu(rsp->write_pointer); @@ -1204,11 +1204,48 @@ int iwl_trans_pcie_dyn_txq_alloc(struct iwl_trans *trans, (txq->write_ptr) | (qid << 16)); IWL_DEBUG_TX_QUEUES(trans, "Activate queue %d\n", qid); - iwl_free_resp(&hcmd); + iwl_free_resp(hcmd); return qid; error_free_resp: - iwl_free_resp(&hcmd); + iwl_free_resp(hcmd); + iwl_pcie_gen2_txq_free_memory(trans, txq); + return ret; +} + +int iwl_trans_pcie_dyn_txq_alloc(struct iwl_trans *trans, + __le16 flags, u8 sta_id, u8 tid, + int cmd_id, int size, + unsigned int timeout) +{ + struct iwl_txq *txq = NULL; + struct iwl_tx_queue_cfg_cmd cmd = { + .flags = flags, + .sta_id = sta_id, + .tid = tid, + }; + struct iwl_host_cmd hcmd = { + .id = cmd_id, + .len = { sizeof(cmd) }, + .data = { &cmd, }, + .flags = CMD_WANT_SKB, + }; + int ret; + + ret = iwl_trans_pcie_dyn_txq_alloc_dma(trans, &txq, size, timeout); + if (ret) + return ret; + + cmd.tfdq_addr = cpu_to_le64(txq->dma_addr); + cmd.byte_cnt_addr = cpu_to_le64(txq->bc_tbl.dma); + cmd.cb_size = cpu_to_le32(TFD_QUEUE_CB_SIZE(size)); + + ret = iwl_trans_send_cmd(trans, &hcmd); + if (ret) + goto error; + + return iwl_trans_pcie_txq_alloc_response(trans, txq, &hcmd); + error: iwl_pcie_gen2_txq_free_memory(trans, txq); return ret; From 930ab73c3759b8848c97749f34c6748ca5cf0e4c Mon Sep 17 00:00:00 2001 From: Ayala Beker Date: Tue, 1 May 2018 14:40:03 +0300 Subject: [PATCH 069/276] iwlwifi: mvm: activate fragmented EBS in case of fragmented scan In case of fragmented scan on the HB channels, configure EBS to be fragmented as well. Signed-off-by: Ayala Beker Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/api/scan.h | 1 + drivers/net/wireless/intel/iwlwifi/mvm/scan.c | 12 +++++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/scan.h b/drivers/net/wireless/intel/iwlwifi/fw/api/scan.h index a17c4a79b8d4..310b01e3cce1 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/scan.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/scan.h @@ -262,6 +262,7 @@ enum iwl_scan_channel_flags { IWL_SCAN_CHANNEL_FLAG_EBS = BIT(0), IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE = BIT(1), IWL_SCAN_CHANNEL_FLAG_CACHE_ADD = BIT(2), + IWL_SCAN_CHANNEL_FLAG_EBS_FRAG = BIT(3), }; /* struct iwl_scan_channel_opt - CHANNEL_OPTIMIZATION_API_S diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c index 003bf0848386..e9048a98e793 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c @@ -1455,11 +1455,21 @@ static int iwl_mvm_scan_umac(struct iwl_mvm *mvm, struct ieee80211_vif *vif, if (type == IWL_MVM_SCAN_SCHED || type == IWL_MVM_SCAN_NETDETECT) cmd->flags = cpu_to_le32(IWL_UMAC_SCAN_FLAG_PREEMPTIVE); - if (iwl_mvm_scan_use_ebs(mvm, vif)) + if (iwl_mvm_scan_use_ebs(mvm, vif)) { channel_flags = IWL_SCAN_CHANNEL_FLAG_EBS | IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE | IWL_SCAN_CHANNEL_FLAG_CACHE_ADD; + /* set fragmented ebs for fragmented scan on HB channels */ + if (iwl_mvm_is_frag_ebs_supported(mvm)) { + if (gen_flags & + IWL_UMAC_SCAN_GEN_FLAGS_LMAC2_FRAGMENTED || + (!iwl_mvm_is_cdb_supported(mvm) && + gen_flags & IWL_UMAC_SCAN_GEN_FLAGS_FRAGMENTED)) + channel_flags |= IWL_SCAN_CHANNEL_FLAG_EBS_FRAG; + } + } + chan_param->flags = channel_flags; chan_param->count = params->n_channels; From ea7c2bfdec6d57cf8b7e60c745cf4d651bad68f0 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 17 May 2018 16:02:36 +0200 Subject: [PATCH 070/276] Revert "iwlwifi: allow memory debug TLV to specify the memory type" This reverts the addition of memory type in the memory debug TLV as the firmware never ended up implementing it, and now the PRPH dump is added as a different TLV. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 55 ++++---------------- drivers/net/wireless/intel/iwlwifi/fw/file.h | 15 +----- drivers/net/wireless/intel/iwlwifi/iwl-drv.c | 15 ------ 3 files changed, 12 insertions(+), 73 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index 3435a83e4d18..9963d6c84908 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -455,8 +455,8 @@ static const struct iwl_prph_range iwl_prph_dump_addr_9000[] = { { .start = 0x00a02400, .end = 0x00a02758 }, }; -static void _iwl_read_prph_block(struct iwl_trans *trans, u32 start, - u32 len_bytes, __le32 *data) +static void iwl_read_prph_block(struct iwl_trans *trans, u32 start, + u32 len_bytes, __le32 *data) { u32 i; @@ -464,21 +464,6 @@ static void _iwl_read_prph_block(struct iwl_trans *trans, u32 start, *data++ = cpu_to_le32(iwl_read_prph_no_grab(trans, start + i)); } -static bool iwl_read_prph_block(struct iwl_trans *trans, u32 start, - u32 len_bytes, __le32 *data) -{ - unsigned long flags; - bool success = false; - - if (iwl_trans_grab_nic_access(trans, &flags)) { - success = true; - _iwl_read_prph_block(trans, start, len_bytes, data); - iwl_trans_release_nic_access(trans, &flags); - } - - return success; -} - static void iwl_dump_prph(struct iwl_trans *trans, struct iwl_fw_error_dump_data **data, const struct iwl_prph_range *iwl_prph_dump_addr, @@ -504,11 +489,11 @@ static void iwl_dump_prph(struct iwl_trans *trans, prph = (void *)(*data)->data; prph->prph_start = cpu_to_le32(iwl_prph_dump_addr[i].start); - _iwl_read_prph_block(trans, iwl_prph_dump_addr[i].start, - /* our range is inclusive, hence + 4 */ - iwl_prph_dump_addr[i].end - - iwl_prph_dump_addr[i].start + 4, - (void *)prph->data); + iwl_read_prph_block(trans, iwl_prph_dump_addr[i].start, + /* our range is inclusive, hence + 4 */ + iwl_prph_dump_addr[i].end - + iwl_prph_dump_addr[i].start + 4, + (void *)prph->data); *data = iwl_fw_error_next_data(*data); } @@ -883,7 +868,6 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt) for (i = 0; i < fwrt->fw->n_dbg_mem_tlv; i++) { u32 len = le32_to_cpu(fw_dbg_mem[i].len); u32 ofs = le32_to_cpu(fw_dbg_mem[i].ofs); - bool success; if (!(fwrt->fw->dbg_dump_mask & BIT(IWL_FW_ERROR_DUMP_MEM))) break; @@ -897,28 +881,11 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt) IWL_DEBUG_INFO(fwrt, "WRT memory dump. Type=%u\n", dump_mem->type); - switch (dump_mem->type & cpu_to_le32(FW_DBG_MEM_TYPE_MASK)) { - case cpu_to_le32(FW_DBG_MEM_TYPE_REGULAR): - iwl_trans_read_mem_bytes(fwrt->trans, ofs, - dump_mem->data, - len); - success = true; - break; - case cpu_to_le32(FW_DBG_MEM_TYPE_PRPH): - success = iwl_read_prph_block(fwrt->trans, ofs, len, - (void *)dump_mem->data); - break; - default: - /* - * shouldn't get here, we ignored this kind - * of TLV earlier during the TLV parsing?! - */ - WARN_ON(1); - success = false; - } + iwl_trans_read_mem_bytes(fwrt->trans, ofs, + dump_mem->data, + len); - if (success) - dump_data = iwl_fw_error_next_data(dump_data); + dump_data = iwl_fw_error_next_data(dump_data); } if (smem_len && fwrt->fw->dbg_dump_mask & BIT(IWL_FW_ERROR_DUMP_MEM)) { diff --git a/drivers/net/wireless/intel/iwlwifi/fw/file.h b/drivers/net/wireless/intel/iwlwifi/fw/file.h index 858af103e6fd..335b8bde3dcd 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/file.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/file.h @@ -532,23 +532,10 @@ enum iwl_fw_dbg_monitor_mode { MIPI_MODE = 3, }; -/** - * enum iwl_fw_mem_seg_type - memory segment type - * @FW_DBG_MEM_TYPE_MASK: mask for the type indication - * @FW_DBG_MEM_TYPE_REGULAR: regular memory - * @FW_DBG_MEM_TYPE_PRPH: periphery memory (requires special reading) - */ -enum iwl_fw_mem_seg_type { - FW_DBG_MEM_TYPE_MASK = 0xff000000, - FW_DBG_MEM_TYPE_REGULAR = 0x00000000, - FW_DBG_MEM_TYPE_PRPH = 0x01000000, -}; - /** * struct iwl_fw_dbg_mem_seg_tlv - configures the debug data memory segments * - * @data_type: the memory segment type to record, see &enum iwl_fw_mem_seg_type - * for what we care about + * @data_type: the memory segment type to record * @ofs: the memory segment offset * @len: the memory segment length, in bytes * diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c index 76f50b99af2a..d3a60d1aacb5 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c @@ -1060,30 +1060,15 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv, case IWL_UCODE_TLV_FW_MEM_SEG: { struct iwl_fw_dbg_mem_seg_tlv *dbg_mem = (void *)tlv_data; - u32 type; size_t size; struct iwl_fw_dbg_mem_seg_tlv *n; if (tlv_len != (sizeof(*dbg_mem))) goto invalid_tlv_len; - type = le32_to_cpu(dbg_mem->data_type); - IWL_DEBUG_INFO(drv, "Found debug memory segment: %u\n", dbg_mem->data_type); - switch (type & FW_DBG_MEM_TYPE_MASK) { - case FW_DBG_MEM_TYPE_REGULAR: - case FW_DBG_MEM_TYPE_PRPH: - /* we know how to handle these */ - break; - default: - IWL_ERR(drv, - "Found debug memory segment with invalid type: 0x%x\n", - type); - return -EINVAL; - } - size = sizeof(*pieces->dbg_mem_tlv) * (pieces->n_dbg_mem_tlv + 1); n = krealloc(pieces->dbg_mem_tlv, size, GFP_KERNEL); From ab27926d9e4ae23df4f4d98e31f067c8b486bb4f Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Wed, 15 Aug 2018 22:07:25 +0300 Subject: [PATCH 071/276] iwlwifi: fix devices with PCI Device ID 0x34F0 and 11ac RF modules The devices with PCI device ID 0x34F0 are part of the SoC and can be combined with some different external RF modules. The configuration for these devices should reflect that, but are currently mixed up. To avoid confusion with discrete devices, add part of the firmware to be used and the official name of the device to the cfg structs. This is least reorganization possible (without messing things even more) that could be done as a bugfix for this SoC. Further reorganization of this code will be done separately. Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/cfg/22000.c | 65 ++++++++++++++++++- .../net/wireless/intel/iwlwifi/iwl-config.h | 9 ++- drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 55 ++++++++-------- 3 files changed, 97 insertions(+), 32 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c index c6b738c8fd84..204a51fd6375 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c @@ -77,10 +77,13 @@ #define IWL_22000_HR_FW_PRE "iwlwifi-Qu-a0-hr-a0-" #define IWL_22000_HR_CDB_FW_PRE "iwlwifi-QuIcp-z0-hrcdb-a0-" #define IWL_22000_HR_A_F0_FW_PRE "iwlwifi-QuQnj-f0-hr-a0-" -#define IWL_22000_HR_B_FW_PRE "iwlwifi-Qu-b0-hr-b0-" +#define IWL_22000_HR_B_F0_FW_PRE "iwlwifi-Qu-b0-hr-b0-" +#define IWL_22000_QU_B_HR_B_FW_PRE "iwlwifi-Qu-b0-hr-b0-" +#define IWL_22000_HR_B_FW_PRE "iwlwifi-QuQnj-b0-hr-b0-" #define IWL_22000_JF_B0_FW_PRE "iwlwifi-QuQnj-a0-jf-b0-" #define IWL_22000_HR_A0_FW_PRE "iwlwifi-QuQnj-a0-hr-a0-" #define IWL_22000_SU_Z0_FW_PRE "iwlwifi-su-z0-" +#define IWL_QU_B_JF_B_FW_PRE "iwlwifi-Qu-b0-jf-b0-" #define IWL_22000_HR_MODULE_FIRMWARE(api) \ IWL_22000_HR_FW_PRE __stringify(api) ".ucode" @@ -88,7 +91,11 @@ IWL_22000_JF_FW_PRE __stringify(api) ".ucode" #define IWL_22000_HR_A_F0_QNJ_MODULE_FIRMWARE(api) \ IWL_22000_HR_A_F0_FW_PRE __stringify(api) ".ucode" -#define IWL_22000_HR_B_QNJ_MODULE_FIRMWARE(api) \ +#define IWL_22000_HR_B_F0_QNJ_MODULE_FIRMWARE(api) \ + IWL_22000_HR_B_F0_FW_PRE __stringify(api) ".ucode" +#define IWL_22000_QU_B_HR_B_MODULE_FIRMWARE(api) \ + IWL_22000_QU_B_HR_B_FW_PRE __stringify(api) ".ucode" +#define IWL_22000_HR_B_QNJ_MODULE_FIRMWARE(api) \ IWL_22000_HR_B_FW_PRE __stringify(api) ".ucode" #define IWL_22000_JF_B0_QNJ_MODULE_FIRMWARE(api) \ IWL_22000_JF_B0_FW_PRE __stringify(api) ".ucode" @@ -96,6 +103,8 @@ IWL_22000_HR_A0_FW_PRE __stringify(api) ".ucode" #define IWL_22000_SU_Z0_MODULE_FIRMWARE(api) \ IWL_22000_SU_Z0_FW_PRE __stringify(api) ".ucode" +#define IWL_QU_B_JF_B_MODULE_FIRMWARE(api) \ + IWL_QU_B_JF_B_FW_PRE __stringify(api) ".ucode" #define NVM_HW_SECTION_NUM_FAMILY_22000 10 @@ -192,7 +201,54 @@ const struct iwl_cfg iwl22000_2ac_cfg_jf = { const struct iwl_cfg iwl22000_2ax_cfg_hr = { .name = "Intel(R) Dual Band Wireless AX 22000", - .fw_name_pre = IWL_22000_HR_FW_PRE, + .fw_name_pre = IWL_22000_QU_B_HR_B_FW_PRE, + IWL_DEVICE_22500, + /* + * This device doesn't support receiving BlockAck with a large bitmap + * so we need to restrict the size of transmitted aggregation to the + * HT size; mac80211 would otherwise pick the HE max (256) by default. + */ + .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, +}; + +/* + * All JF radio modules are part of the 9000 series, but the MAC part + * looks more like 22000. That's why this device is here, but called + * 9560 nevertheless. + */ +const struct iwl_cfg iwl9461_2ac_cfg_qu_b0_jf_b0 = { + .name = "Intel(R) Wireless-AC 9461", + .fw_name_pre = IWL_QU_B_JF_B_FW_PRE, + IWL_DEVICE_22500, +}; + +const struct iwl_cfg iwl9462_2ac_cfg_qu_b0_jf_b0 = { + .name = "Intel(R) Wireless-AC 9462", + .fw_name_pre = IWL_QU_B_JF_B_FW_PRE, + IWL_DEVICE_22500, +}; + +const struct iwl_cfg iwl9560_2ac_cfg_qu_b0_jf_b0 = { + .name = "Intel(R) Wireless-AC 9560", + .fw_name_pre = IWL_QU_B_JF_B_FW_PRE, + IWL_DEVICE_22500, +}; + +const struct iwl_cfg killer1550i_2ac_cfg_qu_b0_jf_b0 = { + .name = "Killer (R) Wireless-AC 1550i Wireless Network Adapter (9560NGW)", + .fw_name_pre = IWL_QU_B_JF_B_FW_PRE, + IWL_DEVICE_22500, +}; + +const struct iwl_cfg killer1550s_2ac_cfg_qu_b0_jf_b0 = { + .name = "Killer (R) Wireless-AC 1550s Wireless Network Adapter (9560NGW)", + .fw_name_pre = IWL_QU_B_JF_B_FW_PRE, + IWL_DEVICE_22500, +}; + +const struct iwl_cfg iwl22000_2ax_cfg_jf = { + .name = "Intel(R) Dual Band Wireless AX 22000", + .fw_name_pre = IWL_QU_B_JF_B_FW_PRE, IWL_DEVICE_22500, /* * This device doesn't support receiving BlockAck with a large bitmap @@ -266,7 +322,10 @@ const struct iwl_cfg iwl22560_2ax_cfg_su_cdb = { MODULE_FIRMWARE(IWL_22000_HR_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL_22000_JF_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL_22000_HR_A_F0_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); +MODULE_FIRMWARE(IWL_22000_HR_B_F0_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); +MODULE_FIRMWARE(IWL_22000_QU_B_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL_22000_HR_B_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL_22000_JF_B0_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL_22000_HR_A0_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL_22000_SU_Z0_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); +MODULE_FIRMWARE(IWL_QU_B_JF_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h b/drivers/net/wireless/intel/iwlwifi/iwl-config.h index 5e1280783376..5eb906a0d0d2 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h @@ -573,11 +573,18 @@ extern const struct iwl_cfg iwl22000_2ac_cfg_hr; extern const struct iwl_cfg iwl22000_2ac_cfg_hr_cdb; extern const struct iwl_cfg iwl22000_2ac_cfg_jf; extern const struct iwl_cfg iwl22000_2ax_cfg_hr; +extern const struct iwl_cfg iwl9461_2ac_cfg_qu_b0_jf_b0; +extern const struct iwl_cfg iwl9462_2ac_cfg_qu_b0_jf_b0; +extern const struct iwl_cfg iwl9560_2ac_cfg_qu_b0_jf_b0; +extern const struct iwl_cfg killer1550i_2ac_cfg_qu_b0_jf_b0; +extern const struct iwl_cfg killer1550s_2ac_cfg_qu_b0_jf_b0; +extern const struct iwl_cfg iwl22000_2ax_cfg_jf; extern const struct iwl_cfg iwl22000_2ax_cfg_qnj_hr_a0_f0; +extern const struct iwl_cfg iwl22000_2ax_cfg_qnj_hr_b0_f0; extern const struct iwl_cfg iwl22000_2ax_cfg_qnj_hr_b0; extern const struct iwl_cfg iwl22000_2ax_cfg_qnj_jf_b0; extern const struct iwl_cfg iwl22000_2ax_cfg_qnj_hr_a0; extern const struct iwl_cfg iwl22560_2ax_cfg_su_cdb; -#endif /* CONFIG_IWLMVM */ +#endif /* CPTCFG_IWLMVM || CPTCFG_IWLFMAC */ #endif /* __IWL_CONFIG_H__ */ diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c index 0d40864ac90f..9e015212c2c0 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -641,34 +641,33 @@ static const struct pci_device_id iwl_hw_card_ids[] = { {IWL_PCI_DEVICE(0x31DC, 0x40A4, iwl9462_2ac_cfg_shared_clk)}, {IWL_PCI_DEVICE(0x31DC, 0x4234, iwl9560_2ac_cfg_shared_clk)}, {IWL_PCI_DEVICE(0x31DC, 0x42A4, iwl9462_2ac_cfg_shared_clk)}, - {IWL_PCI_DEVICE(0x34F0, 0x0030, iwl9560_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x34F0, 0x0034, iwl9560_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x34F0, 0x0038, iwl9560_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x34F0, 0x003C, iwl9560_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x34F0, 0x0060, iwl9461_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x34F0, 0x0064, iwl9461_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x34F0, 0x00A0, iwl9462_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x34F0, 0x00A4, iwl9462_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x34F0, 0x0230, iwl9560_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x34F0, 0x0234, iwl9560_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x34F0, 0x0238, iwl9560_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x34F0, 0x023C, iwl9560_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x34F0, 0x0260, iwl9461_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x34F0, 0x0264, iwl9461_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x34F0, 0x02A0, iwl9462_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x34F0, 0x02A4, iwl9462_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x34F0, 0x1010, iwl9260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x34F0, 0x1030, iwl9560_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x34F0, 0x1210, iwl9260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x34F0, 0x1551, iwl9560_killer_s_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x34F0, 0x1552, iwl9560_killer_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x34F0, 0x2030, iwl9560_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x34F0, 0x2034, iwl9560_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x34F0, 0x4030, iwl9560_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x34F0, 0x4034, iwl9560_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x34F0, 0x40A4, iwl9462_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x34F0, 0x4234, iwl9560_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x34F0, 0x42A4, iwl9462_2ac_cfg_soc)}, + + {IWL_PCI_DEVICE(0x34F0, 0x0030, iwl9560_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x34F0, 0x0034, iwl9560_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x34F0, 0x0038, iwl9560_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x34F0, 0x003C, iwl9560_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x34F0, 0x0060, iwl9461_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x34F0, 0x0064, iwl9461_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x34F0, 0x00A0, iwl9462_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x34F0, 0x00A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x34F0, 0x0230, iwl9560_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x34F0, 0x0234, iwl9560_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x34F0, 0x0238, iwl9560_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x34F0, 0x023C, iwl9560_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x34F0, 0x0260, iwl9461_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x34F0, 0x0264, iwl9461_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x34F0, 0x02A0, iwl9462_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x34F0, 0x02A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x34F0, 0x1551, killer1550s_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x34F0, 0x1552, killer1550i_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x34F0, 0x2030, iwl9560_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x34F0, 0x2034, iwl9560_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x34F0, 0x4030, iwl9560_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x34F0, 0x4034, iwl9560_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x34F0, 0x40A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x34F0, 0x4234, iwl9560_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x34F0, 0x42A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x3DF0, 0x0030, iwl9560_2ac_cfg_soc)}, {IWL_PCI_DEVICE(0x3DF0, 0x0034, iwl9560_2ac_cfg_soc)}, {IWL_PCI_DEVICE(0x3DF0, 0x0038, iwl9560_2ac_cfg_soc)}, From 9e9e11d83238b068c78dbb5c63340132dc76fd8b Mon Sep 17 00:00:00 2001 From: Varsha Rao Date: Wed, 25 Jul 2018 20:56:22 +0200 Subject: [PATCH 072/276] brcmsmac: Remove extra parentheses Remove the unnecessary parentheses to fix the clang warning of extraneous parentheses. Signed-off-by: Varsha Rao Signed-off-by: Kalle Valo --- drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c index bedec1606caa..a57f2711f3c0 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c @@ -25453,12 +25453,12 @@ void wlc_phy_cal_perical_nphy_run(struct brcms_phy *pi, u8 caltype) (pi->cal_type_override == PHY_PERICAL_FULL) ? true : false; - if ((pi->mphase_cal_phase_id > MPHASE_CAL_STATE_INIT)) { + if (pi->mphase_cal_phase_id > MPHASE_CAL_STATE_INIT) { if (pi->nphy_txiqlocal_chanspec != pi->radio_chanspec) wlc_phy_cal_perical_mphase_restart(pi); } - if ((pi->mphase_cal_phase_id == MPHASE_CAL_STATE_RXCAL)) + if (pi->mphase_cal_phase_id == MPHASE_CAL_STATE_RXCAL) wlapi_bmac_write_shm(pi->sh->physhim, M_CTS_DURATION, 10000); wlapi_suspend_mac_and_wait(pi->sh->physhim); From 057118edfc365676022cdce4b218074f1fd67672 Mon Sep 17 00:00:00 2001 From: Varsha Rao Date: Wed, 25 Jul 2018 21:00:07 +0200 Subject: [PATCH 073/276] cw1200: Remove extra parentheses Remove unnecessary parentheses to fix the extraneous parentheses clang warning. Signed-off-by: Varsha Rao Signed-off-by: Kalle Valo --- drivers/net/wireless/st/cw1200/txrx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/st/cw1200/txrx.c b/drivers/net/wireless/st/cw1200/txrx.c index f7b1b0062db3..8c800ef23159 100644 --- a/drivers/net/wireless/st/cw1200/txrx.c +++ b/drivers/net/wireless/st/cw1200/txrx.c @@ -624,9 +624,9 @@ cw1200_tx_h_bt(struct cw1200_common *priv, priority = WSM_EPTA_PRIORITY_ACTION; else if (ieee80211_is_mgmt(t->hdr->frame_control)) priority = WSM_EPTA_PRIORITY_MGT; - else if ((wsm->queue_id == WSM_QUEUE_VOICE)) + else if (wsm->queue_id == WSM_QUEUE_VOICE) priority = WSM_EPTA_PRIORITY_VOICE; - else if ((wsm->queue_id == WSM_QUEUE_VIDEO)) + else if (wsm->queue_id == WSM_QUEUE_VIDEO) priority = WSM_EPTA_PRIORITY_VIDEO; else priority = WSM_EPTA_PRIORITY_DATA; From 62a25dc56990a382afeb40891eead0dbf8b598b4 Mon Sep 17 00:00:00 2001 From: Rosen Penev Date: Sat, 11 Aug 2018 16:33:52 -0700 Subject: [PATCH 074/276] mt76x2u: Add support for Alfa AWUS036ACM A 2x2 unit with a USB dock for optimal placement. Signed-off-by: Rosen Penev Acked-by: Lorenzo Bianconi Signed-off-by: Kalle Valo --- drivers/net/wireless/mediatek/mt76/mt76x2_usb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_usb.c b/drivers/net/wireless/mediatek/mt76/mt76x2_usb.c index 1428cfdee579..f5338c364a85 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_usb.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_usb.c @@ -20,6 +20,7 @@ #include "mt76x2u.h" static const struct usb_device_id mt76x2u_device_table[] = { + { USB_DEVICE(0x0e8d, 0x7612) }, /* Alfa AWUS036ACM */ { USB_DEVICE(0x0b05, 0x1833) }, /* Asus USB-AC54 */ { USB_DEVICE(0x0b05, 0x17eb) }, /* Asus USB-AC55 */ { USB_DEVICE(0x0b05, 0x180b) }, /* Asus USB-N53 B1 */ From 3348ef6a6a126706d6a73ed40c18d8033df72783 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 14 Aug 2018 12:07:48 +0300 Subject: [PATCH 075/276] libertas_tf: prevent underflow in process_cmdrequest() If recvlength is less than MESSAGE_HEADER_LEN (4) we would end up corrupting memory. Fixes: c305a19a0d0a ("libertas_tf: usb specific functions") Signed-off-by: Dan Carpenter Signed-off-by: Kalle Valo --- drivers/net/wireless/marvell/libertas_tf/if_usb.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/marvell/libertas_tf/if_usb.c b/drivers/net/wireless/marvell/libertas_tf/if_usb.c index e92fc5001171..789337ea676a 100644 --- a/drivers/net/wireless/marvell/libertas_tf/if_usb.c +++ b/drivers/net/wireless/marvell/libertas_tf/if_usb.c @@ -605,9 +605,10 @@ static inline void process_cmdrequest(int recvlength, uint8_t *recvbuff, { unsigned long flags; - if (recvlength > LBS_CMD_BUFFER_SIZE) { + if (recvlength < MESSAGE_HEADER_LEN || + recvlength > LBS_CMD_BUFFER_SIZE) { lbtf_deb_usbd(&cardp->udev->dev, - "The receive buffer is too large\n"); + "The receive buffer is invalid: %d\n", recvlength); kfree_skb(skb); return; } From 2fef681a4cf7994c882190fd2417b95f30510afb Mon Sep 17 00:00:00 2001 From: Jia-Shyr Chuang Date: Wed, 15 Aug 2018 04:23:09 -0500 Subject: [PATCH 076/276] brcmfmac: add CYW89342 mini-PCIe device CYW89342 is a 2x2 MIMO, 802.11a/b/g/n/ac for WLAN. It is a member of 4355/4359 family. Signed-off-by: Jia-Shyr Chuang Signed-off-by: Chi-Hsien Lin Signed-off-by: Kalle Valo --- drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c index 4fffa6988087..5dea569d63ed 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c @@ -2017,6 +2017,7 @@ static const struct dev_pm_ops brcmf_pciedrvr_pm = { static const struct pci_device_id brcmf_pcie_devid_table[] = { BRCMF_PCIE_DEVICE(BRCM_PCIE_4350_DEVICE_ID), + BRCMF_PCIE_DEVICE_SUB(0x4355, BRCM_PCIE_VENDOR_ID_BROADCOM, 0x4355), BRCMF_PCIE_DEVICE(BRCM_PCIE_4356_DEVICE_ID), BRCMF_PCIE_DEVICE(BRCM_PCIE_43567_DEVICE_ID), BRCMF_PCIE_DEVICE(BRCM_PCIE_43570_DEVICE_ID), From 4ad298da9392975f0dc1355dd302a7e95d3c9801 Mon Sep 17 00:00:00 2001 From: Chung-Hsien Hsu Date: Wed, 15 Aug 2018 05:32:39 -0500 Subject: [PATCH 077/276] brcmfmac: add FT-based AKMs in brcmf_set_key_mgmt() for FT support Add WLAN_AKM_SUITE_FT_8021X and WLAN_AKM_SUITE_FT_PSK in brcmf_set_key_mgmt() for FT support. Signed-off-by: Chung-Hsien Hsu Signed-off-by: Chi-Hsien Lin Signed-off-by: Kalle Valo --- drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 6 ++++++ .../net/wireless/broadcom/brcm80211/include/brcmu_wifi.h | 1 + 2 files changed, 7 insertions(+) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c index 5444e6213d45..c40015d5a51a 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c @@ -1649,6 +1649,12 @@ brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme) case WLAN_AKM_SUITE_PSK: val = WPA2_AUTH_PSK; break; + case WLAN_AKM_SUITE_FT_8021X: + val = WPA2_AUTH_UNSPECIFIED | WPA2_AUTH_FT; + break; + case WLAN_AKM_SUITE_FT_PSK: + val = WPA2_AUTH_PSK | WPA2_AUTH_FT; + break; default: brcmf_err("invalid cipher group (%d)\n", sme->crypto.cipher_group); diff --git a/drivers/net/wireless/broadcom/brcm80211/include/brcmu_wifi.h b/drivers/net/wireless/broadcom/brcm80211/include/brcmu_wifi.h index 7b9a77981df1..91fca79e6158 100644 --- a/drivers/net/wireless/broadcom/brcm80211/include/brcmu_wifi.h +++ b/drivers/net/wireless/broadcom/brcm80211/include/brcmu_wifi.h @@ -237,6 +237,7 @@ static inline bool ac_bitmap_tst(u8 bitmap, int prec) #define WPA2_AUTH_RESERVED4 0x0400 #define WPA2_AUTH_RESERVED5 0x0800 #define WPA2_AUTH_1X_SHA256 0x1000 /* 1X with SHA256 key derivation */ +#define WPA2_AUTH_FT 0x4000 /* Fast BSS Transition */ #define WPA2_AUTH_PSK_SHA256 0x8000 /* PSK with SHA256 key derivation */ #define DOT11_DEFAULT_RTS_LEN 2347 From a858376cdbb3edfef7dc6ca5ec1c70ff94bdbef2 Mon Sep 17 00:00:00 2001 From: Chung-Hsien Hsu Date: Wed, 15 Aug 2018 05:32:40 -0500 Subject: [PATCH 078/276] brcmfmac: add 4-way handshake offload detection for FT-802.1X Add 4-way handshake offload detection for FT with EAP authentication. Signed-off-by: Chung-Hsien Hsu Signed-off-by: Chi-Hsien Lin Signed-off-by: Kalle Valo --- drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c index c40015d5a51a..230a378c26fc 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c @@ -1651,6 +1651,8 @@ brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme) break; case WLAN_AKM_SUITE_FT_8021X: val = WPA2_AUTH_UNSPECIFIED | WPA2_AUTH_FT; + if (sme->want_1x) + profile->use_fwsup = BRCMF_PROFILE_FWSUP_1X; break; case WLAN_AKM_SUITE_FT_PSK: val = WPA2_AUTH_PSK | WPA2_AUTH_FT; From 5945310a175506f743b68fd6812dbcd1b3c95ec1 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Thu, 16 Aug 2018 13:59:44 +0100 Subject: [PATCH 079/276] orinoco: remove unused array encaps_hdr and macro ENCAPS_OVERHEAD Array encaps_hdr and macro ENCAPS_OVERHEAD are declared but are not being used, hence they are redundant and can be removed. Cleans up clang warning: warning: 'encaps_hdr' defined but not used [-Wunused-const-variable=] Signed-off-by: Colin Ian King Signed-off-by: Kalle Valo --- drivers/net/wireless/intersil/orinoco/orinoco_usb.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/net/wireless/intersil/orinoco/orinoco_usb.c b/drivers/net/wireless/intersil/orinoco/orinoco_usb.c index 94ad6fe29e69..d8c27203bc57 100644 --- a/drivers/net/wireless/intersil/orinoco/orinoco_usb.c +++ b/drivers/net/wireless/intersil/orinoco/orinoco_usb.c @@ -73,10 +73,6 @@ #define URB_ASYNC_UNLINK 0 #endif -/* 802.2 LLC/SNAP header used for Ethernet encapsulation over 802.11 */ -static const u8 encaps_hdr[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00}; -#define ENCAPS_OVERHEAD (sizeof(encaps_hdr) + 2) - struct header_struct { /* 802.3 */ u8 dest[ETH_ALEN]; From 199ba9faca909e77ac533449ecd1248123ce89e7 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Mon, 20 Aug 2018 13:48:31 -0500 Subject: [PATCH 080/276] rtl8187: Fix warning generated when strncpy() destination length matches the sixe argument In gcc8, when the 3rd argument (size) of a call to strncpy() matches the length of the first argument, the compiler warns of the possibility of an unterminated string. Using strlcpy() forces a null at the end. Signed-off-by: Larry Finger Signed-off-by: Kalle Valo --- drivers/net/wireless/realtek/rtl818x/rtl8187/leds.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/realtek/rtl818x/rtl8187/leds.c b/drivers/net/wireless/realtek/rtl818x/rtl8187/leds.c index c2d5b495c179..c089540116fa 100644 --- a/drivers/net/wireless/realtek/rtl818x/rtl8187/leds.c +++ b/drivers/net/wireless/realtek/rtl818x/rtl8187/leds.c @@ -146,7 +146,7 @@ static int rtl8187_register_led(struct ieee80211_hw *dev, led->dev = dev; led->ledpin = ledpin; led->is_radio = is_radio; - strncpy(led->name, name, sizeof(led->name)); + strlcpy(led->name, name, sizeof(led->name)); led->led_dev.name = led->name; led->led_dev.default_trigger = default_trigger; From 7bd4628c2f31c51254aa39628ecae521d00d0b90 Mon Sep 17 00:00:00 2001 From: Ganapathi Bhat Date: Tue, 21 Aug 2018 13:23:01 +0530 Subject: [PATCH 081/276] mwifiex: do no submit URB in suspended state There is a possible race between USB suspend and main thread: 1. After processing the command response, main thread will submit rx_cmd URB back so as to process next command response, by calling mwifiex_usb_submit_rx_urb. 2. During USB suspend, the suspend handler will check if rx_cmd URB is pending(submitted) and if true, kill this URB. There is a possible race between #1 and #2, where rx_cmd URB will be submitted by main thread(#1) after the suspend handler check in #2. To fix this, check if device is already suspended in mwifiex_usb_submit_rx_urb, in which case do not submit the URB. Signed-off-by: Vidya Dharmaraju Signed-off-by: Cathy Luo Signed-off-by: Ganapathi Bhat Signed-off-by: Kalle Valo --- drivers/net/wireless/marvell/mwifiex/usb.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/net/wireless/marvell/mwifiex/usb.c b/drivers/net/wireless/marvell/mwifiex/usb.c index 433c6a16870b..76d80fd54523 100644 --- a/drivers/net/wireless/marvell/mwifiex/usb.c +++ b/drivers/net/wireless/marvell/mwifiex/usb.c @@ -298,6 +298,13 @@ static int mwifiex_usb_submit_rx_urb(struct urb_context *ctx, int size) struct mwifiex_adapter *adapter = ctx->adapter; struct usb_card_rec *card = (struct usb_card_rec *)adapter->card; + if (test_bit(MWIFIEX_IS_SUSPENDED, &adapter->work_flags)) { + mwifiex_dbg(adapter, ERROR, + "%s: card removed/suspended, EP %d rx_cmd URB submit skipped\n", + __func__, ctx->ep); + return -1; + } + if (card->rx_cmd_ep != ctx->ep) { ctx->skb = dev_alloc_skb(size); if (!ctx->skb) { From 33a164fa8a4c91408e0b7738f754cb1a7827c5f2 Mon Sep 17 00:00:00 2001 From: Ganapathi Bhat Date: Tue, 21 Aug 2018 13:23:02 +0530 Subject: [PATCH 082/276] mwifex: free rx_cmd skb in suspended state USB suspend handler will kill the presubmitted rx_cmd URB. This triggers a call to the corresponding URB complete handler, which will free the rx_cmd skb, associated with rx_cmd URB. Due to a possible race betwen suspend handler and main thread, depicted in 'commit bfcacac6c84b ("mwifiex: do no submit URB in suspended state")', it is possible that the rx_cmd skb will fail to get freed. This causes a memory leak, since the resume handler will always allocate a new rx_cmd skb. To fix this, free the rx_cmd skb in mwifiex_usb_submit_rx_urb, if the device is in suspended state. Signed-off-by: Vidya Dharmaraju Signed-off-by: Cathy Luo Signed-off-by: Ganapathi Bhat Signed-off-by: Kalle Valo --- drivers/net/wireless/marvell/mwifiex/usb.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/wireless/marvell/mwifiex/usb.c b/drivers/net/wireless/marvell/mwifiex/usb.c index 76d80fd54523..d445acc4786b 100644 --- a/drivers/net/wireless/marvell/mwifiex/usb.c +++ b/drivers/net/wireless/marvell/mwifiex/usb.c @@ -299,6 +299,12 @@ static int mwifiex_usb_submit_rx_urb(struct urb_context *ctx, int size) struct usb_card_rec *card = (struct usb_card_rec *)adapter->card; if (test_bit(MWIFIEX_IS_SUSPENDED, &adapter->work_flags)) { + if (card->rx_cmd_ep == ctx->ep) { + mwifiex_dbg(adapter, INFO, "%s: free rx_cmd skb\n", + __func__); + dev_kfree_skb_any(ctx->skb); + ctx->skb = NULL; + } mwifiex_dbg(adapter, ERROR, "%s: card removed/suspended, EP %d rx_cmd URB submit skipped\n", __func__, ctx->ep); From f483039cf51acf30494cd754194562c22cf98764 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 22 Aug 2018 13:41:26 +0300 Subject: [PATCH 083/276] rt2x00: use simple_read_from_buffer() The problem with this copy_to_user() calls is that they don't ensure that "size" is less than the "length" which the user provided. Obviously, this is debugfs and "size" is normally going to be very small so it probably doesn't matter, but this is the correct thing to do. Signed-off-by: Dan Carpenter Acked-by: Stanislaw Gruszka Signed-off-by: Kalle Valo --- .../net/wireless/ralink/rt2x00/rt2x00debug.c | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00debug.c b/drivers/net/wireless/ralink/rt2x00/rt2x00debug.c index acc399b5574e..61ba573e8bf1 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt2x00debug.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00debug.c @@ -464,11 +464,7 @@ static ssize_t rt2x00debug_read_##__name(struct file *file, \ \ size = sprintf(line, __format, value); \ \ - if (copy_to_user(buf, line, size)) \ - return -EFAULT; \ - \ - *offset += size; \ - return size; \ + return simple_read_from_buffer(buf, length, offset, line, size); \ } #define RT2X00DEBUGFS_OPS_WRITE(__name, __type) \ @@ -545,11 +541,7 @@ static ssize_t rt2x00debug_read_dev_flags(struct file *file, size = sprintf(line, "0x%.8x\n", (unsigned int)intf->rt2x00dev->flags); - if (copy_to_user(buf, line, size)) - return -EFAULT; - - *offset += size; - return size; + return simple_read_from_buffer(buf, length, offset, line, size); } static const struct file_operations rt2x00debug_fop_dev_flags = { @@ -574,11 +566,7 @@ static ssize_t rt2x00debug_read_cap_flags(struct file *file, size = sprintf(line, "0x%.8x\n", (unsigned int)intf->rt2x00dev->cap_flags); - if (copy_to_user(buf, line, size)) - return -EFAULT; - - *offset += size; - return size; + return simple_read_from_buffer(buf, length, offset, line, size); } static const struct file_operations rt2x00debug_fop_cap_flags = { From cb18e2e9ec71d42409a51b83546686c609780dde Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Wed, 22 Aug 2018 15:22:15 +0200 Subject: [PATCH 084/276] brcmfmac: fix wrong strnchr usage strnchr takes arguments in the order of its name: string, max bytes to read, character to search for. Here we're passing '\n' aka 10 as the buffer size, and searching for sizeof(buf) aka BRCMF_DCMD_SMLEN aka 256 (aka '\0', since it's implicitly converted to char) within those 10 bytes. Just interchanging the last two arguments would still leave a bug, because if we've been successful once, there are not sizeof(buf) characters left after the new value of p. Since clmver is immediately afterwards passed as a %s argument, I assume that it is actually a properly nul-terminated string. For that case, we have strreplace(). Signed-off-by: Rasmus Villemoes Signed-off-by: Kalle Valo --- drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c index cd3651069d0c..94044a7a6021 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c @@ -296,9 +296,7 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp) /* Replace all newline/linefeed characters with space * character */ - ptr = clmver; - while ((ptr = strnchr(ptr, '\n', sizeof(buf))) != NULL) - *ptr = ' '; + strreplace(clmver, '\n', ' '); brcmf_dbg(INFO, "CLM version = %s\n", clmver); } From baa8caf4ab7af2d9e84b566b99fe919a4e9e7562 Mon Sep 17 00:00:00 2001 From: Siva Rebbagondla Date: Mon, 27 Aug 2018 17:05:14 +0530 Subject: [PATCH 085/276] rsi: fix memory alignment issue in ARM32 platforms During testing in ARM32 platforms, observed below kernel panic, as driver accessing data beyond the allocated memory while submitting URB to USB. Fix: Resolved this by specifying correct length by considering 64 bit alignment. so that, USB bus driver will access only allocated memory. Unit-test: Tested and confirm that driver bring up and scanning, connection and data transfer works fine with this fix. ...skipping... [ 25.389450] Unable to handle kernel paging request at virtual address 5aa11422 [ 25.403078] Internal error: Oops: 5 [#1] SMP ARM [ 25.407703] Modules linked in: rsi_usb [ 25.411473] CPU: 1 PID: 317 Comm: RX-Thread Not tainted 4.18.0-rc7 #1 [ 25.419221] Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree) [ 25.425764] PC is at skb_release_data+0x90/0x168 [ 25.430393] LR is at skb_release_all+0x28/0x2c [ 25.434842] pc : [<807435b0>] lr : [<80742ba0>] psr: 200e0013 5aa1141e [ 25.464633] Flags: nzCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment none [ 25.477524] Process RX-Thread (pid: 317, stack limit = 0x(ptrval)) [ 25.483709] Stack: (0xedf69ed8 to 0xedf6a000) [ 25.569907] Backtrace: [ 25.572368] [<80743520>] (skb_release_data) from [<80742ba0>] (skb_release_all+0x28/0x2c) [ 25.580555] r9:7f00258c r8:00000001 r7:ee355000 r6:eddab0d0 r5:eddab000 r4:eddbb840 [ 25.588308] [<80742b78>] (skb_release_all) from [<807432cc>] (consume_skb+0x30/0x50) [ 25.596055] r5:eddab000 r4:eddbb840 [ 25.599648] [<8074329c>] (consume_skb) from [<7f00117c>] (rsi_usb_rx_thread+0x64/0x12c [rsi_usb]) [ 25.608524] r5:eddab000 r4:eddbb840 [ 25.612116] [<7f001118>] (rsi_usb_rx_thread [rsi_usb]) from [<80142750>] (kthread+0x11c/0x15c) [ 25.620735] r10:ee9ff9e0 r9:edcde3b8 r8:ee355000 r7:edf68000 r6:edd3a780 r5:00000000 [ 25.628567] r4:edcde380 [ 25.631110] [<80142634>] (kthread) from [<801010e8>] (ret_from_fork+0x14/0x2c) [ 25.638336] Exception stack(0xedf69fb0 to 0xedf69ff8) [ 25.682929] ---[ end trace 8236a5496f5b5d3b ]--- Signed-off-by: Siva Rebbagondla Signed-off-by: Kalle Valo --- drivers/net/wireless/rsi/rsi_91x_usb.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/rsi/rsi_91x_usb.c b/drivers/net/wireless/rsi/rsi_91x_usb.c index c0a163e40402..f360690396dd 100644 --- a/drivers/net/wireless/rsi/rsi_91x_usb.c +++ b/drivers/net/wireless/rsi/rsi_91x_usb.c @@ -266,15 +266,17 @@ static void rsi_rx_done_handler(struct urb *urb) if (urb->status) goto out; - if (urb->actual_length <= 0) { - rsi_dbg(INFO_ZONE, "%s: Zero length packet\n", __func__); + if (urb->actual_length <= 0 || + urb->actual_length > rx_cb->rx_skb->len) { + rsi_dbg(INFO_ZONE, "%s: Invalid packet length = %d\n", + __func__, urb->actual_length); goto out; } if (skb_queue_len(&dev->rx_q) >= RSI_MAX_RX_PKTS) { rsi_dbg(INFO_ZONE, "Max RX packets reached\n"); goto out; } - skb_put(rx_cb->rx_skb, urb->actual_length); + skb_trim(rx_cb->rx_skb, urb->actual_length); skb_queue_tail(&dev->rx_q, rx_cb->rx_skb); rsi_set_event(&dev->rx_thread.event); @@ -308,6 +310,7 @@ static int rsi_rx_urb_submit(struct rsi_hw *adapter, u8 ep_num) if (!skb) return -ENOMEM; skb_reserve(skb, MAX_DWORD_ALIGN_BYTES); + skb_put(skb, RSI_MAX_RX_USB_PKT_SIZE - MAX_DWORD_ALIGN_BYTES); dword_align_bytes = (unsigned long)skb->data & 0x3f; if (dword_align_bytes > 0) skb_push(skb, dword_align_bytes); @@ -319,7 +322,7 @@ static int rsi_rx_urb_submit(struct rsi_hw *adapter, u8 ep_num) usb_rcvbulkpipe(dev->usbdev, dev->bulkin_endpoint_addr[ep_num - 1]), urb->transfer_buffer, - RSI_MAX_RX_USB_PKT_SIZE, + skb->len, rsi_rx_done_handler, rx_cb); From 4c62764d0fc21a34ffc44eec1210038c3a2e4473 Mon Sep 17 00:00:00 2001 From: Siva Rebbagondla Date: Mon, 27 Aug 2018 17:05:15 +0530 Subject: [PATCH 086/276] rsi: improve kernel thread handling to fix kernel panic While running regressions, observed below kernel panic when sdio disconnect called. This is because of, kthread_stop() is taking care of wait_for_completion() by default. When wait_for_completion triggered in kthread_stop and as it was done already, giving kernel panic. Hence, removing redundant wait_for_completion() from rsi_kill_thread(). ... skipping ... BUG: unable to handle kernel NULL pointer dereference at (null) IP: [] exit_creds+0x1f/0x50 PGD 0 Oops: 0002 [#1] SMP CPU: 0 PID: 6502 Comm: rmmod Tainted: G OE 4.15.9-Generic #154-Ubuntu Hardware name: Dell Inc. Edge Gateway 3003/ , BIOS 01.00.00 04/17/2017 Stack: ffff88007392e600 ffff880075847dc0 ffffffff8108160a 0000000000000000 ffff88007392e600 ffff880075847de8 ffffffff810a484b ffff880076127000 ffff88003cd3a800 ffff880074f12a00 ffff880075847e28 ffffffffc09bed15 Call Trace: [] __put_task_struct+0x5a/0x140 [] kthread_stop+0x10b/0x110 [] rsi_disconnect+0x2f5/0x300 [ven_rsi_sdio] [] ? __pm_runtime_resume+0x5b/0x80 [] sdio_bus_remove+0x38/0x100 [] __device_release_driver+0xa4/0x150 [] driver_detach+0xb5/0xc0 [] bus_remove_driver+0x55/0xd0 [] driver_unregister+0x2c/0x50 [] sdio_unregister_driver+0x1a/0x20 [] rsi_module_exit+0x15/0x30 [ven_rsi_sdio] [] SyS_delete_module+0x1b8/0x210 [] entry_SYSCALL_64_fastpath+0x1c/0xbb Signed-off-by: Siva Rebbagondla Signed-off-by: Kalle Valo --- drivers/net/wireless/rsi/rsi_common.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/wireless/rsi/rsi_common.h b/drivers/net/wireless/rsi/rsi_common.h index d9ff3b8be86e..60f1f286b030 100644 --- a/drivers/net/wireless/rsi/rsi_common.h +++ b/drivers/net/wireless/rsi/rsi_common.h @@ -75,7 +75,6 @@ static inline int rsi_kill_thread(struct rsi_thread *handle) atomic_inc(&handle->thread_done); rsi_set_event(&handle->event); - wait_for_completion(&handle->completion); return kthread_stop(handle->task); } From 81c8eccc2404d06082025b773f1d90e8c861bc6a Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 23 Aug 2018 23:27:38 +0200 Subject: [PATCH 087/276] mt76: Fix comparisons with invalid hardware key index MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With gcc 4.1.2: drivers/net/wireless/mediatek/mt76/mt76x0/tx.c: In function ‘mt76x0_tx’: drivers/net/wireless/mediatek/mt76/mt76x0/tx.c:169: warning: comparison is always true due to limited range of data type drivers/net/wireless/mediatek/mt76/mt76x2_tx_common.c: In function ‘mt76x2_tx’: drivers/net/wireless/mediatek/mt76/mt76x2_tx_common.c:35: warning: comparison is always true due to limited range of data type While assigning -1 to a u8 works fine, comparing with -1 does not work as expected. Fix this by comparing with 0xff, like is already done in some other places. Signed-off-by: Geert Uytterhoeven Signed-off-by: Kalle Valo --- drivers/net/wireless/mediatek/mt76/mt76x0/tx.c | 2 +- drivers/net/wireless/mediatek/mt76/mt76x2_tx_common.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c b/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c index 751b49c28ae5..c45d05d5aab1 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c @@ -166,7 +166,7 @@ void mt76x0_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, if (sta) { msta = (struct mt76_sta *) sta->drv_priv; wcid = &msta->wcid; - } else if (vif && (!info->control.hw_key && wcid->hw_key_idx != -1)) { + } else if (vif && (!info->control.hw_key && wcid->hw_key_idx != 0xff)) { struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; wcid = &mvif->group_wcid; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_tx_common.c b/drivers/net/wireless/mediatek/mt76/mt76x2_tx_common.c index 36afb166fa3f..c0ca0df84ed8 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_tx_common.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_tx_common.c @@ -32,7 +32,7 @@ void mt76x2_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, msta = (struct mt76x2_sta *)control->sta->drv_priv; wcid = &msta->wcid; /* sw encrypted frames */ - if (!info->control.hw_key && wcid->hw_key_idx != -1) + if (!info->control.hw_key && wcid->hw_key_idx != 0xff) control->sta = NULL; } From 9b2fd48d36e25b9be9ddb8be8cc1eb263a1d1843 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Fri, 24 Aug 2018 10:17:49 +0200 Subject: [PATCH 088/276] mt76x2u: run device cleanup routine if resume fails Cleanup {tx,rx} and mcu queues if resume operation fails Fixes: ee676cd5017c ("mt76: add driver code for MT76x2u based devices") Signed-off-by: Lorenzo Bianconi Signed-off-by: Kalle Valo --- drivers/net/wireless/mediatek/mt76/mt76x2_usb.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_usb.c b/drivers/net/wireless/mediatek/mt76/mt76x2_usb.c index f5338c364a85..2a465c4e1009 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_usb.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_usb.c @@ -108,16 +108,24 @@ static int __maybe_unused mt76x2u_resume(struct usb_interface *intf) mt76u_mcu_complete_urb, &usb->mcu.cmpl); if (err < 0) - return err; + goto err; err = mt76u_submit_rx_buffers(&dev->mt76); if (err < 0) - return err; + goto err; tasklet_enable(&usb->rx_tasklet); tasklet_enable(&usb->tx_tasklet); - return mt76x2u_init_hardware(dev); + err = mt76x2u_init_hardware(dev); + if (err < 0) + goto err; + + return 0; + +err: + mt76x2u_cleanup(dev); + return err; } MODULE_DEVICE_TABLE(usb, mt76x2u_device_table); From ac5d5b3f199ed93e089754bf5d2a0a1ae6671d6d Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Fri, 24 Aug 2018 12:41:44 +0200 Subject: [PATCH 089/276] mt76: verify evt type in usb mcu response Verify if evt field is set to EVT_CMD_DONE in usb mcu response messages. This is a preliminary patch for usb_mcu layer unification between mt76x0u and mt76x2u driver. Signed-off-by: Lorenzo Bianconi Signed-off-by: Kalle Valo --- drivers/net/wireless/mediatek/mt76/dma.h | 10 ++++++++++ drivers/net/wireless/mediatek/mt76/usb_mcu.c | 3 ++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/mediatek/mt76/dma.h b/drivers/net/wireless/mediatek/mt76/dma.h index 27248e24a19b..828e52ae70e8 100644 --- a/drivers/net/wireless/mediatek/mt76/dma.h +++ b/drivers/net/wireless/mediatek/mt76/dma.h @@ -75,6 +75,16 @@ enum dma_msg_port { DISCARD, }; +enum mt76_mcu_evt_type { + EVT_CMD_DONE, + EVT_CMD_ERROR, + EVT_CMD_RETRY, + EVT_EVENT_PWR_RSP, + EVT_EVENT_WOW_RSP, + EVT_EVENT_CARRIER_DETECT_RSP, + EVT_EVENT_DFS_DETECT_RSP, +}; + int mt76_dma_attach(struct mt76_dev *dev); void mt76_dma_cleanup(struct mt76_dev *dev); diff --git a/drivers/net/wireless/mediatek/mt76/usb_mcu.c b/drivers/net/wireless/mediatek/mt76/usb_mcu.c index 070be803d463..ebf3e7ffb26b 100644 --- a/drivers/net/wireless/mediatek/mt76/usb_mcu.c +++ b/drivers/net/wireless/mediatek/mt76/usb_mcu.c @@ -73,7 +73,8 @@ static int mt76u_mcu_wait_resp(struct mt76_dev *dev, u8 seq) if (ret) return ret; - if (seq == FIELD_GET(MT_RX_FCE_INFO_CMD_SEQ, rxfce)) + if (seq == FIELD_GET(MT_RX_FCE_INFO_CMD_SEQ, rxfce) && + FIELD_GET(MT_RX_FCE_INFO_EVT_TYPE, rxfce) == EVT_CMD_DONE) return 0; dev_err(dev->dev, "error: MCU resp evt:%lx seq:%hhx-%lx\n", From 2735a6dd7df3ca95e1e98273abf1048d4c53c0e5 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 29 Aug 2018 13:16:32 +0200 Subject: [PATCH 090/276] mt76: unify wait_for_mac Create new mt76x02_mac.h for common mac functions of mt76x0 and mt76x2 and unity wait_for_mac for both drivers. Signed-off-by: Stanislaw Gruszka Signed-off-by: Kalle Valo --- .../net/wireless/mediatek/mt76/mt76x0/init.c | 11 +++-- .../wireless/mediatek/mt76/mt76x0/mt76x0.h | 3 +- .../net/wireless/mediatek/mt76/mt76x0/usb.c | 5 ++- .../net/wireless/mediatek/mt76/mt76x02_mac.h | 42 +++++++++++++++++++ drivers/net/wireless/mediatek/mt76/mt76x2.h | 17 -------- .../net/wireless/mediatek/mt76/mt76x2_init.c | 2 +- .../net/wireless/mediatek/mt76/mt76x2_mac.h | 1 + .../net/wireless/mediatek/mt76/mt76x2u_init.c | 4 +- 8 files changed, 57 insertions(+), 28 deletions(-) create mode 100644 drivers/net/wireless/mediatek/mt76/mt76x02_mac.h diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c index 7cdb3e740522..a1883da0543b 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c @@ -384,9 +384,11 @@ int mt76x0_init_hardware(struct mt76x0_dev *dev) mt76x0_chip_onoff(dev, true, true); - ret = mt76x0_wait_asic_ready(dev); - if (ret) + if (!mt76x02_wait_for_mac(&dev->mt76)) { + ret = -ETIMEDOUT; goto err; + } + ret = mt76x0_mcu_init(dev); if (ret) goto err; @@ -399,9 +401,10 @@ int mt76x0_init_hardware(struct mt76x0_dev *dev) } /* Wait for ASIC ready after FW load. */ - ret = mt76x0_wait_asic_ready(dev); - if (ret) + if (!mt76x02_wait_for_mac(&dev->mt76)) { + ret = -ETIMEDOUT; goto err; + } mt76x0_reset_csr_bbp(dev); mt76x0_init_usb_dma(dev); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h index fc9857f61771..84d1afc21f57 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h @@ -26,6 +26,7 @@ #include #include "../mt76.h" +#include "../mt76x02_mac.h" #include "regs.h" #define MT_CALIBRATE_INTERVAL (4 * HZ) @@ -263,8 +264,6 @@ static inline bool is_mt7610e(struct mt76x0_dev *dev) void mt76x0_init_debugfs(struct mt76x0_dev *dev); -int mt76x0_wait_asic_ready(struct mt76x0_dev *dev); - /* Compatibility with mt76 */ #define mt76_rmw_field(_dev, _reg, _field, _val) \ mt76_rmw(_dev, _reg, _field, FIELD_PREP(_field, _val)) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c index 54ae1f113be2..670973363c9f 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c @@ -287,9 +287,10 @@ static int mt76x0_probe(struct usb_interface *usb_intf, /* Disable the HW, otherwise MCU fail to initalize on hot reboot */ mt76x0_chip_onoff(dev, false, false); - ret = mt76x0_wait_asic_ready(dev); - if (ret) + if (!mt76x02_wait_for_mac(&dev->mt76)) { + ret = -ETIMEDOUT; goto err; + } asic_rev = mt76_rr(dev, MT_ASIC_VERSION); mac_rev = mt76_rr(dev, MT_MAC_CSR0); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h new file mode 100644 index 000000000000..4bf14fd8916d --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2016 Felix Fietkau + * Copyright (C) 2018 Stanislaw Gruszka + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef __MT76X02_MAC_H +#define __MT76X02_MAC_H + +static inline bool mt76x02_wait_for_mac(struct mt76_dev *dev) +{ + const u32 MAC_CSR0 = 0x1000; + int i; + + for (i = 0; i < 500; i++) { + if (test_bit(MT76_REMOVED, &dev->state)) + return -EIO; + + switch (dev->bus->rr(dev, MAC_CSR0)) { + case 0: + case ~0: + break; + default: + return true; + } + usleep_range(5000, 10000); + } + return false; +} + +#endif diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2.h b/drivers/net/wireless/mediatek/mt76/mt76x2.h index dca3209bf5f1..4c952b8a777c 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x2.h @@ -163,23 +163,6 @@ struct mt76x2_sta { int inactive_count; }; -static inline bool mt76x2_wait_for_mac(struct mt76x2_dev *dev) -{ - int i; - - for (i = 0; i < 500; i++) { - switch (mt76_rr(dev, MT_MAC_CSR0)) { - case 0: - case ~0: - break; - default: - return true; - } - usleep_range(5000, 10000); - } - return false; -} - static inline bool is_mt7612(struct mt76x2_dev *dev) { return mt76_chip(&dev->mt76) == 0x7612; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_init.c b/drivers/net/wireless/mediatek/mt76/mt76x2_init.c index b814391f79ac..75a4e171da6d 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_init.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_init.c @@ -101,7 +101,7 @@ static int mt76x2_mac_reset(struct mt76x2_dev *dev, bool hard) u32 val; int i, k; - if (!mt76x2_wait_for_mac(dev)) + if (!mt76x02_wait_for_mac(&dev->mt76)) return -ETIMEDOUT; val = mt76_rr(dev, MT_WPDMA_GLO_CFG); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.h b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.h index 5af0107ba748..0f07fc1a19ab 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.h @@ -18,6 +18,7 @@ #define __MT76x2_MAC_H #include "mt76.h" +#include "mt76x02_mac.h" struct mt76x2_dev; struct mt76x2_sta; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2u_init.c b/drivers/net/wireless/mediatek/mt76/mt76x2u_init.c index 9b81e7641c06..276e30608cea 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2u_init.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2u_init.c @@ -184,7 +184,7 @@ int mt76x2u_init_hardware(struct mt76x2_dev *dev) mt76x2_reset_wlan(dev, true); mt76x2u_power_on(dev); - if (!mt76x2_wait_for_mac(dev)) + if (!mt76x02_wait_for_mac(&dev->mt76)) return -ETIMEDOUT; err = mt76x2u_mcu_fw_init(dev); @@ -197,7 +197,7 @@ int mt76x2u_init_hardware(struct mt76x2_dev *dev) return -EIO; /* wait for asic ready after fw load. */ - if (!mt76x2_wait_for_mac(dev)) + if (!mt76x02_wait_for_mac(&dev->mt76)) return -ETIMEDOUT; mt76_wr(dev, MT_HEADER_TRANS_CTRL_REG, 0); From 89e1b1bc075a74a808779e3e7e90d059132266f4 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 29 Aug 2018 13:16:33 +0200 Subject: [PATCH 091/276] mt76: rename mt76x2_regs.h MAC registers are the same for mt76x0 and mt76x2. Rename mt76x2_regs.h file to reflect that. Signed-off-by: Stanislaw Gruszka Signed-off-by: Kalle Valo --- .../wireless/mediatek/mt76/{mt76x2_regs.h => mt76x02_regs.h} | 4 ++-- drivers/net/wireless/mediatek/mt76/mt76x2.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) rename drivers/net/wireless/mediatek/mt76/{mt76x2_regs.h => mt76x02_regs.h} (99%) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_regs.h b/drivers/net/wireless/mediatek/mt76/mt76x02_regs.h similarity index 99% rename from drivers/net/wireless/mediatek/mt76/mt76x2_regs.h rename to drivers/net/wireless/mediatek/mt76/mt76x02_regs.h index 1551ea453180..b0f00107cf2d 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_regs.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_regs.h @@ -14,8 +14,8 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef __MT76x2_REGS_H -#define __MT76x2_REGS_H +#ifndef __MT76X02_REGS_H +#define __MT76X02_REGS_H #define MT_ASIC_VERSION 0x0000 diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2.h b/drivers/net/wireless/mediatek/mt76/mt76x2.h index 4c952b8a777c..8b5c3de9ea32 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x2.h @@ -47,7 +47,7 @@ #define MT_VIF_WCID(_n) (254 - ((_n) & 7)) #include "mt76.h" -#include "mt76x2_regs.h" +#include "mt76x02_regs.h" #include "mt76x2_mac.h" #include "mt76x2_dfs.h" From 797ea240782505ddad901a59651b598385a50302 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 29 Aug 2018 13:16:34 +0200 Subject: [PATCH 092/276] mt76: merge mt76x0/regs.h into mt76x02_regs.h Add missed definitions for mt76x0 into mt76x02_regs.h. Remove mt76x0/regs.h and fixup mt76x0 code to adjust to some diffrent registers/fields names. Signed-off-by: Stanislaw Gruszka Signed-off-by: Kalle Valo --- .../net/wireless/mediatek/mt76/mt76x0/init.c | 16 +- .../net/wireless/mediatek/mt76/mt76x0/mac.c | 10 +- .../net/wireless/mediatek/mt76/mt76x0/main.c | 4 +- .../net/wireless/mediatek/mt76/mt76x0/mcu.c | 4 +- .../wireless/mediatek/mt76/mt76x0/mt76x0.h | 2 +- .../net/wireless/mediatek/mt76/mt76x0/regs.h | 651 ------------------ .../net/wireless/mediatek/mt76/mt76x02_regs.h | 74 +- .../mediatek/mt76/mt76x2_mac_common.c | 6 +- 8 files changed, 91 insertions(+), 676 deletions(-) delete mode 100644 drivers/net/wireless/mediatek/mt76/mt76x0/regs.h diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c index a1883da0543b..f23d1a04b35f 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c @@ -127,9 +127,9 @@ static void mt76x0_init_usb_dma(struct mt76x0_dev *dev) val = mt76_rr(dev, MT_USB_DMA_CFG); - val |= MT_USB_DMA_CFG_RX_DROP_OR_PADDING; + val |= MT_USB_DMA_CFG_RX_DROP_OR_PAD; mt76_wr(dev, MT_USB_DMA_CFG, val); - val &= ~MT_USB_DMA_CFG_RX_DROP_OR_PADDING; + val &= ~MT_USB_DMA_CFG_RX_DROP_OR_PAD; mt76_wr(dev, MT_USB_DMA_CFG, val); } @@ -274,12 +274,12 @@ static int mt76x0_init_wcid_attr_mem(struct mt76x0_dev *dev) static void mt76x0_reset_counters(struct mt76x0_dev *dev) { - mt76_rr(dev, MT_RX_STA_CNT0); - mt76_rr(dev, MT_RX_STA_CNT1); - mt76_rr(dev, MT_RX_STA_CNT2); - mt76_rr(dev, MT_TX_STA_CNT0); - mt76_rr(dev, MT_TX_STA_CNT1); - mt76_rr(dev, MT_TX_STA_CNT2); + mt76_rr(dev, MT_RX_STAT_0); + mt76_rr(dev, MT_RX_STAT_1); + mt76_rr(dev, MT_RX_STAT_2); + mt76_rr(dev, MT_TX_STA_0); + mt76_rr(dev, MT_TX_STA_1); + mt76_rr(dev, MT_TX_STA_2); } int mt76x0_mac_start(struct mt76x0_dev *dev) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c b/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c index 91a84be36d3b..74e922026c9f 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c @@ -355,8 +355,8 @@ void mt76x0_mac_work(struct work_struct *work) u32 span; u64 *stat_base; } spans[] = { - { MT_RX_STA_CNT0, 3, dev->stats.rx_stat }, - { MT_TX_STA_CNT0, 3, dev->stats.tx_stat }, + { MT_RX_STAT_0, 3, dev->stats.rx_stat }, + { MT_TX_STA_0, 3, dev->stats.tx_stat }, { MT_TX_AGG_STAT, 1, dev->stats.aggr_stat }, { MT_MPDU_DENSITY_CNT, 1, dev->stats.zero_len_del }, { MT_TX_AGG_CNT_BASE0, 8, &dev->stats.aggr_n[0] }, @@ -566,7 +566,7 @@ u32 mt76x0_mac_process_rx(struct mt76x0_dev *dev, struct sk_buff *skb, return len; } -static enum mt76_cipher_type +static enum mt76x02_cipher_type mt76_mac_get_key_info(struct ieee80211_key_conf *key, u8 *key_data) { memset(key_data, 0, 32); @@ -595,7 +595,7 @@ mt76_mac_get_key_info(struct ieee80211_key_conf *key, u8 *key_data) int mt76x0_mac_wcid_set_key(struct mt76x0_dev *dev, u8 idx, struct ieee80211_key_conf *key) { - enum mt76_cipher_type cipher; + enum mt76x02_cipher_type cipher; u8 key_data[32]; u8 iv_data[8]; u32 val; @@ -636,7 +636,7 @@ int mt76x0_mac_wcid_set_key(struct mt76x0_dev *dev, u8 idx, int mt76x0_mac_shared_key_setup(struct mt76x0_dev *dev, u8 vif_idx, u8 key_idx, struct ieee80211_key_conf *key) { - enum mt76_cipher_type cipher; + enum mt76x02_cipher_type cipher; u8 key_data[32]; u32 val; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c index cf6ffb1ba4a2..46e458835e58 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c @@ -166,8 +166,8 @@ mt76x0_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, if (changed & BSS_CHANGED_BASIC_RATES) { mt76_wr(dev, MT_LEGACY_BASIC_RATE, info->basic_rates); - mt76_wr(dev, MT_HT_FBK_CFG0, 0x65432100); - mt76_wr(dev, MT_HT_FBK_CFG1, 0xedcba980); + mt76_wr(dev, MT_VHT_HT_FBK_CFG0, 0x65432100); + mt76_wr(dev, MT_VHT_HT_FBK_CFG1, 0xedcba980); mt76_wr(dev, MT_LG_FBK_CFG0, 0xedcba988); mt76_wr(dev, MT_LG_FBK_CFG1, 0x00002100); } diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c index 8affacbab90a..96e04afc73f4 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c @@ -591,9 +591,9 @@ static int mt76x0_load_firmware(struct mt76x0_dev *dev) mt76_wr(dev, MT_FCE_SKIP_FS, 3); val = mt76_rr(dev, MT_USB_DMA_CFG); - val |= MT_USB_DMA_CFG_TX_WL_DROP; + val |= MT_USB_DMA_CFG_UDMA_TX_WL_DROP; mt76_wr(dev, MT_USB_DMA_CFG, val); - val &= ~MT_USB_DMA_CFG_TX_WL_DROP; + val &= ~MT_USB_DMA_CFG_UDMA_TX_WL_DROP; mt76_wr(dev, MT_USB_DMA_CFG, val); ret = mt76x0_upload_firmware(dev, (const struct mt76_fw *)fw->data); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h index 84d1afc21f57..6c52f73c1b94 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h @@ -26,8 +26,8 @@ #include #include "../mt76.h" +#include "../mt76x02_regs.h" #include "../mt76x02_mac.h" -#include "regs.h" #define MT_CALIBRATE_INTERVAL (4 * HZ) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/regs.h b/drivers/net/wireless/mediatek/mt76/mt76x0/regs.h deleted file mode 100644 index 16bed4aaa242..000000000000 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/regs.h +++ /dev/null @@ -1,651 +0,0 @@ -/* - * Copyright (C) 2014 Felix Fietkau - * Copyright (C) 2015 Jakub Kicinski - * Copyright (C) 2018 Stanislaw Gruszka - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef __MT76_REGS_H -#define __MT76_REGS_H - -#include - -#define MT_ASIC_VERSION 0x0000 - -#define MT76XX_REV_E3 0x22 -#define MT76XX_REV_E4 0x33 - -#define MT_CMB_CTRL 0x0020 -#define MT_CMB_CTRL_XTAL_RDY BIT(22) -#define MT_CMB_CTRL_PLL_LD BIT(23) - -#define MT_EFUSE_CTRL 0x0024 -#define MT_EFUSE_CTRL_AOUT GENMASK(5, 0) -#define MT_EFUSE_CTRL_MODE GENMASK(7, 6) -#define MT_EFUSE_CTRL_LDO_OFF_TIME GENMASK(13, 8) -#define MT_EFUSE_CTRL_LDO_ON_TIME GENMASK(15, 14) -#define MT_EFUSE_CTRL_AIN GENMASK(25, 16) -#define MT_EFUSE_CTRL_KICK BIT(30) -#define MT_EFUSE_CTRL_SEL BIT(31) - -#define MT_EFUSE_DATA_BASE 0x0028 -#define MT_EFUSE_DATA(_n) (MT_EFUSE_DATA_BASE + ((_n) << 2)) - -#define MT_COEXCFG0 0x0040 -#define MT_COEXCFG0_COEX_EN BIT(0) - -#define MT_COEXCFG3 0x004c - -#define MT_LDO_CTRL_0 0x006c -#define MT_LDO_CTRL_1 0x0070 - -#define MT_WLAN_FUN_CTRL 0x0080 -#define MT_WLAN_FUN_CTRL_WLAN_EN BIT(0) -#define MT_WLAN_FUN_CTRL_WLAN_CLK_EN BIT(1) -#define MT_WLAN_FUN_CTRL_WLAN_RESET_RF BIT(2) - -#define MT_WLAN_FUN_CTRL_WLAN_RESET BIT(3) /* MT76x0 */ -#define MT_WLAN_FUN_CTRL_CSR_F20M_CKEN BIT(3) /* MT76x2 */ - -#define MT_WLAN_FUN_CTRL_PCIE_CLK_REQ BIT(4) -#define MT_WLAN_FUN_CTRL_FRC_WL_ANT_SEL BIT(5) -#define MT_WLAN_FUN_CTRL_INV_ANT_SEL BIT(6) -#define MT_WLAN_FUN_CTRL_WAKE_HOST BIT(7) - -#define MT_WLAN_FUN_CTRL_THERM_RST BIT(8) /* MT76x2 */ -#define MT_WLAN_FUN_CTRL_THERM_CKEN BIT(9) /* MT76x2 */ - -#define MT_WLAN_FUN_CTRL_GPIO_IN GENMASK(15, 8) /* MT76x0 */ -#define MT_WLAN_FUN_CTRL_GPIO_OUT GENMASK(23, 16) /* MT76x0 */ -#define MT_WLAN_FUN_CTRL_GPIO_OUT_EN GENMASK(31, 24) /* MT76x0 */ - -#define MT_XO_CTRL0 0x0100 -#define MT_XO_CTRL1 0x0104 -#define MT_XO_CTRL2 0x0108 -#define MT_XO_CTRL3 0x010c -#define MT_XO_CTRL4 0x0110 - -#define MT_XO_CTRL5 0x0114 -#define MT_XO_CTRL5_C2_VAL GENMASK(14, 8) - -#define MT_XO_CTRL6 0x0118 -#define MT_XO_CTRL6_C2_CTRL GENMASK(14, 8) - -#define MT_XO_CTRL7 0x011c - -#define MT_IOCFG_6 0x0124 -#define MT_WLAN_MTC_CTRL 0x10148 -#define MT_WLAN_MTC_CTRL_MTCMOS_PWR_UP BIT(0) -#define MT_WLAN_MTC_CTRL_PWR_ACK BIT(12) -#define MT_WLAN_MTC_CTRL_PWR_ACK_S BIT(13) -#define MT_WLAN_MTC_CTRL_BBP_MEM_PD GENMASK(19, 16) -#define MT_WLAN_MTC_CTRL_PBF_MEM_PD BIT(20) -#define MT_WLAN_MTC_CTRL_FCE_MEM_PD BIT(21) -#define MT_WLAN_MTC_CTRL_TSO_MEM_PD BIT(22) -#define MT_WLAN_MTC_CTRL_BBP_MEM_RB BIT(24) -#define MT_WLAN_MTC_CTRL_PBF_MEM_RB BIT(25) -#define MT_WLAN_MTC_CTRL_FCE_MEM_RB BIT(26) -#define MT_WLAN_MTC_CTRL_TSO_MEM_RB BIT(27) -#define MT_WLAN_MTC_CTRL_STATE_UP BIT(28) - -#define MT_INT_SOURCE_CSR 0x0200 -#define MT_INT_MASK_CSR 0x0204 - -#define MT_INT_RX_DONE(_n) BIT(_n) -#define MT_INT_RX_DONE_ALL GENMASK(1, 0) -#define MT_INT_TX_DONE_ALL GENMASK(13, 4) -#define MT_INT_TX_DONE(_n) BIT(_n + 4) -#define MT_INT_RX_COHERENT BIT(16) -#define MT_INT_TX_COHERENT BIT(17) -#define MT_INT_ANY_COHERENT BIT(18) -#define MT_INT_MCU_CMD BIT(19) -#define MT_INT_TBTT BIT(20) -#define MT_INT_PRE_TBTT BIT(21) -#define MT_INT_TX_STAT BIT(22) -#define MT_INT_AUTO_WAKEUP BIT(23) -#define MT_INT_GPTIMER BIT(24) -#define MT_INT_RXDELAYINT BIT(26) -#define MT_INT_TXDELAYINT BIT(27) - -#define MT_WPDMA_GLO_CFG 0x0208 -#define MT_WPDMA_GLO_CFG_TX_DMA_EN BIT(0) -#define MT_WPDMA_GLO_CFG_TX_DMA_BUSY BIT(1) -#define MT_WPDMA_GLO_CFG_RX_DMA_EN BIT(2) -#define MT_WPDMA_GLO_CFG_RX_DMA_BUSY BIT(3) -#define MT_WPDMA_GLO_CFG_DMA_BURST_SIZE GENMASK(5, 4) -#define MT_WPDMA_GLO_CFG_TX_WRITEBACK_DONE BIT(6) -#define MT_WPDMA_GLO_CFG_BIG_ENDIAN BIT(7) -#define MT_WPDMA_GLO_CFG_HDR_SEG_LEN GENMASK(15, 8) -#define MT_WPDMA_GLO_CFG_CLK_GATE_DIS BIT(30) -#define MT_WPDMA_GLO_CFG_RX_2B_OFFSET BIT(31) - -#define MT_WPDMA_RST_IDX 0x020c - -#define MT_WPDMA_DELAY_INT_CFG 0x0210 - -#define MT_WMM_AIFSN 0x0214 -#define MT_WMM_AIFSN_MASK GENMASK(3, 0) -#define MT_WMM_AIFSN_SHIFT(_n) ((_n) * 4) - -#define MT_WMM_CWMIN 0x0218 -#define MT_WMM_CWMIN_MASK GENMASK(3, 0) -#define MT_WMM_CWMIN_SHIFT(_n) ((_n) * 4) - -#define MT_WMM_CWMAX 0x021c -#define MT_WMM_CWMAX_MASK GENMASK(3, 0) -#define MT_WMM_CWMAX_SHIFT(_n) ((_n) * 4) - -#define MT_WMM_TXOP_BASE 0x0220 -#define MT_WMM_TXOP(_n) (MT_WMM_TXOP_BASE + (((_n) / 2) << 2)) -#define MT_WMM_TXOP_SHIFT(_n) ((_n & 1) * 16) -#define MT_WMM_TXOP_MASK GENMASK(15, 0) - -#define MT_WMM_CTRL 0x0230 /* MT76x0 */ - -#define MT_FCE_DMA_ADDR 0x0230 -#define MT_FCE_DMA_LEN 0x0234 - -#define MT_USB_DMA_CFG 0x238 -#define MT_USB_DMA_CFG_RX_BULK_AGG_TOUT GENMASK(7, 0) -#define MT_USB_DMA_CFG_RX_BULK_AGG_LMT GENMASK(15, 8) -#define MT_USB_DMA_CFG_TX_WL_DROP BIT(16) -#define MT_USB_DMA_CFG_WAKEUP_EN BIT(17) -#define MT_USB_DMA_CFG_RX_DROP_OR_PADDING BIT(18) -#define MT_USB_DMA_CFG_TX_CLR BIT(19) -#define MT_USB_DMA_CFG_WL_LPK_EN BIT(20) -#define MT_USB_DMA_CFG_RX_BULK_AGG_EN BIT(21) -#define MT_USB_DMA_CFG_RX_BULK_EN BIT(22) -#define MT_USB_DMA_CFG_TX_BULK_EN BIT(23) -#define MT_USB_DMA_CFG_EP_OUT_VALID GENMASK(29, 24) -#define MT_USB_DMA_CFG_RX_BUSY BIT(30) -#define MT_USB_DMA_CFG_TX_BUSY BIT(31) -#if 0 -#define MT_USB_DMA_CFG_TX_CLR BIT(19) -#define MT_USB_DMA_CFG_TXOP_HALT BIT(20) -#define MT_USB_DMA_CFG_RX_BULK_AGG_EN BIT(21) -#define MT_USB_DMA_CFG_RX_BULK_EN BIT(22) -#define MT_USB_DMA_CFG_TX_BULK_EN BIT(23) -#define MT_USB_DMA_CFG_UDMA_RX_WL_DROP BIT(25) -#endif - -#define MT_TSO_CTRL 0x0250 -#define MT_HEADER_TRANS_CTRL_REG 0x0260 - -#define MT_US_CYC_CFG 0x02a4 -#define MT_US_CYC_CNT GENMASK(7, 0) - -#define MT_TX_RING_BASE 0x0300 -#define MT_RX_RING_BASE 0x03c0 -#define MT_RING_SIZE 0x10 - -#define MT_TX_HW_QUEUE_MCU 8 -#define MT_TX_HW_QUEUE_MGMT 9 - -#define MT_PBF_SYS_CTRL 0x0400 -#define MT_PBF_SYS_CTRL_MCU_RESET BIT(0) -#define MT_PBF_SYS_CTRL_DMA_RESET BIT(1) -#define MT_PBF_SYS_CTRL_MAC_RESET BIT(2) -#define MT_PBF_SYS_CTRL_PBF_RESET BIT(3) -#define MT_PBF_SYS_CTRL_ASY_RESET BIT(4) - -#define MT_PBF_CFG 0x0404 -#define MT_PBF_CFG_TX0Q_EN BIT(0) -#define MT_PBF_CFG_TX1Q_EN BIT(1) -#define MT_PBF_CFG_TX2Q_EN BIT(2) -#define MT_PBF_CFG_TX3Q_EN BIT(3) -#define MT_PBF_CFG_RX0Q_EN BIT(4) -#define MT_PBF_CFG_RX_DROP_EN BIT(8) - -#define MT_PBF_TX_MAX_PCNT 0x0408 -#define MT_PBF_RX_MAX_PCNT 0x040c - -#define MT_BCN_OFFSET_BASE 0x041c -#define MT_BCN_OFFSET(_n) (MT_BCN_OFFSET_BASE + ((_n) << 2)) - -#define MT_RXQ_STA 0x0430 -#define MT_TXQ_STA 0x0434 -#define MT_RF_CSR_CFG 0x0500 -#define MT_RF_CSR_CFG_DATA GENMASK(7, 0) -#define MT_RF_CSR_CFG_REG_ID GENMASK(13, 8) -#define MT_RF_CSR_CFG_REG_BANK GENMASK(17, 14) -#define MT_RF_CSR_CFG_WR BIT(30) -#define MT_RF_CSR_CFG_KICK BIT(31) - -#define MT_RF_BYPASS_0 0x0504 -#define MT_RF_BYPASS_1 0x0508 -#define MT_RF_SETTING_0 0x050c - -#define MT_RF_MISC 0x0518 -#define MT_RF_DATA_WRITE 0x0524 - -#define MT_RF_CTRL 0x0528 -#define MT_RF_CTRL_ADDR GENMASK(11, 0) -#define MT_RF_CTRL_WRITE BIT(12) -#define MT_RF_CTRL_BUSY BIT(13) -#define MT_RF_CTRL_IDX BIT(16) - -#define MT_RF_DATA_READ 0x052c - -#define MT_COM_REG0 0x0730 -#define MT_COM_REG1 0x0734 -#define MT_COM_REG2 0x0738 -#define MT_COM_REG3 0x073C - -#define MT_FCE_PSE_CTRL 0x0800 -#define MT_FCE_PARAMETERS 0x0804 -#define MT_FCE_CSO 0x0808 - -#define MT_FCE_L2_STUFF 0x080c -#define MT_FCE_L2_STUFF_HT_L2_EN BIT(0) -#define MT_FCE_L2_STUFF_QOS_L2_EN BIT(1) -#define MT_FCE_L2_STUFF_RX_STUFF_EN BIT(2) -#define MT_FCE_L2_STUFF_TX_STUFF_EN BIT(3) -#define MT_FCE_L2_STUFF_WR_MPDU_LEN_EN BIT(4) -#define MT_FCE_L2_STUFF_MVINV_BSWAP BIT(5) -#define MT_FCE_L2_STUFF_TS_CMD_QSEL_EN GENMASK(15, 8) -#define MT_FCE_L2_STUFF_TS_LEN_EN GENMASK(23, 16) -#define MT_FCE_L2_STUFF_OTHER_PORT GENMASK(25, 24) - -#define MT_FCE_WLAN_FLOW_CONTROL1 0x0824 - -#define MT_TX_CPU_FROM_FCE_BASE_PTR 0x09a0 -#define MT_TX_CPU_FROM_FCE_MAX_COUNT 0x09a4 -#define MT_TX_CPU_FROM_FCE_CPU_DESC_IDX 0x09a8 - -#define MT_FCE_PDMA_GLOBAL_CONF 0x09c4 - -#define MT_PAUSE_ENABLE_CONTROL1 0x0a38 - -#define MT_FCE_SKIP_FS 0x0a6c - -#define MT_MAC_CSR0 0x1000 -#define MT_MAC_SYS_CTRL 0x1004 -#define MT_MAC_SYS_CTRL_RESET_CSR BIT(0) -#define MT_MAC_SYS_CTRL_RESET_BBP BIT(1) -#define MT_MAC_SYS_CTRL_ENABLE_TX BIT(2) -#define MT_MAC_SYS_CTRL_ENABLE_RX BIT(3) - -#define MT_MAC_ADDR_DW0 0x1008 -#define MT_MAC_ADDR_DW1 0x100c -#define MT_MAC_ADDR_DW1_U2ME_MASK GENMASK(23, 16) - -#define MT_MAC_BSSID_DW0 0x1010 -#define MT_MAC_BSSID_DW1 0x1014 -#define MT_MAC_BSSID_DW1_ADDR GENMASK(15, 0) -#define MT_MAC_BSSID_DW1_MBSS_MODE GENMASK(17, 16) -#define MT_MAC_BSSID_DW1_MBEACON_N GENMASK(20, 18) -#define MT_MAC_BSSID_DW1_MBSS_LOCAL_BIT BIT(21) -#define MT_MAC_BSSID_DW1_MBSS_MODE_B2 BIT(22) -#define MT_MAC_BSSID_DW1_MBEACON_N_B3 BIT(23) -#define MT_MAC_BSSID_DW1_MBSS_IDX_BYTE GENMASK(26, 24) - -#define MT_MAX_LEN_CFG 0x1018 -#define MT_MAX_LEN_CFG_AMPDU GENMASK(13, 12) - -#define MT_LED_CFG 0x102c - -#define MT_AMPDU_MAX_LEN_20M1S 0x1030 -#define MT_AMPDU_MAX_LEN_20M2S 0x1034 -#define MT_AMPDU_MAX_LEN_40M1S 0x1038 -#define MT_AMPDU_MAX_LEN_40M2S 0x103c -#define MT_AMPDU_MAX_LEN 0x1040 - -#define MT_WCID_DROP_BASE 0x106c -#define MT_WCID_DROP(_n) (MT_WCID_DROP_BASE + ((_n) >> 5) * 4) -#define MT_WCID_DROP_MASK(_n) BIT((_n) % 32) - -#define MT_BCN_BYPASS_MASK 0x108c - -#define MT_MAC_APC_BSSID_BASE 0x1090 -#define MT_MAC_APC_BSSID_L(_n) (MT_MAC_APC_BSSID_BASE + ((_n) * 8)) -#define MT_MAC_APC_BSSID_H(_n) (MT_MAC_APC_BSSID_BASE + ((_n) * 8 + 4)) -#define MT_MAC_APC_BSSID_H_ADDR GENMASK(15, 0) -#define MT_MAC_APC_BSSID0_H_EN BIT(16) - -#define MT_XIFS_TIME_CFG 0x1100 -#define MT_XIFS_TIME_CFG_CCK_SIFS GENMASK(7, 0) -#define MT_XIFS_TIME_CFG_OFDM_SIFS GENMASK(15, 8) -#define MT_XIFS_TIME_CFG_OFDM_XIFS GENMASK(19, 16) -#define MT_XIFS_TIME_CFG_EIFS GENMASK(28, 20) -#define MT_XIFS_TIME_CFG_BB_RXEND_EN BIT(29) - -#define MT_BKOFF_SLOT_CFG 0x1104 -#define MT_BKOFF_SLOT_CFG_SLOTTIME GENMASK(7, 0) -#define MT_BKOFF_SLOT_CFG_CC_DELAY GENMASK(11, 8) - -#define MT_BEACON_TIME_CFG 0x1114 -#define MT_BEACON_TIME_CFG_INTVAL GENMASK(15, 0) -#define MT_BEACON_TIME_CFG_TIMER_EN BIT(16) -#define MT_BEACON_TIME_CFG_SYNC_MODE GENMASK(18, 17) -#define MT_BEACON_TIME_CFG_TBTT_EN BIT(19) -#define MT_BEACON_TIME_CFG_BEACON_TX BIT(20) -#define MT_BEACON_TIME_CFG_TSF_COMP GENMASK(31, 24) - -#define MT_TBTT_SYNC_CFG 0x1118 -#define MT_TBTT_TIMER_CFG 0x1124 - -#define MT_INT_TIMER_CFG 0x1128 -#define MT_INT_TIMER_CFG_PRE_TBTT GENMASK(15, 0) -#define MT_INT_TIMER_CFG_GP_TIMER GENMASK(31, 16) - -#define MT_INT_TIMER_EN 0x112c -#define MT_INT_TIMER_EN_PRE_TBTT_EN BIT(0) -#define MT_INT_TIMER_EN_GP_TIMER_EN BIT(1) - -#define MT_MAC_STATUS 0x1200 -#define MT_MAC_STATUS_TX BIT(0) -#define MT_MAC_STATUS_RX BIT(1) - -#define MT_PWR_PIN_CFG 0x1204 -#define MT_AUX_CLK_CFG 0x120c - -#define MT_BB_PA_MODE_CFG0 0x1214 -#define MT_BB_PA_MODE_CFG1 0x1218 -#define MT_RF_PA_MODE_CFG0 0x121c -#define MT_RF_PA_MODE_CFG1 0x1220 - -#define MT_RF_PA_MODE_ADJ0 0x1228 -#define MT_RF_PA_MODE_ADJ1 0x122c - -#define MT_DACCLK_EN_DLY_CFG 0x1264 - -#define MT_EDCA_CFG_BASE 0x1300 -#define MT_EDCA_CFG_AC(_n) (MT_EDCA_CFG_BASE + ((_n) << 2)) -#define MT_EDCA_CFG_TXOP GENMASK(7, 0) -#define MT_EDCA_CFG_AIFSN GENMASK(11, 8) -#define MT_EDCA_CFG_CWMIN GENMASK(15, 12) -#define MT_EDCA_CFG_CWMAX GENMASK(19, 16) - -#define MT_TX_PWR_CFG_0 0x1314 -#define MT_TX_PWR_CFG_1 0x1318 -#define MT_TX_PWR_CFG_2 0x131c -#define MT_TX_PWR_CFG_3 0x1320 -#define MT_TX_PWR_CFG_4 0x1324 - -#define MT_TX_BAND_CFG 0x132c -#define MT_TX_BAND_CFG_UPPER_40M BIT(0) -#define MT_TX_BAND_CFG_5G BIT(1) -#define MT_TX_BAND_CFG_2G BIT(2) - -#define MT_HT_FBK_TO_LEGACY 0x1384 -#define MT_TX_MPDU_ADJ_INT 0x1388 - -#define MT_TX_PWR_CFG_7 0x13d4 -#define MT_TX_PWR_CFG_8 0x13d8 -#define MT_TX_PWR_CFG_9 0x13dc - -#define MT_TX_SW_CFG0 0x1330 -#define MT_TX_SW_CFG1 0x1334 -#define MT_TX_SW_CFG2 0x1338 - -#define MT_TXOP_CTRL_CFG 0x1340 -#define MT_TXOP_TRUN_EN GENMASK(5, 0) -#define MT_TXOP_EXT_CCA_DLY GENMASK(15, 8) -#define MT_TXOP_CTRL - -#define MT_TX_RTS_CFG 0x1344 -#define MT_TX_RTS_CFG_RETRY_LIMIT GENMASK(7, 0) -#define MT_TX_RTS_CFG_THRESH GENMASK(23, 8) -#define MT_TX_RTS_FALLBACK BIT(24) - -#define MT_TX_TIMEOUT_CFG 0x1348 -#define MT_TX_RETRY_CFG 0x134c -#define MT_TX_LINK_CFG 0x1350 -#define MT_HT_FBK_CFG0 0x1354 -#define MT_HT_FBK_CFG1 0x1358 -#define MT_LG_FBK_CFG0 0x135c -#define MT_LG_FBK_CFG1 0x1360 - -#define MT_CCK_PROT_CFG 0x1364 -#define MT_OFDM_PROT_CFG 0x1368 -#define MT_MM20_PROT_CFG 0x136c -#define MT_MM40_PROT_CFG 0x1370 -#define MT_GF20_PROT_CFG 0x1374 -#define MT_GF40_PROT_CFG 0x1378 - -#define MT_PROT_RATE GENMASK(15, 0) -#define MT_PROT_CTRL_RTS_CTS BIT(16) -#define MT_PROT_CTRL_CTS2SELF BIT(17) -#define MT_PROT_NAV_SHORT BIT(18) -#define MT_PROT_NAV_LONG BIT(19) -#define MT_PROT_TXOP_ALLOW_CCK BIT(20) -#define MT_PROT_TXOP_ALLOW_OFDM BIT(21) -#define MT_PROT_TXOP_ALLOW_MM20 BIT(22) -#define MT_PROT_TXOP_ALLOW_MM40 BIT(23) -#define MT_PROT_TXOP_ALLOW_GF20 BIT(24) -#define MT_PROT_TXOP_ALLOW_GF40 BIT(25) -#define MT_PROT_RTS_THR_EN BIT(26) -#define MT_PROT_RATE_CCK_11 0x0003 -#define MT_PROT_RATE_OFDM_6 0x4000 -#define MT_PROT_RATE_OFDM_24 0x4004 -#define MT_PROT_RATE_DUP_OFDM_24 0x4084 -#define MT_PROT_TXOP_ALLOW_ALL GENMASK(25, 20) -#define MT_PROT_TXOP_ALLOW_BW20 (MT_PROT_TXOP_ALLOW_ALL & \ - ~MT_PROT_TXOP_ALLOW_MM40 & \ - ~MT_PROT_TXOP_ALLOW_GF40) - -#define MT_EXP_ACK_TIME 0x1380 - -#define MT_TX_PWR_CFG_0_EXT 0x1390 -#define MT_TX_PWR_CFG_1_EXT 0x1394 - -#define MT_TX_FBK_LIMIT 0x1398 -#define MT_TX_FBK_LIMIT_MPDU_FBK GENMASK(7, 0) -#define MT_TX_FBK_LIMIT_AMPDU_FBK GENMASK(15, 8) -#define MT_TX_FBK_LIMIT_MPDU_UP_CLEAR BIT(16) -#define MT_TX_FBK_LIMIT_AMPDU_UP_CLEAR BIT(17) -#define MT_TX_FBK_LIMIT_RATE_LUT BIT(18) - -#define MT_TX0_RF_GAIN_CORR 0x13a0 -#define MT_TX1_RF_GAIN_CORR 0x13a4 -#define MT_TX0_RF_GAIN_ATTEN 0x13a8 - -#define MT_TX_ALC_CFG_0 0x13b0 -#define MT_TX_ALC_CFG_0_CH_INIT_0 GENMASK(5, 0) -#define MT_TX_ALC_CFG_0_CH_INIT_1 GENMASK(13, 8) -#define MT_TX_ALC_CFG_0_LIMIT_0 GENMASK(21, 16) -#define MT_TX_ALC_CFG_0_LIMIT_1 GENMASK(29, 24) - -#define MT_TX_ALC_CFG_1 0x13b4 -#define MT_TX_ALC_CFG_1_TEMP_COMP GENMASK(5, 0) - -#define MT_TX_ALC_CFG_2 0x13a8 -#define MT_TX_ALC_CFG_2_TEMP_COMP GENMASK(5, 0) - -#define MT_TX0_BB_GAIN_ATTEN 0x13c0 - -#define MT_TX_ALC_VGA3 0x13c8 - -#define MT_TX_PROT_CFG6 0x13e0 -#define MT_TX_PROT_CFG7 0x13e4 -#define MT_TX_PROT_CFG8 0x13e8 - -#define MT_PIFS_TX_CFG 0x13ec - -#define MT_RX_FILTR_CFG 0x1400 - -#define MT_RX_FILTR_CFG_CRC_ERR BIT(0) -#define MT_RX_FILTR_CFG_PHY_ERR BIT(1) -#define MT_RX_FILTR_CFG_PROMISC BIT(2) -#define MT_RX_FILTR_CFG_OTHER_BSS BIT(3) -#define MT_RX_FILTR_CFG_VER_ERR BIT(4) -#define MT_RX_FILTR_CFG_MCAST BIT(5) -#define MT_RX_FILTR_CFG_BCAST BIT(6) -#define MT_RX_FILTR_CFG_DUP BIT(7) -#define MT_RX_FILTR_CFG_CFACK BIT(8) -#define MT_RX_FILTR_CFG_CFEND BIT(9) -#define MT_RX_FILTR_CFG_ACK BIT(10) -#define MT_RX_FILTR_CFG_CTS BIT(11) -#define MT_RX_FILTR_CFG_RTS BIT(12) -#define MT_RX_FILTR_CFG_PSPOLL BIT(13) -#define MT_RX_FILTR_CFG_BA BIT(14) -#define MT_RX_FILTR_CFG_BAR BIT(15) -#define MT_RX_FILTR_CFG_CTRL_RSV BIT(16) - -#define MT_AUTO_RSP_CFG 0x1404 - -#define MT_AUTO_RSP_PREAMB_SHORT BIT(4) - -#define MT_LEGACY_BASIC_RATE 0x1408 -#define MT_HT_BASIC_RATE 0x140c -#define MT_HT_CTRL_CFG 0x1410 -#define MT_RX_PARSER_CFG 0x1418 -#define MT_RX_PARSER_RX_SET_NAV_ALL BIT(0) - -#define MT_EXT_CCA_CFG 0x141c -#define MT_EXT_CCA_CFG_CCA0 GENMASK(1, 0) -#define MT_EXT_CCA_CFG_CCA1 GENMASK(3, 2) -#define MT_EXT_CCA_CFG_CCA2 GENMASK(5, 4) -#define MT_EXT_CCA_CFG_CCA3 GENMASK(7, 6) -#define MT_EXT_CCA_CFG_CCA_MASK GENMASK(11, 8) -#define MT_EXT_CCA_CFG_ED_CCA_MASK GENMASK(15, 12) - -#define MT_TX_SW_CFG3 0x1478 - -#define MT_PN_PAD_MODE 0x150c - -#define MT_TXOP_HLDR_ET 0x1608 - -#define MT_PROT_AUTO_TX_CFG 0x1648 - -#define MT_RX_STA_CNT0 0x1700 -#define MT_RX_STA_CNT1 0x1704 -#define MT_RX_STA_CNT2 0x1708 -#define MT_TX_STA_CNT0 0x170c -#define MT_TX_STA_CNT1 0x1710 -#define MT_TX_STA_CNT2 0x1714 - -/* Vendor driver defines content of the second word of STAT_FIFO as follows: - * MT_TX_STAT_FIFO_RATE GENMASK(26, 16) - * MT_TX_STAT_FIFO_ETXBF BIT(27) - * MT_TX_STAT_FIFO_SND BIT(28) - * MT_TX_STAT_FIFO_ITXBF BIT(29) - * However, tests show that b16-31 have the same layout as TXWI rate_ctl - * with rate set to rate at which frame was acked. - */ -#define MT_TX_STAT_FIFO 0x1718 -#define MT_TX_STAT_FIFO_VALID BIT(0) -#define MT_TX_STAT_FIFO_SUCCESS BIT(5) -#define MT_TX_STAT_FIFO_AGGR BIT(6) -#define MT_TX_STAT_FIFO_ACKREQ BIT(7) -#define MT_TX_STAT_FIFO_WCID GENMASK(15, 8) -#define MT_TX_STAT_FIFO_RATE GENMASK(31, 16) - -#define MT_TX_AGG_STAT 0x171c - -#define MT_TX_AGG_CNT_BASE0 0x1720 - -#define MT_MPDU_DENSITY_CNT 0x1740 - -#define MT_TX_AGG_CNT_BASE1 0x174c - -#define MT_TX_AGG_CNT(_id) ((_id) < 8 ? \ - MT_TX_AGG_CNT_BASE0 + ((_id) << 2) : \ - MT_TX_AGG_CNT_BASE1 + ((_id - 8) << 2)) - -#define MT_TX_STAT_FIFO_EXT 0x1798 -#define MT_TX_STAT_FIFO_EXT_RETRY GENMASK(7, 0) -#define MT_TX_STAT_FIFO_EXT_PKTID GENMASK(15, 8) - -#define MT_BBP_CORE_BASE 0x2000 -#define MT_BBP_IBI_BASE 0x2100 -#define MT_BBP_AGC_BASE 0x2300 -#define MT_BBP_TXC_BASE 0x2400 -#define MT_BBP_RXC_BASE 0x2500 -#define MT_BBP_TXO_BASE 0x2600 -#define MT_BBP_TXBE_BASE 0x2700 -#define MT_BBP_RXFE_BASE 0x2800 -#define MT_BBP_RXO_BASE 0x2900 -#define MT_BBP_DFS_BASE 0x2a00 -#define MT_BBP_TR_BASE 0x2b00 -#define MT_BBP_CAL_BASE 0x2c00 -#define MT_BBP_DSC_BASE 0x2e00 -#define MT_BBP_PFMU_BASE 0x2f00 - -#define MT_BBP(_type, _n) (MT_BBP_##_type##_BASE + ((_n) << 2)) - -#define MT_BBP_CORE_R1_BW GENMASK(4, 3) - -#define MT_BBP_AGC_R0_CTRL_CHAN GENMASK(9, 8) -#define MT_BBP_AGC_R0_BW GENMASK(14, 12) - -/* AGC, R4/R5 */ -#define MT_BBP_AGC_LNA_GAIN GENMASK(21, 16) - -/* AGC, R8/R9 */ -#define MT_BBP_AGC_GAIN GENMASK(14, 8) - -#define MT_BBP_AGC20_RSSI0 GENMASK(7, 0) -#define MT_BBP_AGC20_RSSI1 GENMASK(15, 8) - -#define MT_BBP_TXBE_R0_CTRL_CHAN GENMASK(1, 0) - -#define MT_WCID_ADDR_BASE 0x1800 -#define MT_WCID_ADDR(_n) (MT_WCID_ADDR_BASE + (_n) * 8) - -#define MT_SRAM_BASE 0x4000 - -#define MT_WCID_KEY_BASE 0x8000 -#define MT_WCID_KEY(_n) (MT_WCID_KEY_BASE + (_n) * 32) - -#define MT_WCID_IV_BASE 0xa000 -#define MT_WCID_IV(_n) (MT_WCID_IV_BASE + (_n) * 8) - -#define MT_WCID_ATTR_BASE 0xa800 -#define MT_WCID_ATTR(_n) (MT_WCID_ATTR_BASE + (_n) * 4) - -#define MT_WCID_ATTR_PAIRWISE BIT(0) -#define MT_WCID_ATTR_PKEY_MODE GENMASK(3, 1) -#define MT_WCID_ATTR_BSS_IDX GENMASK(6, 4) -#define MT_WCID_ATTR_RXWI_UDF GENMASK(9, 7) -#define MT_WCID_ATTR_PKEY_MODE_EXT BIT(10) -#define MT_WCID_ATTR_BSS_IDX_EXT BIT(11) -#define MT_WCID_ATTR_WAPI_MCBC BIT(15) -#define MT_WCID_ATTR_WAPI_KEYID GENMASK(31, 24) - -#define MT_SKEY_BASE_0 0xac00 -#define MT_SKEY_BASE_1 0xb400 -#define MT_SKEY_0(_bss, _idx) \ - (MT_SKEY_BASE_0 + (4 * (_bss) + _idx) * 32) -#define MT_SKEY_1(_bss, _idx) \ - (MT_SKEY_BASE_1 + (4 * ((_bss) & 7) + _idx) * 32) -#define MT_SKEY(_bss, _idx) \ - ((_bss & 8) ? MT_SKEY_1(_bss, _idx) : MT_SKEY_0(_bss, _idx)) - -#define MT_SKEY_MODE_BASE_0 0xb000 -#define MT_SKEY_MODE_BASE_1 0xb3f0 -#define MT_SKEY_MODE_0(_bss) \ - (MT_SKEY_MODE_BASE_0 + ((_bss / 2) << 2)) -#define MT_SKEY_MODE_1(_bss) \ - (MT_SKEY_MODE_BASE_1 + ((((_bss) & 7) / 2) << 2)) -#define MT_SKEY_MODE(_bss) \ - ((_bss & 8) ? MT_SKEY_MODE_1(_bss) : MT_SKEY_MODE_0(_bss)) -#define MT_SKEY_MODE_MASK GENMASK(3, 0) -#define MT_SKEY_MODE_SHIFT(_bss, _idx) (4 * ((_idx) + 4 * (_bss & 1))) - -#define MT_BEACON_BASE 0xc000 - -#define MT_TEMP_SENSOR 0x1d000 -#define MT_TEMP_SENSOR_VAL GENMASK(6, 0) - -enum mt76_cipher_type { - MT_CIPHER_NONE, - MT_CIPHER_WEP40, - MT_CIPHER_WEP104, - MT_CIPHER_TKIP, - MT_CIPHER_AES_CCMP, - MT_CIPHER_CKIP40, - MT_CIPHER_CKIP104, - MT_CIPHER_CKIP128, - MT_CIPHER_WAPI, -}; - -#endif diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_regs.h b/drivers/net/wireless/mediatek/mt76/mt76x02_regs.h index b0f00107cf2d..24d1e6d747dd 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_regs.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_regs.h @@ -46,6 +46,11 @@ #define MT_WLAN_FUN_CTRL_WLAN_CLK_EN BIT(1) #define MT_WLAN_FUN_CTRL_WLAN_RESET_RF BIT(2) +#define MT_COEXCFG3 0x004c + +#define MT_LDO_CTRL_0 0x006c +#define MT_LDO_CTRL_1 0x0070 + #define MT_WLAN_FUN_CTRL_WLAN_RESET BIT(3) /* MT76x0 */ #define MT_WLAN_FUN_CTRL_CSR_F20M_CKEN BIT(3) /* MT76x2 */ @@ -75,6 +80,8 @@ #define MT_XO_CTRL7 0x011c +#define MT_IOCFG_6 0x0124 + #define MT_USB_U3DMA_CFG 0x9018 #define MT_USB_DMA_CFG_RX_BULK_AGG_TOUT GENMASK(7, 0) #define MT_USB_DMA_CFG_RX_BULK_AGG_LMT GENMASK(15, 8) @@ -156,18 +163,23 @@ #define MT_WMM_TXOP_SHIFT(_n) ((_n & 1) * 16) #define MT_WMM_TXOP_MASK GENMASK(15, 0) +#define MT_WMM_CTRL 0x0230 /* MT76x0 */ +#define MT_FCE_DMA_ADDR 0x0230 +#define MT_FCE_DMA_LEN 0x0234 +#define MT_USB_DMA_CFG 0x0238 + #define MT_TSO_CTRL 0x0250 #define MT_HEADER_TRANS_CTRL_REG 0x0260 +#define MT_US_CYC_CFG 0x02a4 +#define MT_US_CYC_CNT GENMASK(7, 0) + #define MT_TX_RING_BASE 0x0300 #define MT_RX_RING_BASE 0x03c0 #define MT_TX_HW_QUEUE_MCU 8 #define MT_TX_HW_QUEUE_MGMT 9 -#define MT_US_CYC_CFG 0x02a4 -#define MT_US_CYC_CNT GENMASK(7, 0) - #define MT_PBF_SYS_CTRL 0x0400 #define MT_PBF_SYS_CTRL_MCU_RESET BIT(0) #define MT_PBF_SYS_CTRL_DMA_RESET BIT(1) @@ -189,10 +201,20 @@ #define MT_BCN_OFFSET_BASE 0x041c #define MT_BCN_OFFSET(_n) (MT_BCN_OFFSET_BASE + ((_n) << 2)) +#define MT_RXQ_STA 0x0430 +#define MT_TXQ_STA 0x0434 +#define MT_RF_CSR_CFG 0x0500 +#define MT_RF_CSR_CFG_DATA GENMASK(7, 0) +#define MT_RF_CSR_CFG_REG_ID GENMASK(13, 8) +#define MT_RF_CSR_CFG_REG_BANK GENMASK(17, 14) +#define MT_RF_CSR_CFG_WR BIT(30) +#define MT_RF_CSR_CFG_KICK BIT(31) + #define MT_RF_BYPASS_0 0x0504 #define MT_RF_BYPASS_1 0x0508 #define MT_RF_SETTING_0 0x050c +#define MT_RF_MISC 0x0518 #define MT_RF_DATA_WRITE 0x0524 #define MT_RF_CTRL 0x0528 @@ -203,6 +225,11 @@ #define MT_RF_DATA_READ 0x052c +#define MT_COM_REG0 0x0730 +#define MT_COM_REG1 0x0734 +#define MT_COM_REG2 0x0738 +#define MT_COM_REG3 0x073C + #define MT_FCE_PSE_CTRL 0x0800 #define MT_FCE_PARAMETERS 0x0804 #define MT_FCE_CSO 0x0808 @@ -222,6 +249,7 @@ #define MT_TX_CPU_FROM_FCE_BASE_PTR 0x09a0 #define MT_TX_CPU_FROM_FCE_MAX_COUNT 0x09a4 +#define MT_TX_CPU_FROM_FCE_CPU_DESC_IDX 0x09a8 #define MT_FCE_PDMA_GLOBAL_CONF 0x09c4 #define MT_FCE_SKIP_FS 0x0a6c @@ -250,6 +278,9 @@ #define MT_MAC_BSSID_DW1_MBSS_IDX_BYTE GENMASK(26, 24) #define MT_MAX_LEN_CFG 0x1018 +#define MT_MAX_LEN_CFG_AMPDU GENMASK(13, 12) + +#define MT_LED_CFG 0x102c #define MT_AMPDU_MAX_LEN_20M1S 0x1030 #define MT_AMPDU_MAX_LEN_20M2S 0x1034 @@ -365,6 +396,8 @@ #define MT_TX_SW_CFG2 0x1338 #define MT_TXOP_CTRL_CFG 0x1340 +#define MT_TXOP_TRUN_EN GENMASK(5, 0) +#define MT_TXOP_EXT_CCA_DLY GENMASK(15, 8) #define MT_TX_RTS_CFG 0x1344 #define MT_TX_RTS_CFG_RETRY_LIMIT GENMASK(7, 0) @@ -376,7 +409,10 @@ #define MT_TX_RETRY_CFG 0x134c #define MT_TX_LINK_CFG 0x1350 +#define MT_VHT_HT_FBK_CFG0 0x1354 #define MT_VHT_HT_FBK_CFG1 0x1358 +#define MT_LG_FBK_CFG0 0x135c +#define MT_LG_FBK_CFG1 0x1360 #define MT_PROT_CFG_RATE GENMASK(15, 0) #define MT_PROT_CFG_CTRL GENMASK(17, 16) @@ -391,6 +427,27 @@ #define MT_GF20_PROT_CFG 0x1374 #define MT_GF40_PROT_CFG 0x1378 +#define MT_PROT_RATE GENMASK(15, 0) +#define MT_PROT_CTRL_RTS_CTS BIT(16) +#define MT_PROT_CTRL_CTS2SELF BIT(17) +#define MT_PROT_NAV_SHORT BIT(18) +#define MT_PROT_NAV_LONG BIT(19) +#define MT_PROT_TXOP_ALLOW_CCK BIT(20) +#define MT_PROT_TXOP_ALLOW_OFDM BIT(21) +#define MT_PROT_TXOP_ALLOW_MM20 BIT(22) +#define MT_PROT_TXOP_ALLOW_MM40 BIT(23) +#define MT_PROT_TXOP_ALLOW_GF20 BIT(24) +#define MT_PROT_TXOP_ALLOW_GF40 BIT(25) +#define MT_PROT_RTS_THR_EN BIT(26) +#define MT_PROT_RATE_CCK_11 0x0003 +#define MT_PROT_RATE_OFDM_6 0x4000 +#define MT_PROT_RATE_OFDM_24 0x4004 +#define MT_PROT_RATE_DUP_OFDM_24 0x4084 +#define MT_PROT_TXOP_ALLOW_ALL GENMASK(25, 20) +#define MT_PROT_TXOP_ALLOW_BW20 (MT_PROT_TXOP_ALLOW_ALL & \ + ~MT_PROT_TXOP_ALLOW_MM40 & \ + ~MT_PROT_TXOP_ALLOW_GF40) + #define MT_EXP_ACK_TIME 0x1380 #define MT_TX_PWR_CFG_0_EXT 0x1390 @@ -405,6 +462,8 @@ #define MT_TX0_RF_GAIN_CORR 0x13a0 #define MT_TX1_RF_GAIN_CORR 0x13a4 +#define MT_TX0_RF_GAIN_ATTEN 0x13a8 +#define MT_TX0_RF_GAIN_ATTEN 0x13a8 /* MT76x0 */ #define MT_TX_ALC_CFG_0 0x13b0 #define MT_TX_ALC_CFG_0_CH_INIT_0 GENMASK(5, 0) @@ -421,6 +480,7 @@ #define MT_TX_ALC_CFG_3 0x13ac #define MT_TX_ALC_CFG_4 0x13c0 #define MT_TX_ALC_CFG_4_LOWGAIN_CH_EN BIT(31) +#define MT_TX0_BB_GAIN_ATTEN 0x13c0 /* MT76x0 */ #define MT_TX_ALC_VGA3 0x13c8 @@ -451,10 +511,13 @@ #define MT_RX_FILTR_CFG_CTRL_RSV BIT(16) #define MT_AUTO_RSP_CFG 0x1404 +#define MT_AUTO_RSP_PREAMB_SHORT BIT(4) #define MT_LEGACY_BASIC_RATE 0x1408 #define MT_HT_BASIC_RATE 0x140c #define MT_HT_CTRL_CFG 0x1410 +#define MT_RX_PARSER_CFG 0x1418 +#define MT_RX_PARSER_RX_SET_NAV_ALL BIT(0) #define MT_EXT_CCA_CFG 0x141c #define MT_EXT_CCA_CFG_CCA0 GENMASK(1, 0) @@ -498,7 +561,10 @@ #define MT_TX_STAT_FIFO_WCID GENMASK(15, 8) #define MT_TX_STAT_FIFO_RATE GENMASK(31, 16) +#define MT_TX_AGG_STAT 0x171c + #define MT_TX_AGG_CNT_BASE0 0x1720 +#define MT_MPDU_DENSITY_CNT 0x1740 #define MT_TX_AGG_CNT_BASE1 0x174c #define MT_TX_AGG_CNT(_id) ((_id) < 8 ? \ @@ -604,7 +670,7 @@ struct mt76_wcid_key { u8 rx_mic[8]; } __packed __aligned(4); -enum mt76x2_cipher_type { +enum mt76x02_cipher_type { MT_CIPHER_NONE, MT_CIPHER_WEP40, MT_CIPHER_WEP104, diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mac_common.c b/drivers/net/wireless/mediatek/mt76/mt76x2_mac_common.c index 6542644bc325..95770111918c 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_mac_common.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mac_common.c @@ -229,7 +229,7 @@ void mt76x2_send_tx_status(struct mt76x2_dev *dev, } EXPORT_SYMBOL_GPL(mt76x2_send_tx_status); -static enum mt76x2_cipher_type +static enum mt76x02_cipher_type mt76x2_mac_get_key_info(struct ieee80211_key_conf *key, u8 *key_data) { memset(key_data, 0, 32); @@ -258,7 +258,7 @@ mt76x2_mac_get_key_info(struct ieee80211_key_conf *key, u8 *key_data) int mt76x2_mac_shared_key_setup(struct mt76x2_dev *dev, u8 vif_idx, u8 key_idx, struct ieee80211_key_conf *key) { - enum mt76x2_cipher_type cipher; + enum mt76x02_cipher_type cipher; u8 key_data[32]; u32 val; @@ -281,7 +281,7 @@ EXPORT_SYMBOL_GPL(mt76x2_mac_shared_key_setup); int mt76x2_mac_wcid_set_key(struct mt76x2_dev *dev, u8 idx, struct ieee80211_key_conf *key) { - enum mt76x2_cipher_type cipher; + enum mt76x02_cipher_type cipher; u8 key_data[32]; u8 iv_data[8]; From 108a4861ef19af44dbec89b4f9e2ebc87b781cdc Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 29 Aug 2018 13:16:35 +0200 Subject: [PATCH 093/276] mt76: create new mt76x02-lib module for common mt76x{0,2} code Move rxfilter and mutex to common structure. Create mt76x02-lib.ko for mt76x0 and mt76x2 common functions and create new unified mt76x02_configure_filter() function there. Signed-off-by: Stanislaw Gruszka Signed-off-by: Kalle Valo --- drivers/net/wireless/mediatek/mt76/Kconfig | 6 ++ drivers/net/wireless/mediatek/mt76/Makefile | 3 + drivers/net/wireless/mediatek/mt76/mac80211.c | 1 + drivers/net/wireless/mediatek/mt76/mt76.h | 5 ++ .../net/wireless/mediatek/mt76/mt76x0/init.c | 6 +- .../net/wireless/mediatek/mt76/mt76x0/main.c | 69 ++++--------------- .../wireless/mediatek/mt76/mt76x0/mt76x0.h | 3 - .../net/wireless/mediatek/mt76/mt76x02_util.c | 55 +++++++++++++++ .../net/wireless/mediatek/mt76/mt76x02_util.h | 25 +++++++ drivers/net/wireless/mediatek/mt76/mt76x2.h | 5 -- .../wireless/mediatek/mt76/mt76x2_common.c | 42 ++--------- .../net/wireless/mediatek/mt76/mt76x2_init.c | 5 +- .../net/wireless/mediatek/mt76/mt76x2_main.c | 37 +++++----- .../net/wireless/mediatek/mt76/mt76x2u_init.c | 4 +- .../net/wireless/mediatek/mt76/mt76x2u_mac.c | 2 +- .../net/wireless/mediatek/mt76/mt76x2u_main.c | 25 +++---- 16 files changed, 152 insertions(+), 141 deletions(-) create mode 100644 drivers/net/wireless/mediatek/mt76/mt76x02_util.c create mode 100644 drivers/net/wireless/mediatek/mt76/mt76x02_util.h diff --git a/drivers/net/wireless/mediatek/mt76/Kconfig b/drivers/net/wireless/mediatek/mt76/Kconfig index b6c5f17dca30..6a270e759006 100644 --- a/drivers/net/wireless/mediatek/mt76/Kconfig +++ b/drivers/net/wireless/mediatek/mt76/Kconfig @@ -5,8 +5,13 @@ config MT76_USB tristate depends on MT76_CORE +config MT76x02_LIB + tristate + depends on MT76_CORE + config MT76x2_COMMON tristate + select MT76x02_LIB depends on MT76_CORE config MT76x0U @@ -14,6 +19,7 @@ config MT76x0U select MT76_CORE depends on MAC80211 depends on USB + select MT76x02_LIB help This adds support for MT7610U-based wireless USB dongles. diff --git a/drivers/net/wireless/mediatek/mt76/Makefile b/drivers/net/wireless/mediatek/mt76/Makefile index 158d10d2716c..7d95f141cd73 100644 --- a/drivers/net/wireless/mediatek/mt76/Makefile +++ b/drivers/net/wireless/mediatek/mt76/Makefile @@ -1,6 +1,7 @@ obj-$(CONFIG_MT76_CORE) += mt76.o obj-$(CONFIG_MT76_USB) += mt76-usb.o obj-$(CONFIG_MT76x0U) += mt76x0/ +obj-$(CONFIG_MT76x02_LIB) += mt76x02-lib.o obj-$(CONFIG_MT76x2_COMMON) += mt76x2-common.o obj-$(CONFIG_MT76x2E) += mt76x2e.o obj-$(CONFIG_MT76x2U) += mt76x2u.o @@ -13,6 +14,8 @@ mt76-usb-y := usb.o usb_trace.o usb_mcu.o CFLAGS_trace.o := -I$(src) CFLAGS_usb_trace.o := -I$(src) +mt76x02-lib-y := mt76x02_util.o + mt76x2-common-y := \ mt76x2_eeprom.o mt76x2_tx_common.o mt76x2_mac_common.o \ mt76x2_init_common.o mt76x2_common.o mt76x2_phy_common.o \ diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c b/drivers/net/wireless/mediatek/mt76/mac80211.c index 029d54bce9e8..df670d04f5a2 100644 --- a/drivers/net/wireless/mediatek/mt76/mac80211.c +++ b/drivers/net/wireless/mediatek/mt76/mac80211.c @@ -283,6 +283,7 @@ mt76_alloc_device(unsigned int size, const struct ieee80211_ops *ops) spin_lock_init(&dev->rx_lock); spin_lock_init(&dev->lock); spin_lock_init(&dev->cc_lock); + mutex_init(&dev->mutex); init_waitqueue_head(&dev->tx_wait); return dev; diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h index 2eab35879163..79017dbd364d 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76.h +++ b/drivers/net/wireless/mediatek/mt76/mt76.h @@ -317,6 +317,9 @@ struct mt76_dev { spinlock_t lock; spinlock_t cc_lock; + + struct mutex mutex; + const struct mt76_bus_ops *bus; const struct mt76_driver_ops *drv; void __iomem *regs; @@ -353,6 +356,8 @@ struct mt76_dev { bool led_al; u8 led_pin; + u32 rxfilter; + struct mt76_usb usb; }; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c index f23d1a04b35f..33924643946d 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c @@ -290,14 +290,14 @@ int mt76x0_mac_start(struct mt76x0_dev *dev) MT_WPDMA_GLO_CFG_RX_DMA_BUSY, 0, 200000)) return -ETIMEDOUT; - dev->rxfilter = MT_RX_FILTR_CFG_CRC_ERR | + dev->mt76.rxfilter = MT_RX_FILTR_CFG_CRC_ERR | MT_RX_FILTR_CFG_PHY_ERR | MT_RX_FILTR_CFG_PROMISC | MT_RX_FILTR_CFG_VER_ERR | MT_RX_FILTR_CFG_DUP | MT_RX_FILTR_CFG_CFACK | MT_RX_FILTR_CFG_CFEND | MT_RX_FILTR_CFG_ACK | MT_RX_FILTR_CFG_CTS | MT_RX_FILTR_CFG_RTS | MT_RX_FILTR_CFG_PSPOLL | MT_RX_FILTR_CFG_BA | MT_RX_FILTR_CFG_CTRL_RSV; - mt76_wr(dev, MT_RX_FILTR_CFG, dev->rxfilter); + mt76_wr(dev, MT_RX_FILTR_CFG, dev->mt76.rxfilter); mt76_wr(dev, MT_MAC_SYS_CTRL, MT_MAC_SYS_CTRL_ENABLE_TX | MT_MAC_SYS_CTRL_ENABLE_RX); @@ -495,7 +495,7 @@ struct mt76x0_dev *mt76x0_alloc_device(struct device *pdev) mutex_init(&dev->usb_ctrl_mtx); mutex_init(&dev->reg_atomic_mutex); mutex_init(&dev->hw_atomic_mutex); - mutex_init(&dev->mutex); + mutex_init(&dev->mt76.mutex); spin_lock_init(&dev->tx_lock); spin_lock_init(&dev->rx_lock); spin_lock_init(&dev->mt76.lock); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c index 46e458835e58..8fc270b94819 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c @@ -15,6 +15,7 @@ #include "mt76x0.h" #include "mac.h" +#include "../mt76x02_util.h" #include static int mt76x0_start(struct ieee80211_hw *hw) @@ -22,7 +23,7 @@ static int mt76x0_start(struct ieee80211_hw *hw) struct mt76x0_dev *dev = hw->priv; int ret; - mutex_lock(&dev->mutex); + mutex_lock(&dev->mt76.mutex); ret = mt76x0_mac_start(dev); if (ret) @@ -33,7 +34,7 @@ static int mt76x0_start(struct ieee80211_hw *hw) ieee80211_queue_delayed_work(dev->mt76.hw, &dev->cal_work, MT_CALIBRATE_INTERVAL); out: - mutex_unlock(&dev->mutex); + mutex_unlock(&dev->mt76.mutex); return ret; } @@ -41,13 +42,13 @@ static void mt76x0_stop(struct ieee80211_hw *hw) { struct mt76x0_dev *dev = hw->priv; - mutex_lock(&dev->mutex); + mutex_lock(&dev->mt76.mutex); cancel_delayed_work_sync(&dev->cal_work); cancel_delayed_work_sync(&dev->mac_work); mt76x0_mac_stop(dev); - mutex_unlock(&dev->mutex); + mutex_unlock(&dev->mt76.mutex); } @@ -87,16 +88,7 @@ static int mt76x0_config(struct ieee80211_hw *hw, u32 changed) struct mt76x0_dev *dev = hw->priv; int ret = 0; - mutex_lock(&dev->mutex); - - if (changed & IEEE80211_CONF_CHANGE_MONITOR) { - if (!(hw->conf.flags & IEEE80211_CONF_MONITOR)) - dev->rxfilter |= MT_RX_FILTR_CFG_PROMISC; - else - dev->rxfilter &= ~MT_RX_FILTR_CFG_PROMISC; - - mt76_wr(dev, MT_RX_FILTR_CFG, dev->rxfilter); - } + mutex_lock(&dev->mt76.mutex); if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { ieee80211_stop_queues(hw); @@ -104,51 +96,18 @@ static int mt76x0_config(struct ieee80211_hw *hw, u32 changed) ieee80211_wake_queues(hw); } - mutex_unlock(&dev->mutex); + mutex_unlock(&dev->mt76.mutex); return ret; } -static void -mt76_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags, - unsigned int *total_flags, u64 multicast) -{ - struct mt76x0_dev *dev = hw->priv; - u32 flags = 0; - -#define MT76_FILTER(_flag, _hw) do { \ - flags |= *total_flags & FIF_##_flag; \ - dev->rxfilter &= ~(_hw); \ - dev->rxfilter |= !(flags & FIF_##_flag) * (_hw); \ - } while (0) - - mutex_lock(&dev->mutex); - - dev->rxfilter &= ~MT_RX_FILTR_CFG_OTHER_BSS; - - MT76_FILTER(FCSFAIL, MT_RX_FILTR_CFG_CRC_ERR); - MT76_FILTER(PLCPFAIL, MT_RX_FILTR_CFG_PHY_ERR); - MT76_FILTER(CONTROL, MT_RX_FILTR_CFG_ACK | - MT_RX_FILTR_CFG_CTS | - MT_RX_FILTR_CFG_CFEND | - MT_RX_FILTR_CFG_CFACK | - MT_RX_FILTR_CFG_BA | - MT_RX_FILTR_CFG_CTRL_RSV); - MT76_FILTER(PSPOLL, MT_RX_FILTR_CFG_PSPOLL); - - *total_flags = flags; - mt76_wr(dev, MT_RX_FILTR_CFG, dev->rxfilter); - - mutex_unlock(&dev->mutex); -} - static void mt76x0_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_bss_conf *info, u32 changed) { struct mt76x0_dev *dev = hw->priv; - mutex_lock(&dev->mutex); + mutex_lock(&dev->mt76.mutex); if (changed & BSS_CHANGED_ASSOC) mt76x0_phy_con_cal_onoff(dev, info); @@ -192,7 +151,7 @@ mt76x0_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, if (changed & BSS_CHANGED_ASSOC) mt76x0_phy_recalibrate_after_assoc(dev); - mutex_unlock(&dev->mutex); + mutex_unlock(&dev->mt76.mutex); } static int @@ -205,7 +164,7 @@ mt76x0_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, int ret = 0; int idx = 0; - mutex_lock(&dev->mutex); + mutex_lock(&dev->mt76.mutex); idx = mt76_wcid_alloc(dev->wcid_mask, ARRAY_SIZE(dev->wcid)); if (idx < 0) { @@ -221,7 +180,7 @@ mt76x0_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, mt76x0_mac_set_ampdu_factor(dev); out: - mutex_unlock(&dev->mutex); + mutex_unlock(&dev->mt76.mutex); return ret; } @@ -234,13 +193,13 @@ mt76x0_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct mt76_sta *msta = (struct mt76_sta *) sta->drv_priv; int idx = msta->wcid.idx; - mutex_lock(&dev->mutex); + mutex_lock(&dev->mt76.mutex); rcu_assign_pointer(dev->wcid[idx], NULL); mt76_set(dev, MT_WCID_DROP(idx), MT_WCID_DROP_MASK(idx)); dev->wcid_mask[idx / BITS_PER_LONG] &= ~BIT(idx % BITS_PER_LONG); mt76x0_mac_wcid_setup(dev, idx, 0, NULL); mt76x0_mac_set_ampdu_factor(dev); - mutex_unlock(&dev->mutex); + mutex_unlock(&dev->mt76.mutex); return 0; } @@ -388,7 +347,7 @@ const struct ieee80211_ops mt76x0_ops = { .add_interface = mt76x0_add_interface, .remove_interface = mt76x0_remove_interface, .config = mt76x0_config, - .configure_filter = mt76_configure_filter, + .configure_filter = mt76x02_configure_filter, .bss_info_changed = mt76x0_bss_info_changed, .sta_add = mt76x0_sta_add, .sta_remove = mt76x0_sta_remove, diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h index 6c52f73c1b94..967b262495e7 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h @@ -147,8 +147,6 @@ enum mt_bw { struct mt76x0_dev { struct mt76_dev mt76; /* must be first */ - struct mutex mutex; - struct mutex usb_ctrl_mtx; u8 data[32]; @@ -184,7 +182,6 @@ struct mt76x0_dev { struct mutex reg_atomic_mutex; struct mutex hw_atomic_mutex; - u32 rxfilter; u32 debugfs_reg; /* TX */ diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c new file mode 100644 index 000000000000..971e2d9f9ca3 --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2018 Stanislaw Gruszka + * Copyright (C) 2016 Felix Fietkau + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "mt76.h" +#include "mt76x02_regs.h" + +void mt76x02_configure_filter(struct ieee80211_hw *hw, + unsigned int changed_flags, + unsigned int *total_flags, u64 multicast) +{ + struct mt76_dev *dev = hw->priv; + u32 flags = 0; + +#define MT76_FILTER(_flag, _hw) do { \ + flags |= *total_flags & FIF_##_flag; \ + dev->rxfilter &= ~(_hw); \ + dev->rxfilter |= !(flags & FIF_##_flag) * (_hw); \ + } while (0) + + mutex_lock(&dev->mutex); + + dev->rxfilter &= ~MT_RX_FILTR_CFG_OTHER_BSS; + + MT76_FILTER(FCSFAIL, MT_RX_FILTR_CFG_CRC_ERR); + MT76_FILTER(PLCPFAIL, MT_RX_FILTR_CFG_PHY_ERR); + MT76_FILTER(CONTROL, MT_RX_FILTR_CFG_ACK | + MT_RX_FILTR_CFG_CTS | + MT_RX_FILTR_CFG_CFEND | + MT_RX_FILTR_CFG_CFACK | + MT_RX_FILTR_CFG_BA | + MT_RX_FILTR_CFG_CTRL_RSV); + MT76_FILTER(PSPOLL, MT_RX_FILTR_CFG_PSPOLL); + + *total_flags = flags; + dev->bus->wr(dev, MT_RX_FILTR_CFG, dev->rxfilter); + + mutex_unlock(&dev->mutex); +} +EXPORT_SYMBOL_GPL(mt76x02_configure_filter); + +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.h b/drivers/net/wireless/mediatek/mt76/mt76x02_util.h new file mode 100644 index 000000000000..7ff3d473bc75 --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2016 Felix Fietkau + * Copyright (C) 2018 Stanislaw Gruszka + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef __MT76X02_UTIL_H +#define __MT76X02_UTIL_H + +void mt76x02_configure_filter(struct ieee80211_hw *hw, + unsigned int changed_flags, + unsigned int *total_flags, u64 multicast); + +#endif diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2.h b/drivers/net/wireless/mediatek/mt76/mt76x2.h index 8b5c3de9ea32..e9b57fce9685 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x2.h @@ -131,8 +131,6 @@ struct mt76x2_dev { u16 chainmask; - u32 rxfilter; - struct mt76x2_calibration cal; s8 target_power; @@ -293,9 +291,6 @@ int mt76x2_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, struct ieee80211_key_conf *key); int mt76x2_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u16 queue, const struct ieee80211_tx_queue_params *params); -void mt76x2_configure_filter(struct ieee80211_hw *hw, - unsigned int changed_flags, - unsigned int *total_flags, u64 multicast); void mt76x2_txq_init(struct mt76x2_dev *dev, struct ieee80211_txq *txq); void mt76x2_sta_rate_tbl_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif, diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_common.c b/drivers/net/wireless/mediatek/mt76/mt76x2_common.c index a2338ba139b4..fe0b394fd9ea 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_common.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_common.c @@ -102,7 +102,7 @@ int mt76x2_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, int idx = 0; int i; - mutex_lock(&dev->mutex); + mutex_lock(&dev->mt76.mutex); idx = mt76_wcid_alloc(dev->wcid_mask, ARRAY_SIZE(dev->wcid)); if (idx < 0) { @@ -127,7 +127,7 @@ int mt76x2_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, rcu_assign_pointer(dev->wcid[idx], &msta->wcid); out: - mutex_unlock(&dev->mutex); + mutex_unlock(&dev->mt76.mutex); return ret; } @@ -141,14 +141,14 @@ int mt76x2_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, int idx = msta->wcid.idx; int i; - mutex_lock(&dev->mutex); + mutex_lock(&dev->mt76.mutex); rcu_assign_pointer(dev->wcid[idx], NULL); for (i = 0; i < ARRAY_SIZE(sta->txq); i++) mt76_txq_remove(&dev->mt76, sta->txq[i]); mt76x2_mac_wcid_set_drop(dev, idx, true); mt76_wcid_free(dev->wcid_mask, idx); mt76x2_mac_wcid_setup(dev, idx, 0, NULL); - mutex_unlock(&dev->mutex); + mutex_unlock(&dev->mt76.mutex); return 0; } @@ -274,40 +274,6 @@ int mt76x2_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, } EXPORT_SYMBOL_GPL(mt76x2_conf_tx); -void mt76x2_configure_filter(struct ieee80211_hw *hw, - unsigned int changed_flags, - unsigned int *total_flags, u64 multicast) -{ - struct mt76x2_dev *dev = hw->priv; - u32 flags = 0; - -#define MT76_FILTER(_flag, _hw) do { \ - flags |= *total_flags & FIF_##_flag; \ - dev->rxfilter &= ~(_hw); \ - dev->rxfilter |= !(flags & FIF_##_flag) * (_hw); \ - } while (0) - - mutex_lock(&dev->mutex); - - dev->rxfilter &= ~MT_RX_FILTR_CFG_OTHER_BSS; - - MT76_FILTER(FCSFAIL, MT_RX_FILTR_CFG_CRC_ERR); - MT76_FILTER(PLCPFAIL, MT_RX_FILTR_CFG_PHY_ERR); - MT76_FILTER(CONTROL, MT_RX_FILTR_CFG_ACK | - MT_RX_FILTR_CFG_CTS | - MT_RX_FILTR_CFG_CFEND | - MT_RX_FILTR_CFG_CFACK | - MT_RX_FILTR_CFG_BA | - MT_RX_FILTR_CFG_CTRL_RSV); - MT76_FILTER(PSPOLL, MT_RX_FILTR_CFG_PSPOLL); - - *total_flags = flags; - mt76_wr(dev, MT_RX_FILTR_CFG, dev->rxfilter); - - mutex_unlock(&dev->mutex); -} -EXPORT_SYMBOL_GPL(mt76x2_configure_filter); - void mt76x2_sta_rate_tbl_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_init.c b/drivers/net/wireless/mediatek/mt76/mt76x2_init.c index 75a4e171da6d..07ef0a368f1e 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_init.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_init.c @@ -214,7 +214,7 @@ int mt76x2_mac_start(struct mt76x2_dev *dev) mt76_clear(dev, MT_WPDMA_GLO_CFG, MT_WPDMA_GLO_CFG_TX_WRITEBACK_DONE); - mt76_wr(dev, MT_RX_FILTR_CFG, dev->rxfilter); + mt76_wr(dev, MT_RX_FILTR_CFG, dev->mt76.rxfilter); mt76_wr(dev, MT_MAC_SYS_CTRL, MT_MAC_SYS_CTRL_ENABLE_TX | @@ -377,7 +377,7 @@ int mt76x2_init_hardware(struct mt76x2_dev *dev) if (ret) return ret; - dev->rxfilter = mt76_rr(dev, MT_RX_FILTR_CFG); + dev->mt76.rxfilter = mt76_rr(dev, MT_RX_FILTR_CFG); ret = mt76x2_dma_init(dev); if (ret) @@ -435,7 +435,6 @@ struct mt76x2_dev *mt76x2_alloc_device(struct device *pdev) dev = container_of(mdev, struct mt76x2_dev, mt76); mdev->dev = pdev; mdev->drv = &drv_ops; - mutex_init(&dev->mutex); spin_lock_init(&dev->irq_lock); return dev; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_main.c b/drivers/net/wireless/mediatek/mt76/mt76x2_main.c index 680a89f8aa87..577c6ee39fb8 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_main.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_main.c @@ -15,6 +15,7 @@ */ #include "mt76x2.h" +#include "mt76x02_util.h" static int mt76x2_start(struct ieee80211_hw *hw) @@ -22,7 +23,7 @@ mt76x2_start(struct ieee80211_hw *hw) struct mt76x2_dev *dev = hw->priv; int ret; - mutex_lock(&dev->mutex); + mutex_lock(&dev->mt76.mutex); ret = mt76x2_mac_start(dev); if (ret) @@ -38,7 +39,7 @@ mt76x2_start(struct ieee80211_hw *hw) set_bit(MT76_STATE_RUNNING, &dev->mt76.state); out: - mutex_unlock(&dev->mutex); + mutex_unlock(&dev->mt76.mutex); return ret; } @@ -47,10 +48,10 @@ mt76x2_stop(struct ieee80211_hw *hw) { struct mt76x2_dev *dev = hw->priv; - mutex_lock(&dev->mutex); + mutex_lock(&dev->mt76.mutex); clear_bit(MT76_STATE_RUNNING, &dev->mt76.state); mt76x2_stop_hardware(dev); - mutex_unlock(&dev->mutex); + mutex_unlock(&dev->mt76.mutex); } static int @@ -127,15 +128,15 @@ mt76x2_config(struct ieee80211_hw *hw, u32 changed) struct mt76x2_dev *dev = hw->priv; int ret = 0; - mutex_lock(&dev->mutex); + mutex_lock(&dev->mt76.mutex); if (changed & IEEE80211_CONF_CHANGE_MONITOR) { if (!(hw->conf.flags & IEEE80211_CONF_MONITOR)) - dev->rxfilter |= MT_RX_FILTR_CFG_PROMISC; + dev->mt76.rxfilter |= MT_RX_FILTR_CFG_PROMISC; else - dev->rxfilter &= ~MT_RX_FILTR_CFG_PROMISC; + dev->mt76.rxfilter &= ~MT_RX_FILTR_CFG_PROMISC; - mt76_wr(dev, MT_RX_FILTR_CFG, dev->rxfilter); + mt76_wr(dev, MT_RX_FILTR_CFG, dev->mt76.rxfilter); } if (changed & IEEE80211_CONF_CHANGE_POWER) { @@ -156,7 +157,7 @@ mt76x2_config(struct ieee80211_hw *hw, u32 changed) ieee80211_wake_queues(hw); } - mutex_unlock(&dev->mutex); + mutex_unlock(&dev->mt76.mutex); return ret; } @@ -168,7 +169,7 @@ mt76x2_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct mt76x2_dev *dev = hw->priv; struct mt76x2_vif *mvif = (struct mt76x2_vif *) vif->drv_priv; - mutex_lock(&dev->mutex); + mutex_lock(&dev->mt76.mutex); if (changed & BSS_CHANGED_BSSID) mt76x2_mac_set_bssid(dev, mvif->idx, info->bssid); @@ -195,7 +196,7 @@ mt76x2_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, mt76x2_set_tx_ackto(dev); } - mutex_unlock(&dev->mutex); + mutex_unlock(&dev->mt76.mutex); } void @@ -252,10 +253,10 @@ static void mt76x2_set_coverage_class(struct ieee80211_hw *hw, { struct mt76x2_dev *dev = hw->priv; - mutex_lock(&dev->mutex); + mutex_lock(&dev->mt76.mutex); dev->coverage_class = coverage_class; mt76x2_set_tx_ackto(dev); - mutex_unlock(&dev->mutex); + mutex_unlock(&dev->mt76.mutex); } static int @@ -272,7 +273,7 @@ static int mt76x2_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, if (!tx_ant || tx_ant > 3 || tx_ant != rx_ant) return -EINVAL; - mutex_lock(&dev->mutex); + mutex_lock(&dev->mt76.mutex); dev->chainmask = (tx_ant == 3) ? 0x202 : 0x101; dev->mt76.antenna_mask = tx_ant; @@ -280,7 +281,7 @@ static int mt76x2_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, mt76_set_stream_caps(&dev->mt76, true); mt76x2_phy_set_antenna(dev); - mutex_unlock(&dev->mutex); + mutex_unlock(&dev->mt76.mutex); return 0; } @@ -290,10 +291,10 @@ static int mt76x2_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, { struct mt76x2_dev *dev = hw->priv; - mutex_lock(&dev->mutex); + mutex_lock(&dev->mt76.mutex); *tx_ant = dev->mt76.antenna_mask; *rx_ant = dev->mt76.antenna_mask; - mutex_unlock(&dev->mutex); + mutex_unlock(&dev->mt76.mutex); return 0; } @@ -320,7 +321,7 @@ const struct ieee80211_ops mt76x2_ops = { .add_interface = mt76x2_add_interface, .remove_interface = mt76x2_remove_interface, .config = mt76x2_config, - .configure_filter = mt76x2_configure_filter, + .configure_filter = mt76x02_configure_filter, .bss_info_changed = mt76x2_bss_info_changed, .sta_add = mt76x2_sta_add, .sta_remove = mt76x2_sta_remove, diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2u_init.c b/drivers/net/wireless/mediatek/mt76/mt76x2u_init.c index 276e30608cea..709e37de3b3f 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2u_init.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2u_init.c @@ -151,8 +151,6 @@ struct mt76x2_dev *mt76x2u_alloc_device(struct device *pdev) mdev->dev = pdev; mdev->drv = &drv_ops; - mutex_init(&dev->mutex); - return dev; } @@ -214,7 +212,7 @@ int mt76x2u_init_hardware(struct mt76x2_dev *dev) return err; mt76x2u_mac_setaddr(dev, dev->mt76.eeprom.data + MT_EE_MAC_ADDR); - dev->rxfilter = mt76_rr(dev, MT_RX_FILTR_CFG); + dev->mt76.rxfilter = mt76_rr(dev, MT_RX_FILTR_CFG); mt76x2u_init_beacon_offsets(dev); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2u_mac.c b/drivers/net/wireless/mediatek/mt76/mt76x2u_mac.c index eab7ab297aa6..9604c6a809be 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2u_mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2u_mac.c @@ -122,7 +122,7 @@ int mt76x2u_mac_start(struct mt76x2_dev *dev) wait_for_wpdma(dev); usleep_range(50, 100); - mt76_wr(dev, MT_RX_FILTR_CFG, dev->rxfilter); + mt76_wr(dev, MT_RX_FILTR_CFG, dev->mt76.rxfilter); mt76_wr(dev, MT_MAC_SYS_CTRL, MT_MAC_SYS_CTRL_ENABLE_TX | diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2u_main.c b/drivers/net/wireless/mediatek/mt76/mt76x2u_main.c index 7367ba111119..9180debc0946 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2u_main.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2u_main.c @@ -15,13 +15,14 @@ */ #include "mt76x2u.h" +#include "mt76x02_util.h" static int mt76x2u_start(struct ieee80211_hw *hw) { struct mt76x2_dev *dev = hw->priv; int ret; - mutex_lock(&dev->mutex); + mutex_lock(&dev->mt76.mutex); ret = mt76x2u_mac_start(dev); if (ret) @@ -30,7 +31,7 @@ static int mt76x2u_start(struct ieee80211_hw *hw) set_bit(MT76_STATE_RUNNING, &dev->mt76.state); out: - mutex_unlock(&dev->mutex); + mutex_unlock(&dev->mt76.mutex); return ret; } @@ -38,10 +39,10 @@ static void mt76x2u_stop(struct ieee80211_hw *hw) { struct mt76x2_dev *dev = hw->priv; - mutex_lock(&dev->mutex); + mutex_lock(&dev->mt76.mutex); clear_bit(MT76_STATE_RUNNING, &dev->mt76.state); mt76x2u_stop_hw(dev); - mutex_unlock(&dev->mutex); + mutex_unlock(&dev->mt76.mutex); } static int mt76x2u_add_interface(struct ieee80211_hw *hw, @@ -93,7 +94,7 @@ mt76x2u_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, { struct mt76x2_dev *dev = hw->priv; - mutex_lock(&dev->mutex); + mutex_lock(&dev->mt76.mutex); if (changed & BSS_CHANGED_ASSOC) { mt76x2u_phy_channel_calibrate(dev); @@ -107,7 +108,7 @@ mt76x2u_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, get_unaligned_le16(info->bssid + 4)); } - mutex_unlock(&dev->mutex); + mutex_unlock(&dev->mt76.mutex); } static int @@ -116,14 +117,14 @@ mt76x2u_config(struct ieee80211_hw *hw, u32 changed) struct mt76x2_dev *dev = hw->priv; int err = 0; - mutex_lock(&dev->mutex); + mutex_lock(&dev->mt76.mutex); if (changed & IEEE80211_CONF_CHANGE_MONITOR) { if (!(hw->conf.flags & IEEE80211_CONF_MONITOR)) - dev->rxfilter |= MT_RX_FILTR_CFG_PROMISC; + dev->mt76.rxfilter |= MT_RX_FILTR_CFG_PROMISC; else - dev->rxfilter &= ~MT_RX_FILTR_CFG_PROMISC; - mt76_wr(dev, MT_RX_FILTR_CFG, dev->rxfilter); + dev->mt76.rxfilter &= ~MT_RX_FILTR_CFG_PROMISC; + mt76_wr(dev, MT_RX_FILTR_CFG, dev->mt76.rxfilter); } if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { @@ -142,7 +143,7 @@ mt76x2u_config(struct ieee80211_hw *hw, u32 changed) mt76x2_phy_set_txpower(dev); } - mutex_unlock(&dev->mutex); + mutex_unlock(&dev->mt76.mutex); return err; } @@ -177,7 +178,7 @@ const struct ieee80211_ops mt76x2u_ops = { .config = mt76x2u_config, .wake_tx_queue = mt76_wake_tx_queue, .bss_info_changed = mt76x2u_bss_info_changed, - .configure_filter = mt76x2_configure_filter, + .configure_filter = mt76x02_configure_filter, .conf_tx = mt76x2_conf_tx, .sw_scan_start = mt76x2u_sw_scan, .sw_scan_complete = mt76x2u_sw_scan_complete, From c378f2473466fa403fb809566f4e81d704d34d21 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 29 Aug 2018 13:16:36 +0200 Subject: [PATCH 094/276] mt76: unify mac_get_key_info Merge mt76x{0,2} mac_get_key_info into new mt76x02_mac.c file. Signed-off-by: Stanislaw Gruszka Signed-off-by: Kalle Valo --- drivers/net/wireless/mediatek/mt76/Makefile | 2 +- .../net/wireless/mediatek/mt76/mt76x0/mac.c | 30 +----------- .../net/wireless/mediatek/mt76/mt76x02_mac.c | 46 +++++++++++++++++++ .../net/wireless/mediatek/mt76/mt76x02_mac.h | 3 ++ .../mediatek/mt76/mt76x2_mac_common.c | 30 +----------- 5 files changed, 54 insertions(+), 57 deletions(-) create mode 100644 drivers/net/wireless/mediatek/mt76/mt76x02_mac.c diff --git a/drivers/net/wireless/mediatek/mt76/Makefile b/drivers/net/wireless/mediatek/mt76/Makefile index 7d95f141cd73..a7fe5d6da857 100644 --- a/drivers/net/wireless/mediatek/mt76/Makefile +++ b/drivers/net/wireless/mediatek/mt76/Makefile @@ -14,7 +14,7 @@ mt76-usb-y := usb.o usb_trace.o usb_mcu.o CFLAGS_trace.o := -I$(src) CFLAGS_usb_trace.o := -I$(src) -mt76x02-lib-y := mt76x02_util.o +mt76x02-lib-y := mt76x02_util.o mt76x02_mac.o mt76x2-common-y := \ mt76x2_eeprom.o mt76x2_tx_common.o mt76x2_mac_common.o \ diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c b/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c index 74e922026c9f..4b5d48246879 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c @@ -566,32 +566,6 @@ u32 mt76x0_mac_process_rx(struct mt76x0_dev *dev, struct sk_buff *skb, return len; } -static enum mt76x02_cipher_type -mt76_mac_get_key_info(struct ieee80211_key_conf *key, u8 *key_data) -{ - memset(key_data, 0, 32); - if (!key) - return MT_CIPHER_NONE; - - if (key->keylen > 32) - return MT_CIPHER_NONE; - - memcpy(key_data, key->key, key->keylen); - - switch (key->cipher) { - case WLAN_CIPHER_SUITE_WEP40: - return MT_CIPHER_WEP40; - case WLAN_CIPHER_SUITE_WEP104: - return MT_CIPHER_WEP104; - case WLAN_CIPHER_SUITE_TKIP: - return MT_CIPHER_TKIP; - case WLAN_CIPHER_SUITE_CCMP: - return MT_CIPHER_AES_CCMP; - default: - return MT_CIPHER_NONE; - } -} - int mt76x0_mac_wcid_set_key(struct mt76x0_dev *dev, u8 idx, struct ieee80211_key_conf *key) { @@ -600,7 +574,7 @@ int mt76x0_mac_wcid_set_key(struct mt76x0_dev *dev, u8 idx, u8 iv_data[8]; u32 val; - cipher = mt76_mac_get_key_info(key, key_data); + cipher = mt76x02_mac_get_key_info(key, key_data); if (cipher == MT_CIPHER_NONE && key) return -EINVAL; @@ -640,7 +614,7 @@ int mt76x0_mac_shared_key_setup(struct mt76x0_dev *dev, u8 vif_idx, u8 key_idx, u8 key_data[32]; u32 val; - cipher = mt76_mac_get_key_info(key, key_data); + cipher = mt76x02_mac_get_key_info(key, key_data); if (cipher == MT_CIPHER_NONE && key) return -EINVAL; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c new file mode 100644 index 000000000000..7137fd2a370e --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2016 Felix Fietkau + * Copyright (C) 2018 Stanislaw Gruszka + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "mt76.h" +#include "mt76x02_regs.h" + +enum mt76x02_cipher_type +mt76x02_mac_get_key_info(struct ieee80211_key_conf *key, u8 *key_data) +{ + memset(key_data, 0, 32); + if (!key) + return MT_CIPHER_NONE; + + if (key->keylen > 32) + return MT_CIPHER_NONE; + + memcpy(key_data, key->key, key->keylen); + + switch (key->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + return MT_CIPHER_WEP40; + case WLAN_CIPHER_SUITE_WEP104: + return MT_CIPHER_WEP104; + case WLAN_CIPHER_SUITE_TKIP: + return MT_CIPHER_TKIP; + case WLAN_CIPHER_SUITE_CCMP: + return MT_CIPHER_AES_CCMP; + default: + return MT_CIPHER_NONE; + } +} +EXPORT_SYMBOL_GPL(mt76x02_mac_get_key_info); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h index 4bf14fd8916d..e06a1ff3a77f 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h @@ -39,4 +39,7 @@ static inline bool mt76x02_wait_for_mac(struct mt76_dev *dev) return false; } +enum mt76x02_cipher_type +mt76x02_mac_get_key_info(struct ieee80211_key_conf *key, u8 *key_data); + #endif diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mac_common.c b/drivers/net/wireless/mediatek/mt76/mt76x2_mac_common.c index 95770111918c..92621fc5fbf8 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_mac_common.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mac_common.c @@ -229,32 +229,6 @@ void mt76x2_send_tx_status(struct mt76x2_dev *dev, } EXPORT_SYMBOL_GPL(mt76x2_send_tx_status); -static enum mt76x02_cipher_type -mt76x2_mac_get_key_info(struct ieee80211_key_conf *key, u8 *key_data) -{ - memset(key_data, 0, 32); - if (!key) - return MT_CIPHER_NONE; - - if (key->keylen > 32) - return MT_CIPHER_NONE; - - memcpy(key_data, key->key, key->keylen); - - switch (key->cipher) { - case WLAN_CIPHER_SUITE_WEP40: - return MT_CIPHER_WEP40; - case WLAN_CIPHER_SUITE_WEP104: - return MT_CIPHER_WEP104; - case WLAN_CIPHER_SUITE_TKIP: - return MT_CIPHER_TKIP; - case WLAN_CIPHER_SUITE_CCMP: - return MT_CIPHER_AES_CCMP; - default: - return MT_CIPHER_NONE; - } -} - int mt76x2_mac_shared_key_setup(struct mt76x2_dev *dev, u8 vif_idx, u8 key_idx, struct ieee80211_key_conf *key) { @@ -262,7 +236,7 @@ int mt76x2_mac_shared_key_setup(struct mt76x2_dev *dev, u8 vif_idx, u8 key_idx, u8 key_data[32]; u32 val; - cipher = mt76x2_mac_get_key_info(key, key_data); + cipher = mt76x02_mac_get_key_info(key, key_data); if (cipher == MT_CIPHER_NONE && key) return -EOPNOTSUPP; @@ -285,7 +259,7 @@ int mt76x2_mac_wcid_set_key(struct mt76x2_dev *dev, u8 idx, u8 key_data[32]; u8 iv_data[8]; - cipher = mt76x2_mac_get_key_info(key, key_data); + cipher = mt76x02_mac_get_key_info(key, key_data); if (cipher == MT_CIPHER_NONE && key) return -EOPNOTSUPP; From d413127359c36ab81d1e5f25d57cce9c4ae40890 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 29 Aug 2018 13:16:37 +0200 Subject: [PATCH 095/276] mt76: add helpers for register access with mt76_dev struct Add helpers for register access from common code. Signed-off-by: Stanislaw Gruszka Signed-off-by: Kalle Valo --- drivers/net/wireless/mediatek/mt76/mt76.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h index 79017dbd364d..10959c4669bd 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76.h +++ b/drivers/net/wireless/mediatek/mt76/mt76.h @@ -404,6 +404,11 @@ struct mt76_rx_status { s8 chain_signal[IEEE80211_MAX_CHAINS]; }; +#define __mt76_rr(dev, ...) (dev)->bus->rr((dev), __VA_ARGS__) +#define __mt76_wr(dev, ...) (dev)->bus->wr((dev), __VA_ARGS__) +#define __mt76_rmw(dev, ...) (dev)->bus->rmw((dev), __VA_ARGS__) +#define __mt76_wr_copy(dev, ...) (dev)->bus->copy((dev), __VA_ARGS__) + #define mt76_rr(dev, ...) (dev)->mt76.bus->rr(&((dev)->mt76), __VA_ARGS__) #define mt76_wr(dev, ...) (dev)->mt76.bus->wr(&((dev)->mt76), __VA_ARGS__) #define mt76_rmw(dev, ...) (dev)->mt76.bus->rmw(&((dev)->mt76), __VA_ARGS__) From 047aed1c38cf4bfd5cf42ed845ef721aa6ed1283 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 29 Aug 2018 13:16:38 +0200 Subject: [PATCH 096/276] mt76: unify mac_shared_key_setup Merge mt76x{0,2} mac_shared_key_setup into common code. Signed-off-by: Stanislaw Gruszka Signed-off-by: Kalle Valo --- .../net/wireless/mediatek/mt76/mt76x0/mac.c | 24 ------------------- .../net/wireless/mediatek/mt76/mt76x0/mac.h | 2 -- .../net/wireless/mediatek/mt76/mt76x0/main.c | 2 +- .../net/wireless/mediatek/mt76/mt76x02_mac.c | 23 ++++++++++++++++++ .../net/wireless/mediatek/mt76/mt76x02_mac.h | 2 ++ .../wireless/mediatek/mt76/mt76x2_common.c | 3 ++- .../net/wireless/mediatek/mt76/mt76x2_init.c | 2 +- .../net/wireless/mediatek/mt76/mt76x2_mac.h | 3 --- .../mediatek/mt76/mt76x2_mac_common.c | 23 ------------------ 9 files changed, 29 insertions(+), 55 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c b/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c index 4b5d48246879..6d0a6fb18be9 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c @@ -606,27 +606,3 @@ int mt76x0_mac_wcid_set_key(struct mt76x0_dev *dev, u8 idx, return 0; } - -int mt76x0_mac_shared_key_setup(struct mt76x0_dev *dev, u8 vif_idx, u8 key_idx, - struct ieee80211_key_conf *key) -{ - enum mt76x02_cipher_type cipher; - u8 key_data[32]; - u32 val; - - cipher = mt76x02_mac_get_key_info(key, key_data); - if (cipher == MT_CIPHER_NONE && key) - return -EINVAL; - - trace_mt76x0_set_shared_key(&dev->mt76, vif_idx, key_idx); - - mt76_wr_copy(dev, MT_SKEY(vif_idx, key_idx), - key_data, sizeof(key_data)); - - val = mt76_rr(dev, MT_SKEY_MODE(vif_idx)); - val &= ~(MT_SKEY_MODE_MASK << MT_SKEY_MODE_SHIFT(vif_idx, key_idx)); - val |= cipher << MT_SKEY_MODE_SHIFT(vif_idx, key_idx); - mt76_wr(dev, MT_SKEY_MODE(vif_idx), val); - - return 0; -} diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mac.h b/drivers/net/wireless/mediatek/mt76/mt76x0/mac.h index bea067b71c13..d44ef1e9a1dd 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mac.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mac.h @@ -143,8 +143,6 @@ int mt76x0_mac_wcid_set_key(struct mt76x0_dev *dev, u8 idx, void mt76x0_mac_wcid_set_rate(struct mt76x0_dev *dev, struct mt76_wcid *wcid, const struct ieee80211_tx_rate *rate); -int mt76x0_mac_shared_key_setup(struct mt76x0_dev *dev, u8 vif_idx, u8 key_idx, - struct ieee80211_key_conf *key); u16 mt76x0_mac_tx_rate_val(struct mt76x0_dev *dev, const struct ieee80211_tx_rate *rate, u8 *nss_val); struct mt76_tx_status diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c index 8fc270b94819..fb31c103aeee 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c @@ -264,7 +264,7 @@ mt76x0_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, return ret; } - return mt76x0_mac_shared_key_setup(dev, mvif->idx, idx, key); + return mt76x02_mac_shared_key_setup(&dev->mt76, mvif->idx, idx, key); } return mt76x0_mac_wcid_set_key(dev, msta->wcid.idx, key); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c index 7137fd2a370e..6d45adc0522f 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c @@ -44,3 +44,26 @@ mt76x02_mac_get_key_info(struct ieee80211_key_conf *key, u8 *key_data) } } EXPORT_SYMBOL_GPL(mt76x02_mac_get_key_info); + +int mt76x02_mac_shared_key_setup(struct mt76_dev *dev, u8 vif_idx, u8 key_idx, + struct ieee80211_key_conf *key) +{ + enum mt76x02_cipher_type cipher; + u8 key_data[32]; + u32 val; + + cipher = mt76x02_mac_get_key_info(key, key_data); + if (cipher == MT_CIPHER_NONE && key) + return -EOPNOTSUPP; + + val = __mt76_rr(dev, MT_SKEY_MODE(vif_idx)); + val &= ~(MT_SKEY_MODE_MASK << MT_SKEY_MODE_SHIFT(vif_idx, key_idx)); + val |= cipher << MT_SKEY_MODE_SHIFT(vif_idx, key_idx); + __mt76_wr(dev, MT_SKEY_MODE(vif_idx), val); + + __mt76_wr_copy(dev, MT_SKEY(vif_idx, key_idx), key_data, + sizeof(key_data)); + + return 0; +} +EXPORT_SYMBOL_GPL(mt76x02_mac_shared_key_setup); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h index e06a1ff3a77f..6f8b8a1d02cf 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h @@ -42,4 +42,6 @@ static inline bool mt76x02_wait_for_mac(struct mt76_dev *dev) enum mt76x02_cipher_type mt76x02_mac_get_key_info(struct ieee80211_key_conf *key, u8 *key_data); +int mt76x02_mac_shared_key_setup(struct mt76_dev *dev, u8 vif_idx, u8 key_idx, + struct ieee80211_key_conf *key); #endif diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_common.c b/drivers/net/wireless/mediatek/mt76/mt76x2_common.c index fe0b394fd9ea..56cceeac78d8 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_common.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_common.c @@ -16,6 +16,7 @@ */ #include "mt76x2.h" +#include "mt76x02_mac.h" void mt76x2_txq_init(struct mt76x2_dev *dev, struct ieee80211_txq *txq) { @@ -223,7 +224,7 @@ int mt76x2_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, return ret; } - return mt76x2_mac_shared_key_setup(dev, mvif->idx, idx, key); + return mt76x02_mac_shared_key_setup(&dev->mt76, mvif->idx, idx, key); } return mt76x2_mac_wcid_set_key(dev, msta->wcid.idx, key); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_init.c b/drivers/net/wireless/mediatek/mt76/mt76x2_init.c index 07ef0a368f1e..1c5c3552a719 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_init.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_init.c @@ -167,7 +167,7 @@ static int mt76x2_mac_reset(struct mt76x2_dev *dev, bool hard) for (i = 0; i < 16; i++) for (k = 0; k < 4; k++) - mt76x2_mac_shared_key_setup(dev, i, k, NULL); + mt76x02_mac_shared_key_setup(&dev->mt76, i, k, NULL); for (i = 0; i < 8; i++) { mt76x2_mac_set_bssid(dev, i, null_addr); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.h b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.h index 0f07fc1a19ab..4be2e0e64847 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.h @@ -175,9 +175,6 @@ void mt76x2_mac_wcid_set_rate(struct mt76x2_dev *dev, struct mt76_wcid *wcid, const struct ieee80211_tx_rate *rate); void mt76x2_mac_wcid_set_drop(struct mt76x2_dev *dev, u8 idx, bool drop); -int mt76x2_mac_shared_key_setup(struct mt76x2_dev *dev, u8 vif_idx, u8 key_idx, - struct ieee80211_key_conf *key); - int mt76x2_mac_set_beacon(struct mt76x2_dev *dev, u8 vif_idx, struct sk_buff *skb); void mt76x2_mac_set_beacon_enable(struct mt76x2_dev *dev, u8 vif_idx, bool val); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mac_common.c b/drivers/net/wireless/mediatek/mt76/mt76x2_mac_common.c index 92621fc5fbf8..7359ef647268 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_mac_common.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mac_common.c @@ -229,29 +229,6 @@ void mt76x2_send_tx_status(struct mt76x2_dev *dev, } EXPORT_SYMBOL_GPL(mt76x2_send_tx_status); -int mt76x2_mac_shared_key_setup(struct mt76x2_dev *dev, u8 vif_idx, u8 key_idx, - struct ieee80211_key_conf *key) -{ - enum mt76x02_cipher_type cipher; - u8 key_data[32]; - u32 val; - - cipher = mt76x02_mac_get_key_info(key, key_data); - if (cipher == MT_CIPHER_NONE && key) - return -EOPNOTSUPP; - - val = mt76_rr(dev, MT_SKEY_MODE(vif_idx)); - val &= ~(MT_SKEY_MODE_MASK << MT_SKEY_MODE_SHIFT(vif_idx, key_idx)); - val |= cipher << MT_SKEY_MODE_SHIFT(vif_idx, key_idx); - mt76_wr(dev, MT_SKEY_MODE(vif_idx), val); - - mt76_wr_copy(dev, MT_SKEY(vif_idx, key_idx), key_data, - sizeof(key_data)); - - return 0; -} -EXPORT_SYMBOL_GPL(mt76x2_mac_shared_key_setup); - int mt76x2_mac_wcid_set_key(struct mt76x2_dev *dev, u8 idx, struct ieee80211_key_conf *key) { From 46436b5ef9dd2b44349641301c35c2181bf7f568 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 29 Aug 2018 13:16:39 +0200 Subject: [PATCH 097/276] mt76: unify mac_wcid_set_key Merge mt76x{0,2}_mac_wcid_set_key into common code. Signed-off-by: Stanislaw Gruszka Signed-off-by: Kalle Valo --- drivers/net/wireless/mediatek/mt76/mt76.h | 3 ++ .../net/wireless/mediatek/mt76/mt76x0/mac.c | 41 ------------------- .../net/wireless/mediatek/mt76/mt76x0/mac.h | 2 - .../net/wireless/mediatek/mt76/mt76x0/main.c | 4 +- .../net/wireless/mediatek/mt76/mt76x02_mac.c | 29 +++++++++++++ .../net/wireless/mediatek/mt76/mt76x02_mac.h | 2 + .../wireless/mediatek/mt76/mt76x2_common.c | 4 +- .../net/wireless/mediatek/mt76/mt76x2_mac.h | 2 - .../mediatek/mt76/mt76x2_mac_common.c | 29 ------------- 9 files changed, 38 insertions(+), 78 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h index 10959c4669bd..b02b4191ef37 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76.h +++ b/drivers/net/wireless/mediatek/mt76/mt76.h @@ -423,6 +423,9 @@ struct mt76_rx_status { #define mt76_rmw_field(_dev, _reg, _field, _val) \ mt76_rmw(_dev, _reg, _field, FIELD_PREP(_field, _val)) +#define __mt76_rmw_field(_dev, _reg, _field, _val) \ + __mt76_rmw(_dev, _reg, _field, FIELD_PREP(_field, _val)) + #define mt76_hw(dev) (dev)->mt76.hw bool __mt76_poll(struct mt76_dev *dev, u32 offset, u32 mask, u32 val, diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c b/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c index 6d0a6fb18be9..2fcdedd0cadc 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c @@ -565,44 +565,3 @@ u32 mt76x0_mac_process_rx(struct mt76x0_dev *dev, struct sk_buff *skb, return len; } - -int mt76x0_mac_wcid_set_key(struct mt76x0_dev *dev, u8 idx, - struct ieee80211_key_conf *key) -{ - enum mt76x02_cipher_type cipher; - u8 key_data[32]; - u8 iv_data[8]; - u32 val; - - cipher = mt76x02_mac_get_key_info(key, key_data); - if (cipher == MT_CIPHER_NONE && key) - return -EINVAL; - - trace_mt76x0_set_key(&dev->mt76, idx); - - mt76_wr_copy(dev, MT_WCID_KEY(idx), key_data, sizeof(key_data)); - - memset(iv_data, 0, sizeof(iv_data)); - if (key) { - iv_data[3] = key->keyidx << 6; - if (cipher >= MT_CIPHER_TKIP) { - /* Note: start with 1 to comply with spec, - * (see comment on common/cmm_wpa.c:4291). - */ - iv_data[0] |= 1; - iv_data[3] |= 0x20; - } - } - mt76_wr_copy(dev, MT_WCID_IV(idx), iv_data, sizeof(iv_data)); - - val = mt76_rr(dev, MT_WCID_ATTR(idx)); - val &= ~MT_WCID_ATTR_PKEY_MODE & ~MT_WCID_ATTR_PKEY_MODE_EXT; - val |= FIELD_PREP(MT_WCID_ATTR_PKEY_MODE, cipher & 7) | - FIELD_PREP(MT_WCID_ATTR_PKEY_MODE_EXT, cipher >> 3); - val &= ~MT_WCID_ATTR_PAIRWISE; - val |= MT_WCID_ATTR_PAIRWISE * - !!(key && key->flags & IEEE80211_KEY_FLAG_PAIRWISE); - mt76_wr(dev, MT_WCID_ATTR(idx), val); - - return 0; -} diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mac.h b/drivers/net/wireless/mediatek/mt76/mt76x0/mac.h index d44ef1e9a1dd..f8074c477044 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mac.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mac.h @@ -138,8 +138,6 @@ struct mt76_txwi { u32 mt76x0_mac_process_rx(struct mt76x0_dev *dev, struct sk_buff *skb, u8 *data, void *rxi); -int mt76x0_mac_wcid_set_key(struct mt76x0_dev *dev, u8 idx, - struct ieee80211_key_conf *key); void mt76x0_mac_wcid_set_rate(struct mt76x0_dev *dev, struct mt76_wcid *wcid, const struct ieee80211_tx_rate *rate); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c index fb31c103aeee..5b39f4d28072 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c @@ -259,7 +259,7 @@ mt76x0_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, if (!msta) { if (key || wcid->hw_key_idx == idx) { - ret = mt76x0_mac_wcid_set_key(dev, wcid->idx, key); + ret = mt76x02_mac_wcid_set_key(&dev->mt76, wcid->idx, key); if (ret) return ret; } @@ -267,7 +267,7 @@ mt76x0_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, return mt76x02_mac_shared_key_setup(&dev->mt76, mvif->idx, idx, key); } - return mt76x0_mac_wcid_set_key(dev, msta->wcid.idx, key); + return mt76x02_mac_wcid_set_key(&dev->mt76, msta->wcid.idx, key); } static int mt76x0_set_rts_threshold(struct ieee80211_hw *hw, u32 value) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c index 6d45adc0522f..3261c510a8c8 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c @@ -67,3 +67,32 @@ int mt76x02_mac_shared_key_setup(struct mt76_dev *dev, u8 vif_idx, u8 key_idx, return 0; } EXPORT_SYMBOL_GPL(mt76x02_mac_shared_key_setup); + +int mt76x02_mac_wcid_set_key(struct mt76_dev *dev, u8 idx, + struct ieee80211_key_conf *key) +{ + enum mt76x02_cipher_type cipher; + u8 key_data[32]; + u8 iv_data[8]; + + cipher = mt76x02_mac_get_key_info(key, key_data); + if (cipher == MT_CIPHER_NONE && key) + return -EOPNOTSUPP; + + __mt76_wr_copy(dev, MT_WCID_KEY(idx), key_data, sizeof(key_data)); + __mt76_rmw_field(dev, MT_WCID_ATTR(idx), MT_WCID_ATTR_PKEY_MODE, cipher); + + memset(iv_data, 0, sizeof(iv_data)); + if (key) { + __mt76_rmw_field(dev, MT_WCID_ATTR(idx), MT_WCID_ATTR_PAIRWISE, + !!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)); + iv_data[3] = key->keyidx << 6; + if (cipher >= MT_CIPHER_TKIP) + iv_data[3] |= 0x20; + } + + __mt76_wr_copy(dev, MT_WCID_IV(idx), iv_data, sizeof(iv_data)); + + return 0; +} +EXPORT_SYMBOL_GPL(mt76x02_mac_wcid_set_key); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h index 6f8b8a1d02cf..aebc7dcf7435 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h @@ -44,4 +44,6 @@ mt76x02_mac_get_key_info(struct ieee80211_key_conf *key, u8 *key_data); int mt76x02_mac_shared_key_setup(struct mt76_dev *dev, u8 vif_idx, u8 key_idx, struct ieee80211_key_conf *key); +int mt76x02_mac_wcid_set_key(struct mt76_dev *dev, u8 idx, + struct ieee80211_key_conf *key); #endif diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_common.c b/drivers/net/wireless/mediatek/mt76/mt76x2_common.c index 56cceeac78d8..1de191c4f6a0 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_common.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_common.c @@ -219,7 +219,7 @@ int mt76x2_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, if (!msta) { if (key || wcid->hw_key_idx == idx) { - ret = mt76x2_mac_wcid_set_key(dev, wcid->idx, key); + ret = mt76x02_mac_wcid_set_key(&dev->mt76, wcid->idx, key); if (ret) return ret; } @@ -227,7 +227,7 @@ int mt76x2_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, return mt76x02_mac_shared_key_setup(&dev->mt76, mvif->idx, idx, key); } - return mt76x2_mac_wcid_set_key(dev, msta->wcid.idx, key); + return mt76x02_mac_wcid_set_key(&dev->mt76, msta->wcid.idx, key); } EXPORT_SYMBOL_GPL(mt76x2_set_key); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.h b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.h index 4be2e0e64847..77dd01da9bb9 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.h @@ -169,8 +169,6 @@ void mt76x2_mac_write_txwi(struct mt76x2_dev *dev, struct mt76x2_txwi *txwi, struct sk_buff *skb, struct mt76_wcid *wcid, struct ieee80211_sta *sta, int len); void mt76x2_mac_wcid_setup(struct mt76x2_dev *dev, u8 idx, u8 vif_idx, u8 *mac); -int mt76x2_mac_wcid_set_key(struct mt76x2_dev *dev, u8 idx, - struct ieee80211_key_conf *key); void mt76x2_mac_wcid_set_rate(struct mt76x2_dev *dev, struct mt76_wcid *wcid, const struct ieee80211_tx_rate *rate); void mt76x2_mac_wcid_set_drop(struct mt76x2_dev *dev, u8 idx, bool drop); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mac_common.c b/drivers/net/wireless/mediatek/mt76/mt76x2_mac_common.c index 7359ef647268..c218434af347 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_mac_common.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mac_common.c @@ -229,35 +229,6 @@ void mt76x2_send_tx_status(struct mt76x2_dev *dev, } EXPORT_SYMBOL_GPL(mt76x2_send_tx_status); -int mt76x2_mac_wcid_set_key(struct mt76x2_dev *dev, u8 idx, - struct ieee80211_key_conf *key) -{ - enum mt76x02_cipher_type cipher; - u8 key_data[32]; - u8 iv_data[8]; - - cipher = mt76x02_mac_get_key_info(key, key_data); - if (cipher == MT_CIPHER_NONE && key) - return -EOPNOTSUPP; - - mt76_rmw_field(dev, MT_WCID_ATTR(idx), MT_WCID_ATTR_PKEY_MODE, cipher); - mt76_wr_copy(dev, MT_WCID_KEY(idx), key_data, sizeof(key_data)); - - memset(iv_data, 0, sizeof(iv_data)); - if (key) { - mt76_rmw_field(dev, MT_WCID_ATTR(idx), MT_WCID_ATTR_PAIRWISE, - !!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)); - iv_data[3] = key->keyidx << 6; - if (cipher >= MT_CIPHER_TKIP) - iv_data[3] |= 0x20; - } - - mt76_wr_copy(dev, MT_WCID_IV(idx), iv_data, sizeof(iv_data)); - - return 0; -} -EXPORT_SYMBOL_GPL(mt76x2_mac_wcid_set_key); - static __le16 mt76x2_mac_tx_rate_val(struct mt76x2_dev *dev, const struct ieee80211_tx_rate *rate, u8 *nss_val) From 32bb405fe2bc30dc2f2236e97d2767d549021ec3 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 29 Aug 2018 13:16:40 +0200 Subject: [PATCH 098/276] mt76: unify mac_wcid_setup Merge mt76x{0,2}_mac_wcid_setup into common code. Signed-off-by: Stanislaw Gruszka Signed-off-by: Kalle Valo --- .../net/wireless/mediatek/mt76/mt76x0/mac.c | 17 -------------- .../net/wireless/mediatek/mt76/mt76x0/main.c | 6 ++--- .../wireless/mediatek/mt76/mt76x0/mt76x0.h | 2 -- .../net/wireless/mediatek/mt76/mt76x02_mac.c | 23 +++++++++++++++++++ .../net/wireless/mediatek/mt76/mt76x02_mac.h | 1 + .../wireless/mediatek/mt76/mt76x2_common.c | 4 ++-- .../net/wireless/mediatek/mt76/mt76x2_init.c | 4 ++-- .../net/wireless/mediatek/mt76/mt76x2_mac.h | 1 - .../mediatek/mt76/mt76x2_mac_common.c | 23 ------------------- 9 files changed, 31 insertions(+), 50 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c b/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c index 2fcdedd0cadc..2bf5c81ecf10 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c @@ -399,23 +399,6 @@ void mt76x0_mac_work(struct work_struct *work) ieee80211_queue_delayed_work(dev->mt76.hw, &dev->mac_work, 10 * HZ); } -void -mt76x0_mac_wcid_setup(struct mt76x0_dev *dev, u8 idx, u8 vif_idx, u8 *mac) -{ - u8 zmac[ETH_ALEN] = {}; - u32 attr; - - attr = FIELD_PREP(MT_WCID_ATTR_BSS_IDX, vif_idx & 7) | - FIELD_PREP(MT_WCID_ATTR_BSS_IDX_EXT, !!(vif_idx & 8)); - - mt76_wr(dev, MT_WCID_ATTR(idx), attr); - - if (mac) - memcpy(zmac, mac, sizeof(zmac)); - - mt76x0_addr_wr(dev, MT_WCID_ADDR(idx), zmac); -} - void mt76x0_mac_set_ampdu_factor(struct mt76x0_dev *dev) { struct ieee80211_sta *sta; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c index 5b39f4d28072..2c15c7ae12ef 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c @@ -156,7 +156,7 @@ mt76x0_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, static int mt76x0_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - struct ieee80211_sta *sta) + struct ieee80211_sta *sta) { struct mt76x0_dev *dev = hw->priv; struct mt76_sta *msta = (struct mt76_sta *) sta->drv_priv; @@ -174,7 +174,7 @@ mt76x0_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, msta->wcid.idx = idx; msta->wcid.hw_key_idx = -1; - mt76x0_mac_wcid_setup(dev, idx, mvif->idx, sta->addr); + mt76x02_mac_wcid_setup(&dev->mt76, idx, mvif->idx, sta->addr); mt76_clear(dev, MT_WCID_DROP(idx), MT_WCID_DROP_MASK(idx)); rcu_assign_pointer(dev->wcid[idx], &msta->wcid); mt76x0_mac_set_ampdu_factor(dev); @@ -197,7 +197,7 @@ mt76x0_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, rcu_assign_pointer(dev->wcid[idx], NULL); mt76_set(dev, MT_WCID_DROP(idx), MT_WCID_DROP_MASK(idx)); dev->wcid_mask[idx / BITS_PER_LONG] &= ~BIT(idx % BITS_PER_LONG); - mt76x0_mac_wcid_setup(dev, idx, 0, NULL); + mt76x02_mac_wcid_setup(&dev->mt76, idx, 0, NULL); mt76x0_mac_set_ampdu_factor(dev); mutex_unlock(&dev->mt76.mutex); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h index 967b262495e7..7ad68dc2df30 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h @@ -301,8 +301,6 @@ void mt76x0_mac_set_protection(struct mt76x0_dev *dev, bool legacy_prot, int ht_mode); void mt76x0_mac_set_short_preamble(struct mt76x0_dev *dev, bool short_preamb); void mt76x0_mac_config_tsf(struct mt76x0_dev *dev, bool enable, int interval); -void -mt76x0_mac_wcid_setup(struct mt76x0_dev *dev, u8 idx, u8 vif_idx, u8 *mac); void mt76x0_mac_set_ampdu_factor(struct mt76x0_dev *dev); /* TX */ diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c index 3261c510a8c8..119229b2dd71 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c @@ -96,3 +96,26 @@ int mt76x02_mac_wcid_set_key(struct mt76_dev *dev, u8 idx, return 0; } EXPORT_SYMBOL_GPL(mt76x02_mac_wcid_set_key); + +void mt76x02_mac_wcid_setup(struct mt76_dev *dev, u8 idx, u8 vif_idx, u8 *mac) +{ + struct mt76_wcid_addr addr = {}; + u32 attr; + + attr = FIELD_PREP(MT_WCID_ATTR_BSS_IDX, vif_idx & 7) | + FIELD_PREP(MT_WCID_ATTR_BSS_IDX_EXT, !!(vif_idx & 8)); + + __mt76_wr(dev, MT_WCID_ATTR(idx), attr); + + __mt76_wr(dev, MT_WCID_TX_RATE(idx), 0); + __mt76_wr(dev, MT_WCID_TX_RATE(idx) + 4, 0); + + if (idx >= 128) + return; + + if (mac) + memcpy(addr.macaddr, mac, ETH_ALEN); + + __mt76_wr_copy(dev, MT_WCID_ADDR(idx), &addr, sizeof(addr)); +} +EXPORT_SYMBOL_GPL(mt76x02_mac_wcid_setup); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h index aebc7dcf7435..2fb8b581bf4c 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h @@ -46,4 +46,5 @@ int mt76x02_mac_shared_key_setup(struct mt76_dev *dev, u8 vif_idx, u8 key_idx, struct ieee80211_key_conf *key); int mt76x02_mac_wcid_set_key(struct mt76_dev *dev, u8 idx, struct ieee80211_key_conf *key); +void mt76x02_mac_wcid_setup(struct mt76_dev *dev, u8 idx, u8 vif_idx, u8 *mac); #endif diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_common.c b/drivers/net/wireless/mediatek/mt76/mt76x2_common.c index 1de191c4f6a0..706dedee8674 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_common.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_common.c @@ -115,7 +115,7 @@ int mt76x2_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, msta->wcid.sta = 1; msta->wcid.idx = idx; msta->wcid.hw_key_idx = -1; - mt76x2_mac_wcid_setup(dev, idx, mvif->idx, sta->addr); + mt76x02_mac_wcid_setup(&dev->mt76, idx, mvif->idx, sta->addr); mt76x2_mac_wcid_set_drop(dev, idx, false); for (i = 0; i < ARRAY_SIZE(sta->txq); i++) mt76x2_txq_init(dev, sta->txq[i]); @@ -148,7 +148,7 @@ int mt76x2_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, mt76_txq_remove(&dev->mt76, sta->txq[i]); mt76x2_mac_wcid_set_drop(dev, idx, true); mt76_wcid_free(dev->wcid_mask, idx); - mt76x2_mac_wcid_setup(dev, idx, 0, NULL); + mt76x02_mac_wcid_setup(&dev->mt76, idx, 0, NULL); mutex_unlock(&dev->mt76.mutex); return 0; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_init.c b/drivers/net/wireless/mediatek/mt76/mt76x2_init.c index 1c5c3552a719..f5cf01f912b9 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_init.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_init.c @@ -160,10 +160,10 @@ static int mt76x2_mac_reset(struct mt76x2_dev *dev, bool hard) mt76_wr(dev, MT_WCID_DROP_BASE + i * 4, 0); for (i = 0; i < 256; i++) - mt76x2_mac_wcid_setup(dev, i, 0, NULL); + mt76x02_mac_wcid_setup(&dev->mt76, i, 0, NULL); for (i = 0; i < MT_MAX_VIFS; i++) - mt76x2_mac_wcid_setup(dev, MT_VIF_WCID(i), i, NULL); + mt76x02_mac_wcid_setup(&dev->mt76, MT_VIF_WCID(i), i, NULL); for (i = 0; i < 16; i++) for (k = 0; k < 4; k++) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.h b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.h index 77dd01da9bb9..1b156a04fb7f 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.h @@ -168,7 +168,6 @@ int mt76x2_mac_process_rx(struct mt76x2_dev *dev, struct sk_buff *skb, void mt76x2_mac_write_txwi(struct mt76x2_dev *dev, struct mt76x2_txwi *txwi, struct sk_buff *skb, struct mt76_wcid *wcid, struct ieee80211_sta *sta, int len); -void mt76x2_mac_wcid_setup(struct mt76x2_dev *dev, u8 idx, u8 vif_idx, u8 *mac); void mt76x2_mac_wcid_set_rate(struct mt76x2_dev *dev, struct mt76_wcid *wcid, const struct ieee80211_tx_rate *rate); void mt76x2_mac_wcid_set_drop(struct mt76x2_dev *dev, u8 idx, bool drop); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mac_common.c b/drivers/net/wireless/mediatek/mt76/mt76x2_mac_common.c index c218434af347..f4e72a280132 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_mac_common.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mac_common.c @@ -394,29 +394,6 @@ void mt76x2_mac_wcid_set_drop(struct mt76x2_dev *dev, u8 idx, bool drop) } EXPORT_SYMBOL_GPL(mt76x2_mac_wcid_set_drop); -void mt76x2_mac_wcid_setup(struct mt76x2_dev *dev, u8 idx, u8 vif_idx, u8 *mac) -{ - struct mt76_wcid_addr addr = {}; - u32 attr; - - attr = FIELD_PREP(MT_WCID_ATTR_BSS_IDX, vif_idx & 7) | - FIELD_PREP(MT_WCID_ATTR_BSS_IDX_EXT, !!(vif_idx & 8)); - - mt76_wr(dev, MT_WCID_ATTR(idx), attr); - - mt76_wr(dev, MT_WCID_TX_RATE(idx), 0); - mt76_wr(dev, MT_WCID_TX_RATE(idx) + 4, 0); - - if (idx >= 128) - return; - - if (mac) - memcpy(addr.macaddr, mac, ETH_ALEN); - - mt76_wr_copy(dev, MT_WCID_ADDR(idx), &addr, sizeof(addr)); -} -EXPORT_SYMBOL_GPL(mt76x2_mac_wcid_setup); - static int mt76x2_mac_process_rate(struct mt76_rx_status *status, u16 rate) { From 516ea2a2a9d43a562879634c7d57254b51b0dc60 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 29 Aug 2018 13:16:41 +0200 Subject: [PATCH 099/276] mt76: use mac_wcid_set_drop in mt76x0 Move mt76x02_mac_wcid_set_drop to common code and use it in mt76x0. Signed-off-by: Stanislaw Gruszka Signed-off-by: Kalle Valo --- drivers/net/wireless/mediatek/mt76/mt76x0/main.c | 3 ++- drivers/net/wireless/mediatek/mt76/mt76x02_mac.c | 11 +++++++++++ drivers/net/wireless/mediatek/mt76/mt76x02_mac.h | 1 + drivers/net/wireless/mediatek/mt76/mt76x2_common.c | 4 ++-- drivers/net/wireless/mediatek/mt76/mt76x2_mac.h | 1 - .../net/wireless/mediatek/mt76/mt76x2_mac_common.c | 11 ----------- drivers/net/wireless/mediatek/mt76/mt76x2_main.c | 2 +- drivers/net/wireless/mediatek/mt76/mt76x2_tx.c | 2 +- 8 files changed, 18 insertions(+), 17 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c index 2c15c7ae12ef..a5bdd324f6ec 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c @@ -175,6 +175,7 @@ mt76x0_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, msta->wcid.idx = idx; msta->wcid.hw_key_idx = -1; mt76x02_mac_wcid_setup(&dev->mt76, idx, mvif->idx, sta->addr); + mt76x02_mac_wcid_set_drop(&dev->mt76, idx, false); mt76_clear(dev, MT_WCID_DROP(idx), MT_WCID_DROP_MASK(idx)); rcu_assign_pointer(dev->wcid[idx], &msta->wcid); mt76x0_mac_set_ampdu_factor(dev); @@ -195,7 +196,7 @@ mt76x0_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, mutex_lock(&dev->mt76.mutex); rcu_assign_pointer(dev->wcid[idx], NULL); - mt76_set(dev, MT_WCID_DROP(idx), MT_WCID_DROP_MASK(idx)); + mt76x02_mac_wcid_set_drop(&dev->mt76, idx, true); dev->wcid_mask[idx / BITS_PER_LONG] &= ~BIT(idx % BITS_PER_LONG); mt76x02_mac_wcid_setup(&dev->mt76, idx, 0, NULL); mt76x0_mac_set_ampdu_factor(dev); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c index 119229b2dd71..2242c0d7e200 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c @@ -119,3 +119,14 @@ void mt76x02_mac_wcid_setup(struct mt76_dev *dev, u8 idx, u8 vif_idx, u8 *mac) __mt76_wr_copy(dev, MT_WCID_ADDR(idx), &addr, sizeof(addr)); } EXPORT_SYMBOL_GPL(mt76x02_mac_wcid_setup); + +void mt76x02_mac_wcid_set_drop(struct mt76_dev *dev, u8 idx, bool drop) +{ + u32 val = __mt76_rr(dev, MT_WCID_DROP(idx)); + u32 bit = MT_WCID_DROP_MASK(idx); + + /* prevent unnecessary writes */ + if ((val & bit) != (bit * drop)) + __mt76_wr(dev, MT_WCID_DROP(idx), (val & ~bit) | (bit * drop)); +} +EXPORT_SYMBOL_GPL(mt76x02_mac_wcid_set_drop); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h index 2fb8b581bf4c..7dc11cf70f7e 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h @@ -47,4 +47,5 @@ int mt76x02_mac_shared_key_setup(struct mt76_dev *dev, u8 vif_idx, u8 key_idx, int mt76x02_mac_wcid_set_key(struct mt76_dev *dev, u8 idx, struct ieee80211_key_conf *key); void mt76x02_mac_wcid_setup(struct mt76_dev *dev, u8 idx, u8 vif_idx, u8 *mac); +void mt76x02_mac_wcid_set_drop(struct mt76_dev *dev, u8 idx, bool drop); #endif diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_common.c b/drivers/net/wireless/mediatek/mt76/mt76x2_common.c index 706dedee8674..9ef692930d89 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_common.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_common.c @@ -116,7 +116,7 @@ int mt76x2_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, msta->wcid.idx = idx; msta->wcid.hw_key_idx = -1; mt76x02_mac_wcid_setup(&dev->mt76, idx, mvif->idx, sta->addr); - mt76x2_mac_wcid_set_drop(dev, idx, false); + mt76x02_mac_wcid_set_drop(&dev->mt76, idx, false); for (i = 0; i < ARRAY_SIZE(sta->txq); i++) mt76x2_txq_init(dev, sta->txq[i]); @@ -146,7 +146,7 @@ int mt76x2_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, rcu_assign_pointer(dev->wcid[idx], NULL); for (i = 0; i < ARRAY_SIZE(sta->txq); i++) mt76_txq_remove(&dev->mt76, sta->txq[i]); - mt76x2_mac_wcid_set_drop(dev, idx, true); + mt76x02_mac_wcid_set_drop(&dev->mt76, idx, true); mt76_wcid_free(dev->wcid_mask, idx); mt76x02_mac_wcid_setup(&dev->mt76, idx, 0, NULL); mutex_unlock(&dev->mt76.mutex); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.h b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.h index 1b156a04fb7f..ad22d375c847 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.h @@ -170,7 +170,6 @@ void mt76x2_mac_write_txwi(struct mt76x2_dev *dev, struct mt76x2_txwi *txwi, struct ieee80211_sta *sta, int len); void mt76x2_mac_wcid_set_rate(struct mt76x2_dev *dev, struct mt76_wcid *wcid, const struct ieee80211_tx_rate *rate); -void mt76x2_mac_wcid_set_drop(struct mt76x2_dev *dev, u8 idx, bool drop); int mt76x2_mac_set_beacon(struct mt76x2_dev *dev, u8 vif_idx, struct sk_buff *skb); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mac_common.c b/drivers/net/wireless/mediatek/mt76/mt76x2_mac_common.c index f4e72a280132..f4ae0f157aaa 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_mac_common.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mac_common.c @@ -383,17 +383,6 @@ void mt76x2_mac_write_txwi(struct mt76x2_dev *dev, struct mt76x2_txwi *txwi, } EXPORT_SYMBOL_GPL(mt76x2_mac_write_txwi); -void mt76x2_mac_wcid_set_drop(struct mt76x2_dev *dev, u8 idx, bool drop) -{ - u32 val = mt76_rr(dev, MT_WCID_DROP(idx)); - u32 bit = MT_WCID_DROP_MASK(idx); - - /* prevent unnecessary writes */ - if ((val & bit) != (bit * drop)) - mt76_wr(dev, MT_WCID_DROP(idx), (val & ~bit) | (bit * drop)); -} -EXPORT_SYMBOL_GPL(mt76x2_mac_wcid_set_drop); - static int mt76x2_mac_process_rate(struct mt76_rx_status *status, u16 rate) { diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_main.c b/drivers/net/wireless/mediatek/mt76/mt76x2_main.c index 577c6ee39fb8..7d2b4a419566 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_main.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_main.c @@ -207,7 +207,7 @@ mt76x2_sta_ps(struct mt76_dev *mdev, struct ieee80211_sta *sta, bool ps) int idx = msta->wcid.idx; mt76_stop_tx_queues(&dev->mt76, sta, true); - mt76x2_mac_wcid_set_drop(dev, idx, ps); + mt76x02_mac_wcid_set_drop(&dev->mt76, idx, ps); } static void diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_tx.c b/drivers/net/wireless/mediatek/mt76/mt76x2_tx.c index 4c907882e8b0..6874db52b846 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_tx.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_tx.c @@ -34,7 +34,7 @@ int mt76x2_tx_prepare_skb(struct mt76_dev *mdev, void *txwi, int ret; if (q == &dev->mt76.q_tx[MT_TXQ_PSD] && wcid && wcid->idx < 128) - mt76x2_mac_wcid_set_drop(dev, wcid->idx, false); + mt76x02_mac_wcid_set_drop(&dev->mt76, wcid->idx, false); mt76x2_mac_write_txwi(dev, txwi, skb, wcid, sta, skb->len); From 459e237f14cda04232753aa9a44c0da8b629d69b Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 29 Aug 2018 13:16:42 +0200 Subject: [PATCH 100/276] mt76x0: use mt76_wcid_free in mt76x0 Use helper from util instead of custom code. Signed-off-by: Stanislaw Gruszka Signed-off-by: Kalle Valo --- drivers/net/wireless/mediatek/mt76/mt76x0/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c index a5bdd324f6ec..66e8389d489f 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c @@ -197,7 +197,7 @@ mt76x0_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, mutex_lock(&dev->mt76.mutex); rcu_assign_pointer(dev->wcid[idx], NULL); mt76x02_mac_wcid_set_drop(&dev->mt76, idx, true); - dev->wcid_mask[idx / BITS_PER_LONG] &= ~BIT(idx % BITS_PER_LONG); + mt76_wcid_free(dev->wcid_mask, idx); mt76x02_mac_wcid_setup(&dev->mt76, idx, 0, NULL); mt76x0_mac_set_ampdu_factor(dev); mutex_unlock(&dev->mt76.mutex); From 98ff26e5e21733be4527a9b3ecffe529b282542a Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 29 Aug 2018 13:16:43 +0200 Subject: [PATCH 101/276] mt76: unify mt76x02_vif struct Private vif structures definitions are the same for mt76x2 and mt76x0. Signed-off-by: Stanislaw Gruszka Signed-off-by: Kalle Valo --- drivers/net/wireless/mediatek/mt76/mt76x0/init.c | 2 +- drivers/net/wireless/mediatek/mt76/mt76x0/main.c | 8 ++++---- drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h | 6 ------ drivers/net/wireless/mediatek/mt76/mt76x0/tx.c | 2 +- drivers/net/wireless/mediatek/mt76/mt76x02_mac.h | 6 ++++++ drivers/net/wireless/mediatek/mt76/mt76x2.h | 8 +------- drivers/net/wireless/mediatek/mt76/mt76x2_common.c | 8 ++++---- drivers/net/wireless/mediatek/mt76/mt76x2_init_common.c | 2 +- drivers/net/wireless/mediatek/mt76/mt76x2_mac.h | 2 +- drivers/net/wireless/mediatek/mt76/mt76x2_main.c | 4 ++-- drivers/net/wireless/mediatek/mt76/mt76x2_tx.c | 6 +++--- drivers/net/wireless/mediatek/mt76/mt76x2_tx_common.c | 4 ++-- drivers/net/wireless/mediatek/mt76/mt76x2u_main.c | 2 +- 13 files changed, 27 insertions(+), 33 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c index 33924643946d..41c9c7b5deea 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c @@ -689,7 +689,7 @@ int mt76x0_register_device(struct mt76x0_dev *dev) hw->max_rate_tries = 1; hw->sta_data_size = sizeof(struct mt76_sta); - hw->vif_data_size = sizeof(struct mt76_vif); + hw->vif_data_size = sizeof(struct mt76x02_vif); SET_IEEE80211_PERM_ADDR(hw, dev->macaddr); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c index 66e8389d489f..1cf06bffaa71 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c @@ -56,7 +56,7 @@ static int mt76x0_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { struct mt76x0_dev *dev = hw->priv; - struct mt76_vif *mvif = (struct mt76_vif *) vif->drv_priv; + struct mt76x02_vif *mvif = (struct mt76x02_vif *) vif->drv_priv; unsigned int idx; idx = ffs(~dev->vif_mask); @@ -77,7 +77,7 @@ static void mt76x0_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { struct mt76x0_dev *dev = hw->priv; - struct mt76_vif *mvif = (struct mt76_vif *) vif->drv_priv; + struct mt76x02_vif *mvif = (struct mt76x02_vif *) vif->drv_priv; unsigned int wcid = mvif->group_wcid.idx; dev->wcid_mask[wcid / BITS_PER_LONG] &= ~BIT(wcid % BITS_PER_LONG); @@ -160,7 +160,7 @@ mt76x0_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, { struct mt76x0_dev *dev = hw->priv; struct mt76_sta *msta = (struct mt76_sta *) sta->drv_priv; - struct mt76_vif *mvif = (struct mt76_vif *) vif->drv_priv; + struct mt76x02_vif *mvif = (struct mt76x02_vif *) vif->drv_priv; int ret = 0; int idx = 0; @@ -242,7 +242,7 @@ mt76x0_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, struct ieee80211_key_conf *key) { struct mt76x0_dev *dev = hw->priv; - struct mt76_vif *mvif = (struct mt76_vif *) vif->drv_priv; + struct mt76x02_vif *mvif = (struct mt76x02_vif *) vif->drv_priv; struct mt76_sta *msta = sta ? (struct mt76_sta *) sta->drv_priv : NULL; struct mt76_wcid *wcid = msta ? &msta->wcid : &mvif->group_wcid; int idx = key->keyidx; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h index 7ad68dc2df30..a1b9a705b173 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h @@ -219,12 +219,6 @@ struct mt76x0_wcid { u8 tx_rate_nss; }; -struct mt76_vif { - u8 idx; - - struct mt76_wcid group_wcid; -}; - struct mt76_tx_status { u8 valid:1; u8 success:1; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c b/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c index c45d05d5aab1..0c0ac2283c35 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c @@ -167,7 +167,7 @@ void mt76x0_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, msta = (struct mt76_sta *) sta->drv_priv; wcid = &msta->wcid; } else if (vif && (!info->control.hw_key && wcid->hw_key_idx != 0xff)) { - struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; + struct mt76x02_vif *mvif = (struct mt76x02_vif *)vif->drv_priv; wcid = &mvif->group_wcid; } diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h index 7dc11cf70f7e..fa9532cdf6b7 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h @@ -18,6 +18,12 @@ #ifndef __MT76X02_MAC_H #define __MT76X02_MAC_H +struct mt76x02_vif { + u8 idx; + + struct mt76_wcid group_wcid; +}; + static inline bool mt76x02_wait_for_mac(struct mt76_dev *dev) { const u32 MAC_CSR0 = 0x1000; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2.h b/drivers/net/wireless/mediatek/mt76/mt76x2.h index e9b57fce9685..703d5c041b2a 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x2.h @@ -144,16 +144,10 @@ struct mt76x2_dev { struct mt76x2_dfs_pattern_detector dfs_pd; }; -struct mt76x2_vif { - u8 idx; - - struct mt76_wcid group_wcid; -}; - struct mt76x2_sta { struct mt76_wcid wcid; /* must be first */ - struct mt76x2_vif *vif; + struct mt76x02_vif *vif; struct mt76x2_tx_status status; int n_frames; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_common.c b/drivers/net/wireless/mediatek/mt76/mt76x2_common.c index 9ef692930d89..93e6e57f1ba3 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_common.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_common.c @@ -32,9 +32,9 @@ void mt76x2_txq_init(struct mt76x2_dev *dev, struct ieee80211_txq *txq) sta = (struct mt76x2_sta *) txq->sta->drv_priv; mtxq->wcid = &sta->wcid; } else { - struct mt76x2_vif *mvif; + struct mt76x02_vif *mvif; - mvif = (struct mt76x2_vif *) txq->vif->drv_priv; + mvif = (struct mt76x02_vif *) txq->vif->drv_priv; mtxq->wcid = &mvif->group_wcid; } @@ -98,7 +98,7 @@ int mt76x2_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, { struct mt76x2_dev *dev = hw->priv; struct mt76x2_sta *msta = (struct mt76x2_sta *) sta->drv_priv; - struct mt76x2_vif *mvif = (struct mt76x2_vif *) vif->drv_priv; + struct mt76x02_vif *mvif = (struct mt76x02_vif *) vif->drv_priv; int ret = 0; int idx = 0; int i; @@ -169,7 +169,7 @@ int mt76x2_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, struct ieee80211_key_conf *key) { struct mt76x2_dev *dev = hw->priv; - struct mt76x2_vif *mvif = (struct mt76x2_vif *) vif->drv_priv; + struct mt76x02_vif *mvif = (struct mt76x02_vif *) vif->drv_priv; struct mt76x2_sta *msta; struct mt76_wcid *wcid; int idx = key->keyidx; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_init_common.c b/drivers/net/wireless/mediatek/mt76/mt76x2_init_common.c index 324b2a4b8b67..5885c4fff4c6 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_init_common.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_init_common.c @@ -209,7 +209,7 @@ void mt76x2_init_device(struct mt76x2_dev *dev) hw->extra_tx_headroom = 2; hw->sta_data_size = sizeof(struct mt76x2_sta); - hw->vif_data_size = sizeof(struct mt76x2_vif); + hw->vif_data_size = sizeof(struct mt76x02_vif); ieee80211_hw_set(hw, SUPPORTS_HT_CCK_RATES); ieee80211_hw_set(hw, SUPPORTS_REORDERING_BUFFER); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.h b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.h index ad22d375c847..5e29887e443b 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.h @@ -22,7 +22,7 @@ struct mt76x2_dev; struct mt76x2_sta; -struct mt76x2_vif; +struct mt76x02_vif; struct mt76x2_txwi; struct mt76x2_tx_status { diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_main.c b/drivers/net/wireless/mediatek/mt76/mt76x2_main.c index 7d2b4a419566..80d33bca7f90 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_main.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_main.c @@ -58,7 +58,7 @@ static int mt76x2_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { struct mt76x2_dev *dev = hw->priv; - struct mt76x2_vif *mvif = (struct mt76x2_vif *) vif->drv_priv; + struct mt76x02_vif *mvif = (struct mt76x02_vif *) vif->drv_priv; unsigned int idx = 0; if (vif->addr[0] & BIT(1)) @@ -167,7 +167,7 @@ mt76x2_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_bss_conf *info, u32 changed) { struct mt76x2_dev *dev = hw->priv; - struct mt76x2_vif *mvif = (struct mt76x2_vif *) vif->drv_priv; + struct mt76x02_vif *mvif = (struct mt76x02_vif *) vif->drv_priv; mutex_lock(&dev->mt76.mutex); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_tx.c b/drivers/net/wireless/mediatek/mt76/mt76x2_tx.c index 6874db52b846..5338e8efa606 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_tx.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_tx.c @@ -58,7 +58,7 @@ static void mt76x2_update_beacon_iter(void *priv, u8 *mac, struct ieee80211_vif *vif) { struct mt76x2_dev *dev = (struct mt76x2_dev *) priv; - struct mt76x2_vif *mvif = (struct mt76x2_vif *) vif->drv_priv; + struct mt76x02_vif *mvif = (struct mt76x02_vif *) vif->drv_priv; struct sk_buff *skb = NULL; if (!(dev->beacon_mask & BIT(mvif->idx))) @@ -76,7 +76,7 @@ mt76x2_add_buffered_bc(void *priv, u8 *mac, struct ieee80211_vif *vif) { struct beacon_bc_data *data = priv; struct mt76x2_dev *dev = data->dev; - struct mt76x2_vif *mvif = (struct mt76x2_vif *) vif->drv_priv; + struct mt76x02_vif *mvif = (struct mt76x02_vif *) vif->drv_priv; struct ieee80211_tx_info *info; struct sk_buff *skb; @@ -164,7 +164,7 @@ void mt76x2_pre_tbtt_tasklet(unsigned long arg) while ((skb = __skb_dequeue(&data.q)) != NULL) { struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct ieee80211_vif *vif = info->control.vif; - struct mt76x2_vif *mvif = (struct mt76x2_vif *) vif->drv_priv; + struct mt76x02_vif *mvif = (struct mt76x02_vif *) vif->drv_priv; mt76_dma_tx_queue_skb(&dev->mt76, q, skb, &mvif->group_wcid, NULL); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_tx_common.c b/drivers/net/wireless/mediatek/mt76/mt76x2_tx_common.c index c0ca0df84ed8..16086ad12320 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_tx_common.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_tx_common.c @@ -37,9 +37,9 @@ void mt76x2_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, } if (vif && !control->sta) { - struct mt76x2_vif *mvif; + struct mt76x02_vif *mvif; - mvif = (struct mt76x2_vif *)vif->drv_priv; + mvif = (struct mt76x02_vif *)vif->drv_priv; wcid = &mvif->group_wcid; } diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2u_main.c b/drivers/net/wireless/mediatek/mt76/mt76x2u_main.c index 9180debc0946..fde334877bc5 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2u_main.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2u_main.c @@ -49,7 +49,7 @@ static int mt76x2u_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { struct mt76x2_dev *dev = hw->priv; - struct mt76x2_vif *mvif = (struct mt76x2_vif *)vif->drv_priv; + struct mt76x02_vif *mvif = (struct mt76x02_vif *)vif->drv_priv; unsigned int idx = 0; if (!ether_addr_equal(dev->mt76.macaddr, vif->addr)) From f5a7f126e5fe7dd597ef45e812ddd991be348f64 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 29 Aug 2018 13:16:44 +0200 Subject: [PATCH 102/276] mt76: unify sta structure part 1 First part of unifying mt76x02_sta structure between mt76x0 and mt76x2. Signed-off-by: Stanislaw Gruszka Signed-off-by: Kalle Valo --- .../net/wireless/mediatek/mt76/mt76x02_mac.c | 25 ++++++++++++++++++ .../net/wireless/mediatek/mt76/mt76x02_mac.h | 21 +++++++++++++++ .../wireless/mediatek/mt76/mt76x2_common.c | 26 +------------------ .../net/wireless/mediatek/mt76/mt76x2_main.c | 2 +- .../net/wireless/mediatek/mt76/mt76x2u_main.c | 2 +- 5 files changed, 49 insertions(+), 27 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c index 2242c0d7e200..67c53089229e 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c @@ -17,6 +17,7 @@ #include "mt76.h" #include "mt76x02_regs.h" +#include "mt76x02_mac.h" enum mt76x02_cipher_type mt76x02_mac_get_key_info(struct ieee80211_key_conf *key, u8 *key_data) @@ -130,3 +131,27 @@ void mt76x02_mac_wcid_set_drop(struct mt76_dev *dev, u8 idx, bool drop) __mt76_wr(dev, MT_WCID_DROP(idx), (val & ~bit) | (bit * drop)); } EXPORT_SYMBOL_GPL(mt76x02_mac_wcid_set_drop); + +void mt76x02_txq_init(struct mt76_dev *dev, struct ieee80211_txq *txq) +{ + struct mt76_txq *mtxq; + + if (!txq) + return; + + mtxq = (struct mt76_txq *) txq->drv_priv; + if (txq->sta) { + struct mt76x02_sta *sta; + + sta = (struct mt76x02_sta *) txq->sta->drv_priv; + mtxq->wcid = &sta->wcid; + } else { + struct mt76x02_vif *mvif; + + mvif = (struct mt76x02_vif *) txq->vif->drv_priv; + mtxq->wcid = &mvif->group_wcid; + } + + mt76_txq_init(dev, txq); +} +EXPORT_SYMBOL_GPL(mt76x02_txq_init); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h index fa9532cdf6b7..461ac61f45dc 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h @@ -18,12 +18,31 @@ #ifndef __MT76X02_MAC_H #define __MT76X02_MAC_H +struct mt76x02_tx_status { + u8 valid:1; + u8 success:1; + u8 aggr:1; + u8 ack_req:1; + u8 wcid; + u8 pktid; + u8 retry; + u16 rate; +} __packed __aligned(2); + struct mt76x02_vif { u8 idx; struct mt76_wcid group_wcid; }; +struct mt76x02_sta { + struct mt76_wcid wcid; /* must be first */ + + struct mt76x02_vif *vif; + struct mt76x02_tx_status status; + int n_frames; +}; + static inline bool mt76x02_wait_for_mac(struct mt76_dev *dev) { const u32 MAC_CSR0 = 0x1000; @@ -45,6 +64,8 @@ static inline bool mt76x02_wait_for_mac(struct mt76_dev *dev) return false; } +void mt76x02_txq_init(struct mt76_dev *dev, struct ieee80211_txq *txq); + enum mt76x02_cipher_type mt76x02_mac_get_key_info(struct ieee80211_key_conf *key, u8 *key_data); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_common.c b/drivers/net/wireless/mediatek/mt76/mt76x2_common.c index 93e6e57f1ba3..182dd6e24d44 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_common.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_common.c @@ -18,30 +18,6 @@ #include "mt76x2.h" #include "mt76x02_mac.h" -void mt76x2_txq_init(struct mt76x2_dev *dev, struct ieee80211_txq *txq) -{ - struct mt76_txq *mtxq; - - if (!txq) - return; - - mtxq = (struct mt76_txq *) txq->drv_priv; - if (txq->sta) { - struct mt76x2_sta *sta; - - sta = (struct mt76x2_sta *) txq->sta->drv_priv; - mtxq->wcid = &sta->wcid; - } else { - struct mt76x02_vif *mvif; - - mvif = (struct mt76x02_vif *) txq->vif->drv_priv; - mtxq->wcid = &mvif->group_wcid; - } - - mt76_txq_init(&dev->mt76, txq); -} -EXPORT_SYMBOL_GPL(mt76x2_txq_init); - int mt76x2_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_ampdu_params *params) { @@ -118,7 +94,7 @@ int mt76x2_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, mt76x02_mac_wcid_setup(&dev->mt76, idx, mvif->idx, sta->addr); mt76x02_mac_wcid_set_drop(&dev->mt76, idx, false); for (i = 0; i < ARRAY_SIZE(sta->txq); i++) - mt76x2_txq_init(dev, sta->txq[i]); + mt76x02_txq_init(&dev->mt76, sta->txq[i]); if (vif->type == NL80211_IFTYPE_AP) set_bit(MT_WCID_FLAG_CHECK_PS, &msta->wcid.flags); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_main.c b/drivers/net/wireless/mediatek/mt76/mt76x2_main.c index 80d33bca7f90..c445073a1a41 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_main.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_main.c @@ -83,7 +83,7 @@ mt76x2_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) mvif->idx = idx; mvif->group_wcid.idx = MT_VIF_WCID(idx); mvif->group_wcid.hw_key_idx = -1; - mt76x2_txq_init(dev, vif->txq); + mt76x02_txq_init(&dev->mt76, vif->txq); return 0; } diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2u_main.c b/drivers/net/wireless/mediatek/mt76/mt76x2u_main.c index fde334877bc5..1b6a04d202bb 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2u_main.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2u_main.c @@ -58,7 +58,7 @@ static int mt76x2u_add_interface(struct ieee80211_hw *hw, mvif->idx = idx; mvif->group_wcid.idx = MT_VIF_WCID(idx); mvif->group_wcid.hw_key_idx = -1; - mt76x2_txq_init(dev, vif->txq); + mt76x02_txq_init(&dev->mt76, vif->txq); return 0; } From b2d91fb30223a7c0e90b89ccc56bb311729fb7f1 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 29 Aug 2018 13:16:45 +0200 Subject: [PATCH 103/276] mt76: unify sta structure part 2 Second part of unifying mt76x02_sta structure between mt76x0 and mt76x2. Signed-off-by: Stanislaw Gruszka Signed-off-by: Kalle Valo --- .../net/wireless/mediatek/mt76/mt76x02_mac.h | 7 +++++++ drivers/net/wireless/mediatek/mt76/mt76x2.h | 20 +++---------------- .../wireless/mediatek/mt76/mt76x2_common.c | 12 +++++------ .../net/wireless/mediatek/mt76/mt76x2_init.c | 2 +- .../mediatek/mt76/mt76x2_init_common.c | 2 +- .../net/wireless/mediatek/mt76/mt76x2_mac.c | 4 ++-- .../net/wireless/mediatek/mt76/mt76x2_mac.h | 11 ---------- .../mediatek/mt76/mt76x2_mac_common.c | 18 ++++++++--------- .../net/wireless/mediatek/mt76/mt76x2_main.c | 2 +- .../mediatek/mt76/mt76x2_phy_common.c | 4 ++-- .../net/wireless/mediatek/mt76/mt76x2_trace.h | 2 +- .../wireless/mediatek/mt76/mt76x2_tx_common.c | 4 ++-- .../net/wireless/mediatek/mt76/mt76x2u_core.c | 2 +- 13 files changed, 36 insertions(+), 54 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h index 461ac61f45dc..6712bb1f9181 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h @@ -18,6 +18,8 @@ #ifndef __MT76X02_MAC_H #define __MT76X02_MAC_H +#include + struct mt76x02_tx_status { u8 valid:1; u8 success:1; @@ -35,12 +37,17 @@ struct mt76x02_vif { struct mt76_wcid group_wcid; }; +DECLARE_EWMA(signal, 10, 8); + struct mt76x02_sta { struct mt76_wcid wcid; /* must be first */ struct mt76x02_vif *vif; struct mt76x02_tx_status status; int n_frames; + + struct ewma_signal rssi; + int inactive_count; }; static inline bool mt76x02_wait_for_mac(struct mt76_dev *dev) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2.h b/drivers/net/wireless/mediatek/mt76/mt76x2.h index 703d5c041b2a..63e88d9147a8 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x2.h @@ -27,7 +27,6 @@ #include #include #include -#include #define MT7662_FIRMWARE "mt7662.bin" #define MT7662_ROM_PATCH "mt7662_rom_patch.bin" @@ -51,8 +50,6 @@ #include "mt76x2_mac.h" #include "mt76x2_dfs.h" -DECLARE_EWMA(signal, 10, 8) - struct mt76x2_mcu { struct mutex mutex; @@ -104,7 +101,7 @@ struct mt76x2_dev { int txpower_cur; u8 txdone_seq; - DECLARE_KFIFO_PTR(txstatus_fifo, struct mt76x2_tx_status); + DECLARE_KFIFO_PTR(txstatus_fifo, struct mt76x02_tx_status); struct mt76x2_mcu mcu; struct sk_buff *rx_head; @@ -144,17 +141,6 @@ struct mt76x2_dev { struct mt76x2_dfs_pattern_detector dfs_pd; }; -struct mt76x2_sta { - struct mt76_wcid wcid; /* must be first */ - - struct mt76x02_vif *vif; - struct mt76x2_tx_status status; - int n_frames; - - struct ewma_signal rssi; - int inactive_count; -}; - static inline bool is_mt7612(struct mt76x2_dev *dev) { return mt76_chip(&dev->mt76) == 0x7612; @@ -264,9 +250,9 @@ void mt76x2_tx_set_txpwr_auto(struct mt76x2_dev *dev, s8 txpwr); int mt76x2_insert_hdr_pad(struct sk_buff *skb); bool mt76x2_mac_load_tx_status(struct mt76x2_dev *dev, - struct mt76x2_tx_status *stat); + struct mt76x02_tx_status *stat); void mt76x2_send_tx_status(struct mt76x2_dev *dev, - struct mt76x2_tx_status *stat, u8 *update); + struct mt76x02_tx_status *stat, u8 *update); void mt76x2_reset_wlan(struct mt76x2_dev *dev, bool enable); void mt76x2_init_txpower(struct mt76x2_dev *dev, struct ieee80211_supported_band *sband); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_common.c b/drivers/net/wireless/mediatek/mt76/mt76x2_common.c index 182dd6e24d44..11ff60360ce6 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_common.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_common.c @@ -24,7 +24,7 @@ int mt76x2_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, enum ieee80211_ampdu_mlme_action action = params->action; struct ieee80211_sta *sta = params->sta; struct mt76x2_dev *dev = hw->priv; - struct mt76x2_sta *msta = (struct mt76x2_sta *) sta->drv_priv; + struct mt76x02_sta *msta = (struct mt76x02_sta *) sta->drv_priv; struct ieee80211_txq *txq = sta->txq[params->tid]; u16 tid = params->tid; u16 *ssn = ¶ms->ssn; @@ -73,7 +73,7 @@ int mt76x2_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta) { struct mt76x2_dev *dev = hw->priv; - struct mt76x2_sta *msta = (struct mt76x2_sta *) sta->drv_priv; + struct mt76x02_sta *msta = (struct mt76x02_sta *) sta->drv_priv; struct mt76x02_vif *mvif = (struct mt76x02_vif *) vif->drv_priv; int ret = 0; int idx = 0; @@ -114,7 +114,7 @@ int mt76x2_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta) { struct mt76x2_dev *dev = hw->priv; - struct mt76x2_sta *msta = (struct mt76x2_sta *) sta->drv_priv; + struct mt76x02_sta *msta = (struct mt76x02_sta *) sta->drv_priv; int idx = msta->wcid.idx; int i; @@ -146,7 +146,7 @@ int mt76x2_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, { struct mt76x2_dev *dev = hw->priv; struct mt76x02_vif *mvif = (struct mt76x02_vif *) vif->drv_priv; - struct mt76x2_sta *msta; + struct mt76x02_sta *msta; struct mt76_wcid *wcid; int idx = key->keyidx; int ret; @@ -173,7 +173,7 @@ int mt76x2_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) return -EOPNOTSUPP; - msta = sta ? (struct mt76x2_sta *) sta->drv_priv : NULL; + msta = sta ? (struct mt76x02_sta *) sta->drv_priv : NULL; wcid = msta ? &msta->wcid : &mvif->group_wcid; if (cmd == SET_KEY) { @@ -256,7 +256,7 @@ void mt76x2_sta_rate_tbl_update(struct ieee80211_hw *hw, struct ieee80211_sta *sta) { struct mt76x2_dev *dev = hw->priv; - struct mt76x2_sta *msta = (struct mt76x2_sta *) sta->drv_priv; + struct mt76x02_sta *msta = (struct mt76x02_sta *) sta->drv_priv; struct ieee80211_sta_rates *rates = rcu_dereference(sta->rates); struct ieee80211_tx_rate rate = {}; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_init.c b/drivers/net/wireless/mediatek/mt76/mt76x2_init.c index f5cf01f912b9..1f397c5e64a3 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_init.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_init.c @@ -533,7 +533,7 @@ int mt76x2_register_device(struct mt76x2_dev *dev) int fifo_size; int i, ret; - fifo_size = roundup_pow_of_two(32 * sizeof(struct mt76x2_tx_status)); + fifo_size = roundup_pow_of_two(32 * sizeof(struct mt76x02_tx_status)); status_fifo = devm_kzalloc(dev->mt76.dev, fifo_size, GFP_KERNEL); if (!status_fifo) return -ENOMEM; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_init_common.c b/drivers/net/wireless/mediatek/mt76/mt76x2_init_common.c index 5885c4fff4c6..eccdf80628a6 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_init_common.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_init_common.c @@ -208,7 +208,7 @@ void mt76x2_init_device(struct mt76x2_dev *dev) hw->max_rate_tries = 1; hw->extra_tx_headroom = 2; - hw->sta_data_size = sizeof(struct mt76x2_sta); + hw->sta_data_size = sizeof(struct mt76x02_sta); hw->vif_data_size = sizeof(struct mt76x02_vif); ieee80211_hw_set(hw, SUPPORTS_HT_CCK_RATES); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c index 23cf437d14f9..71ab06050e23 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c @@ -30,7 +30,7 @@ void mt76x2_mac_set_bssid(struct mt76x2_dev *dev, u8 idx, const u8 *addr) void mt76x2_mac_poll_tx_status(struct mt76x2_dev *dev, bool irq) { - struct mt76x2_tx_status stat = {}; + struct mt76x02_tx_status stat = {}; unsigned long flags; u8 update = 1; bool ret; @@ -78,7 +78,7 @@ mt76x2_mac_queue_txdone(struct mt76x2_dev *dev, struct sk_buff *skb, void mt76x2_mac_process_tx_status_fifo(struct mt76x2_dev *dev) { - struct mt76x2_tx_status stat; + struct mt76x02_tx_status stat; u8 update = 1; while (kfifo_get(&dev->txstatus_fifo, &stat)) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.h b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.h index 5e29887e443b..14089e8e5a02 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.h @@ -25,17 +25,6 @@ struct mt76x2_sta; struct mt76x02_vif; struct mt76x2_txwi; -struct mt76x2_tx_status { - u8 valid:1; - u8 success:1; - u8 aggr:1; - u8 ack_req:1; - u8 wcid; - u8 pktid; - u8 retry; - u16 rate; -} __packed __aligned(2); - struct mt76x2_tx_info { unsigned long jiffies; u8 tries; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mac_common.c b/drivers/net/wireless/mediatek/mt76/mt76x2_mac_common.c index f4ae0f157aaa..bdad454108b9 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_mac_common.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mac_common.c @@ -54,7 +54,7 @@ void mt76x2_mac_stop(struct mt76x2_dev *dev, bool force) EXPORT_SYMBOL_GPL(mt76x2_mac_stop); bool mt76x2_mac_load_tx_status(struct mt76x2_dev *dev, - struct mt76x2_tx_status *stat) + struct mt76x02_tx_status *stat) { u32 stat1, stat2; @@ -138,7 +138,7 @@ mt76x2_mac_process_tx_rate(struct ieee80211_tx_rate *txrate, u16 rate, static void mt76x2_mac_fill_tx_status(struct mt76x2_dev *dev, struct ieee80211_tx_info *info, - struct mt76x2_tx_status *st, int n_frames) + struct mt76x02_tx_status *st, int n_frames) { struct ieee80211_tx_rate *rate = info->status.rates; int cur_idx, last_rate; @@ -178,12 +178,12 @@ mt76x2_mac_fill_tx_status(struct mt76x2_dev *dev, } void mt76x2_send_tx_status(struct mt76x2_dev *dev, - struct mt76x2_tx_status *stat, u8 *update) + struct mt76x02_tx_status *stat, u8 *update) { struct ieee80211_tx_info info = {}; struct ieee80211_sta *sta = NULL; struct mt76_wcid *wcid = NULL; - struct mt76x2_sta *msta = NULL; + struct mt76x02_sta *msta = NULL; rcu_read_lock(); if (stat->wcid < ARRAY_SIZE(dev->wcid)) @@ -192,7 +192,7 @@ void mt76x2_send_tx_status(struct mt76x2_dev *dev, if (wcid) { void *priv; - priv = msta = container_of(wcid, struct mt76x2_sta, wcid); + priv = msta = container_of(wcid, struct mt76x02_sta, wcid); sta = container_of(priv, struct ieee80211_sta, drv_priv); } @@ -472,7 +472,7 @@ int mt76x2_mac_get_rssi(struct mt76x2_dev *dev, s8 rssi, int chain) return rssi; } -static struct mt76x2_sta * +static struct mt76x02_sta * mt76x2_rx_get_sta(struct mt76x2_dev *dev, u8 idx) { struct mt76_wcid *wcid; @@ -484,11 +484,11 @@ mt76x2_rx_get_sta(struct mt76x2_dev *dev, u8 idx) if (!wcid) return NULL; - return container_of(wcid, struct mt76x2_sta, wcid); + return container_of(wcid, struct mt76x02_sta, wcid); } static struct mt76_wcid * -mt76x2_rx_get_sta_wcid(struct mt76x2_dev *dev, struct mt76x2_sta *sta, +mt76x2_rx_get_sta_wcid(struct mt76x2_dev *dev, struct mt76x02_sta *sta, bool unicast) { if (!sta) @@ -505,7 +505,7 @@ int mt76x2_mac_process_rx(struct mt76x2_dev *dev, struct sk_buff *skb, { struct mt76_rx_status *status = (struct mt76_rx_status *) skb->cb; struct mt76x2_rxwi *rxwi = rxi; - struct mt76x2_sta *sta; + struct mt76x02_sta *sta; u32 rxinfo = le32_to_cpu(rxwi->rxinfo); u32 ctl = le32_to_cpu(rxwi->ctl); u16 rate = le16_to_cpu(rxwi->rate); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_main.c b/drivers/net/wireless/mediatek/mt76/mt76x2_main.c index c445073a1a41..f212f329cebe 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_main.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_main.c @@ -202,7 +202,7 @@ mt76x2_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, void mt76x2_sta_ps(struct mt76_dev *mdev, struct ieee80211_sta *sta, bool ps) { - struct mt76x2_sta *msta = (struct mt76x2_sta *) sta->drv_priv; + struct mt76x02_sta *msta = (struct mt76x02_sta *) sta->drv_priv; struct mt76x2_dev *dev = container_of(mdev, struct mt76x2_dev, mt76); int idx = msta->wcid.idx; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_phy_common.c b/drivers/net/wireless/mediatek/mt76/mt76x2_phy_common.c index 9fd6ab4cbb94..4830ca20a32d 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_phy_common.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_phy_common.c @@ -303,7 +303,7 @@ EXPORT_SYMBOL_GPL(mt76x2_phy_set_band); int mt76x2_phy_get_min_avg_rssi(struct mt76x2_dev *dev) { - struct mt76x2_sta *sta; + struct mt76x02_sta *sta; struct mt76_wcid *wcid; int i, j, min_rssi = 0; s8 cur_rssi; @@ -325,7 +325,7 @@ int mt76x2_phy_get_min_avg_rssi(struct mt76x2_dev *dev) if (!wcid) continue; - sta = container_of(wcid, struct mt76x2_sta, wcid); + sta = container_of(wcid, struct mt76x02_sta, wcid); spin_lock(&dev->mt76.rx_lock); if (sta->inactive_count++ < 5) cur_rssi = ewma_signal_read(&sta->rssi); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_trace.h b/drivers/net/wireless/mediatek/mt76/mt76x2_trace.h index 4cd424148d4b..eb5afeaefa44 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_trace.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_trace.h @@ -75,7 +75,7 @@ DEFINE_EVENT(dev_txid_evt, mac_txdone_add, TRACE_EVENT(mac_txstat_fetch, TP_PROTO(struct mt76x2_dev *dev, - struct mt76x2_tx_status *stat), + struct mt76x02_tx_status *stat), TP_ARGS(dev, stat), diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_tx_common.c b/drivers/net/wireless/mediatek/mt76/mt76x2_tx_common.c index 16086ad12320..d968f9ad6f50 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_tx_common.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_tx_common.c @@ -27,9 +27,9 @@ void mt76x2_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, struct mt76_wcid *wcid = &dev->global_wcid; if (control->sta) { - struct mt76x2_sta *msta; + struct mt76x02_sta *msta; - msta = (struct mt76x2_sta *)control->sta->drv_priv; + msta = (struct mt76x02_sta *)control->sta->drv_priv; wcid = &msta->wcid; /* sw encrypted frames */ if (!info->control.hw_key && wcid->hw_key_idx != 0xff) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2u_core.c b/drivers/net/wireless/mediatek/mt76/mt76x2u_core.c index 1ca5dd05b265..500d7db338aa 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2u_core.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2u_core.c @@ -66,7 +66,7 @@ mt76x2u_set_txinfo(struct sk_buff *skb, bool mt76x2u_tx_status_data(struct mt76_dev *mdev, u8 *update) { struct mt76x2_dev *dev = container_of(mdev, struct mt76x2_dev, mt76); - struct mt76x2_tx_status stat; + struct mt76x02_tx_status stat; if (!mt76x2_mac_load_tx_status(dev, &stat)) return false; From 78dae93fd8ff0a9f791621b9da0b274413c7fa60 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 29 Aug 2018 13:16:46 +0200 Subject: [PATCH 104/276] mt76x0: initalize custom tx queues Signed-off-by: Stanislaw Gruszka Signed-off-by: Kalle Valo --- drivers/net/wireless/mediatek/mt76/mt76x0/main.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c index 1cf06bffaa71..fd92a67dc379 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c @@ -69,6 +69,7 @@ static int mt76x0_add_interface(struct ieee80211_hw *hw, mvif->idx = idx; mvif->group_wcid.idx = GROUP_WCID(idx); mvif->group_wcid.hw_key_idx = -1; + mt76x02_txq_init(&dev->mt76, vif->txq); return 0; } @@ -81,6 +82,7 @@ static void mt76x0_remove_interface(struct ieee80211_hw *hw, unsigned int wcid = mvif->group_wcid.idx; dev->wcid_mask[wcid / BITS_PER_LONG] &= ~BIT(wcid % BITS_PER_LONG); + mt76_txq_remove(&dev->mt76, vif->txq); } static int mt76x0_config(struct ieee80211_hw *hw, u32 changed) @@ -163,6 +165,7 @@ mt76x0_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct mt76x02_vif *mvif = (struct mt76x02_vif *) vif->drv_priv; int ret = 0; int idx = 0; + int i; mutex_lock(&dev->mt76.mutex); @@ -178,6 +181,8 @@ mt76x0_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, mt76x02_mac_wcid_set_drop(&dev->mt76, idx, false); mt76_clear(dev, MT_WCID_DROP(idx), MT_WCID_DROP_MASK(idx)); rcu_assign_pointer(dev->wcid[idx], &msta->wcid); + for (i = 0; i < ARRAY_SIZE(sta->txq); i++) + mt76x02_txq_init(&dev->mt76, sta->txq[i]); mt76x0_mac_set_ampdu_factor(dev); out: @@ -193,11 +198,14 @@ mt76x0_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct mt76x0_dev *dev = hw->priv; struct mt76_sta *msta = (struct mt76_sta *) sta->drv_priv; int idx = msta->wcid.idx; + int i; mutex_lock(&dev->mt76.mutex); rcu_assign_pointer(dev->wcid[idx], NULL); mt76x02_mac_wcid_set_drop(&dev->mt76, idx, true); mt76_wcid_free(dev->wcid_mask, idx); + for (i = 0; i < ARRAY_SIZE(sta->txq); i++) + mt76_txq_remove(&dev->mt76, sta->txq[i]); mt76x02_mac_wcid_setup(&dev->mt76, idx, 0, NULL); mt76x0_mac_set_ampdu_factor(dev); mutex_unlock(&dev->mt76.mutex); From 16c8a792ea4467ccb41df4667f9b13699154004b Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 29 Aug 2018 13:16:47 +0200 Subject: [PATCH 105/276] mt76x0: use mt76x02_sta and mt76x02_tx_status Use common mt76x02_sta and mt76x02_tx_status structures in mt76x0 sub-driver. Signed-off-by: Stanislaw Gruszka Signed-off-by: Kalle Valo --- .../net/wireless/mediatek/mt76/mt76x0/init.c | 2 +- .../net/wireless/mediatek/mt76/mt76x0/mac.c | 14 ++++++------- .../net/wireless/mediatek/mt76/mt76x0/mac.h | 4 ++-- .../net/wireless/mediatek/mt76/mt76x0/main.c | 21 ++++++++++++------- .../wireless/mediatek/mt76/mt76x0/mt76x0.h | 19 ----------------- .../net/wireless/mediatek/mt76/mt76x0/trace.h | 4 ++-- .../net/wireless/mediatek/mt76/mt76x0/tx.c | 6 +++--- 7 files changed, 28 insertions(+), 42 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c index 41c9c7b5deea..24fc4c31667b 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c @@ -688,7 +688,7 @@ int mt76x0_register_device(struct mt76x0_dev *dev) hw->max_report_rates = 7; hw->max_rate_tries = 1; - hw->sta_data_size = sizeof(struct mt76_sta); + hw->sta_data_size = sizeof(struct mt76x02_sta); hw->vif_data_size = sizeof(struct mt76x02_vif); SET_IEEE80211_PERM_ADDR(hw, dev->macaddr); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c b/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c index 2bf5c81ecf10..0931c1821597 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c @@ -76,7 +76,7 @@ mt76_mac_process_tx_rate(struct ieee80211_tx_rate *txrate, u16 rate, static void mt76_mac_fill_tx_status(struct mt76x0_dev *dev, struct ieee80211_tx_info *info, - struct mt76_tx_status *st, int n_frames) + struct mt76x02_tx_status *st, int n_frames) { struct ieee80211_tx_rate *rate = info->status.rates; int cur_idx, last_rate; @@ -177,9 +177,9 @@ void mt76x0_mac_wcid_set_rate(struct mt76x0_dev *dev, struct mt76_wcid *wcid, spin_unlock_irqrestore(&dev->mt76.lock, flags); } -struct mt76_tx_status mt76x0_mac_fetch_tx_status(struct mt76x0_dev *dev) +struct mt76x02_tx_status mt76x0_mac_fetch_tx_status(struct mt76x0_dev *dev) { - struct mt76_tx_status stat = {}; + struct mt76x02_tx_status stat = {}; u32 stat2, stat1; stat2 = mt76_rr(dev, MT_TX_STAT_FIFO_EXT); @@ -198,12 +198,12 @@ struct mt76_tx_status mt76x0_mac_fetch_tx_status(struct mt76x0_dev *dev) return stat; } -void mt76x0_send_tx_status(struct mt76x0_dev *dev, struct mt76_tx_status *stat, u8 *update) +void mt76x0_send_tx_status(struct mt76x0_dev *dev, struct mt76x02_tx_status *stat, u8 *update) { struct ieee80211_tx_info info = {}; struct ieee80211_sta *sta = NULL; struct mt76_wcid *wcid = NULL; - struct mt76_sta *msta = NULL; + struct mt76x02_sta *msta = NULL; rcu_read_lock(); if (stat->wcid < ARRAY_SIZE(dev->wcid)) @@ -211,7 +211,7 @@ void mt76x0_send_tx_status(struct mt76x0_dev *dev, struct mt76_tx_status *stat, if (wcid) { void *priv; - priv = msta = container_of(wcid, struct mt76_sta, wcid); + priv = msta = container_of(wcid, struct mt76x02_sta, wcid); sta = container_of(priv, struct ieee80211_sta, drv_priv); } @@ -413,7 +413,7 @@ void mt76x0_mac_set_ampdu_factor(struct mt76x0_dev *dev) if (!wcid) continue; - msta = container_of(wcid, struct mt76_sta, wcid); + msta = container_of(wcid, struct mt76x02_sta, wcid); sta = container_of(msta, struct ieee80211_sta, drv_priv); min_factor = min(min_factor, sta->ht_cap.ampdu_factor); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mac.h b/drivers/net/wireless/mediatek/mt76/mt76x0/mac.h index f8074c477044..a6153a1ae206 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mac.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mac.h @@ -143,8 +143,8 @@ void mt76x0_mac_wcid_set_rate(struct mt76x0_dev *dev, struct mt76_wcid *wcid, u16 mt76x0_mac_tx_rate_val(struct mt76x0_dev *dev, const struct ieee80211_tx_rate *rate, u8 *nss_val); -struct mt76_tx_status +struct mt76x02_tx_status mt76x0_mac_fetch_tx_status(struct mt76x0_dev *dev); -void mt76x0_send_tx_status(struct mt76x0_dev *dev, struct mt76_tx_status *stat, u8 *update); +void mt76x0_send_tx_status(struct mt76x0_dev *dev, struct mt76x02_tx_status *stat, u8 *update); #endif diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c index fd92a67dc379..a969fa9fcd57 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c @@ -161,7 +161,7 @@ mt76x0_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta) { struct mt76x0_dev *dev = hw->priv; - struct mt76_sta *msta = (struct mt76_sta *) sta->drv_priv; + struct mt76x02_sta *msta = (struct mt76x02_sta *) sta->drv_priv; struct mt76x02_vif *mvif = (struct mt76x02_vif *) vif->drv_priv; int ret = 0; int idx = 0; @@ -196,7 +196,7 @@ mt76x0_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta) { struct mt76x0_dev *dev = hw->priv; - struct mt76_sta *msta = (struct mt76_sta *) sta->drv_priv; + struct mt76x02_sta *msta = (struct mt76x02_sta *) sta->drv_priv; int idx = msta->wcid.idx; int i; @@ -251,7 +251,7 @@ mt76x0_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, { struct mt76x0_dev *dev = hw->priv; struct mt76x02_vif *mvif = (struct mt76x02_vif *) vif->drv_priv; - struct mt76_sta *msta = sta ? (struct mt76_sta *) sta->drv_priv : NULL; + struct mt76x02_sta *msta = sta ? (struct mt76x02_sta *) sta->drv_priv : NULL; struct mt76_wcid *wcid = msta ? &msta->wcid : &mvif->group_wcid; int idx = key->keyidx; int ret; @@ -294,12 +294,17 @@ mt76_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, { struct mt76x0_dev *dev = hw->priv; struct ieee80211_sta *sta = params->sta; + struct mt76x02_sta *msta = (struct mt76x02_sta *) sta->drv_priv; enum ieee80211_ampdu_mlme_action action = params->action; + struct ieee80211_txq *txq = sta->txq[params->tid]; u16 tid = params->tid; u16 *ssn = ¶ms->ssn; - struct mt76_sta *msta = (struct mt76_sta *) sta->drv_priv; + struct mt76_txq *mtxq; - WARN_ON(msta->wcid.idx > N_WCIDS); + if (!txq) + return -EINVAL; + + mtxq = (struct mt76_txq *)txq->drv_priv; switch (action) { case IEEE80211_AMPDU_RX_START: @@ -309,13 +314,13 @@ mt76_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, mt76_clear(dev, MT_WCID_ADDR(msta->wcid.idx) + 4, BIT(16 + tid)); break; case IEEE80211_AMPDU_TX_OPERATIONAL: - ieee80211_send_bar(vif, sta->addr, tid, msta->agg_ssn[tid]); + ieee80211_send_bar(vif, sta->addr, tid, mtxq->agg_ssn); break; case IEEE80211_AMPDU_TX_STOP_FLUSH: case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: break; case IEEE80211_AMPDU_TX_START: - msta->agg_ssn[tid] = *ssn << 4; + mtxq->agg_ssn = *ssn << 4; ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); break; case IEEE80211_AMPDU_TX_STOP_CONT: @@ -331,7 +336,7 @@ mt76_sta_rate_tbl_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta) { struct mt76x0_dev *dev = hw->priv; - struct mt76_sta *msta = (struct mt76_sta *) sta->drv_priv; + struct mt76x02_sta *msta = (struct mt76x02_sta *) sta->drv_priv; struct ieee80211_sta_rates *rates; struct ieee80211_tx_rate rate = {}; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h index a1b9a705b173..15353a2a921b 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h @@ -219,25 +219,6 @@ struct mt76x0_wcid { u8 tx_rate_nss; }; -struct mt76_tx_status { - u8 valid:1; - u8 success:1; - u8 aggr:1; - u8 ack_req:1; - u8 is_probe:1; - u8 wcid; - u8 pktid; - u8 retry; - u16 rate; -} __packed __aligned(2); - -struct mt76_sta { - struct mt76_wcid wcid; - struct mt76_tx_status status; - int n_frames; - u16 agg_ssn[IEEE80211_NUM_TIDS]; -}; - struct mt76_reg_pair { u32 reg; u32 value; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/trace.h b/drivers/net/wireless/mediatek/mt76/mt76x0/trace.h index 8a752a09f2dc..d31ba71b9d5b 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/trace.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/trace.h @@ -197,13 +197,13 @@ TRACE_EVENT(mt76x0_rx, TRACE_EVENT(mt76x0_tx, TP_PROTO(struct mt76_dev *dev, struct sk_buff *skb, - struct mt76_sta *sta, struct mt76_txwi *h), + struct mt76x02_sta *sta, struct mt76_txwi *h), TP_ARGS(dev, skb, sta, h), TP_STRUCT__entry( DEV_ENTRY __field_struct(struct mt76_txwi, h) __field(struct sk_buff *, skb) - __field(struct mt76_sta *, sta) + __field(struct mt76x02_sta *, sta) ), TP_fast_assign( DEV_ASSIGN; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c b/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c index 0c0ac2283c35..fd2baa5cc92d 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c @@ -149,7 +149,7 @@ void mt76x0_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, struct mt76x0_dev *dev = hw->priv; struct ieee80211_vif *vif = info->control.vif; struct ieee80211_sta *sta = control->sta; - struct mt76_sta *msta = NULL; + struct mt76x02_sta *msta = NULL; struct mt76_wcid *wcid = dev->mon_wcid; struct mt76_txwi *txwi; int pkt_len = skb->len; @@ -164,7 +164,7 @@ void mt76x0_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, } if (sta) { - msta = (struct mt76_sta *) sta->drv_priv; + msta = (struct mt76x02_sta *) sta->drv_priv; wcid = &msta->wcid; } else if (vif && (!info->control.hw_key && wcid->hw_key_idx != 0xff)) { struct mt76x02_vif *mvif = (struct mt76x02_vif *)vif->drv_priv; @@ -184,7 +184,7 @@ void mt76x0_tx_stat(struct work_struct *work) { struct mt76x0_dev *dev = container_of(work, struct mt76x0_dev, stat_work.work); - struct mt76_tx_status stat; + struct mt76x02_tx_status stat; unsigned long flags; int cleaned = 0; u8 update = 1; From 5090efa4a2e85beeb170b4424923c083462ede13 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Sat, 25 Aug 2018 12:40:41 +0200 Subject: [PATCH 106/276] mt76: move mt76_reg_pair definition in mt76.h Move common definition of mt76_reg_pair in mt76.h and remove duplicated code in mt76x2_init_common.c Signed-off-by: Lorenzo Bianconi Signed-off-by: Kalle Valo --- drivers/net/wireless/mediatek/mt76/mt76.h | 5 +++++ drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h | 5 ----- .../net/wireless/mediatek/mt76/mt76x2_init_common.c | 11 +++-------- 3 files changed, 8 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h index b02b4191ef37..fc27260080af 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76.h +++ b/drivers/net/wireless/mediatek/mt76/mt76.h @@ -53,6 +53,11 @@ enum mt76_txq_id { __MT_TXQ_MAX }; +struct mt76_reg_pair { + u32 reg; + u32 value; +}; + enum mt76_rxq_id { MT_RXQ_MAIN, MT_RXQ_MCU, diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h index 15353a2a921b..50bfbffeb6a6 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h @@ -219,11 +219,6 @@ struct mt76x0_wcid { u8 tx_rate_nss; }; -struct mt76_reg_pair { - u32 reg; - u32 value; -}; - struct mt76x0_rxwi; extern const struct ieee80211_ops mt76x0_ops; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_init_common.c b/drivers/net/wireless/mediatek/mt76/mt76x2_init_common.c index eccdf80628a6..9dca0e92e3f7 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_init_common.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_init_common.c @@ -47,11 +47,6 @@ struct ieee80211_rate mt76x2_rates[] = { }; EXPORT_SYMBOL_GPL(mt76x2_rates); -struct mt76x2_reg_pair { - u32 reg; - u32 value; -}; - static void mt76x2_set_wlan_state(struct mt76x2_dev *dev, bool enable) { @@ -93,7 +88,7 @@ EXPORT_SYMBOL_GPL(mt76x2_reset_wlan); static void mt76x2_write_reg_pairs(struct mt76x2_dev *dev, - const struct mt76x2_reg_pair *data, int len) + const struct mt76_reg_pair *data, int len) { while (len > 0) { mt76_wr(dev, data->reg, data->value); @@ -128,7 +123,7 @@ void mt76_write_mac_initvals(struct mt76x2_dev *dev) FIELD_PREP(MT_PROT_CFG_NAV, 1) | \ FIELD_PREP(MT_PROT_CFG_TXOP_ALLOW, 0x3f)) - static const struct mt76x2_reg_pair vals[] = { + static const struct mt76_reg_pair vals[] = { /* Copied from MediaTek reference source */ { MT_PBF_SYS_CTRL, 0x00080c00 }, { MT_PBF_CFG, 0x1efebcff }, @@ -184,7 +179,7 @@ void mt76_write_mac_initvals(struct mt76x2_dev *dev) { MT_PROT_AUTO_TX_CFG, 0x00830083 }, { MT_HT_CTRL_CFG, 0x000001ff }, }; - struct mt76x2_reg_pair prot_vals[] = { + struct mt76_reg_pair prot_vals[] = { { MT_CCK_PROT_CFG, DEFAULT_PROT_CFG_CCK }, { MT_OFDM_PROT_CFG, DEFAULT_PROT_CFG_OFDM }, { MT_MM20_PROT_CFG, DEFAULT_PROT_CFG_20 }, From 4c89ff2c74e39b60f1f6e650721f6f92f007ea5b Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Sat, 25 Aug 2018 12:40:42 +0200 Subject: [PATCH 107/276] mt76: split __mt76u_mcu_send_msg and mt76u_mcu_send_msg routines Split __mt76u_mcu_send_msg and mt76u_mcu_send_msg in order to be reused by mt76x0 driver in usb mcu layer unification between mt76x0 and mt76x2u drivers Signed-off-by: Lorenzo Bianconi Signed-off-by: Kalle Valo --- drivers/net/wireless/mediatek/mt76/mt76.h | 2 ++ drivers/net/wireless/mediatek/mt76/usb_mcu.c | 27 +++++++++++++------- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h index fc27260080af..5579b90afee9 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76.h +++ b/drivers/net/wireless/mediatek/mt76/mt76.h @@ -623,6 +623,8 @@ int mt76u_mcu_fw_send_data(struct mt76_dev *dev, const void *data, int data_len, u32 max_payload, u32 offset); void mt76u_mcu_complete_urb(struct urb *urb); struct sk_buff *mt76u_mcu_msg_alloc(const void *data, int len); +int __mt76u_mcu_send_msg(struct mt76_dev *dev, struct sk_buff *skb, + int cmd, bool wait_resp); int mt76u_mcu_send_msg(struct mt76_dev *dev, struct sk_buff *skb, int cmd, bool wait_resp); void mt76u_mcu_fw_reset(struct mt76_dev *dev); diff --git a/drivers/net/wireless/mediatek/mt76/usb_mcu.c b/drivers/net/wireless/mediatek/mt76/usb_mcu.c index ebf3e7ffb26b..4039b0b709a0 100644 --- a/drivers/net/wireless/mediatek/mt76/usb_mcu.c +++ b/drivers/net/wireless/mediatek/mt76/usb_mcu.c @@ -86,8 +86,8 @@ static int mt76u_mcu_wait_resp(struct mt76_dev *dev, u8 seq) return -ETIMEDOUT; } -int mt76u_mcu_send_msg(struct mt76_dev *dev, struct sk_buff *skb, - int cmd, bool wait_resp) +int __mt76u_mcu_send_msg(struct mt76_dev *dev, struct sk_buff *skb, + int cmd, bool wait_resp) { struct usb_interface *intf = to_usb_interface(dev->dev); struct usb_device *udev = interface_to_usbdev(intf); @@ -100,8 +100,6 @@ int mt76u_mcu_send_msg(struct mt76_dev *dev, struct sk_buff *skb, if (test_bit(MT76_REMOVED, &dev->state)) return 0; - mutex_lock(&usb->mcu.mutex); - pipe = usb_sndbulkpipe(udev, usb->out_ep[MT_EP_OUT_INBAND_CMD]); if (wait_resp) { seq = ++usb->mcu.msg_seq & 0xf; @@ -114,22 +112,33 @@ int mt76u_mcu_send_msg(struct mt76_dev *dev, struct sk_buff *skb, MT_MCU_MSG_TYPE_CMD; ret = mt76u_skb_dma_info(skb, CPU_TX_PORT, info); if (ret) - goto out; + return ret; ret = usb_bulk_msg(udev, pipe, skb->data, skb->len, &sent, 500); if (ret) - goto out; + return ret; if (wait_resp) ret = mt76u_mcu_wait_resp(dev, seq); -out: - mutex_unlock(&usb->mcu.mutex); - consume_skb(skb); return ret; } +EXPORT_SYMBOL_GPL(__mt76u_mcu_send_msg); + +int mt76u_mcu_send_msg(struct mt76_dev *dev, struct sk_buff *skb, + int cmd, bool wait_resp) +{ + struct mt76_usb *usb = &dev->usb; + int err; + + mutex_lock(&usb->mcu.mutex); + err = __mt76u_mcu_send_msg(dev, skb, cmd, wait_resp); + mutex_unlock(&usb->mcu.mutex); + + return err; +} EXPORT_SYMBOL_GPL(mt76u_mcu_send_msg); void mt76u_mcu_fw_reset(struct mt76_dev *dev) From 288d600a8880efdfebc3654fbadf326e9be77908 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Sat, 25 Aug 2018 12:40:43 +0200 Subject: [PATCH 108/276] mt76: move mt76x2u_mcu_deinit routine in mt76-usb module Move mt76x2u_mcu_deinit routine in usb_mcu layer in order to be reused by mt76x0 driver in usb mcu layer unification between mt76x0 and mt76x2u drivers Signed-off-by: Lorenzo Bianconi Signed-off-by: Kalle Valo --- drivers/net/wireless/mediatek/mt76/mt76.h | 1 + drivers/net/wireless/mediatek/mt76/mt76x2u.h | 1 - drivers/net/wireless/mediatek/mt76/mt76x2u_init.c | 2 +- drivers/net/wireless/mediatek/mt76/mt76x2u_mcu.c | 8 -------- drivers/net/wireless/mediatek/mt76/usb_mcu.c | 9 +++++++++ 5 files changed, 11 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h index 5579b90afee9..f84f35c2e37a 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76.h +++ b/drivers/net/wireless/mediatek/mt76/mt76.h @@ -629,5 +629,6 @@ int mt76u_mcu_send_msg(struct mt76_dev *dev, struct sk_buff *skb, int cmd, bool wait_resp); void mt76u_mcu_fw_reset(struct mt76_dev *dev); int mt76u_mcu_init_rx(struct mt76_dev *dev); +void mt76u_mcu_deinit(struct mt76_dev *dev); #endif diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2u.h b/drivers/net/wireless/mediatek/mt76/mt76x2u.h index 008092f0cd8a..a83c17cb6be5 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2u.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x2u.h @@ -65,7 +65,6 @@ int mt76x2u_mcu_load_cr(struct mt76x2_dev *dev, u8 type, u8 temp_level, u8 channel); int mt76x2u_mcu_init(struct mt76x2_dev *dev); int mt76x2u_mcu_fw_init(struct mt76x2_dev *dev); -void mt76x2u_mcu_deinit(struct mt76x2_dev *dev); int mt76x2u_alloc_queues(struct mt76x2_dev *dev); void mt76x2u_queues_deinit(struct mt76x2_dev *dev); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2u_init.c b/drivers/net/wireless/mediatek/mt76/mt76x2u_init.c index 709e37de3b3f..53ace9d21fc8 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2u_init.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2u_init.c @@ -312,5 +312,5 @@ void mt76x2u_cleanup(struct mt76x2_dev *dev) mt76x2u_mcu_set_radio_state(dev, false); mt76x2u_stop_hw(dev); mt76u_queues_deinit(&dev->mt76); - mt76x2u_mcu_deinit(dev); + mt76u_mcu_deinit(&dev->mt76); } diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2u_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x2u_mcu.c index 22c16d638baa..31677e898427 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2u_mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2u_mcu.c @@ -453,11 +453,3 @@ int mt76x2u_mcu_init(struct mt76x2_dev *dev) return mt76x2u_mcu_set_radio_state(dev, true); } - -void mt76x2u_mcu_deinit(struct mt76x2_dev *dev) -{ - struct mt76_usb *usb = &dev->mt76.usb; - - usb_kill_urb(usb->mcu.res.urb); - mt76u_buf_free(&usb->mcu.res); -} diff --git a/drivers/net/wireless/mediatek/mt76/usb_mcu.c b/drivers/net/wireless/mediatek/mt76/usb_mcu.c index 4039b0b709a0..1edc5c3d637b 100644 --- a/drivers/net/wireless/mediatek/mt76/usb_mcu.c +++ b/drivers/net/wireless/mediatek/mt76/usb_mcu.c @@ -250,3 +250,12 @@ int mt76u_mcu_init_rx(struct mt76_dev *dev) return err; } EXPORT_SYMBOL_GPL(mt76u_mcu_init_rx); + +void mt76u_mcu_deinit(struct mt76_dev *dev) +{ + struct mt76_usb *usb = &dev->usb; + + usb_kill_urb(usb->mcu.res.urb); + mt76u_buf_free(&usb->mcu.res); +} +EXPORT_SYMBOL_GPL(mt76u_mcu_deinit); From 851ab66e293c5ea4a6136c799edc08d4be622e72 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Sat, 25 Aug 2018 12:40:44 +0200 Subject: [PATCH 109/276] mt76: add multiple regs read support to usb_mcu layer Introduce multiple regs read support to mcu layer in mt76-usb module. Multiple regs read will be reused by mt76x0 driver in usb mcu layer unification between mt76x0 and mt76x2u drivers Signed-off-by: Lorenzo Bianconi Signed-off-by: Kalle Valo --- drivers/net/wireless/mediatek/mt76/mt76.h | 6 +++ drivers/net/wireless/mediatek/mt76/usb_mcu.c | 39 +++++++++++++++++++- 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h index f84f35c2e37a..e9e46612c7f3 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76.h +++ b/drivers/net/wireless/mediatek/mt76/mt76.h @@ -312,6 +312,12 @@ struct mt76_usb { struct completion cmpl; struct mt76u_buf res; u32 msg_seq; + + /* multiple reads */ + struct mt76_reg_pair *rp; + int rp_len; + u32 base; + bool burst; } mcu; }; diff --git a/drivers/net/wireless/mediatek/mt76/usb_mcu.c b/drivers/net/wireless/mediatek/mt76/usb_mcu.c index 1edc5c3d637b..d80dbfafba6d 100644 --- a/drivers/net/wireless/mediatek/mt76/usb_mcu.c +++ b/drivers/net/wireless/mediatek/mt76/usb_mcu.c @@ -49,12 +49,44 @@ void mt76u_mcu_complete_urb(struct urb *urb) } EXPORT_SYMBOL_GPL(mt76u_mcu_complete_urb); +static void +mt76u_multiple_mcu_reads(struct mt76_dev *dev, u8 *data, + int len) +{ + struct mt76_usb *usb = &dev->usb; + u32 reg, val; + int i; + + if (usb->mcu.burst) { + WARN_ON_ONCE(len / 4 != usb->mcu.rp_len); + + reg = usb->mcu.rp[0].reg - usb->mcu.base; + for (i = 0; i < usb->mcu.rp_len; i++) { + val = get_unaligned_le32(data + 4 * i); + usb->mcu.rp[i].reg = reg++; + usb->mcu.rp[i].value = val; + } + } else { + WARN_ON_ONCE(len / 8 != usb->mcu.rp_len); + + for (i = 0; i < usb->mcu.rp_len; i++) { + reg = get_unaligned_le32(data + 8 * i) - + usb->mcu.base; + val = get_unaligned_le32(data + 8 * i + 4); + + WARN_ON_ONCE(usb->mcu.rp[i].reg != reg); + usb->mcu.rp[i].value = val; + } + } +} + static int mt76u_mcu_wait_resp(struct mt76_dev *dev, u8 seq) { struct mt76_usb *usb = &dev->usb; struct mt76u_buf *buf = &usb->mcu.res; int i, ret; u32 rxfce; + u8 *data; for (i = 0; i < 5; i++) { if (!wait_for_completion_timeout(&usb->mcu.cmpl, @@ -64,7 +96,12 @@ static int mt76u_mcu_wait_resp(struct mt76_dev *dev, u8 seq) if (buf->urb->status) return -EIO; - rxfce = get_unaligned_le32(sg_virt(&buf->urb->sg[0])); + data = sg_virt(&buf->urb->sg[0]); + if (usb->mcu.rp) + mt76u_multiple_mcu_reads(dev, data + 4, + buf->urb->actual_length - 8); + + rxfce = get_unaligned_le32(data); ret = mt76u_submit_buf(dev, USB_DIR_IN, MT_EP_IN_CMD_RESP, buf, GFP_KERNEL, From 795dbf0fd20cd351178358f90503b56f766ddc3d Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Sat, 25 Aug 2018 12:40:45 +0200 Subject: [PATCH 110/276] mt76x0: use mt76u_init for bus initialization Use mt76u_init utility routine for usb initialization. Moreover remove following unused routines: - mt76x0_rr - mt76x0_wr - mt76x0_rmw - mt76x0_wr_copy - mt76x0_assign_pipes Signed-off-by: Lorenzo Bianconi Signed-off-by: Kalle Valo --- .../net/wireless/mediatek/mt76/mt76x0/dma.c | 6 +- .../net/wireless/mediatek/mt76/mt76x0/init.c | 3 +- .../net/wireless/mediatek/mt76/mt76x0/mcu.c | 3 +- .../net/wireless/mediatek/mt76/mt76x0/usb.c | 109 +----------------- 4 files changed, 12 insertions(+), 109 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/dma.c b/drivers/net/wireless/mediatek/mt76/mt76x0/dma.c index e2efb430419b..715c3734a307 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/dma.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/dma.c @@ -279,7 +279,8 @@ static int mt76x0_dma_submit_tx(struct mt76x0_dev *dev, struct sk_buff *skb, u8 ep) { struct usb_device *usb_dev = mt76x0_to_usb_dev(dev); - unsigned snd_pipe = usb_sndbulkpipe(usb_dev, dev->out_ep[ep]); + struct mt76_usb *usb = &dev->mt76.usb; + unsigned snd_pipe = usb_sndbulkpipe(usb_dev, usb->out_ep[ep]); struct mt76x0_dma_buf_tx *e; struct mt76x0_tx_queue *q = &dev->tx_q[ep]; unsigned long flags; @@ -375,11 +376,12 @@ static int mt76x0_submit_rx_buf(struct mt76x0_dev *dev, struct mt76x0_dma_buf_rx *e, gfp_t gfp) { struct usb_device *usb_dev = mt76x0_to_usb_dev(dev); + struct mt76_usb *usb = &dev->mt76.usb; u8 *buf = page_address(e->p); unsigned pipe; int ret; - pipe = usb_rcvbulkpipe(usb_dev, dev->in_ep[MT_EP_IN_PKT_RX]); + pipe = usb_rcvbulkpipe(usb_dev, usb->in_ep[MT_EP_IN_PKT_RX]); usb_fill_bulk_urb(e->urb, usb_dev, pipe, buf, MT_RX_URB_SIZE, mt76x0_complete_rx, dev); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c index 24fc4c31667b..1d5b74d05b75 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c @@ -109,6 +109,7 @@ static void mt76x0_reset_csr_bbp(struct mt76x0_dev *dev) static void mt76x0_init_usb_dma(struct mt76x0_dev *dev) { + struct mt76_usb *usb = &dev->mt76.usb; u32 val; val = mt76_rr(dev, MT_USB_DMA_CFG); @@ -117,7 +118,7 @@ static void mt76x0_init_usb_dma(struct mt76x0_dev *dev) FIELD_PREP(MT_USB_DMA_CFG_RX_BULK_AGG_LMT, MT_USB_AGGR_SIZE_LIMIT) | MT_USB_DMA_CFG_RX_BULK_EN | MT_USB_DMA_CFG_TX_BULK_EN; - if (dev->in_max_packet == 512) + if (usb->in_max_packet == 512) val |= MT_USB_DMA_CFG_RX_BULK_AGG_EN; mt76_wr(dev, MT_USB_DMA_CFG, val); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c index 96e04afc73f4..75768ebf8b30 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c @@ -154,8 +154,9 @@ __mt76x0_mcu_msg_send(struct mt76x0_dev *dev, struct sk_buff *skb, enum mcu_cmd cmd, bool wait_resp) { struct usb_device *usb_dev = mt76x0_to_usb_dev(dev); + struct mt76_usb *usb = &dev->mt76.usb; unsigned cmd_pipe = usb_sndbulkpipe(usb_dev, - dev->out_ep[MT_EP_OUT_INBAND_CMD]); + usb->out_ep[MT_EP_OUT_INBAND_CMD]); int sent, ret; u8 seq = 0; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c index 670973363c9f..533409c44ec6 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c @@ -71,13 +71,14 @@ int mt76x0_usb_submit_buf(struct mt76x0_dev *dev, int dir, int ep_idx, usb_complete_t complete_fn, void *context) { struct usb_device *usb_dev = mt76x0_to_usb_dev(dev); + struct mt76_usb *usb = &dev->mt76.usb; unsigned pipe; int ret; if (dir == USB_DIR_IN) - pipe = usb_rcvbulkpipe(usb_dev, dev->in_ep[ep_idx]); + pipe = usb_rcvbulkpipe(usb_dev, usb->in_ep[ep_idx]); else - pipe = usb_sndbulkpipe(usb_dev, dev->out_ep[ep_idx]); + pipe = usb_sndbulkpipe(usb_dev, usb->out_ep[ep_idx]); usb_fill_bulk_urb(buf->urb, usb_dev, pipe, buf->buf, buf->len, complete_fn, context); @@ -136,30 +137,6 @@ void mt76x0_vendor_reset(struct mt76x0_dev *dev) MT_VEND_DEV_MODE_RESET, 0, NULL, 0); } -static u32 mt76x0_rr(struct mt76_dev *dev, u32 offset) -{ - struct mt76x0_dev *mdev = (struct mt76x0_dev *) dev; - int ret; - u32 val = ~0; - - WARN_ONCE(offset > USHRT_MAX, "read high off:%08x", offset); - - mutex_lock(&mdev->usb_ctrl_mtx); - - ret = mt76x0_vendor_request((struct mt76x0_dev *)dev, MT_VEND_MULTI_READ, USB_DIR_IN, - 0, offset, mdev->data, MT_VEND_BUF); - if (ret == MT_VEND_BUF) - val = get_unaligned_le32(mdev->data); - else if (ret > 0) - dev_err(dev->dev, "Error: wrong size read:%d off:%08x\n", - ret, offset); - - mutex_unlock(&mdev->usb_ctrl_mtx); - - trace_mt76x0_reg_read(dev, offset, val); - return val; -} - int mt76x0_vendor_single_wr(struct mt76x0_dev *dev, const u8 req, const u16 offset, const u32 val) { @@ -179,82 +156,12 @@ int mt76x0_vendor_single_wr(struct mt76x0_dev *dev, const u8 req, return ret; } -static void mt76x0_wr(struct mt76_dev *dev, u32 offset, u32 val) -{ - struct mt76x0_dev *mdev = (struct mt76x0_dev *) dev; - int ret; - - WARN_ONCE(offset > USHRT_MAX, "write high off:%08x", offset); - - mutex_lock(&mdev->usb_ctrl_mtx); - - put_unaligned_le32(val, mdev->data); - ret = mt76x0_vendor_request(mdev, MT_VEND_MULTI_WRITE, USB_DIR_OUT, - 0, offset, mdev->data, MT_VEND_BUF); - trace_mt76x0_reg_write(dev, offset, val); - - mutex_unlock(&mdev->usb_ctrl_mtx); -} - -static u32 mt76x0_rmw(struct mt76_dev *dev, u32 offset, u32 mask, u32 val) -{ - val |= mt76x0_rr(dev, offset) & ~mask; - mt76x0_wr(dev, offset, val); - return val; -} - -static void mt76x0_wr_copy(struct mt76_dev *dev, u32 offset, - const void *data, int len) -{ - WARN_ONCE(offset & 3, "unaligned write copy off:%08x", offset); - WARN_ONCE(len & 3, "short write copy off:%08x", offset); - - mt76x0_burst_write_regs((struct mt76x0_dev *) dev, offset, data, len / 4); -} - void mt76x0_addr_wr(struct mt76x0_dev *dev, const u32 offset, const u8 *addr) { mt76_wr(dev, offset, get_unaligned_le32(addr)); mt76_wr(dev, offset + 4, addr[4] | addr[5] << 8); } -static int mt76x0_assign_pipes(struct usb_interface *usb_intf, - struct mt76x0_dev *dev) -{ - struct usb_endpoint_descriptor *ep_desc; - struct usb_host_interface *intf_desc = usb_intf->cur_altsetting; - unsigned i, ep_i = 0, ep_o = 0; - - BUILD_BUG_ON(sizeof(dev->in_ep) < __MT_EP_IN_MAX); - BUILD_BUG_ON(sizeof(dev->out_ep) < __MT_EP_OUT_MAX); - - for (i = 0; i < intf_desc->desc.bNumEndpoints; i++) { - ep_desc = &intf_desc->endpoint[i].desc; - - if (usb_endpoint_is_bulk_in(ep_desc) && - ep_i++ < __MT_EP_IN_MAX) { - dev->in_ep[ep_i - 1] = usb_endpoint_num(ep_desc); - dev->in_max_packet = usb_endpoint_maxp(ep_desc); - /* Note: this is ignored by usb sub-system but vendor - * code does it. We can drop this at some point. - */ - dev->in_ep[ep_i - 1] |= USB_DIR_IN; - } else if (usb_endpoint_is_bulk_out(ep_desc) && - ep_o++ < __MT_EP_OUT_MAX) { - dev->out_ep[ep_o - 1] = usb_endpoint_num(ep_desc); - dev->out_max_packet = usb_endpoint_maxp(ep_desc); - } - } - - if (ep_i != __MT_EP_IN_MAX || ep_o != __MT_EP_OUT_MAX) { - dev_err(dev->mt76.dev, "Error: wrong pipe number in:%d out:%d\n", - ep_i, ep_o); - return -EINVAL; - } - - return 0; -} - static int mt76x0_probe(struct usb_interface *usb_intf, const struct usb_device_id *id) { @@ -262,12 +169,6 @@ static int mt76x0_probe(struct usb_interface *usb_intf, struct mt76x0_dev *dev; u32 asic_rev, mac_rev; int ret; - static const struct mt76_bus_ops usb_ops = { - .rr = mt76x0_rr, - .wr = mt76x0_wr, - .rmw = mt76x0_rmw, - .copy = mt76x0_wr_copy, - }; dev = mt76x0_alloc_device(&usb_intf->dev); if (!dev) @@ -278,9 +179,7 @@ static int mt76x0_probe(struct usb_interface *usb_intf, usb_set_intfdata(usb_intf, dev); - dev->mt76.bus = &usb_ops; - - ret = mt76x0_assign_pipes(usb_intf, dev); + ret = mt76u_init(&dev->mt76, usb_intf); if (ret) goto err; From e9fa647a0ad3700240d494168b9976cb69444f27 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Sat, 25 Aug 2018 12:40:46 +0200 Subject: [PATCH 111/276] mt76x0: remove mt76x0_vendor_reset routine Remove mt76x0_vendor_reset duplicated routine and use mt76u_mcu_fw_reset utility function for mcu fw reset Signed-off-by: Lorenzo Bianconi Signed-off-by: Kalle Valo --- drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c | 2 +- drivers/net/wireless/mediatek/mt76/mt76x0/usb.c | 6 ------ drivers/net/wireless/mediatek/mt76/mt76x0/usb.h | 1 - 3 files changed, 1 insertion(+), 8 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c index 75768ebf8b30..c8ea3126e7dc 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c @@ -571,7 +571,7 @@ static int mt76x0_load_firmware(struct mt76x0_dev *dev) mt76_set(dev, MT_USB_DMA_CFG, (MT_USB_DMA_CFG_RX_BULK_EN | MT_USB_DMA_CFG_TX_BULK_EN) | FIELD_PREP(MT_USB_DMA_CFG_RX_BULK_AGG_TOUT, 0x20)); - mt76x0_vendor_reset(dev); + mt76u_mcu_fw_reset(&dev->mt76); msleep(5); /* mt76x0_rmw(dev, MT_PBF_CFG, 0, (MT_PBF_CFG_TX0Q_EN | diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c index 533409c44ec6..a0052ef36266 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c @@ -131,12 +131,6 @@ int mt76x0_vendor_request(struct mt76x0_dev *dev, const u8 req, return ret; } -void mt76x0_vendor_reset(struct mt76x0_dev *dev) -{ - mt76x0_vendor_request(dev, MT_VEND_DEV_MODE, USB_DIR_OUT, - MT_VEND_DEV_MODE_RESET, 0, NULL, 0); -} - int mt76x0_vendor_single_wr(struct mt76x0_dev *dev, const u8 req, const u16 offset, const u32 val) { diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.h b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.h index 492e431390a8..d23ca45a294e 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.h @@ -54,7 +54,6 @@ void mt76x0_complete_urb(struct urb *urb); int mt76x0_vendor_request(struct mt76x0_dev *dev, const u8 req, const u8 direction, const u16 val, const u16 offset, void *buf, const size_t buflen); -void mt76x0_vendor_reset(struct mt76x0_dev *dev); int mt76x0_vendor_single_wr(struct mt76x0_dev *dev, const u8 req, const u16 offset, const u32 val); From 72750efddba928b98fc86a73ce714bdd3c2b4502 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Sat, 25 Aug 2018 12:40:47 +0200 Subject: [PATCH 112/276] mt76x0: remove mt76x0_vendor_single_wr routine Remove mt76x0_vendor_single_wr routine and use mt76u_single_wr utility function for mcu firmware loading Signed-off-by: Lorenzo Bianconi Signed-off-by: Kalle Valo --- .../net/wireless/mediatek/mt76/mt76x0/mcu.c | 13 +++++-------- .../net/wireless/mediatek/mt76/mt76x0/usb.c | 19 ------------------- .../net/wireless/mediatek/mt76/mt76x0/usb.h | 2 -- 3 files changed, 5 insertions(+), 29 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c index c8ea3126e7dc..cf3acee12dc3 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c @@ -416,15 +416,12 @@ static int __mt76x0_dma_fw(struct mt76x0_dev *dev, memcpy(buf.buf + sizeof(reg), data, len); memset(buf.buf + sizeof(reg) + len, 0, 8); - ret = mt76x0_vendor_single_wr(dev, MT_VEND_WRITE_FCE, - MT_FCE_DMA_ADDR, dst_addr); - if (ret) - return ret; + mt76u_single_wr(&dev->mt76, MT_VEND_WRITE_FCE, MT_FCE_DMA_ADDR, + dst_addr); + len = roundup(len, 4); - ret = mt76x0_vendor_single_wr(dev, MT_VEND_WRITE_FCE, - MT_FCE_DMA_LEN, len << 16); - if (ret) - return ret; + mt76u_single_wr(&dev->mt76, MT_VEND_WRITE_FCE, MT_FCE_DMA_LEN, + len << 16); buf.len = MT_DMA_HDR_LEN + len + 4; ret = mt76x0_usb_submit_buf(dev, USB_DIR_OUT, MT_EP_OUT_INBAND_CMD, diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c index a0052ef36266..a6cb0c3ce5a6 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c @@ -131,25 +131,6 @@ int mt76x0_vendor_request(struct mt76x0_dev *dev, const u8 req, return ret; } -int mt76x0_vendor_single_wr(struct mt76x0_dev *dev, const u8 req, - const u16 offset, const u32 val) -{ - struct mt76x0_dev *mdev = dev; - int ret; - - mutex_lock(&mdev->usb_ctrl_mtx); - - ret = mt76x0_vendor_request(dev, req, USB_DIR_OUT, - val & 0xffff, offset, NULL, 0); - if (!ret) - ret = mt76x0_vendor_request(dev, req, USB_DIR_OUT, - val >> 16, offset + 2, NULL, 0); - - mutex_unlock(&mdev->usb_ctrl_mtx); - - return ret; -} - void mt76x0_addr_wr(struct mt76x0_dev *dev, const u32 offset, const u8 *addr) { mt76_wr(dev, offset, get_unaligned_le32(addr)); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.h b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.h index d23ca45a294e..931c36554ff4 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.h @@ -54,7 +54,5 @@ void mt76x0_complete_urb(struct urb *urb); int mt76x0_vendor_request(struct mt76x0_dev *dev, const u8 req, const u8 direction, const u16 val, const u16 offset, void *buf, const size_t buflen); -int mt76x0_vendor_single_wr(struct mt76x0_dev *dev, const u8 req, - const u16 offset, const u32 val); #endif From 84740d5dc66ebe09682f457bae9784a264a94d3c Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Sat, 25 Aug 2018 12:40:48 +0200 Subject: [PATCH 113/276] mt76x0: remove mt76x0_mcu_msg_alloc routine Remove mt76x0_mcu_msg_alloc duplicated routine and use mt76u_mcu_msg_alloc utility function for usb mcu message allocation Signed-off-by: Lorenzo Bianconi Signed-off-by: Kalle Valo --- .../net/wireless/mediatek/mt76/mt76x0/mcu.c | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c index cf3acee12dc3..8a258fa33c2a 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c @@ -59,21 +59,6 @@ static inline void trace_mt76x0_mcu_msg_send_cs(struct mt76_dev *dev, trace_mt76x0_mcu_msg_send(dev, skb, csum, need_resp); } -static struct sk_buff * -mt76x0_mcu_msg_alloc(struct mt76x0_dev *dev, const void *data, int len) -{ - struct sk_buff *skb; - - WARN_ON(len % 4); /* if length is not divisible by 4 we need to pad */ - - skb = alloc_skb(len + MT_DMA_HDR_LEN + 4, GFP_KERNEL); - if (skb) { - skb_reserve(skb, MT_DMA_HDR_LEN); - memcpy(skb_put(skb, len), data, len); - } - return skb; -} - static void mt76x0_read_resp_regs(struct mt76x0_dev *dev, int len) { int i; @@ -217,7 +202,7 @@ int mt76x0_mcu_function_select(struct mt76x0_dev *dev, .value = cpu_to_le32(val), }; - skb = mt76x0_mcu_msg_alloc(dev, &msg, sizeof(msg)); + skb = mt76u_mcu_msg_alloc(&msg, sizeof(msg)); if (!skb) return -ENOMEM; return mt76x0_mcu_msg_send(dev, skb, CMD_FUN_SET_OP, func == 5); @@ -235,7 +220,7 @@ mt76x0_mcu_calibrate(struct mt76x0_dev *dev, enum mcu_calibrate cal, u32 val) .value = cpu_to_le32(val), }; - skb = mt76x0_mcu_msg_alloc(dev, &msg, sizeof(msg)); + skb = mt76u_mcu_msg_alloc(&msg, sizeof(msg)); if (!skb) return -ENOMEM; return mt76x0_mcu_msg_send(dev, skb, CMD_CALIBRATION_OP, true); From ad27c4ae0ba7a4725628c60e2191df7551fbb36e Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Sat, 25 Aug 2018 12:40:49 +0200 Subject: [PATCH 114/276] mt76x0: use shared mt76 usb mcu completion Use mt76 usb shared completion data structure in mt76x0_mcu_wait_resp routine and remove mt76x0 private one Signed-off-by: Lorenzo Bianconi Signed-off-by: Kalle Valo --- drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c | 11 ++++++----- drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h | 1 - 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c index 8a258fa33c2a..bfaabe018216 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c @@ -93,11 +93,12 @@ static void mt76x0_read_resp_regs(struct mt76x0_dev *dev, int len) static int mt76x0_mcu_wait_resp(struct mt76x0_dev *dev, u8 seq) { struct urb *urb = dev->mcu.resp.urb; + struct mt76_usb *usb = &dev->mt76.usb; u32 rxfce; int urb_status, ret, try = 5; while (try--) { - if (!wait_for_completion_timeout(&dev->mcu.resp_cmpl, + if (!wait_for_completion_timeout(&usb->mcu.cmpl, msecs_to_jiffies(300))) { dev_warn(dev->mt76.dev, "Warning: %s retrying\n", __func__); continue; @@ -113,7 +114,7 @@ static int mt76x0_mcu_wait_resp(struct mt76x0_dev *dev, u8 seq) ret = mt76x0_usb_submit_buf(dev, USB_DIR_IN, MT_EP_IN_CMD_RESP, &dev->mcu.resp, GFP_KERNEL, mt76x0_complete_urb, - &dev->mcu.resp_cmpl); + &usb->mcu.cmpl); if (ret) return ret; @@ -151,7 +152,7 @@ __mt76x0_mcu_msg_send(struct mt76x0_dev *dev, struct sk_buff *skb, mt76x0_dma_skb_wrap_cmd(skb, seq, cmd); - if (dev->mcu.resp_cmpl.done) + if (&usb->mcu.cmpl.done) dev_err(dev->mt76.dev, "Error: MCU response pre-completed!\n"); trace_mt76x0_mcu_msg_send_cs(&dev->mt76, skb, wait_resp); @@ -609,13 +610,13 @@ int mt76x0_mcu_init(struct mt76x0_dev *dev) int mt76x0_mcu_cmd_init(struct mt76x0_dev *dev) { + struct mt76_usb *usb = &dev->mt76.usb; int ret; ret = mt76x0_mcu_function_select(dev, Q_SELECT, 1); if (ret) return ret; - init_completion(&dev->mcu.resp_cmpl); if (mt76x0_usb_alloc_buf(dev, MCU_RESP_URB_SIZE, &dev->mcu.resp)) { mt76x0_usb_free_buf(dev, &dev->mcu.resp); return -ENOMEM; @@ -623,7 +624,7 @@ int mt76x0_mcu_cmd_init(struct mt76x0_dev *dev) ret = mt76x0_usb_submit_buf(dev, USB_DIR_IN, MT_EP_IN_CMD_RESP, &dev->mcu.resp, GFP_KERNEL, - mt76x0_complete_urb, &dev->mcu.resp_cmpl); + mt76x0_complete_urb, &usb->mcu.cmpl); if (ret) { mt76x0_usb_free_buf(dev, &dev->mcu.resp); return ret; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h index 50bfbffeb6a6..c9bc243b3619 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h @@ -55,7 +55,6 @@ struct mt76x0_mcu { u8 msg_seq; struct mt76x0_dma_buf resp; - struct completion resp_cmpl; struct mt76_reg_pair *reg_pairs; unsigned int reg_pairs_len; From 73d411e2d499adea41ff4c949b257c458b3b4cd3 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Sat, 25 Aug 2018 12:40:50 +0200 Subject: [PATCH 115/276] mt76x0: remove mt76x0_complete_urb routine Remove mt76x0_complete_urb routine and use mt76u_mcu_complete_urb utility function as usb mcu completion handler Signed-off-by: Lorenzo Bianconi Signed-off-by: Kalle Valo --- drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c | 6 +++--- drivers/net/wireless/mediatek/mt76/mt76x0/usb.c | 7 ------- drivers/net/wireless/mediatek/mt76/mt76x0/usb.h | 1 - 3 files changed, 3 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c index bfaabe018216..3f985c1d45f0 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c @@ -113,7 +113,7 @@ static int mt76x0_mcu_wait_resp(struct mt76x0_dev *dev, u8 seq) ret = mt76x0_usb_submit_buf(dev, USB_DIR_IN, MT_EP_IN_CMD_RESP, &dev->mcu.resp, GFP_KERNEL, - mt76x0_complete_urb, + mt76u_mcu_complete_urb, &usb->mcu.cmpl); if (ret) return ret; @@ -412,7 +412,7 @@ static int __mt76x0_dma_fw(struct mt76x0_dev *dev, buf.len = MT_DMA_HDR_LEN + len + 4; ret = mt76x0_usb_submit_buf(dev, USB_DIR_OUT, MT_EP_OUT_INBAND_CMD, &buf, GFP_KERNEL, - mt76x0_complete_urb, &cmpl); + mt76u_mcu_complete_urb, &cmpl); if (ret) return ret; @@ -624,7 +624,7 @@ int mt76x0_mcu_cmd_init(struct mt76x0_dev *dev) ret = mt76x0_usb_submit_buf(dev, USB_DIR_IN, MT_EP_IN_CMD_RESP, &dev->mcu.resp, GFP_KERNEL, - mt76x0_complete_urb, &usb->mcu.cmpl); + mt76u_mcu_complete_urb, &usb->mcu.cmpl); if (ret) { mt76x0_usb_free_buf(dev, &dev->mcu.resp); return ret; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c index a6cb0c3ce5a6..d2edb269622d 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c @@ -93,13 +93,6 @@ int mt76x0_usb_submit_buf(struct mt76x0_dev *dev, int dir, int ep_idx, return ret; } -void mt76x0_complete_urb(struct urb *urb) -{ - struct completion *cmpl = urb->context; - - complete(cmpl); -} - int mt76x0_vendor_request(struct mt76x0_dev *dev, const u8 req, const u8 direction, const u16 val, const u16 offset, void *buf, const size_t buflen) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.h b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.h index 931c36554ff4..0d1ba95dcf2e 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.h @@ -49,7 +49,6 @@ void mt76x0_usb_free_buf(struct mt76x0_dev *dev, struct mt76x0_dma_buf *buf); int mt76x0_usb_submit_buf(struct mt76x0_dev *dev, int dir, int ep_idx, struct mt76x0_dma_buf *buf, gfp_t gfp, usb_complete_t complete_fn, void *context); -void mt76x0_complete_urb(struct urb *urb); int mt76x0_vendor_request(struct mt76x0_dev *dev, const u8 req, const u8 direction, const u16 val, const u16 offset, From 172222cff0665c9cbced365d0c1a314507a37d31 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Sat, 25 Aug 2018 12:40:51 +0200 Subject: [PATCH 116/276] mt76x0: remove mt76x0_vendor_request routine Remove mt76x0_vendor_request routine and use mt76u_vendor_request utility function from mt76-usb layer in mt76x0_upload_firmware Signed-off-by: Lorenzo Bianconi Signed-off-by: Kalle Valo --- .../net/wireless/mediatek/mt76/mt76x0/mcu.c | 5 +-- .../net/wireless/mediatek/mt76/mt76x0/usb.c | 31 ------------------- .../net/wireless/mediatek/mt76/mt76x0/usb.h | 4 --- 3 files changed, 3 insertions(+), 37 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c index 3f985c1d45f0..7c2217307828 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c @@ -488,8 +488,9 @@ mt76x0_upload_firmware(struct mt76x0_dev *dev, const struct mt76_fw *fw) if (ret) goto error; - ret = mt76x0_vendor_request(dev, MT_VEND_DEV_MODE, USB_DIR_OUT, - 0x12, 0, ivb, sizeof(fw->ivb)); + ret = mt76u_vendor_request(&dev->mt76, MT_VEND_DEV_MODE, + USB_DIR_OUT | USB_TYPE_VENDOR, + 0x12, 0, ivb, sizeof(fw->ivb)); if (ret < 0) goto error; ret = 0; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c index d2edb269622d..845eef63cf5a 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c @@ -93,37 +93,6 @@ int mt76x0_usb_submit_buf(struct mt76x0_dev *dev, int dir, int ep_idx, return ret; } -int mt76x0_vendor_request(struct mt76x0_dev *dev, const u8 req, - const u8 direction, const u16 val, const u16 offset, - void *buf, const size_t buflen) -{ - int i, ret; - struct usb_device *usb_dev = mt76x0_to_usb_dev(dev); - const u8 req_type = direction | USB_TYPE_VENDOR | USB_RECIP_DEVICE; - const unsigned int pipe = (direction == USB_DIR_IN) ? - usb_rcvctrlpipe(usb_dev, 0) : usb_sndctrlpipe(usb_dev, 0); - - for (i = 0; i < MT_VEND_REQ_MAX_RETRY; i++) { - ret = usb_control_msg(usb_dev, pipe, req, req_type, - val, offset, buf, buflen, - MT_VEND_REQ_TOUT_MS); - trace_mt76x0_vend_req(&dev->mt76, pipe, req, req_type, val, offset, - buf, buflen, ret); - - if (ret == -ENODEV) - set_bit(MT76_REMOVED, &dev->mt76.state); - if (ret >= 0 || ret == -ENODEV) - return ret; - - msleep(5); - } - - dev_err(dev->mt76.dev, "Vendor request req:%02x off:%04x failed:%d\n", - req, offset, ret); - - return ret; -} - void mt76x0_addr_wr(struct mt76x0_dev *dev, const u32 offset, const u8 *addr) { mt76_wr(dev, offset, get_unaligned_le32(addr)); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.h b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.h index 0d1ba95dcf2e..b4a5d98416ab 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.h @@ -50,8 +50,4 @@ int mt76x0_usb_submit_buf(struct mt76x0_dev *dev, int dir, int ep_idx, struct mt76x0_dma_buf *buf, gfp_t gfp, usb_complete_t complete_fn, void *context); -int mt76x0_vendor_request(struct mt76x0_dev *dev, const u8 req, - const u8 direction, const u16 val, const u16 offset, - void *buf, const size_t buflen); - #endif From 876d3d02ee314250ac53d81977360b72c278be1b Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Sat, 25 Aug 2018 12:40:52 +0200 Subject: [PATCH 117/276] mt76x0: remove unused mt76x0_wait_asic_ready routine Delete core.c source file since, removing mt76x0_wait_asic_ready routine, it is no longer needed Signed-off-by: Lorenzo Bianconi Signed-off-by: Kalle Valo --- .../wireless/mediatek/mt76/mt76x0/Makefile | 2 +- .../net/wireless/mediatek/mt76/mt76x0/core.c | 34 ------------------- 2 files changed, 1 insertion(+), 35 deletions(-) delete mode 100644 drivers/net/wireless/mediatek/mt76/mt76x0/core.c diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/Makefile b/drivers/net/wireless/mediatek/mt76/mt76x0/Makefile index 7843908261ba..2f1721263aa5 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/Makefile +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/Makefile @@ -2,6 +2,6 @@ obj-$(CONFIG_MT76x0U) += mt76x0.o mt76x0-objs = \ usb.o init.o main.o mcu.o trace.o dma.o eeprom.o phy.o \ - mac.o util.o debugfs.o tx.o core.o + mac.o util.o debugfs.o tx.o # ccflags-y := -DDEBUG CFLAGS_trace.o := -I$(src) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/core.c b/drivers/net/wireless/mediatek/mt76/mt76x0/core.c deleted file mode 100644 index 892803fce842..000000000000 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/core.c +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2014 Felix Fietkau - * Copyright (C) 2015 Jakub Kicinski - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include "mt76x0.h" - -int mt76x0_wait_asic_ready(struct mt76x0_dev *dev) -{ - int i = 100; - u32 val; - - do { - if (test_bit(MT76_REMOVED, &dev->mt76.state)) - return -EIO; - - val = mt76_rr(dev, MT_MAC_CSR0); - if (val && ~val) - return 0; - - udelay(10); - } while (i--); - - return -EIO; -} From 6f4796b7063e334902049b0cc41514b6c3b52876 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Sat, 25 Aug 2018 12:40:53 +0200 Subject: [PATCH 118/276] mt76x0: use mt76u_mcu_send_msg utility routine to send fw cmds Use mt76u_mcu_send_msg/__mt76u_mcu_send_msg utility routines to send commands to usb mcu. Remove following unused routines: - mt76x0_mcu_wait_resp - __mt76x0_mcu_msg_send - mt76x0_mcu_msg_send - mt76x0_dma_skb_wrap_cmd - trace_mt_mcu_msg_send_cs - mt76x0_mcu_cmd_deinit Signed-off-by: Lorenzo Bianconi Signed-off-by: Kalle Valo --- .../net/wireless/mediatek/mt76/mt76x0/init.c | 4 +- .../net/wireless/mediatek/mt76/mt76x0/mcu.c | 226 +++--------------- .../net/wireless/mediatek/mt76/mt76x0/mcu.h | 1 - 3 files changed, 31 insertions(+), 200 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c index 1d5b74d05b75..80783edd9ca5 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c @@ -465,7 +465,7 @@ int mt76x0_init_hardware(struct mt76x0_dev *dev) err_rx: mt76x0_dma_cleanup(dev); err_mcu: - mt76x0_mcu_cmd_deinit(dev); + mt76u_mcu_deinit(&dev->mt76); err: mt76x0_chip_onoff(dev, false, false); return ret; @@ -478,7 +478,7 @@ void mt76x0_cleanup(struct mt76x0_dev *dev) mt76x0_stop_hardware(dev); mt76x0_dma_cleanup(dev); - mt76x0_mcu_cmd_deinit(dev); + mt76u_mcu_deinit(&dev->mt76); } struct mt76x0_dev *mt76x0_alloc_device(struct device *pdev) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c index 7c2217307828..39b2ec0c1ee0 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c @@ -40,157 +40,6 @@ static inline void skb_put_le32(struct sk_buff *skb, u32 val) put_unaligned_le32(val, skb_put(skb, 4)); } -static inline void mt76x0_dma_skb_wrap_cmd(struct sk_buff *skb, - u8 seq, enum mcu_cmd cmd) -{ - WARN_ON(mt76x0_dma_skb_wrap(skb, CPU_TX_PORT, DMA_COMMAND, - FIELD_PREP(MT_TXD_CMD_SEQ, seq) | - FIELD_PREP(MT_TXD_CMD_TYPE, cmd))); -} - -static inline void trace_mt76x0_mcu_msg_send_cs(struct mt76_dev *dev, - struct sk_buff *skb, bool need_resp) -{ - u32 i, csum = 0; - - for (i = 0; i < skb->len / 4; i++) - csum ^= get_unaligned_le32(skb->data + i * 4); - - trace_mt76x0_mcu_msg_send(dev, skb, csum, need_resp); -} - -static void mt76x0_read_resp_regs(struct mt76x0_dev *dev, int len) -{ - int i; - int n = dev->mcu.reg_pairs_len; - u8 *buf = dev->mcu.resp.buf; - - buf += 4; - len -= 8; - - if (dev->mcu.burst_read) { - u32 reg = dev->mcu.reg_pairs[0].reg - dev->mcu.reg_base; - - WARN_ON_ONCE(len/4 != n); - for (i = 0; i < n; i++) { - u32 val = get_unaligned_le32(buf + 4*i); - - dev->mcu.reg_pairs[i].reg = reg++; - dev->mcu.reg_pairs[i].value = val; - } - } else { - WARN_ON_ONCE(len/8 != n); - for (i = 0; i < n; i++) { - u32 reg = get_unaligned_le32(buf + 8*i) - dev->mcu.reg_base; - u32 val = get_unaligned_le32(buf + 8*i + 4); - - WARN_ON_ONCE(dev->mcu.reg_pairs[i].reg != reg); - dev->mcu.reg_pairs[i].value = val; - } - } -} - -static int mt76x0_mcu_wait_resp(struct mt76x0_dev *dev, u8 seq) -{ - struct urb *urb = dev->mcu.resp.urb; - struct mt76_usb *usb = &dev->mt76.usb; - u32 rxfce; - int urb_status, ret, try = 5; - - while (try--) { - if (!wait_for_completion_timeout(&usb->mcu.cmpl, - msecs_to_jiffies(300))) { - dev_warn(dev->mt76.dev, "Warning: %s retrying\n", __func__); - continue; - } - - /* Make copies of important data before reusing the urb */ - rxfce = get_unaligned_le32(dev->mcu.resp.buf); - urb_status = urb->status * mt76x0_urb_has_error(urb); - - if (urb_status == 0 && dev->mcu.reg_pairs) - mt76x0_read_resp_regs(dev, urb->actual_length); - - ret = mt76x0_usb_submit_buf(dev, USB_DIR_IN, MT_EP_IN_CMD_RESP, - &dev->mcu.resp, GFP_KERNEL, - mt76u_mcu_complete_urb, - &usb->mcu.cmpl); - if (ret) - return ret; - - if (urb_status) - dev_err(dev->mt76.dev, "Error: MCU resp urb failed:%d\n", - urb_status); - - if (FIELD_GET(MT_RXD_CMD_INFO_CMD_SEQ, rxfce) == seq && - FIELD_GET(MT_RXD_CMD_INFO_EVT_TYPE, rxfce) == CMD_DONE) - return 0; - - dev_err(dev->mt76.dev, "Error: MCU resp evt:%lx seq:%hhx-%lx!\n", - FIELD_GET(MT_RXD_CMD_INFO_EVT_TYPE, rxfce), - seq, FIELD_GET(MT_RXD_CMD_INFO_CMD_SEQ, rxfce)); - } - - dev_err(dev->mt76.dev, "Error: %s timed out\n", __func__); - return -ETIMEDOUT; -} - -static int -__mt76x0_mcu_msg_send(struct mt76x0_dev *dev, struct sk_buff *skb, - enum mcu_cmd cmd, bool wait_resp) -{ - struct usb_device *usb_dev = mt76x0_to_usb_dev(dev); - struct mt76_usb *usb = &dev->mt76.usb; - unsigned cmd_pipe = usb_sndbulkpipe(usb_dev, - usb->out_ep[MT_EP_OUT_INBAND_CMD]); - int sent, ret; - u8 seq = 0; - - if (wait_resp) - while (!seq) - seq = ++dev->mcu.msg_seq & 0xf; - - mt76x0_dma_skb_wrap_cmd(skb, seq, cmd); - - if (&usb->mcu.cmpl.done) - dev_err(dev->mt76.dev, "Error: MCU response pre-completed!\n"); - - trace_mt76x0_mcu_msg_send_cs(&dev->mt76, skb, wait_resp); - trace_mt76x0_submit_urb_sync(&dev->mt76, cmd_pipe, skb->len); - - ret = usb_bulk_msg(usb_dev, cmd_pipe, skb->data, skb->len, &sent, 500); - if (ret) { - dev_err(dev->mt76.dev, "Error: send MCU cmd failed:%d\n", ret); - goto out; - } - if (sent != skb->len) - dev_err(dev->mt76.dev, "Error: %s sent != skb->len\n", __func__); - - if (wait_resp) - ret = mt76x0_mcu_wait_resp(dev, seq); - -out: - return ret; -} - -static int -mt76x0_mcu_msg_send(struct mt76x0_dev *dev, struct sk_buff *skb, - enum mcu_cmd cmd, bool wait_resp) -{ - int ret; - - if (test_bit(MT76_REMOVED, &dev->mt76.state)) - return 0; - - mutex_lock(&dev->mcu.mutex); - ret = __mt76x0_mcu_msg_send(dev, skb, cmd, wait_resp); - mutex_unlock(&dev->mcu.mutex); - - consume_skb(skb); - - return ret; -} - int mt76x0_mcu_function_select(struct mt76x0_dev *dev, enum mcu_function func, u32 val) { @@ -206,7 +55,8 @@ int mt76x0_mcu_function_select(struct mt76x0_dev *dev, skb = mt76u_mcu_msg_alloc(&msg, sizeof(msg)); if (!skb) return -ENOMEM; - return mt76x0_mcu_msg_send(dev, skb, CMD_FUN_SET_OP, func == 5); + return mt76u_mcu_send_msg(&dev->mt76, skb, CMD_FUN_SET_OP, + func == 5); } int @@ -224,7 +74,8 @@ mt76x0_mcu_calibrate(struct mt76x0_dev *dev, enum mcu_calibrate cal, u32 val) skb = mt76u_mcu_msg_alloc(&msg, sizeof(msg)); if (!skb) return -ENOMEM; - return mt76x0_mcu_msg_send(dev, skb, CMD_CALIBRATION_OP, true); + return mt76u_mcu_send_msg(&dev->mt76, skb, CMD_CALIBRATION_OP, + true); } int mt76x0_write_reg_pairs(struct mt76x0_dev *dev, u32 base, @@ -249,7 +100,8 @@ int mt76x0_write_reg_pairs(struct mt76x0_dev *dev, u32 base, skb_put_le32(skb, data[i].value); } - ret = mt76x0_mcu_msg_send(dev, skb, CMD_RANDOM_WRITE, cnt == n); + ret = mt76u_mcu_send_msg(&dev->mt76, skb, CMD_RANDOM_WRITE, + cnt == n); if (ret) return ret; @@ -260,6 +112,7 @@ int mt76x0_read_reg_pairs(struct mt76x0_dev *dev, u32 base, struct mt76_reg_pair *data, int n) { const int max_vals_per_cmd = INBAND_PACKET_MAX_LEN / 8; + struct mt76_usb *usb = &dev->mt76.usb; struct sk_buff *skb; int cnt, i, ret; @@ -280,20 +133,19 @@ int mt76x0_read_reg_pairs(struct mt76x0_dev *dev, u32 base, skb_put_le32(skb, data[i].value); } - mutex_lock(&dev->mcu.mutex); + mutex_lock(&usb->mcu.mutex); - dev->mcu.reg_pairs = data; - dev->mcu.reg_pairs_len = n; - dev->mcu.reg_base = base; - dev->mcu.burst_read = false; + usb->mcu.rp = data; + usb->mcu.rp_len = n; + usb->mcu.base = base; + usb->mcu.burst = false; - ret = __mt76x0_mcu_msg_send(dev, skb, CMD_RANDOM_READ, true); + ret = __mt76u_mcu_send_msg(&dev->mt76, skb, CMD_RANDOM_READ, + true); - dev->mcu.reg_pairs = NULL; + usb->mcu.rp = NULL; - mutex_unlock(&dev->mcu.mutex); - - consume_skb(skb); + mutex_unlock(&usb->mcu.mutex); return ret; @@ -320,7 +172,8 @@ int mt76x0_burst_write_regs(struct mt76x0_dev *dev, u32 offset, for (i = 0; i < cnt; i++) skb_put_le32(skb, data[i]); - ret = mt76x0_mcu_msg_send(dev, skb, CMD_BURST_WRITE, cnt == n); + ret = mt76u_mcu_send_msg(&dev->mt76, skb, CMD_BURST_WRITE, + cnt == n); if (ret) return ret; @@ -333,6 +186,7 @@ static int mt76x0_burst_read_regs(struct mt76x0_dev *dev, u32 base, struct mt76_reg_pair *data, int n) { const int max_vals_per_cmd = INBAND_PACKET_MAX_LEN / 4 - 1; + struct mt76_usb *usb = &dev->mt76.usb; struct sk_buff *skb; int cnt, ret; @@ -351,18 +205,18 @@ static int mt76x0_burst_read_regs(struct mt76x0_dev *dev, u32 base, skb_put_le32(skb, base + data[0].reg); skb_put_le32(skb, n); - mutex_lock(&dev->mcu.mutex); + mutex_lock(&usb->mcu.mutex); - dev->mcu.reg_pairs = data; - dev->mcu.reg_pairs_len = n; - dev->mcu.reg_base = base; - dev->mcu.burst_read = true; + usb->mcu.rp = data; + usb->mcu.rp_len = n; + usb->mcu.base = base; + usb->mcu.burst = false; - ret = __mt76x0_mcu_msg_send(dev, skb, CMD_BURST_READ, true); + ret = __mt76u_mcu_send_msg(&dev->mt76, skb, CMD_BURST_READ, true); - dev->mcu.reg_pairs = NULL; + usb->mcu.rp = NULL; - mutex_unlock(&dev->mcu.mutex); + mutex_unlock(&usb->mcu.mutex); consume_skb(skb); @@ -611,31 +465,9 @@ int mt76x0_mcu_init(struct mt76x0_dev *dev) int mt76x0_mcu_cmd_init(struct mt76x0_dev *dev) { - struct mt76_usb *usb = &dev->mt76.usb; - int ret; - - ret = mt76x0_mcu_function_select(dev, Q_SELECT, 1); + int ret = mt76x0_mcu_function_select(dev, Q_SELECT, 1); if (ret) return ret; - if (mt76x0_usb_alloc_buf(dev, MCU_RESP_URB_SIZE, &dev->mcu.resp)) { - mt76x0_usb_free_buf(dev, &dev->mcu.resp); - return -ENOMEM; - } - - ret = mt76x0_usb_submit_buf(dev, USB_DIR_IN, MT_EP_IN_CMD_RESP, - &dev->mcu.resp, GFP_KERNEL, - mt76u_mcu_complete_urb, &usb->mcu.cmpl); - if (ret) { - mt76x0_usb_free_buf(dev, &dev->mcu.resp); - return ret; - } - - return 0; -} - -void mt76x0_mcu_cmd_deinit(struct mt76x0_dev *dev) -{ - usb_kill_urb(dev->mcu.resp.urb); - mt76x0_usb_free_buf(dev, &dev->mcu.resp); + return mt76u_mcu_init_rx(&dev->mt76); } diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.h b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.h index 8c2f77f4c3f5..010a7f2bbae9 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.h @@ -90,7 +90,6 @@ enum mcu_calibrate { int mt76x0_mcu_init(struct mt76x0_dev *dev); int mt76x0_mcu_cmd_init(struct mt76x0_dev *dev); -void mt76x0_mcu_cmd_deinit(struct mt76x0_dev *dev); int mt76x0_mcu_calibrate(struct mt76x0_dev *dev, enum mcu_calibrate cal, u32 val); From 0e3612e06be42a91accec101fdc98bbcbd31f3fe Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Sat, 25 Aug 2018 12:40:54 +0200 Subject: [PATCH 119/276] mt76x0: remove unused mt76x0_mcu structure Remove no longer used mt76x0_mcu data structure Signed-off-by: Lorenzo Bianconi Signed-off-by: Kalle Valo --- drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c | 2 -- .../net/wireless/mediatek/mt76/mt76x0/mt76x0.h | 15 --------------- 2 files changed, 17 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c index 39b2ec0c1ee0..d49557834658 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c @@ -452,8 +452,6 @@ int mt76x0_mcu_init(struct mt76x0_dev *dev) { int ret; - mutex_init(&dev->mcu.mutex); - ret = mt76x0_load_firmware(dev); if (ret) return ret; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h index c9bc243b3619..c53ea04e1618 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h @@ -49,19 +49,6 @@ struct mt76x0_dma_buf { size_t len; }; -struct mt76x0_mcu { - struct mutex mutex; - - u8 msg_seq; - - struct mt76x0_dma_buf resp; - - struct mt76_reg_pair *reg_pairs; - unsigned int reg_pairs_len; - u32 reg_base; - bool burst_read; -}; - struct mac_stats { u64 rx_stat[6]; u64 tx_stat[6]; @@ -160,8 +147,6 @@ struct mt76x0_dev { unsigned long wcid_mask[DIV_ROUND_UP(N_WCIDS, BITS_PER_LONG)]; unsigned long vif_mask; - struct mt76x0_mcu mcu; - struct delayed_work cal_work; struct delayed_work mac_work; From a0b65ca60ec7e6fade309dc874f166b1be19a812 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Sat, 25 Aug 2018 12:40:55 +0200 Subject: [PATCH 120/276] mt76x0: use mt76u_mcu_fw_send_data for fw uploading Use mt76u_mcu_fw_send_data utility routine for firmware uploading and remove unused __mt76x0_dma_fw/mt76x0_dma_fw functions Signed-off-by: Lorenzo Bianconi Signed-off-by: Kalle Valo --- .../net/wireless/mediatek/mt76/mt76x0/mcu.c | 88 ++----------------- 1 file changed, 6 insertions(+), 82 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c index d49557834658..0a0deaf1c65d 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c @@ -239,83 +239,9 @@ struct mt76_fw { u8 ilm[]; }; -static int __mt76x0_dma_fw(struct mt76x0_dev *dev, - const struct mt76x0_dma_buf *dma_buf, - const void *data, u32 len, u32 dst_addr) -{ - DECLARE_COMPLETION_ONSTACK(cmpl); - struct mt76x0_dma_buf buf = *dma_buf; /* we need to fake length */ - __le32 reg; - u32 val; - int ret; - - reg = cpu_to_le32(FIELD_PREP(MT_TXD_INFO_TYPE, DMA_COMMAND) | - FIELD_PREP(MT_TXD_INFO_D_PORT, CPU_TX_PORT) | - FIELD_PREP(MT_TXD_INFO_LEN, len)); - memcpy(buf.buf, ®, sizeof(reg)); - memcpy(buf.buf + sizeof(reg), data, len); - memset(buf.buf + sizeof(reg) + len, 0, 8); - - mt76u_single_wr(&dev->mt76, MT_VEND_WRITE_FCE, MT_FCE_DMA_ADDR, - dst_addr); - - len = roundup(len, 4); - mt76u_single_wr(&dev->mt76, MT_VEND_WRITE_FCE, MT_FCE_DMA_LEN, - len << 16); - - buf.len = MT_DMA_HDR_LEN + len + 4; - ret = mt76x0_usb_submit_buf(dev, USB_DIR_OUT, MT_EP_OUT_INBAND_CMD, - &buf, GFP_KERNEL, - mt76u_mcu_complete_urb, &cmpl); - if (ret) - return ret; - - if (!wait_for_completion_timeout(&cmpl, msecs_to_jiffies(1000))) { - dev_err(dev->mt76.dev, "Error: firmware upload timed out\n"); - usb_kill_urb(buf.urb); - return -ETIMEDOUT; - } - if (mt76x0_urb_has_error(buf.urb)) { - dev_err(dev->mt76.dev, "Error: firmware upload urb failed:%d\n", - buf.urb->status); - return buf.urb->status; - } - - val = mt76_rr(dev, MT_TX_CPU_FROM_FCE_CPU_DESC_IDX); - val++; - mt76_wr(dev, MT_TX_CPU_FROM_FCE_CPU_DESC_IDX, val); - - msleep(5); - - return 0; -} - -static int -mt76x0_dma_fw(struct mt76x0_dev *dev, struct mt76x0_dma_buf *dma_buf, - const void *data, int len, u32 dst_addr) -{ - int n, ret; - - if (len == 0) - return 0; - - n = min(MCU_FW_URB_MAX_PAYLOAD, len); - ret = __mt76x0_dma_fw(dev, dma_buf, data, n, dst_addr); - if (ret) - return ret; - -#if 0 - if (!mt76_poll_msec(dev, MT_MCU_COM_REG1, BIT(31), BIT(31), 500)) - return -ETIMEDOUT; -#endif - - return mt76x0_dma_fw(dev, dma_buf, data + n, len - n, dst_addr + n); -} - static int mt76x0_upload_firmware(struct mt76x0_dev *dev, const struct mt76_fw *fw) { - struct mt76x0_dma_buf dma_buf; void *ivb; u32 ilm_len, dlm_len; int i, ret; @@ -323,22 +249,21 @@ mt76x0_upload_firmware(struct mt76x0_dev *dev, const struct mt76_fw *fw) ivb = kmemdup(fw->ivb, sizeof(fw->ivb), GFP_KERNEL); if (!ivb) return -ENOMEM; - if (mt76x0_usb_alloc_buf(dev, MCU_FW_URB_SIZE, &dma_buf)) { - ret = -ENOMEM; - goto error; - } ilm_len = le32_to_cpu(fw->hdr.ilm_len) - sizeof(fw->ivb); dev_dbg(dev->mt76.dev, "loading FW - ILM %u + IVB %zu\n", ilm_len, sizeof(fw->ivb)); - ret = mt76x0_dma_fw(dev, &dma_buf, fw->ilm, ilm_len, sizeof(fw->ivb)); + ret = mt76u_mcu_fw_send_data(&dev->mt76, fw->ilm, ilm_len, + MCU_FW_URB_MAX_PAYLOAD, + sizeof(fw->ivb)); if (ret) goto error; dlm_len = le32_to_cpu(fw->hdr.dlm_len); dev_dbg(dev->mt76.dev, "loading FW - DLM %u\n", dlm_len); - ret = mt76x0_dma_fw(dev, &dma_buf, fw->ilm + ilm_len, - dlm_len, MT_MCU_DLM_OFFSET); + ret = mt76u_mcu_fw_send_data(&dev->mt76, fw->ilm + ilm_len, + dlm_len, MCU_FW_URB_MAX_PAYLOAD, + MT_MCU_DLM_OFFSET); if (ret) goto error; @@ -359,7 +284,6 @@ mt76x0_upload_firmware(struct mt76x0_dev *dev, const struct mt76_fw *fw) dev_dbg(dev->mt76.dev, "Firmware running!\n"); error: kfree(ivb); - mt76x0_usb_free_buf(dev, &dma_buf); return ret; } From 01b302cd5874e98cb44835ec766597b1524fb7a8 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Sat, 25 Aug 2018 12:40:56 +0200 Subject: [PATCH 121/276] mt76x0: remove unused routines for usb_buff alloc/free Remove the following unused routines for usb buffer allocation/free/submit: - mt76x0_usb_alloc_buf - mt76x0_usb_free_buf - mt76x0_usb_submit_buf Signed-off-by: Lorenzo Bianconi Signed-off-by: Kalle Valo --- .../net/wireless/mediatek/mt76/mt76x0/usb.c | 47 ------------------- .../net/wireless/mediatek/mt76/mt76x0/usb.h | 7 --- 2 files changed, 54 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c index 845eef63cf5a..a5ca74594290 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c @@ -46,53 +46,6 @@ static struct usb_device_id mt76x0_device_table[] = { { 0, } }; -bool mt76x0_usb_alloc_buf(struct mt76x0_dev *dev, size_t len, - struct mt76x0_dma_buf *buf) -{ - struct usb_device *usb_dev = mt76x0_to_usb_dev(dev); - - buf->len = len; - buf->urb = usb_alloc_urb(0, GFP_KERNEL); - buf->buf = usb_alloc_coherent(usb_dev, buf->len, GFP_KERNEL, &buf->dma); - - return !buf->urb || !buf->buf; -} - -void mt76x0_usb_free_buf(struct mt76x0_dev *dev, struct mt76x0_dma_buf *buf) -{ - struct usb_device *usb_dev = mt76x0_to_usb_dev(dev); - - usb_free_coherent(usb_dev, buf->len, buf->buf, buf->dma); - usb_free_urb(buf->urb); -} - -int mt76x0_usb_submit_buf(struct mt76x0_dev *dev, int dir, int ep_idx, - struct mt76x0_dma_buf *buf, gfp_t gfp, - usb_complete_t complete_fn, void *context) -{ - struct usb_device *usb_dev = mt76x0_to_usb_dev(dev); - struct mt76_usb *usb = &dev->mt76.usb; - unsigned pipe; - int ret; - - if (dir == USB_DIR_IN) - pipe = usb_rcvbulkpipe(usb_dev, usb->in_ep[ep_idx]); - else - pipe = usb_sndbulkpipe(usb_dev, usb->out_ep[ep_idx]); - - usb_fill_bulk_urb(buf->urb, usb_dev, pipe, buf->buf, buf->len, - complete_fn, context); - buf->urb->transfer_dma = buf->dma; - buf->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - - trace_mt76x0_submit_urb(&dev->mt76, buf->urb); - ret = usb_submit_urb(buf->urb, gfp); - if (ret) - dev_err(dev->mt76.dev, "Error: submit URB dir:%d ep:%d failed:%d\n", - dir, ep_idx, ret); - return ret; -} - void mt76x0_addr_wr(struct mt76x0_dev *dev, const u32 offset, const u8 *addr) { mt76_wr(dev, offset, get_unaligned_le32(addr)); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.h b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.h index b4a5d98416ab..7bd075319f5b 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.h @@ -43,11 +43,4 @@ static inline bool mt76x0_urb_has_error(struct urb *urb) urb->status != -ESHUTDOWN; } -bool mt76x0_usb_alloc_buf(struct mt76x0_dev *dev, size_t len, - struct mt76x0_dma_buf *buf); -void mt76x0_usb_free_buf(struct mt76x0_dev *dev, struct mt76x0_dma_buf *buf); -int mt76x0_usb_submit_buf(struct mt76x0_dev *dev, int dir, int ep_idx, - struct mt76x0_dma_buf *buf, gfp_t gfp, - usb_complete_t complete_fn, void *context); - #endif From b37b30afc2b39642e1a609d94466965642b1b2a7 Mon Sep 17 00:00:00 2001 From: Kristian Evensen Date: Sat, 1 Sep 2018 10:38:34 +0200 Subject: [PATCH 122/276] mt76: Enable NL80211_EXT_FEATURE_CQM_RSSI_LIST Enable the use of CQM_RSSI_LIST with mt76-devices. The change has been tested with the mt7602, mt7603 and mt7621 PCI wifi-cards. I passed a list of RSSI thresholds to the driver, and when disconnecting/connecting the antenna(s) I got an event each time the RSSI went above/below a threshold. While I have not been able to test the change with any of the mt76 USB-devices (no access to a device), the RX RSSI management code is shared between the two device types. Thus, CQM should also work with the mt76 USB-devices. Signed-off-by: Kristian Evensen Signed-off-by: Kalle Valo --- drivers/net/wireless/mediatek/mt76/mac80211.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c b/drivers/net/wireless/mediatek/mt76/mac80211.c index df670d04f5a2..2bc386f4387c 100644 --- a/drivers/net/wireless/mediatek/mt76/mac80211.c +++ b/drivers/net/wireless/mediatek/mt76/mac80211.c @@ -306,6 +306,8 @@ int mt76_register_device(struct mt76_dev *dev, bool vht, wiphy->features |= NL80211_FEATURE_ACTIVE_MONITOR; + wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST); + wiphy->available_antennas_tx = dev->antenna_mask; wiphy->available_antennas_rx = dev->antenna_mask; From 514502c3a70bcadd9f7d915524acf09e5fc36f89 Mon Sep 17 00:00:00 2001 From: Aleksei Mamlin Date: Thu, 30 Aug 2018 17:05:41 +0300 Subject: [PATCH 123/276] rtl8xxxu: Add rtl8188ctv support The Realtek rtl8188ctv (0x0bda:0x018a) is a highly integrated single-chip WLAN USB2.0 network interface controller. Currently rtl8188ctv is supported by rtlwifi driver. It is similar to the rtl8188cus(0x0bda:0x818a) and uses the same config. Signed-off-by: Aleksei Mamlin Signed-off-by: Kalle Valo --- drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c index 505ab1b055ff..73f6fc0d4a01 100644 --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c @@ -6231,6 +6231,8 @@ static const struct usb_device_id dev_table[] = { {USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3308, 0xff, 0xff, 0xff), .driver_info = (unsigned long)&rtl8192cu_fops}, /* Currently untested 8188 series devices */ +{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x018a, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x8191, 0xff, 0xff, 0xff), .driver_info = (unsigned long)&rtl8192cu_fops}, {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x8170, 0xff, 0xff, 0xff), From 7e41fb504592bd5eefc1808bfcac1448c9465081 Mon Sep 17 00:00:00 2001 From: Igor Stoppa Date: Fri, 31 Aug 2018 18:03:00 +0300 Subject: [PATCH 124/276] wireless: remove unnecessary unlikely() Both WARN_ON() and WARN_ON_ONCE() already contain unlikely(). Signed-off-by: Igor Stoppa Cc: Kalle Valo Cc: Christian Lamparter Cc: Michal Kazior Cc: Larry Finger Cc: Linux Kernel Mailing List Cc: Linux Wireless Mailing List Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/htt_rx.c | 4 ++-- drivers/net/wireless/ath/carl9170/tx.c | 4 ++-- drivers/net/wireless/broadcom/b43/dma.c | 2 +- drivers/net/wireless/broadcom/b43legacy/dma.c | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c index 4d1cd90d6d27..1455007f3eb8 100644 --- a/drivers/net/wireless/ath/ath10k/htt_rx.c +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c @@ -1176,11 +1176,11 @@ static void ath10k_htt_rx_h_undecap_raw(struct ath10k *ar, */ /* This probably shouldn't happen but warn just in case */ - if (unlikely(WARN_ON_ONCE(!is_first))) + if (WARN_ON_ONCE(!is_first)) return; /* This probably shouldn't happen but warn just in case */ - if (unlikely(WARN_ON_ONCE(!(is_first && is_last)))) + if (WARN_ON_ONCE(!(is_first && is_last))) return; skb_trim(msdu, msdu->len - FCS_LEN); diff --git a/drivers/net/wireless/ath/carl9170/tx.c b/drivers/net/wireless/ath/carl9170/tx.c index 0cb5b58925dc..8c75651ede6c 100644 --- a/drivers/net/wireless/ath/carl9170/tx.c +++ b/drivers/net/wireless/ath/carl9170/tx.c @@ -246,8 +246,8 @@ static void carl9170_release_dev_space(struct ar9170 *ar, struct sk_buff *skb) * of available memory blocks, so the number can * never execeed the mem_blocks count. */ - if (unlikely(WARN_ON_ONCE(cookie == 0) || - WARN_ON_ONCE(cookie > ar->fw.mem_blocks))) + if (WARN_ON_ONCE(cookie == 0) || + WARN_ON_ONCE(cookie > ar->fw.mem_blocks)) return; atomic_add(DIV_ROUND_UP(skb->len, ar->fw.mem_block_size), diff --git a/drivers/net/wireless/broadcom/b43/dma.c b/drivers/net/wireless/broadcom/b43/dma.c index 6b0e1ec346cb..d113bd997f4b 100644 --- a/drivers/net/wireless/broadcom/b43/dma.c +++ b/drivers/net/wireless/broadcom/b43/dma.c @@ -1432,7 +1432,7 @@ int b43_dma_tx(struct b43_wldev *dev, struct sk_buff *skb) goto out; } - if (unlikely(WARN_ON(free_slots(ring) < TX_SLOTS_PER_FRAME))) { + if (WARN_ON(free_slots(ring) < TX_SLOTS_PER_FRAME)) { /* If we get here, we have a real error with the queue * full, but queues not stopped. */ b43err(dev->wl, "DMA queue overflow\n"); diff --git a/drivers/net/wireless/broadcom/b43legacy/dma.c b/drivers/net/wireless/broadcom/b43legacy/dma.c index 2f0c64cef65f..1b1da7d83652 100644 --- a/drivers/net/wireless/broadcom/b43legacy/dma.c +++ b/drivers/net/wireless/broadcom/b43legacy/dma.c @@ -1149,7 +1149,7 @@ int b43legacy_dma_tx(struct b43legacy_wldev *dev, return -ENOSPC; } - if (unlikely(WARN_ON(free_slots(ring) < SLOTS_PER_PACKET))) { + if (WARN_ON(free_slots(ring) < SLOTS_PER_PACKET)) { /* If we get here, we have a real error with the queue * full, but queues not stopped. */ b43legacyerr(dev->wl, "DMA queue overflow\n"); From ec7eccf7ad1cd5f13614e77f59c87fe1f37bf56c Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Sat, 1 Sep 2018 07:48:27 +0000 Subject: [PATCH 125/276] rsi: remove set but not used variables 'header_size' and 'tx_params' Fixes gcc '-Wunused-but-set-variable' warning: drivers/net/wireless/rsi/rsi_91x_hal.c: In function 'rsi_send_data_pkt': drivers/net/wireless/rsi/rsi_91x_hal.c:288:5: warning: variable 'header_size' set but not used [-Wunused-but-set-variable] 'tx_params' only used for 'header_size' dereferenced,so also can be removed. Signed-off-by: YueHaibing Signed-off-by: Kalle Valo --- drivers/net/wireless/rsi/rsi_91x_hal.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/net/wireless/rsi/rsi_91x_hal.c b/drivers/net/wireless/rsi/rsi_91x_hal.c index 01edf960ff3c..182b06629371 100644 --- a/drivers/net/wireless/rsi/rsi_91x_hal.c +++ b/drivers/net/wireless/rsi/rsi_91x_hal.c @@ -282,10 +282,8 @@ int rsi_send_data_pkt(struct rsi_common *common, struct sk_buff *skb) struct rsi_hw *adapter = common->priv; struct ieee80211_vif *vif; struct ieee80211_tx_info *info; - struct skb_info *tx_params; struct ieee80211_bss_conf *bss; int status = -EINVAL; - u8 header_size; if (!skb) return 0; @@ -297,8 +295,6 @@ int rsi_send_data_pkt(struct rsi_common *common, struct sk_buff *skb) goto err; vif = info->control.vif; bss = &vif->bss_conf; - tx_params = (struct skb_info *)info->driver_data; - header_size = tx_params->internal_hdr_size; if (((vif->type == NL80211_IFTYPE_STATION) || (vif->type == NL80211_IFTYPE_P2P_CLIENT)) && From b9bcce366bd5cf5da634a689afcd54058767c359 Mon Sep 17 00:00:00 2001 From: Kevin Lo Date: Mon, 3 Sep 2018 22:57:35 +0800 Subject: [PATCH 126/276] rtlwifi: remove set but unused variables Remove set but unused variables from _rtl88ee_hw_configure() and _rtl8723e_hw_configure(). Signed-off-by: Kevin Lo Acked-by: Ping-Ke Shih Signed-off-by: Kalle Valo --- drivers/net/wireless/realtek/rtlwifi/rtl8188ee/hw.c | 6 +----- drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hw.c | 4 +--- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/hw.c index 988d5ac57d02..cfc8762c55f4 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/hw.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/hw.c @@ -951,12 +951,8 @@ static bool _rtl88ee_init_mac(struct ieee80211_hw *hw) static void _rtl88ee_hw_configure(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 reg_bw_opmode; - u32 reg_ratr, reg_prsr; + u32 reg_prsr; - reg_bw_opmode = BW_OPMODE_20MHZ; - reg_ratr = RATE_ALL_CCK | RATE_ALL_OFDM_AG | - RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS; reg_prsr = RATE_ALL_CCK | RATE_ALL_OFDM_AG; rtl_write_dword(rtlpriv, REG_RRSR, reg_prsr); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hw.c index 545115db507e..f783e4a8083d 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hw.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hw.c @@ -799,11 +799,9 @@ static void _rtl8723e_hw_configure(struct ieee80211_hw *hw) struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); struct rtl_priv *rtlpriv = rtl_priv(hw); u8 reg_bw_opmode; - u32 reg_ratr, reg_prsr; + u32 reg_prsr; reg_bw_opmode = BW_OPMODE_20MHZ; - reg_ratr = RATE_ALL_CCK | RATE_ALL_OFDM_AG | - RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS; reg_prsr = RATE_ALL_CCK | RATE_ALL_OFDM_AG; rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL, 0x8); From cf5652c962dae3bff1e256be7eba142b067e74ba Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Mon, 3 Sep 2018 15:17:52 -0500 Subject: [PATCH 127/276] orinoco_usb: fix spelling mistake in fall-through annotation Replace "fall though" with a proper "fall through" annotation. This fix is part of the ongoing efforts to enabling -Wimplicit-fallthrough Signed-off-by: Gustavo A. R. Silva Signed-off-by: Kalle Valo --- drivers/net/wireless/intersil/orinoco/orinoco_usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/intersil/orinoco/orinoco_usb.c b/drivers/net/wireless/intersil/orinoco/orinoco_usb.c index d8c27203bc57..21bb68457cfe 100644 --- a/drivers/net/wireless/intersil/orinoco/orinoco_usb.c +++ b/drivers/net/wireless/intersil/orinoco/orinoco_usb.c @@ -911,7 +911,7 @@ static int ezusb_access_ltv(struct ezusb_priv *upriv, default: err("%s: Unexpected context state %d", __func__, state); - /* fall though */ + /* fall through */ case EZUSB_CTX_REQ_TIMEOUT: case EZUSB_CTX_REQ_FAILED: case EZUSB_CTX_RESP_TIMEOUT: From 3341ba9f0f2637a51738ef5de5114e13a1cd3eca Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Mon, 3 Sep 2018 12:26:21 +0200 Subject: [PATCH 128/276] mt76x0: fix remove_interface We wrongly use wcid_mask instead of vif_mask. This creates problems when the interface is removed more than 8 times, for example with iw: iw dev interface add type iw dev del This caused 'ifconfig up' to fail with error: SIOCSIFFLAGS: No space left on device Fixes: 95e444098a7b ("mt76x0: main file") Reported-and-tested-by: Sid Hayn Signed-off-by: Stanislaw Gruszka Signed-off-by: Kalle Valo --- drivers/net/wireless/mediatek/mt76/mt76x0/main.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c index cf6ffb1ba4a2..22bc9d368728 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c @@ -77,9 +77,8 @@ static void mt76x0_remove_interface(struct ieee80211_hw *hw, { struct mt76x0_dev *dev = hw->priv; struct mt76_vif *mvif = (struct mt76_vif *) vif->drv_priv; - unsigned int wcid = mvif->group_wcid.idx; - dev->wcid_mask[wcid / BITS_PER_LONG] &= ~BIT(wcid % BITS_PER_LONG); + dev->vif_mask &= ~BIT(mvif->idx); } static int mt76x0_config(struct ieee80211_hw *hw, u32 changed) From 36404c065ac310c042aa3334ecd6fa12cd3400eb Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Tue, 4 Sep 2018 16:40:54 +0200 Subject: [PATCH 129/276] mt76: move wcid fields to common mt76_dev struct All current MT devices including new MT7603 type chips support 128 WCIDs, we can unify wcid data in common mt76_dev structure. Signed-off-by: Stanislaw Gruszka Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt76.h | 7 ++++++ .../net/wireless/mediatek/mt76/mt76x0/init.c | 22 ++++++++----------- .../net/wireless/mediatek/mt76/mt76x0/mac.c | 8 +++---- .../net/wireless/mediatek/mt76/mt76x0/main.c | 8 +++---- .../wireless/mediatek/mt76/mt76x0/mt76x0.h | 5 ----- .../net/wireless/mediatek/mt76/mt76x0/tx.c | 2 +- drivers/net/wireless/mediatek/mt76/mt76x2.h | 5 ----- .../wireless/mediatek/mt76/mt76x2_common.c | 8 +++---- .../mediatek/mt76/mt76x2_init_common.c | 4 ++-- .../mediatek/mt76/mt76x2_mac_common.c | 8 +++---- .../mediatek/mt76/mt76x2_phy_common.c | 6 ++--- .../wireless/mediatek/mt76/mt76x2_tx_common.c | 2 +- 12 files changed, 39 insertions(+), 46 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h index e9e46612c7f3..2d0ab28a0977 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76.h +++ b/drivers/net/wireless/mediatek/mt76/mt76.h @@ -148,6 +148,8 @@ enum mt76_wcid_flags { MT_WCID_FLAG_PS, }; +#define MT76_N_WCIDS 128 + struct mt76_wcid { struct mt76_rx_tid __rcu *aggr[IEEE80211_NUM_TIDS]; @@ -348,6 +350,11 @@ struct mt76_dev { wait_queue_head_t tx_wait; + unsigned long wcid_mask[MT76_N_WCIDS / BITS_PER_LONG]; + + struct mt76_wcid global_wcid; + struct mt76_wcid __rcu *wcid[MT76_N_WCIDS]; + u8 macaddr[ETH_ALEN]; u32 rev; unsigned long state; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c index 80783edd9ca5..b5bf22184a69 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c @@ -230,17 +230,17 @@ static int mt76x0_init_wcid_mem(struct mt76x0_dev *dev) u32 *vals; int i, ret; - vals = kmalloc(sizeof(*vals) * N_WCIDS * 2, GFP_KERNEL); + vals = kmalloc(sizeof(*vals) * MT76_N_WCIDS * 2, GFP_KERNEL); if (!vals) return -ENOMEM; - for (i = 0; i < N_WCIDS; i++) { + for (i = 0; i < MT76_N_WCIDS; i++) { vals[i * 2] = 0xffffffff; vals[i * 2 + 1] = 0x00ffffff; } ret = mt76x0_burst_write_regs(dev, MT_WCID_ADDR_BASE, - vals, N_WCIDS * 2); + vals, MT76_N_WCIDS * 2); kfree(vals); return ret; @@ -259,15 +259,15 @@ static int mt76x0_init_wcid_attr_mem(struct mt76x0_dev *dev) u32 *vals; int i, ret; - vals = kmalloc(sizeof(*vals) * N_WCIDS * 2, GFP_KERNEL); + vals = kmalloc(sizeof(*vals) * MT76_N_WCIDS * 2, GFP_KERNEL); if (!vals) return -ENOMEM; - for (i = 0; i < N_WCIDS * 2; i++) + for (i = 0; i < MT76_N_WCIDS * 2; i++) vals[i] = 1; ret = mt76x0_burst_write_regs(dev, MT_WCID_ATTR_BASE, - vals, N_WCIDS * 2); + vals, MT76_N_WCIDS * 2); kfree(vals); return ret; @@ -667,15 +667,11 @@ int mt76x0_register_device(struct mt76x0_dev *dev) /* Reserve WCID 0 for mcast - thanks to this APs WCID will go to * entry no. 1 like it does in the vendor driver. */ - dev->wcid_mask[0] |= 1; + dev->mt76.wcid_mask[0] |= 1; /* init fake wcid for monitor interfaces */ - dev->mon_wcid = devm_kmalloc(dev->mt76.dev, sizeof(*dev->mon_wcid), - GFP_KERNEL); - if (!dev->mon_wcid) - return -ENOMEM; - dev->mon_wcid->idx = 0xff; - dev->mon_wcid->hw_key_idx = -1; + dev->mt76.global_wcid.idx = 0xff; + dev->mt76.global_wcid.hw_key_idx = -1; SET_IEEE80211_DEV(hw, dev->mt76.dev); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c b/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c index 0931c1821597..4c4962bcca11 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c @@ -206,8 +206,8 @@ void mt76x0_send_tx_status(struct mt76x0_dev *dev, struct mt76x02_tx_status *sta struct mt76x02_sta *msta = NULL; rcu_read_lock(); - if (stat->wcid < ARRAY_SIZE(dev->wcid)) - wcid = rcu_dereference(dev->wcid[stat->wcid]); + if (stat->wcid < ARRAY_SIZE(dev->mt76.wcid)) + wcid = rcu_dereference(dev->mt76.wcid[stat->wcid]); if (wcid) { void *priv; @@ -408,8 +408,8 @@ void mt76x0_mac_set_ampdu_factor(struct mt76x0_dev *dev) int i; rcu_read_lock(); - for (i = 0; i < ARRAY_SIZE(dev->wcid); i++) { - wcid = rcu_dereference(dev->wcid[i]); + for (i = 0; i < ARRAY_SIZE(dev->mt76.wcid); i++) { + wcid = rcu_dereference(dev->mt76.wcid[i]); if (!wcid) continue; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c index 3f936a85c171..78b40cb0fdbd 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c @@ -168,7 +168,7 @@ mt76x0_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, mutex_lock(&dev->mt76.mutex); - idx = mt76_wcid_alloc(dev->wcid_mask, ARRAY_SIZE(dev->wcid)); + idx = mt76_wcid_alloc(dev->mt76.wcid_mask, ARRAY_SIZE(dev->mt76.wcid)); if (idx < 0) { ret = -ENOSPC; goto out; @@ -179,7 +179,7 @@ mt76x0_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, mt76x02_mac_wcid_setup(&dev->mt76, idx, mvif->idx, sta->addr); mt76x02_mac_wcid_set_drop(&dev->mt76, idx, false); mt76_clear(dev, MT_WCID_DROP(idx), MT_WCID_DROP_MASK(idx)); - rcu_assign_pointer(dev->wcid[idx], &msta->wcid); + rcu_assign_pointer(dev->mt76.wcid[idx], &msta->wcid); for (i = 0; i < ARRAY_SIZE(sta->txq); i++) mt76x02_txq_init(&dev->mt76, sta->txq[i]); mt76x0_mac_set_ampdu_factor(dev); @@ -200,9 +200,9 @@ mt76x0_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, int i; mutex_lock(&dev->mt76.mutex); - rcu_assign_pointer(dev->wcid[idx], NULL); + rcu_assign_pointer(dev->mt76.wcid[idx], NULL); mt76x02_mac_wcid_set_drop(&dev->mt76, idx, true); - mt76_wcid_free(dev->wcid_mask, idx); + mt76_wcid_free(dev->mt76.wcid_mask, idx); for (i = 0; i < ARRAY_SIZE(sta->txq); i++) mt76_txq_remove(&dev->mt76, sta->txq[i]); mt76x02_mac_wcid_setup(&dev->mt76, idx, 0, NULL); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h index c53ea04e1618..afe592cc7aa9 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h @@ -96,7 +96,6 @@ struct mt76x0_tx_queue { * ...7e: group wcids * 7f: reserved */ -#define N_WCIDS 128 #define GROUP_WCID(idx) (254 - idx) struct mt76x0_eeprom_params; @@ -144,7 +143,6 @@ struct mt76x0_dev { u8 in_ep[__MT_EP_IN_MAX]; u16 in_max_packet; - unsigned long wcid_mask[DIV_ROUND_UP(N_WCIDS, BITS_PER_LONG)]; unsigned long vif_mask; struct delayed_work cal_work; @@ -153,9 +151,6 @@ struct mt76x0_dev { struct workqueue_struct *stat_wq; struct delayed_work stat_work; - struct mt76_wcid *mon_wcid; - struct mt76_wcid __rcu *wcid[N_WCIDS]; - spinlock_t mac_lock; const u16 *beacon_offsets; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c b/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c index fd2baa5cc92d..73ea6d3097f2 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c @@ -150,7 +150,7 @@ void mt76x0_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, struct ieee80211_vif *vif = info->control.vif; struct ieee80211_sta *sta = control->sta; struct mt76x02_sta *msta = NULL; - struct mt76_wcid *wcid = dev->mon_wcid; + struct mt76_wcid *wcid = &dev->mt76.global_wcid; struct mt76_txwi *txwi; int pkt_len = skb->len; int hw_q = skb2q(skb); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2.h b/drivers/net/wireless/mediatek/mt76/mt76x2.h index 63e88d9147a8..94c3f0cbee2a 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x2.h @@ -95,8 +95,6 @@ struct mt76x2_dev { struct mutex mutex; const u16 *beacon_offsets; - unsigned long wcid_mask[128 / BITS_PER_LONG]; - int txpower_conf; int txpower_cur; @@ -113,9 +111,6 @@ struct mt76x2_dev { u32 aggr_stats[32]; - struct mt76_wcid global_wcid; - struct mt76_wcid __rcu *wcid[128]; - spinlock_t irq_lock; u32 irqmask; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_common.c b/drivers/net/wireless/mediatek/mt76/mt76x2_common.c index 11ff60360ce6..b613eb760be5 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_common.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_common.c @@ -81,7 +81,7 @@ int mt76x2_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, mutex_lock(&dev->mt76.mutex); - idx = mt76_wcid_alloc(dev->wcid_mask, ARRAY_SIZE(dev->wcid)); + idx = mt76_wcid_alloc(dev->mt76.wcid_mask, ARRAY_SIZE(dev->mt76.wcid)); if (idx < 0) { ret = -ENOSPC; goto out; @@ -101,7 +101,7 @@ int mt76x2_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, ewma_signal_init(&msta->rssi); - rcu_assign_pointer(dev->wcid[idx], &msta->wcid); + rcu_assign_pointer(dev->mt76.wcid[idx], &msta->wcid); out: mutex_unlock(&dev->mt76.mutex); @@ -119,11 +119,11 @@ int mt76x2_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, int i; mutex_lock(&dev->mt76.mutex); - rcu_assign_pointer(dev->wcid[idx], NULL); + rcu_assign_pointer(dev->mt76.wcid[idx], NULL); for (i = 0; i < ARRAY_SIZE(sta->txq); i++) mt76_txq_remove(&dev->mt76, sta->txq[i]); mt76x02_mac_wcid_set_drop(&dev->mt76, idx, true); - mt76_wcid_free(dev->wcid_mask, idx); + mt76_wcid_free(dev->mt76.wcid_mask, idx); mt76x02_mac_wcid_setup(&dev->mt76, idx, 0, NULL); mutex_unlock(&dev->mt76.mutex); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_init_common.c b/drivers/net/wireless/mediatek/mt76/mt76x2_init_common.c index 9dca0e92e3f7..424d77a82f06 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_init_common.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_init_common.c @@ -213,8 +213,8 @@ void mt76x2_init_device(struct mt76x2_dev *dev) dev->mt76.sband_5g.sband.ht_cap.cap |= IEEE80211_HT_CAP_LDPC_CODING; dev->chainmask = 0x202; - dev->global_wcid.idx = 255; - dev->global_wcid.hw_key_idx = -1; + dev->mt76.global_wcid.idx = 255; + dev->mt76.global_wcid.hw_key_idx = -1; dev->slottime = 9; /* init antenna configuration */ diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mac_common.c b/drivers/net/wireless/mediatek/mt76/mt76x2_mac_common.c index bdad454108b9..ec2326cd724b 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_mac_common.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mac_common.c @@ -186,8 +186,8 @@ void mt76x2_send_tx_status(struct mt76x2_dev *dev, struct mt76x02_sta *msta = NULL; rcu_read_lock(); - if (stat->wcid < ARRAY_SIZE(dev->wcid)) - wcid = rcu_dereference(dev->wcid[stat->wcid]); + if (stat->wcid < ARRAY_SIZE(dev->mt76.wcid)) + wcid = rcu_dereference(dev->mt76.wcid[stat->wcid]); if (wcid) { void *priv; @@ -477,10 +477,10 @@ mt76x2_rx_get_sta(struct mt76x2_dev *dev, u8 idx) { struct mt76_wcid *wcid; - if (idx >= ARRAY_SIZE(dev->wcid)) + if (idx >= ARRAY_SIZE(dev->mt76.wcid)) return NULL; - wcid = rcu_dereference(dev->wcid[idx]); + wcid = rcu_dereference(dev->mt76.wcid[idx]); if (!wcid) return NULL; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_phy_common.c b/drivers/net/wireless/mediatek/mt76/mt76x2_phy_common.c index 4830ca20a32d..c38855342731 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_phy_common.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_phy_common.c @@ -311,8 +311,8 @@ int mt76x2_phy_get_min_avg_rssi(struct mt76x2_dev *dev) local_bh_disable(); rcu_read_lock(); - for (i = 0; i < ARRAY_SIZE(dev->wcid_mask); i++) { - unsigned long mask = dev->wcid_mask[i]; + for (i = 0; i < ARRAY_SIZE(dev->mt76.wcid_mask); i++) { + unsigned long mask = dev->mt76.wcid_mask[i]; if (!mask) continue; @@ -321,7 +321,7 @@ int mt76x2_phy_get_min_avg_rssi(struct mt76x2_dev *dev) if (!(mask & 1)) continue; - wcid = rcu_dereference(dev->wcid[j]); + wcid = rcu_dereference(dev->mt76.wcid[j]); if (!wcid) continue; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_tx_common.c b/drivers/net/wireless/mediatek/mt76/mt76x2_tx_common.c index d968f9ad6f50..b6c6d657b2b7 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_tx_common.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_tx_common.c @@ -24,7 +24,7 @@ void mt76x2_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct mt76x2_dev *dev = hw->priv; struct ieee80211_vif *vif = info->control.vif; - struct mt76_wcid *wcid = &dev->global_wcid; + struct mt76_wcid *wcid = &dev->mt76.global_wcid; if (control->sta) { struct mt76x02_sta *msta; From 624400e4cd254777b05415d35a3c7baa7d568820 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Tue, 4 Sep 2018 16:40:55 +0200 Subject: [PATCH 130/276] mt76: unify sta_add / sta_remove Merge mt76x0 and mt76x0 sta add/remove callback. We drop mt76x0_mac_set_ampdu_factor() for now. Need to consider to add it to common code, but mt76x2 don't do it so perhaps mt76x0 don't need it as well. Signed-off-by: Stanislaw Gruszka Signed-off-by: Felix Fietkau --- .../net/wireless/mediatek/mt76/mt76x0/main.c | 61 +----------------- .../net/wireless/mediatek/mt76/mt76x02_util.c | 63 +++++++++++++++++++ .../net/wireless/mediatek/mt76/mt76x02_util.h | 5 +- .../wireless/mediatek/mt76/mt76x2_common.c | 62 ------------------ .../net/wireless/mediatek/mt76/mt76x2_main.c | 4 +- .../net/wireless/mediatek/mt76/mt76x2u_main.c | 4 +- 6 files changed, 73 insertions(+), 126 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c index 78b40cb0fdbd..697ba18a7a36 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c @@ -155,63 +155,6 @@ mt76x0_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, mutex_unlock(&dev->mt76.mutex); } -static int -mt76x0_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - struct ieee80211_sta *sta) -{ - struct mt76x0_dev *dev = hw->priv; - struct mt76x02_sta *msta = (struct mt76x02_sta *) sta->drv_priv; - struct mt76x02_vif *mvif = (struct mt76x02_vif *) vif->drv_priv; - int ret = 0; - int idx = 0; - int i; - - mutex_lock(&dev->mt76.mutex); - - idx = mt76_wcid_alloc(dev->mt76.wcid_mask, ARRAY_SIZE(dev->mt76.wcid)); - if (idx < 0) { - ret = -ENOSPC; - goto out; - } - - msta->wcid.idx = idx; - msta->wcid.hw_key_idx = -1; - mt76x02_mac_wcid_setup(&dev->mt76, idx, mvif->idx, sta->addr); - mt76x02_mac_wcid_set_drop(&dev->mt76, idx, false); - mt76_clear(dev, MT_WCID_DROP(idx), MT_WCID_DROP_MASK(idx)); - rcu_assign_pointer(dev->mt76.wcid[idx], &msta->wcid); - for (i = 0; i < ARRAY_SIZE(sta->txq); i++) - mt76x02_txq_init(&dev->mt76, sta->txq[i]); - mt76x0_mac_set_ampdu_factor(dev); - -out: - mutex_unlock(&dev->mt76.mutex); - - return ret; -} - -static int -mt76x0_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - struct ieee80211_sta *sta) -{ - struct mt76x0_dev *dev = hw->priv; - struct mt76x02_sta *msta = (struct mt76x02_sta *) sta->drv_priv; - int idx = msta->wcid.idx; - int i; - - mutex_lock(&dev->mt76.mutex); - rcu_assign_pointer(dev->mt76.wcid[idx], NULL); - mt76x02_mac_wcid_set_drop(&dev->mt76, idx, true); - mt76_wcid_free(dev->mt76.wcid_mask, idx); - for (i = 0; i < ARRAY_SIZE(sta->txq); i++) - mt76_txq_remove(&dev->mt76, sta->txq[i]); - mt76x02_mac_wcid_setup(&dev->mt76, idx, 0, NULL); - mt76x0_mac_set_ampdu_factor(dev); - mutex_unlock(&dev->mt76.mutex); - - return 0; -} - static void mt76x0_sta_notify(struct ieee80211_hw *hw, struct ieee80211_vif *vif, enum sta_notify_cmd cmd, struct ieee80211_sta *sta) @@ -362,8 +305,8 @@ const struct ieee80211_ops mt76x0_ops = { .config = mt76x0_config, .configure_filter = mt76x02_configure_filter, .bss_info_changed = mt76x0_bss_info_changed, - .sta_add = mt76x0_sta_add, - .sta_remove = mt76x0_sta_remove, + .sta_add = mt76x02_sta_add, + .sta_remove = mt76x02_sta_remove, .sta_notify = mt76x0_sta_notify, .set_key = mt76x0_set_key, .conf_tx = mt76x0_conf_tx, diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c index 971e2d9f9ca3..07df1e979be5 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c @@ -17,6 +17,7 @@ #include "mt76.h" #include "mt76x02_regs.h" +#include "mt76x02_mac.h" void mt76x02_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags, @@ -52,4 +53,66 @@ void mt76x02_configure_filter(struct ieee80211_hw *hw, } EXPORT_SYMBOL_GPL(mt76x02_configure_filter); +int mt76x02_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_sta *sta) +{ + struct mt76_dev *dev = hw->priv; + struct mt76x02_sta *msta = (struct mt76x02_sta *) sta->drv_priv; + struct mt76x02_vif *mvif = (struct mt76x02_vif *) vif->drv_priv; + int ret = 0; + int idx = 0; + int i; + + mutex_lock(&dev->mutex); + + idx = mt76_wcid_alloc(dev->wcid_mask, ARRAY_SIZE(dev->wcid)); + if (idx < 0) { + ret = -ENOSPC; + goto out; + } + + msta->vif = mvif; + msta->wcid.sta = 1; + msta->wcid.idx = idx; + msta->wcid.hw_key_idx = -1; + mt76x02_mac_wcid_setup(dev, idx, mvif->idx, sta->addr); + mt76x02_mac_wcid_set_drop(dev, idx, false); + for (i = 0; i < ARRAY_SIZE(sta->txq); i++) + mt76x02_txq_init(dev, sta->txq[i]); + + if (vif->type == NL80211_IFTYPE_AP) + set_bit(MT_WCID_FLAG_CHECK_PS, &msta->wcid.flags); + + ewma_signal_init(&msta->rssi); + + rcu_assign_pointer(dev->wcid[idx], &msta->wcid); + +out: + mutex_unlock(&dev->mutex); + + return ret; +} +EXPORT_SYMBOL_GPL(mt76x02_sta_add); + +int mt76x02_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_sta *sta) +{ + struct mt76_dev *dev = hw->priv; + struct mt76x02_sta *msta = (struct mt76x02_sta *) sta->drv_priv; + int idx = msta->wcid.idx; + int i; + + mutex_lock(&dev->mutex); + rcu_assign_pointer(dev->wcid[idx], NULL); + for (i = 0; i < ARRAY_SIZE(sta->txq); i++) + mt76_txq_remove(dev, sta->txq[i]); + mt76x02_mac_wcid_set_drop(dev, idx, true); + mt76_wcid_free(dev->wcid_mask, idx); + mt76x02_mac_wcid_setup(dev, idx, 0, NULL); + mutex_unlock(&dev->mutex); + + return 0; +} +EXPORT_SYMBOL_GPL(mt76x02_sta_remove); + MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.h b/drivers/net/wireless/mediatek/mt76/mt76x02_util.h index 7ff3d473bc75..5d2acc685a35 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.h @@ -21,5 +21,8 @@ void mt76x02_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags, unsigned int *total_flags, u64 multicast); - +int mt76x02_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_sta *sta); +int mt76x02_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_sta *sta); #endif diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_common.c b/drivers/net/wireless/mediatek/mt76/mt76x2_common.c index b613eb760be5..5d5d2701aed8 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_common.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_common.c @@ -69,68 +69,6 @@ int mt76x2_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, } EXPORT_SYMBOL_GPL(mt76x2_ampdu_action); -int mt76x2_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - struct ieee80211_sta *sta) -{ - struct mt76x2_dev *dev = hw->priv; - struct mt76x02_sta *msta = (struct mt76x02_sta *) sta->drv_priv; - struct mt76x02_vif *mvif = (struct mt76x02_vif *) vif->drv_priv; - int ret = 0; - int idx = 0; - int i; - - mutex_lock(&dev->mt76.mutex); - - idx = mt76_wcid_alloc(dev->mt76.wcid_mask, ARRAY_SIZE(dev->mt76.wcid)); - if (idx < 0) { - ret = -ENOSPC; - goto out; - } - - msta->vif = mvif; - msta->wcid.sta = 1; - msta->wcid.idx = idx; - msta->wcid.hw_key_idx = -1; - mt76x02_mac_wcid_setup(&dev->mt76, idx, mvif->idx, sta->addr); - mt76x02_mac_wcid_set_drop(&dev->mt76, idx, false); - for (i = 0; i < ARRAY_SIZE(sta->txq); i++) - mt76x02_txq_init(&dev->mt76, sta->txq[i]); - - if (vif->type == NL80211_IFTYPE_AP) - set_bit(MT_WCID_FLAG_CHECK_PS, &msta->wcid.flags); - - ewma_signal_init(&msta->rssi); - - rcu_assign_pointer(dev->mt76.wcid[idx], &msta->wcid); - -out: - mutex_unlock(&dev->mt76.mutex); - - return ret; -} -EXPORT_SYMBOL_GPL(mt76x2_sta_add); - -int mt76x2_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - struct ieee80211_sta *sta) -{ - struct mt76x2_dev *dev = hw->priv; - struct mt76x02_sta *msta = (struct mt76x02_sta *) sta->drv_priv; - int idx = msta->wcid.idx; - int i; - - mutex_lock(&dev->mt76.mutex); - rcu_assign_pointer(dev->mt76.wcid[idx], NULL); - for (i = 0; i < ARRAY_SIZE(sta->txq); i++) - mt76_txq_remove(&dev->mt76, sta->txq[i]); - mt76x02_mac_wcid_set_drop(&dev->mt76, idx, true); - mt76_wcid_free(dev->mt76.wcid_mask, idx); - mt76x02_mac_wcid_setup(&dev->mt76, idx, 0, NULL); - mutex_unlock(&dev->mt76.mutex); - - return 0; -} -EXPORT_SYMBOL_GPL(mt76x2_sta_remove); - void mt76x2_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_main.c b/drivers/net/wireless/mediatek/mt76/mt76x2_main.c index f212f329cebe..9b1b3dfdd0dd 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_main.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_main.c @@ -323,8 +323,8 @@ const struct ieee80211_ops mt76x2_ops = { .config = mt76x2_config, .configure_filter = mt76x02_configure_filter, .bss_info_changed = mt76x2_bss_info_changed, - .sta_add = mt76x2_sta_add, - .sta_remove = mt76x2_sta_remove, + .sta_add = mt76x02_sta_add, + .sta_remove = mt76x02_sta_remove, .set_key = mt76x2_set_key, .conf_tx = mt76x2_conf_tx, .sw_scan_start = mt76x2_sw_scan, diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2u_main.c b/drivers/net/wireless/mediatek/mt76/mt76x2u_main.c index 1b6a04d202bb..6b110c695b4b 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2u_main.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2u_main.c @@ -171,8 +171,8 @@ const struct ieee80211_ops mt76x2u_ops = { .stop = mt76x2u_stop, .add_interface = mt76x2u_add_interface, .remove_interface = mt76x2_remove_interface, - .sta_add = mt76x2_sta_add, - .sta_remove = mt76x2_sta_remove, + .sta_add = mt76x02_sta_add, + .sta_remove = mt76x02_sta_remove, .set_key = mt76x2_set_key, .ampdu_action = mt76x2_ampdu_action, .config = mt76x2u_config, From cab12953ec1e7ab923213bcc07033d6c5615433c Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Tue, 4 Sep 2018 16:40:56 +0200 Subject: [PATCH 131/276] mt76: pratially unify add_interface Create common mt76x02_vif_init function and use int on drivers add_interface callback. Signed-off-by: Stanislaw Gruszka Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt76x0/main.c | 7 +------ drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h | 9 --------- drivers/net/wireless/mediatek/mt76/mt76x02_mac.h | 3 +++ drivers/net/wireless/mediatek/mt76/mt76x02_util.c | 12 ++++++++++++ drivers/net/wireless/mediatek/mt76/mt76x02_util.h | 3 +++ drivers/net/wireless/mediatek/mt76/mt76x2.h | 3 --- drivers/net/wireless/mediatek/mt76/mt76x2_main.c | 7 +------ drivers/net/wireless/mediatek/mt76/mt76x2u_main.c | 8 +------- 8 files changed, 21 insertions(+), 31 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c index 697ba18a7a36..1b0ddba96ea1 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c @@ -56,7 +56,6 @@ static int mt76x0_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { struct mt76x0_dev *dev = hw->priv; - struct mt76x02_vif *mvif = (struct mt76x02_vif *) vif->drv_priv; unsigned int idx; idx = ffs(~dev->vif_mask); @@ -66,11 +65,7 @@ static int mt76x0_add_interface(struct ieee80211_hw *hw, idx--; dev->vif_mask |= BIT(idx); - mvif->idx = idx; - mvif->group_wcid.idx = GROUP_WCID(idx); - mvif->group_wcid.hw_key_idx = -1; - mt76x02_txq_init(&dev->mt76, vif->txq); - + mt76x02_vif_init(&dev->mt76, vif, idx); return 0; } diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h index afe592cc7aa9..3fc2b6efeda3 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h @@ -89,15 +89,6 @@ struct mt76x0_tx_queue { unsigned int fifo_seq; }; -/* WCID allocation: - * 0: mcast wcid - * 1: bssid wcid - * 1...: STAs - * ...7e: group wcids - * 7f: reserved - */ -#define GROUP_WCID(idx) (254 - idx) - struct mt76x0_eeprom_params; #define MT_EE_TEMPERATURE_SLOPE 39 diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h index 6712bb1f9181..551970da9025 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h @@ -31,6 +31,9 @@ struct mt76x02_tx_status { u16 rate; } __packed __aligned(2); +#define MT_VIF_WCID(_n) (254 - ((_n) & 7)) +#define MT_MAX_VIFS 8 + struct mt76x02_vif { u8 idx; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c index 07df1e979be5..6660ecf58d0a 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c @@ -115,4 +115,16 @@ int mt76x02_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, } EXPORT_SYMBOL_GPL(mt76x02_sta_remove); +void mt76x02_vif_init(struct mt76_dev *dev, struct ieee80211_vif *vif, + unsigned int idx) +{ + struct mt76x02_vif *mvif = (struct mt76x02_vif *) vif->drv_priv; + + mvif->idx = idx; + mvif->group_wcid.idx = MT_VIF_WCID(idx); + mvif->group_wcid.hw_key_idx = -1; + mt76x02_txq_init(dev, vif->txq); +} +EXPORT_SYMBOL_GPL(mt76x02_vif_init); + MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.h b/drivers/net/wireless/mediatek/mt76/mt76x02_util.h index 5d2acc685a35..9ed4404930c6 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.h @@ -25,4 +25,7 @@ int mt76x02_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta); int mt76x02_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta); + +void mt76x02_vif_init(struct mt76_dev *dev, struct ieee80211_vif *vif, + unsigned int idx); #endif diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2.h b/drivers/net/wireless/mediatek/mt76/mt76x2.h index 94c3f0cbee2a..b5cf720612e6 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x2.h @@ -42,9 +42,6 @@ #define MT_CALIBRATE_INTERVAL HZ -#define MT_MAX_VIFS 8 -#define MT_VIF_WCID(_n) (254 - ((_n) & 7)) - #include "mt76.h" #include "mt76x02_regs.h" #include "mt76x2_mac.h" diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_main.c b/drivers/net/wireless/mediatek/mt76/mt76x2_main.c index 9b1b3dfdd0dd..870ee01fe409 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_main.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_main.c @@ -58,7 +58,6 @@ static int mt76x2_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { struct mt76x2_dev *dev = hw->priv; - struct mt76x02_vif *mvif = (struct mt76x02_vif *) vif->drv_priv; unsigned int idx = 0; if (vif->addr[0] & BIT(1)) @@ -80,11 +79,7 @@ mt76x2_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) if (vif->type == NL80211_IFTYPE_STATION) idx += 8; - mvif->idx = idx; - mvif->group_wcid.idx = MT_VIF_WCID(idx); - mvif->group_wcid.hw_key_idx = -1; - mt76x02_txq_init(&dev->mt76, vif->txq); - + mt76x02_vif_init(&dev->mt76, vif, idx); return 0; } diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2u_main.c b/drivers/net/wireless/mediatek/mt76/mt76x2u_main.c index 6b110c695b4b..49818e290ccd 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2u_main.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2u_main.c @@ -49,17 +49,11 @@ static int mt76x2u_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { struct mt76x2_dev *dev = hw->priv; - struct mt76x02_vif *mvif = (struct mt76x02_vif *)vif->drv_priv; - unsigned int idx = 0; if (!ether_addr_equal(dev->mt76.macaddr, vif->addr)) mt76x2u_mac_setaddr(dev, vif->addr); - mvif->idx = idx; - mvif->group_wcid.idx = MT_VIF_WCID(idx); - mvif->group_wcid.hw_key_idx = -1; - mt76x02_txq_init(&dev->mt76, vif->txq); - + mt76x02_vif_init(&dev->mt76, vif, 0); return 0; } From 22c575c4f1777fdcb718f1c610ed8d25ae5ce653 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Tue, 4 Sep 2018 16:40:58 +0200 Subject: [PATCH 132/276] mt76: unify ampdu_action Use mt76x2_ampdu_action as common function, mt76x0 ampdu_action was diffrent, but mt76x2 version should work for this driver as well. Signed-off-by: Stanislaw Gruszka Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt76.h | 3 ++ .../net/wireless/mediatek/mt76/mt76x0/main.c | 45 +--------------- .../net/wireless/mediatek/mt76/mt76x02_util.c | 50 ++++++++++++++++++ .../net/wireless/mediatek/mt76/mt76x02_util.h | 3 ++ drivers/net/wireless/mediatek/mt76/mt76x2.h | 2 - .../wireless/mediatek/mt76/mt76x2_common.c | 51 ------------------- .../net/wireless/mediatek/mt76/mt76x2_main.c | 2 +- .../net/wireless/mediatek/mt76/mt76x2u_main.c | 2 +- 8 files changed, 59 insertions(+), 99 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h index 2d0ab28a0977..cb9b9852f32f 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76.h +++ b/drivers/net/wireless/mediatek/mt76/mt76.h @@ -427,6 +427,9 @@ struct mt76_rx_status { #define __mt76_rmw(dev, ...) (dev)->bus->rmw((dev), __VA_ARGS__) #define __mt76_wr_copy(dev, ...) (dev)->bus->copy((dev), __VA_ARGS__) +#define __mt76_set(dev, offset, val) __mt76_rmw(dev, offset, 0, val) +#define __mt76_clear(dev, offset, val) __mt76_rmw(dev, offset, val, 0) + #define mt76_rr(dev, ...) (dev)->mt76.bus->rr(&((dev)->mt76), __VA_ARGS__) #define mt76_wr(dev, ...) (dev)->mt76.bus->wr(&((dev)->mt76), __VA_ARGS__) #define mt76_rmw(dev, ...) (dev)->mt76.bus->rmw(&((dev)->mt76), __VA_ARGS__) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c index 1b0ddba96ea1..d2e243785b67 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c @@ -225,49 +225,6 @@ static int mt76x0_set_rts_threshold(struct ieee80211_hw *hw, u32 value) return 0; } -static int -mt76_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - struct ieee80211_ampdu_params *params) -{ - struct mt76x0_dev *dev = hw->priv; - struct ieee80211_sta *sta = params->sta; - struct mt76x02_sta *msta = (struct mt76x02_sta *) sta->drv_priv; - enum ieee80211_ampdu_mlme_action action = params->action; - struct ieee80211_txq *txq = sta->txq[params->tid]; - u16 tid = params->tid; - u16 *ssn = ¶ms->ssn; - struct mt76_txq *mtxq; - - if (!txq) - return -EINVAL; - - mtxq = (struct mt76_txq *)txq->drv_priv; - - switch (action) { - case IEEE80211_AMPDU_RX_START: - mt76_set(dev, MT_WCID_ADDR(msta->wcid.idx) + 4, BIT(16 + tid)); - break; - case IEEE80211_AMPDU_RX_STOP: - mt76_clear(dev, MT_WCID_ADDR(msta->wcid.idx) + 4, BIT(16 + tid)); - break; - case IEEE80211_AMPDU_TX_OPERATIONAL: - ieee80211_send_bar(vif, sta->addr, tid, mtxq->agg_ssn); - break; - case IEEE80211_AMPDU_TX_STOP_FLUSH: - case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: - break; - case IEEE80211_AMPDU_TX_START: - mtxq->agg_ssn = *ssn << 4; - ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); - break; - case IEEE80211_AMPDU_TX_STOP_CONT: - ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); - break; - } - - return 0; -} - static void mt76_sta_rate_tbl_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta) @@ -307,7 +264,7 @@ const struct ieee80211_ops mt76x0_ops = { .conf_tx = mt76x0_conf_tx, .sw_scan_start = mt76x0_sw_scan, .sw_scan_complete = mt76x0_sw_scan_complete, - .ampdu_action = mt76_ampdu_action, + .ampdu_action = mt76x02_ampdu_action, .sta_rate_tbl_update = mt76_sta_rate_tbl_update, .set_rts_threshold = mt76x0_set_rts_threshold, }; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c index 6660ecf58d0a..b3225024ac72 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c @@ -127,4 +127,54 @@ void mt76x02_vif_init(struct mt76_dev *dev, struct ieee80211_vif *vif, } EXPORT_SYMBOL_GPL(mt76x02_vif_init); +int mt76x02_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_ampdu_params *params) +{ + enum ieee80211_ampdu_mlme_action action = params->action; + struct ieee80211_sta *sta = params->sta; + struct mt76_dev *dev = hw->priv; + struct mt76x02_sta *msta = (struct mt76x02_sta *) sta->drv_priv; + struct ieee80211_txq *txq = sta->txq[params->tid]; + u16 tid = params->tid; + u16 *ssn = ¶ms->ssn; + struct mt76_txq *mtxq; + + if (!txq) + return -EINVAL; + + mtxq = (struct mt76_txq *)txq->drv_priv; + + switch (action) { + case IEEE80211_AMPDU_RX_START: + mt76_rx_aggr_start(dev, &msta->wcid, tid, *ssn, params->buf_size); + __mt76_set(dev, MT_WCID_ADDR(msta->wcid.idx) + 4, BIT(16 + tid)); + break; + case IEEE80211_AMPDU_RX_STOP: + mt76_rx_aggr_stop(dev, &msta->wcid, tid); + __mt76_clear(dev, MT_WCID_ADDR(msta->wcid.idx) + 4, BIT(16 + tid)); + break; + case IEEE80211_AMPDU_TX_OPERATIONAL: + mtxq->aggr = true; + mtxq->send_bar = false; + ieee80211_send_bar(vif, sta->addr, tid, mtxq->agg_ssn); + break; + case IEEE80211_AMPDU_TX_STOP_FLUSH: + case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: + mtxq->aggr = false; + ieee80211_send_bar(vif, sta->addr, tid, mtxq->agg_ssn); + break; + case IEEE80211_AMPDU_TX_START: + mtxq->agg_ssn = *ssn << 4; + ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); + break; + case IEEE80211_AMPDU_TX_STOP_CONT: + mtxq->aggr = false; + ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); + break; + } + + return 0; +} +EXPORT_SYMBOL_GPL(mt76x02_ampdu_action); + MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.h b/drivers/net/wireless/mediatek/mt76/mt76x02_util.h index 9ed4404930c6..245e32738eeb 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.h @@ -28,4 +28,7 @@ int mt76x02_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, void mt76x02_vif_init(struct mt76_dev *dev, struct ieee80211_vif *vif, unsigned int idx); + +int mt76x02_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_ampdu_params *params); #endif diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2.h b/drivers/net/wireless/mediatek/mt76/mt76x2.h index b5cf720612e6..b1fdf2825ad7 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x2.h @@ -250,8 +250,6 @@ void mt76x2_init_txpower(struct mt76x2_dev *dev, struct ieee80211_supported_band *sband); void mt76_write_mac_initvals(struct mt76x2_dev *dev); -int mt76x2_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - struct ieee80211_ampdu_params *params); int mt76x2_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta); int mt76x2_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_common.c b/drivers/net/wireless/mediatek/mt76/mt76x2_common.c index 5d5d2701aed8..c458781a70aa 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_common.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_common.c @@ -18,57 +18,6 @@ #include "mt76x2.h" #include "mt76x02_mac.h" -int mt76x2_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - struct ieee80211_ampdu_params *params) -{ - enum ieee80211_ampdu_mlme_action action = params->action; - struct ieee80211_sta *sta = params->sta; - struct mt76x2_dev *dev = hw->priv; - struct mt76x02_sta *msta = (struct mt76x02_sta *) sta->drv_priv; - struct ieee80211_txq *txq = sta->txq[params->tid]; - u16 tid = params->tid; - u16 *ssn = ¶ms->ssn; - struct mt76_txq *mtxq; - - if (!txq) - return -EINVAL; - - mtxq = (struct mt76_txq *)txq->drv_priv; - - switch (action) { - case IEEE80211_AMPDU_RX_START: - mt76_rx_aggr_start(&dev->mt76, &msta->wcid, tid, *ssn, params->buf_size); - mt76_set(dev, MT_WCID_ADDR(msta->wcid.idx) + 4, BIT(16 + tid)); - break; - case IEEE80211_AMPDU_RX_STOP: - mt76_rx_aggr_stop(&dev->mt76, &msta->wcid, tid); - mt76_clear(dev, MT_WCID_ADDR(msta->wcid.idx) + 4, - BIT(16 + tid)); - break; - case IEEE80211_AMPDU_TX_OPERATIONAL: - mtxq->aggr = true; - mtxq->send_bar = false; - ieee80211_send_bar(vif, sta->addr, tid, mtxq->agg_ssn); - break; - case IEEE80211_AMPDU_TX_STOP_FLUSH: - case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: - mtxq->aggr = false; - ieee80211_send_bar(vif, sta->addr, tid, mtxq->agg_ssn); - break; - case IEEE80211_AMPDU_TX_START: - mtxq->agg_ssn = *ssn << 4; - ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); - break; - case IEEE80211_AMPDU_TX_STOP_CONT: - mtxq->aggr = false; - ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); - break; - } - - return 0; -} -EXPORT_SYMBOL_GPL(mt76x2_ampdu_action); - void mt76x2_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_main.c b/drivers/net/wireless/mediatek/mt76/mt76x2_main.c index 870ee01fe409..137bd73c473a 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_main.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_main.c @@ -325,7 +325,7 @@ const struct ieee80211_ops mt76x2_ops = { .sw_scan_start = mt76x2_sw_scan, .sw_scan_complete = mt76x2_sw_scan_complete, .flush = mt76x2_flush, - .ampdu_action = mt76x2_ampdu_action, + .ampdu_action = mt76x02_ampdu_action, .get_txpower = mt76x2_get_txpower, .wake_tx_queue = mt76_wake_tx_queue, .sta_rate_tbl_update = mt76x2_sta_rate_tbl_update, diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2u_main.c b/drivers/net/wireless/mediatek/mt76/mt76x2u_main.c index 49818e290ccd..b358ee46a4a3 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2u_main.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2u_main.c @@ -168,7 +168,7 @@ const struct ieee80211_ops mt76x2u_ops = { .sta_add = mt76x02_sta_add, .sta_remove = mt76x02_sta_remove, .set_key = mt76x2_set_key, - .ampdu_action = mt76x2_ampdu_action, + .ampdu_action = mt76x02_ampdu_action, .config = mt76x2u_config, .wake_tx_queue = mt76_wake_tx_queue, .bss_info_changed = mt76x2u_bss_info_changed, From 60c26859e863c1b83757759176517453599db500 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Tue, 4 Sep 2018 16:40:59 +0200 Subject: [PATCH 133/276] mt76: unify set_key Merge mt76x0 and mt76x2 set_key mac80211 callback. Signed-off-by: Stanislaw Gruszka Signed-off-by: Felix Fietkau --- .../net/wireless/mediatek/mt76/mt76x0/main.c | 37 +--------- .../net/wireless/mediatek/mt76/mt76x02_util.c | 67 +++++++++++++++++++ .../net/wireless/mediatek/mt76/mt76x02_util.h | 4 ++ drivers/net/wireless/mediatek/mt76/mt76x2.h | 3 - .../wireless/mediatek/mt76/mt76x2_common.c | 67 ------------------- .../net/wireless/mediatek/mt76/mt76x2_main.c | 2 +- .../net/wireless/mediatek/mt76/mt76x2u_main.c | 2 +- 7 files changed, 74 insertions(+), 108 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c index d2e243785b67..f58c7ee332e0 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c @@ -181,41 +181,6 @@ mt76x0_sw_scan_complete(struct ieee80211_hw *hw, MT_CALIBRATE_INTERVAL); } -static int -mt76x0_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, - struct ieee80211_vif *vif, struct ieee80211_sta *sta, - struct ieee80211_key_conf *key) -{ - struct mt76x0_dev *dev = hw->priv; - struct mt76x02_vif *mvif = (struct mt76x02_vif *) vif->drv_priv; - struct mt76x02_sta *msta = sta ? (struct mt76x02_sta *) sta->drv_priv : NULL; - struct mt76_wcid *wcid = msta ? &msta->wcid : &mvif->group_wcid; - int idx = key->keyidx; - int ret; - - if (cmd == SET_KEY) { - key->hw_key_idx = wcid->idx; - wcid->hw_key_idx = idx; - } else { - if (idx == wcid->hw_key_idx) - wcid->hw_key_idx = -1; - - key = NULL; - } - - if (!msta) { - if (key || wcid->hw_key_idx == idx) { - ret = mt76x02_mac_wcid_set_key(&dev->mt76, wcid->idx, key); - if (ret) - return ret; - } - - return mt76x02_mac_shared_key_setup(&dev->mt76, mvif->idx, idx, key); - } - - return mt76x02_mac_wcid_set_key(&dev->mt76, msta->wcid.idx, key); -} - static int mt76x0_set_rts_threshold(struct ieee80211_hw *hw, u32 value) { struct mt76x0_dev *dev = hw->priv; @@ -260,7 +225,7 @@ const struct ieee80211_ops mt76x0_ops = { .sta_add = mt76x02_sta_add, .sta_remove = mt76x02_sta_remove, .sta_notify = mt76x0_sta_notify, - .set_key = mt76x0_set_key, + .set_key = mt76x02_set_key, .conf_tx = mt76x0_conf_tx, .sw_scan_start = mt76x0_sw_scan, .sw_scan_complete = mt76x0_sw_scan_complete, diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c index b3225024ac72..4375fce0606d 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c @@ -177,4 +177,71 @@ int mt76x02_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, } EXPORT_SYMBOL_GPL(mt76x02_ampdu_action); +int mt76x02_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, + struct ieee80211_vif *vif, struct ieee80211_sta *sta, + struct ieee80211_key_conf *key) +{ + struct mt76_dev *dev = hw->priv; + struct mt76x02_vif *mvif = (struct mt76x02_vif *) vif->drv_priv; + struct mt76x02_sta *msta; + struct mt76_wcid *wcid; + int idx = key->keyidx; + int ret; + + /* fall back to sw encryption for unsupported ciphers */ + switch (key->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + case WLAN_CIPHER_SUITE_TKIP: + case WLAN_CIPHER_SUITE_CCMP: + break; + default: + return -EOPNOTSUPP; + } + + /* + * The hardware does not support per-STA RX GTK, fall back + * to software mode for these. + */ + if ((vif->type == NL80211_IFTYPE_ADHOC || + vif->type == NL80211_IFTYPE_MESH_POINT) && + (key->cipher == WLAN_CIPHER_SUITE_TKIP || + key->cipher == WLAN_CIPHER_SUITE_CCMP) && + !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) + return -EOPNOTSUPP; + + msta = sta ? (struct mt76x02_sta *) sta->drv_priv : NULL; + wcid = msta ? &msta->wcid : &mvif->group_wcid; + + if (cmd == SET_KEY) { + key->hw_key_idx = wcid->idx; + wcid->hw_key_idx = idx; + if (key->flags & IEEE80211_KEY_FLAG_RX_MGMT) { + key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX; + wcid->sw_iv = true; + } + } else { + if (idx == wcid->hw_key_idx) { + wcid->hw_key_idx = -1; + wcid->sw_iv = true; + } + + key = NULL; + } + mt76_wcid_key_setup(dev, wcid, key); + + if (!msta) { + if (key || wcid->hw_key_idx == idx) { + ret = mt76x02_mac_wcid_set_key(dev, wcid->idx, key); + if (ret) + return ret; + } + + return mt76x02_mac_shared_key_setup(dev, mvif->idx, idx, key); + } + + return mt76x02_mac_wcid_set_key(dev, msta->wcid.idx, key); +} +EXPORT_SYMBOL_GPL(mt76x02_set_key); + MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.h b/drivers/net/wireless/mediatek/mt76/mt76x02_util.h index 245e32738eeb..31f144d7f6d5 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.h @@ -31,4 +31,8 @@ void mt76x02_vif_init(struct mt76_dev *dev, struct ieee80211_vif *vif, int mt76x02_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_ampdu_params *params); + +int mt76x02_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, + struct ieee80211_vif *vif, struct ieee80211_sta *sta, + struct ieee80211_key_conf *key); #endif diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2.h b/drivers/net/wireless/mediatek/mt76/mt76x2.h index b1fdf2825ad7..ada01186d3c3 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x2.h @@ -256,9 +256,6 @@ int mt76x2_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta); void mt76x2_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif); -int mt76x2_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, - struct ieee80211_vif *vif, struct ieee80211_sta *sta, - struct ieee80211_key_conf *key); int mt76x2_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u16 queue, const struct ieee80211_tx_queue_params *params); void mt76x2_txq_init(struct mt76x2_dev *dev, struct ieee80211_txq *txq); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_common.c b/drivers/net/wireless/mediatek/mt76/mt76x2_common.c index c458781a70aa..7f05aebf67ec 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_common.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_common.c @@ -27,73 +27,6 @@ void mt76x2_remove_interface(struct ieee80211_hw *hw, } EXPORT_SYMBOL_GPL(mt76x2_remove_interface); -int mt76x2_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, - struct ieee80211_vif *vif, struct ieee80211_sta *sta, - struct ieee80211_key_conf *key) -{ - struct mt76x2_dev *dev = hw->priv; - struct mt76x02_vif *mvif = (struct mt76x02_vif *) vif->drv_priv; - struct mt76x02_sta *msta; - struct mt76_wcid *wcid; - int idx = key->keyidx; - int ret; - - /* fall back to sw encryption for unsupported ciphers */ - switch (key->cipher) { - case WLAN_CIPHER_SUITE_WEP40: - case WLAN_CIPHER_SUITE_WEP104: - case WLAN_CIPHER_SUITE_TKIP: - case WLAN_CIPHER_SUITE_CCMP: - break; - default: - return -EOPNOTSUPP; - } - - /* - * The hardware does not support per-STA RX GTK, fall back - * to software mode for these. - */ - if ((vif->type == NL80211_IFTYPE_ADHOC || - vif->type == NL80211_IFTYPE_MESH_POINT) && - (key->cipher == WLAN_CIPHER_SUITE_TKIP || - key->cipher == WLAN_CIPHER_SUITE_CCMP) && - !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) - return -EOPNOTSUPP; - - msta = sta ? (struct mt76x02_sta *) sta->drv_priv : NULL; - wcid = msta ? &msta->wcid : &mvif->group_wcid; - - if (cmd == SET_KEY) { - key->hw_key_idx = wcid->idx; - wcid->hw_key_idx = idx; - if (key->flags & IEEE80211_KEY_FLAG_RX_MGMT) { - key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX; - wcid->sw_iv = true; - } - } else { - if (idx == wcid->hw_key_idx) { - wcid->hw_key_idx = -1; - wcid->sw_iv = true; - } - - key = NULL; - } - mt76_wcid_key_setup(&dev->mt76, wcid, key); - - if (!msta) { - if (key || wcid->hw_key_idx == idx) { - ret = mt76x02_mac_wcid_set_key(&dev->mt76, wcid->idx, key); - if (ret) - return ret; - } - - return mt76x02_mac_shared_key_setup(&dev->mt76, mvif->idx, idx, key); - } - - return mt76x02_mac_wcid_set_key(&dev->mt76, msta->wcid.idx, key); -} -EXPORT_SYMBOL_GPL(mt76x2_set_key); - int mt76x2_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u16 queue, const struct ieee80211_tx_queue_params *params) { diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_main.c b/drivers/net/wireless/mediatek/mt76/mt76x2_main.c index 137bd73c473a..143d8abed403 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_main.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_main.c @@ -320,7 +320,7 @@ const struct ieee80211_ops mt76x2_ops = { .bss_info_changed = mt76x2_bss_info_changed, .sta_add = mt76x02_sta_add, .sta_remove = mt76x02_sta_remove, - .set_key = mt76x2_set_key, + .set_key = mt76x02_set_key, .conf_tx = mt76x2_conf_tx, .sw_scan_start = mt76x2_sw_scan, .sw_scan_complete = mt76x2_sw_scan_complete, diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2u_main.c b/drivers/net/wireless/mediatek/mt76/mt76x2u_main.c index b358ee46a4a3..62d0eb75cac3 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2u_main.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2u_main.c @@ -167,7 +167,7 @@ const struct ieee80211_ops mt76x2u_ops = { .remove_interface = mt76x2_remove_interface, .sta_add = mt76x02_sta_add, .sta_remove = mt76x02_sta_remove, - .set_key = mt76x2_set_key, + .set_key = mt76x02_set_key, .ampdu_action = mt76x02_ampdu_action, .config = mt76x2u_config, .wake_tx_queue = mt76_wake_tx_queue, From 436d9586afddfdfc619ae1db80288768b18d66b3 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Tue, 4 Sep 2018 16:41:00 +0200 Subject: [PATCH 134/276] mt76x0: remove empty sta_notify Remove empty implementation of sta_notify. Signed-off-by: Stanislaw Gruszka Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt76x0/main.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c index f58c7ee332e0..24fe92febe50 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c @@ -150,12 +150,6 @@ mt76x0_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, mutex_unlock(&dev->mt76.mutex); } -static void -mt76x0_sta_notify(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - enum sta_notify_cmd cmd, struct ieee80211_sta *sta) -{ -} - static void mt76x0_sw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, @@ -224,7 +218,6 @@ const struct ieee80211_ops mt76x0_ops = { .bss_info_changed = mt76x0_bss_info_changed, .sta_add = mt76x02_sta_add, .sta_remove = mt76x02_sta_remove, - .sta_notify = mt76x0_sta_notify, .set_key = mt76x02_set_key, .conf_tx = mt76x0_conf_tx, .sw_scan_start = mt76x0_sw_scan, From 1d0496c63f8d299b23ed35eef276bde37957c402 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Tue, 4 Sep 2018 16:41:01 +0200 Subject: [PATCH 135/276] mt76: unify AC to hw queue mapping Use the same AC to hardware queue mappings for all subdrivers. Note: this change BK and BE mappings for USB drivers. Signed-off-by: Stanislaw Gruszka Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt76.h | 8 +------- drivers/net/wireless/mediatek/mt76/mt76x0/tx.c | 4 ++-- drivers/net/wireless/mediatek/mt76/mt76x2_dma.c | 10 ++-------- drivers/net/wireless/mediatek/mt76/tx.c | 16 ++++++++++++++++ drivers/net/wireless/mediatek/mt76/usb.c | 2 +- 5 files changed, 22 insertions(+), 18 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h index cb9b9852f32f..7a7d13b16508 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76.h +++ b/drivers/net/wireless/mediatek/mt76/mt76.h @@ -519,13 +519,7 @@ static inline int mt76_decr(int val, int size) return (val - 1) & (size - 1); } -/* Hardware uses mirrored order of queues with Q3 - * having the highest priority - */ -static inline u8 q2hwq(u8 q) -{ - return q ^ 0x3; -} +u8 mt76_ac_to_hwq(u8 ac); static inline struct ieee80211_txq * mtxq_to_txq(struct mt76_txq *mtxq) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c b/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c index 73ea6d3097f2..acf830bc9b4e 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c @@ -25,7 +25,7 @@ static u8 skb2q(struct sk_buff *skb) skb_set_queue_mapping(skb, qid); } - return q2hwq(qid); + return mt76_ac_to_hwq(qid); } static void mt76x0_tx_skb_remove_dma_overhead(struct sk_buff *skb, @@ -216,7 +216,7 @@ int mt76x0_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u16 queue, const struct ieee80211_tx_queue_params *params) { struct mt76x0_dev *dev = hw->priv; - u8 cw_min = 5, cw_max = 10, hw_q = q2hwq(queue); + u8 cw_min = 5, cw_max = 10, hw_q = mt76_ac_to_hwq(queue); u32 val; /* TODO: should we do funny things with the parameters? diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_dma.c b/drivers/net/wireless/mediatek/mt76/mt76x2_dma.c index 6720a6a1313f..1c8e5d7be425 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_dma.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_dma.c @@ -102,12 +102,6 @@ mt76x2_tx_tasklet(unsigned long data) int mt76x2_dma_init(struct mt76x2_dev *dev) { - static const u8 wmm_queue_map[] = { - [IEEE80211_AC_BE] = 0, - [IEEE80211_AC_BK] = 1, - [IEEE80211_AC_VI] = 2, - [IEEE80211_AC_VO] = 3, - }; int ret; int i; struct mt76_txwi_cache __maybe_unused *t; @@ -125,9 +119,9 @@ int mt76x2_dma_init(struct mt76x2_dev *dev) mt76_wr(dev, MT_WPDMA_RST_IDX, ~0); - for (i = 0; i < ARRAY_SIZE(wmm_queue_map); i++) { + for (i = 0; i < IEEE80211_NUM_ACS; i++) { ret = mt76x2_init_tx_queue(dev, &dev->mt76.q_tx[i], - wmm_queue_map[i], MT_TX_RING_SIZE); + mt76_ac_to_hwq(i), MT_TX_RING_SIZE); if (ret) return ret; } diff --git a/drivers/net/wireless/mediatek/mt76/tx.c b/drivers/net/wireless/mediatek/mt76/tx.c index af48d43bb7dc..cf79b8c67b52 100644 --- a/drivers/net/wireless/mediatek/mt76/tx.c +++ b/drivers/net/wireless/mediatek/mt76/tx.c @@ -442,3 +442,19 @@ void mt76_txq_init(struct mt76_dev *dev, struct ieee80211_txq *txq) mtxq->hwq = &dev->q_tx[mt76_txq_get_qid(txq)]; } EXPORT_SYMBOL_GPL(mt76_txq_init); + +u8 mt76_ac_to_hwq(u8 ac) +{ + static const u8 wmm_queue_map[] = { + [IEEE80211_AC_BE] = 0, + [IEEE80211_AC_BK] = 1, + [IEEE80211_AC_VI] = 2, + [IEEE80211_AC_VO] = 3, + }; + + if (WARN_ON(ac >= IEEE80211_NUM_ACS)) + return 0; + + return wmm_queue_map[ac]; +} +EXPORT_SYMBOL_GPL(mt76_ac_to_hwq); diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c index 7780b07543bb..333b2c8ca7a4 100644 --- a/drivers/net/wireless/mediatek/mt76/usb.c +++ b/drivers/net/wireless/mediatek/mt76/usb.c @@ -715,7 +715,7 @@ static int mt76u_alloc_tx(struct mt76_dev *dev) q = &dev->q_tx[i]; spin_lock_init(&q->lock); INIT_LIST_HEAD(&q->swq); - q->hw_idx = q2hwq(i); + q->hw_idx = mt76_ac_to_hwq(i); q->entry = devm_kzalloc(dev->dev, MT_NUM_TX_ENTRIES * sizeof(*q->entry), From 10337263dcfa697dbfa7fa4bc8e0d06d7e0236e7 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Tue, 4 Sep 2018 16:41:03 +0200 Subject: [PATCH 136/276] mt76: unify conf_tx Use one conf_tx implementation in mt76x0 and mt76x2. Note this change conf_tx for mt76x0, but it should work with mt76x2 version. Signed-off-by: Stanislaw Gruszka Signed-off-by: Felix Fietkau --- .../net/wireless/mediatek/mt76/mt76x0/main.c | 2 +- .../wireless/mediatek/mt76/mt76x0/mt76x0.h | 2 - .../net/wireless/mediatek/mt76/mt76x0/tx.c | 57 ------------------- .../net/wireless/mediatek/mt76/mt76x02_util.c | 44 ++++++++++++++ .../net/wireless/mediatek/mt76/mt76x02_util.h | 3 +- .../wireless/mediatek/mt76/mt76x2_common.c | 44 -------------- .../net/wireless/mediatek/mt76/mt76x2_main.c | 2 +- .../net/wireless/mediatek/mt76/mt76x2u_main.c | 2 +- 8 files changed, 49 insertions(+), 107 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c index 24fe92febe50..f87103aea868 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c @@ -219,7 +219,7 @@ const struct ieee80211_ops mt76x0_ops = { .sta_add = mt76x02_sta_add, .sta_remove = mt76x02_sta_remove, .set_key = mt76x02_set_key, - .conf_tx = mt76x0_conf_tx, + .conf_tx = mt76x02_conf_tx, .sw_scan_start = mt76x0_sw_scan, .sw_scan_complete = mt76x0_sw_scan_complete, .ampdu_action = mt76x02_ampdu_action, diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h index 3fc2b6efeda3..e65e6c09877c 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h @@ -246,8 +246,6 @@ void mt76x0_mac_set_ampdu_factor(struct mt76x0_dev *dev); /* TX */ void mt76x0_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, struct sk_buff *skb); -int mt76x0_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - u16 queue, const struct ieee80211_tx_queue_params *params); void mt76x0_tx_status(struct mt76x0_dev *dev, struct sk_buff *skb); void mt76x0_tx_stat(struct work_struct *work); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c b/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c index acf830bc9b4e..ce80763ec557 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c @@ -211,60 +211,3 @@ void mt76x0_tx_stat(struct work_struct *work) clear_bit(MT76_READING_STATS, &dev->mt76.state); spin_unlock_irqrestore(&dev->tx_lock, flags); } - -int mt76x0_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - u16 queue, const struct ieee80211_tx_queue_params *params) -{ - struct mt76x0_dev *dev = hw->priv; - u8 cw_min = 5, cw_max = 10, hw_q = mt76_ac_to_hwq(queue); - u32 val; - - /* TODO: should we do funny things with the parameters? - * See what mt76x0_set_default_edca() used to do in init.c. - */ - - if (params->cw_min) - cw_min = fls(params->cw_min); - if (params->cw_max) - cw_max = fls(params->cw_max); - - WARN_ON(params->txop > 0xff); - WARN_ON(params->aifs > 0xf); - WARN_ON(cw_min > 0xf); - WARN_ON(cw_max > 0xf); - - val = FIELD_PREP(MT_EDCA_CFG_AIFSN, params->aifs) | - FIELD_PREP(MT_EDCA_CFG_CWMIN, cw_min) | - FIELD_PREP(MT_EDCA_CFG_CWMAX, cw_max); - /* TODO: based on user-controlled EnableTxBurst var vendor drv sets - * a really long txop on AC0 (see connect.c:2009) but only on - * connect? When not connected should be 0. - */ - if (!hw_q) - val |= 0x60; - else - val |= FIELD_PREP(MT_EDCA_CFG_TXOP, params->txop); - mt76_wr(dev, MT_EDCA_CFG_AC(hw_q), val); - - val = mt76_rr(dev, MT_WMM_TXOP(hw_q)); - val &= ~(MT_WMM_TXOP_MASK << MT_WMM_TXOP_SHIFT(hw_q)); - val |= params->txop << MT_WMM_TXOP_SHIFT(hw_q); - mt76_wr(dev, MT_WMM_TXOP(hw_q), val); - - val = mt76_rr(dev, MT_WMM_AIFSN); - val &= ~(MT_WMM_AIFSN_MASK << MT_WMM_AIFSN_SHIFT(hw_q)); - val |= params->aifs << MT_WMM_AIFSN_SHIFT(hw_q); - mt76_wr(dev, MT_WMM_AIFSN, val); - - val = mt76_rr(dev, MT_WMM_CWMIN); - val &= ~(MT_WMM_CWMIN_MASK << MT_WMM_CWMIN_SHIFT(hw_q)); - val |= cw_min << MT_WMM_CWMIN_SHIFT(hw_q); - mt76_wr(dev, MT_WMM_CWMIN, val); - - val = mt76_rr(dev, MT_WMM_CWMAX); - val &= ~(MT_WMM_CWMAX_MASK << MT_WMM_CWMAX_SHIFT(hw_q)); - val |= cw_max << MT_WMM_CWMAX_SHIFT(hw_q); - mt76_wr(dev, MT_WMM_CWMAX, val); - - return 0; -} diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c index 4375fce0606d..140e43817a39 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c @@ -244,4 +244,48 @@ int mt76x02_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, } EXPORT_SYMBOL_GPL(mt76x02_set_key); +int mt76x02_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + u16 queue, const struct ieee80211_tx_queue_params *params) +{ + struct mt76_dev *dev = hw->priv; + u8 cw_min = 5, cw_max = 10, qid; + u32 val; + + qid = dev->q_tx[queue].hw_idx; + + if (params->cw_min) + cw_min = fls(params->cw_min); + if (params->cw_max) + cw_max = fls(params->cw_max); + + val = FIELD_PREP(MT_EDCA_CFG_TXOP, params->txop) | + FIELD_PREP(MT_EDCA_CFG_AIFSN, params->aifs) | + FIELD_PREP(MT_EDCA_CFG_CWMIN, cw_min) | + FIELD_PREP(MT_EDCA_CFG_CWMAX, cw_max); + __mt76_wr(dev, MT_EDCA_CFG_AC(qid), val); + + val = __mt76_rr(dev, MT_WMM_TXOP(qid)); + val &= ~(MT_WMM_TXOP_MASK << MT_WMM_TXOP_SHIFT(qid)); + val |= params->txop << MT_WMM_TXOP_SHIFT(qid); + __mt76_wr(dev, MT_WMM_TXOP(qid), val); + + val = __mt76_rr(dev, MT_WMM_AIFSN); + val &= ~(MT_WMM_AIFSN_MASK << MT_WMM_AIFSN_SHIFT(qid)); + val |= params->aifs << MT_WMM_AIFSN_SHIFT(qid); + __mt76_wr(dev, MT_WMM_AIFSN, val); + + val = __mt76_rr(dev, MT_WMM_CWMIN); + val &= ~(MT_WMM_CWMIN_MASK << MT_WMM_CWMIN_SHIFT(qid)); + val |= cw_min << MT_WMM_CWMIN_SHIFT(qid); + __mt76_wr(dev, MT_WMM_CWMIN, val); + + val = __mt76_rr(dev, MT_WMM_CWMAX); + val &= ~(MT_WMM_CWMAX_MASK << MT_WMM_CWMAX_SHIFT(qid)); + val |= cw_max << MT_WMM_CWMAX_SHIFT(qid); + __mt76_wr(dev, MT_WMM_CWMAX, val); + + return 0; +} +EXPORT_SYMBOL_GPL(mt76x02_conf_tx); + MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.h b/drivers/net/wireless/mediatek/mt76/mt76x02_util.h index 31f144d7f6d5..54f895d8cdbe 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.h @@ -31,8 +31,9 @@ void mt76x02_vif_init(struct mt76_dev *dev, struct ieee80211_vif *vif, int mt76x02_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_ampdu_params *params); - int mt76x02_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, struct ieee80211_vif *vif, struct ieee80211_sta *sta, struct ieee80211_key_conf *key); +int mt76x02_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + u16 queue, const struct ieee80211_tx_queue_params *params); #endif diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_common.c b/drivers/net/wireless/mediatek/mt76/mt76x2_common.c index 7f05aebf67ec..5ce9fbc654a2 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_common.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_common.c @@ -27,50 +27,6 @@ void mt76x2_remove_interface(struct ieee80211_hw *hw, } EXPORT_SYMBOL_GPL(mt76x2_remove_interface); -int mt76x2_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - u16 queue, const struct ieee80211_tx_queue_params *params) -{ - struct mt76x2_dev *dev = hw->priv; - u8 cw_min = 5, cw_max = 10, qid; - u32 val; - - qid = dev->mt76.q_tx[queue].hw_idx; - - if (params->cw_min) - cw_min = fls(params->cw_min); - if (params->cw_max) - cw_max = fls(params->cw_max); - - val = FIELD_PREP(MT_EDCA_CFG_TXOP, params->txop) | - FIELD_PREP(MT_EDCA_CFG_AIFSN, params->aifs) | - FIELD_PREP(MT_EDCA_CFG_CWMIN, cw_min) | - FIELD_PREP(MT_EDCA_CFG_CWMAX, cw_max); - mt76_wr(dev, MT_EDCA_CFG_AC(qid), val); - - val = mt76_rr(dev, MT_WMM_TXOP(qid)); - val &= ~(MT_WMM_TXOP_MASK << MT_WMM_TXOP_SHIFT(qid)); - val |= params->txop << MT_WMM_TXOP_SHIFT(qid); - mt76_wr(dev, MT_WMM_TXOP(qid), val); - - val = mt76_rr(dev, MT_WMM_AIFSN); - val &= ~(MT_WMM_AIFSN_MASK << MT_WMM_AIFSN_SHIFT(qid)); - val |= params->aifs << MT_WMM_AIFSN_SHIFT(qid); - mt76_wr(dev, MT_WMM_AIFSN, val); - - val = mt76_rr(dev, MT_WMM_CWMIN); - val &= ~(MT_WMM_CWMIN_MASK << MT_WMM_CWMIN_SHIFT(qid)); - val |= cw_min << MT_WMM_CWMIN_SHIFT(qid); - mt76_wr(dev, MT_WMM_CWMIN, val); - - val = mt76_rr(dev, MT_WMM_CWMAX); - val &= ~(MT_WMM_CWMAX_MASK << MT_WMM_CWMAX_SHIFT(qid)); - val |= cw_max << MT_WMM_CWMAX_SHIFT(qid); - mt76_wr(dev, MT_WMM_CWMAX, val); - - return 0; -} -EXPORT_SYMBOL_GPL(mt76x2_conf_tx); - void mt76x2_sta_rate_tbl_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_main.c b/drivers/net/wireless/mediatek/mt76/mt76x2_main.c index 143d8abed403..87302845d582 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_main.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_main.c @@ -321,7 +321,7 @@ const struct ieee80211_ops mt76x2_ops = { .sta_add = mt76x02_sta_add, .sta_remove = mt76x02_sta_remove, .set_key = mt76x02_set_key, - .conf_tx = mt76x2_conf_tx, + .conf_tx = mt76x02_conf_tx, .sw_scan_start = mt76x2_sw_scan, .sw_scan_complete = mt76x2_sw_scan_complete, .flush = mt76x2_flush, diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2u_main.c b/drivers/net/wireless/mediatek/mt76/mt76x2u_main.c index 62d0eb75cac3..1dcc6ced15a5 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2u_main.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2u_main.c @@ -173,7 +173,7 @@ const struct ieee80211_ops mt76x2u_ops = { .wake_tx_queue = mt76_wake_tx_queue, .bss_info_changed = mt76x2u_bss_info_changed, .configure_filter = mt76x02_configure_filter, - .conf_tx = mt76x2_conf_tx, + .conf_tx = mt76x02_conf_tx, .sw_scan_start = mt76x2u_sw_scan, .sw_scan_complete = mt76x2u_sw_scan_complete, .sta_rate_tbl_update = mt76x2_sta_rate_tbl_update, From 900c0f4746a1adff64d68c0cb94c480aa8232671 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Tue, 4 Sep 2018 16:41:04 +0200 Subject: [PATCH 137/276] mt76x0: remove vif_mask Make remove_interface more similar to mt76x2. Signed-off-by: Stanislaw Gruszka Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt76x0/main.c | 11 +---------- drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h | 2 -- 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c index f87103aea868..a818a47f8e4e 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c @@ -56,14 +56,7 @@ static int mt76x0_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { struct mt76x0_dev *dev = hw->priv; - unsigned int idx; - - idx = ffs(~dev->vif_mask); - if (!idx || idx > 8) - return -ENOSPC; - - idx--; - dev->vif_mask |= BIT(idx); + unsigned int idx = 0; mt76x02_vif_init(&dev->mt76, vif, idx); return 0; @@ -73,9 +66,7 @@ static void mt76x0_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { struct mt76x0_dev *dev = hw->priv; - struct mt76x02_vif *mvif = (struct mt76x02_vif *) vif->drv_priv; - dev->vif_mask &= ~BIT(mvif->idx); mt76_txq_remove(&dev->mt76, vif->txq); } diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h index e65e6c09877c..c3669735965b 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h @@ -134,8 +134,6 @@ struct mt76x0_dev { u8 in_ep[__MT_EP_IN_MAX]; u16 in_max_packet; - unsigned long vif_mask; - struct delayed_work cal_work; struct delayed_work mac_work; From 0cd47bae2264411d461701a7f5a9625af6b94b26 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Tue, 4 Sep 2018 16:41:05 +0200 Subject: [PATCH 138/276] mt76: unify remove_interface Use common remove_interface callback in mt76x0 and mt76x2. Signed-off-by: Stanislaw Gruszka Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt76x0/main.c | 10 +--------- drivers/net/wireless/mediatek/mt76/mt76x02_util.c | 9 +++++++++ drivers/net/wireless/mediatek/mt76/mt76x02_util.h | 2 ++ drivers/net/wireless/mediatek/mt76/mt76x2_common.c | 9 --------- drivers/net/wireless/mediatek/mt76/mt76x2_main.c | 2 +- drivers/net/wireless/mediatek/mt76/mt76x2u_main.c | 2 +- 6 files changed, 14 insertions(+), 20 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c index a818a47f8e4e..d8efa009126c 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c @@ -62,14 +62,6 @@ static int mt76x0_add_interface(struct ieee80211_hw *hw, return 0; } -static void mt76x0_remove_interface(struct ieee80211_hw *hw, - struct ieee80211_vif *vif) -{ - struct mt76x0_dev *dev = hw->priv; - - mt76_txq_remove(&dev->mt76, vif->txq); -} - static int mt76x0_config(struct ieee80211_hw *hw, u32 changed) { struct mt76x0_dev *dev = hw->priv; @@ -203,7 +195,7 @@ const struct ieee80211_ops mt76x0_ops = { .start = mt76x0_start, .stop = mt76x0_stop, .add_interface = mt76x0_add_interface, - .remove_interface = mt76x0_remove_interface, + .remove_interface = mt76x02_remove_interface, .config = mt76x0_config, .configure_filter = mt76x02_configure_filter, .bss_info_changed = mt76x0_bss_info_changed, diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c index 140e43817a39..3b68102e55ae 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c @@ -127,6 +127,15 @@ void mt76x02_vif_init(struct mt76_dev *dev, struct ieee80211_vif *vif, } EXPORT_SYMBOL_GPL(mt76x02_vif_init); +void mt76x02_remove_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) +{ + struct mt76_dev *dev = hw->priv; + + mt76_txq_remove(dev, vif->txq); +} +EXPORT_SYMBOL_GPL(mt76x02_remove_interface); + int mt76x02_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_ampdu_params *params) { diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.h b/drivers/net/wireless/mediatek/mt76/mt76x02_util.h index 54f895d8cdbe..a61c9f2b9a62 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.h @@ -28,6 +28,8 @@ int mt76x02_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, void mt76x02_vif_init(struct mt76_dev *dev, struct ieee80211_vif *vif, unsigned int idx); +void mt76x02_remove_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif); int mt76x02_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_ampdu_params *params); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_common.c b/drivers/net/wireless/mediatek/mt76/mt76x2_common.c index 5ce9fbc654a2..be4e00fe7586 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_common.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_common.c @@ -18,15 +18,6 @@ #include "mt76x2.h" #include "mt76x02_mac.h" -void mt76x2_remove_interface(struct ieee80211_hw *hw, - struct ieee80211_vif *vif) -{ - struct mt76x2_dev *dev = hw->priv; - - mt76_txq_remove(&dev->mt76, vif->txq); -} -EXPORT_SYMBOL_GPL(mt76x2_remove_interface); - void mt76x2_sta_rate_tbl_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_main.c b/drivers/net/wireless/mediatek/mt76/mt76x2_main.c index 87302845d582..128a1c1c0f64 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_main.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_main.c @@ -314,7 +314,7 @@ const struct ieee80211_ops mt76x2_ops = { .start = mt76x2_start, .stop = mt76x2_stop, .add_interface = mt76x2_add_interface, - .remove_interface = mt76x2_remove_interface, + .remove_interface = mt76x02_remove_interface, .config = mt76x2_config, .configure_filter = mt76x02_configure_filter, .bss_info_changed = mt76x2_bss_info_changed, diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2u_main.c b/drivers/net/wireless/mediatek/mt76/mt76x2u_main.c index 1dcc6ced15a5..66a923a32e51 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2u_main.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2u_main.c @@ -164,7 +164,7 @@ const struct ieee80211_ops mt76x2u_ops = { .start = mt76x2u_start, .stop = mt76x2u_stop, .add_interface = mt76x2u_add_interface, - .remove_interface = mt76x2_remove_interface, + .remove_interface = mt76x02_remove_interface, .sta_add = mt76x02_sta_add, .sta_remove = mt76x02_sta_remove, .set_key = mt76x02_set_key, From 212926eb449309489b55ae46e433d26808337bcf Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Tue, 4 Sep 2018 16:41:06 +0200 Subject: [PATCH 139/276] mt76: unify add_interface Make common add_interface for mt76x0 and mt76x2e. This change behavior for mt76x0, but it should work with the new implementation. mt76x2u has different implementation. Maybe it can use common one, but for now leave it as is. Signed-off-by: Stanislaw Gruszka Signed-off-by: Felix Fietkau --- .../net/wireless/mediatek/mt76/mt76x0/main.c | 13 +------- .../net/wireless/mediatek/mt76/mt76x02_util.c | 30 ++++++++++++++++++ .../net/wireless/mediatek/mt76/mt76x02_util.h | 2 ++ .../net/wireless/mediatek/mt76/mt76x2_main.c | 31 +------------------ 4 files changed, 34 insertions(+), 42 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c index d8efa009126c..809ee41e7121 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c @@ -51,17 +51,6 @@ static void mt76x0_stop(struct ieee80211_hw *hw) mutex_unlock(&dev->mt76.mutex); } - -static int mt76x0_add_interface(struct ieee80211_hw *hw, - struct ieee80211_vif *vif) -{ - struct mt76x0_dev *dev = hw->priv; - unsigned int idx = 0; - - mt76x02_vif_init(&dev->mt76, vif, idx); - return 0; -} - static int mt76x0_config(struct ieee80211_hw *hw, u32 changed) { struct mt76x0_dev *dev = hw->priv; @@ -194,7 +183,7 @@ const struct ieee80211_ops mt76x0_ops = { .tx = mt76x0_tx, .start = mt76x0_start, .stop = mt76x0_stop, - .add_interface = mt76x0_add_interface, + .add_interface = mt76x02_add_interface, .remove_interface = mt76x02_remove_interface, .config = mt76x0_config, .configure_filter = mt76x02_configure_filter, diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c index 3b68102e55ae..41406ba09296 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c @@ -127,6 +127,36 @@ void mt76x02_vif_init(struct mt76_dev *dev, struct ieee80211_vif *vif, } EXPORT_SYMBOL_GPL(mt76x02_vif_init); +int +mt76x02_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) +{ + struct mt76_dev *dev = hw->priv; + unsigned int idx = 0; + + if (vif->addr[0] & BIT(1)) + idx = 1 + (((dev->macaddr[0] ^ vif->addr[0]) >> 2) & 7); + + /* + * Client mode typically only has one configurable BSSID register, + * which is used for bssidx=0. This is linked to the MAC address. + * Since mac80211 allows changing interface types, and we cannot + * force the use of the primary MAC address for a station mode + * interface, we need some other way of configuring a per-interface + * remote BSSID. + * The hardware provides an AP-Client feature, where bssidx 0-7 are + * used for AP mode and bssidx 8-15 for client mode. + * We shift the station interface bss index by 8 to force the + * hardware to recognize the BSSID. + * The resulting bssidx mismatch for unicast frames is ignored by hw. + */ + if (vif->type == NL80211_IFTYPE_STATION) + idx += 8; + + mt76x02_vif_init(dev, vif, idx); + return 0; +} +EXPORT_SYMBOL_GPL(mt76x02_add_interface); + void mt76x02_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.h b/drivers/net/wireless/mediatek/mt76/mt76x02_util.h index a61c9f2b9a62..f8890ab7b04e 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.h @@ -28,6 +28,8 @@ int mt76x02_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, void mt76x02_vif_init(struct mt76_dev *dev, struct ieee80211_vif *vif, unsigned int idx); +int mt76x02_add_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif); void mt76x02_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_main.c b/drivers/net/wireless/mediatek/mt76/mt76x2_main.c index 128a1c1c0f64..99d9033efa15 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_main.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_main.c @@ -54,35 +54,6 @@ mt76x2_stop(struct ieee80211_hw *hw) mutex_unlock(&dev->mt76.mutex); } -static int -mt76x2_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) -{ - struct mt76x2_dev *dev = hw->priv; - unsigned int idx = 0; - - if (vif->addr[0] & BIT(1)) - idx = 1 + (((dev->mt76.macaddr[0] ^ vif->addr[0]) >> 2) & 7); - - /* - * Client mode typically only has one configurable BSSID register, - * which is used for bssidx=0. This is linked to the MAC address. - * Since mac80211 allows changing interface types, and we cannot - * force the use of the primary MAC address for a station mode - * interface, we need some other way of configuring a per-interface - * remote BSSID. - * The hardware provides an AP-Client feature, where bssidx 0-7 are - * used for AP mode and bssidx 8-15 for client mode. - * We shift the station interface bss index by 8 to force the - * hardware to recognize the BSSID. - * The resulting bssidx mismatch for unicast frames is ignored by hw. - */ - if (vif->type == NL80211_IFTYPE_STATION) - idx += 8; - - mt76x02_vif_init(&dev->mt76, vif, idx); - return 0; -} - static int mt76x2_set_channel(struct mt76x2_dev *dev, struct cfg80211_chan_def *chandef) { @@ -313,7 +284,7 @@ const struct ieee80211_ops mt76x2_ops = { .tx = mt76x2_tx, .start = mt76x2_start, .stop = mt76x2_stop, - .add_interface = mt76x2_add_interface, + .add_interface = mt76x02_add_interface, .remove_interface = mt76x02_remove_interface, .config = mt76x2_config, .configure_filter = mt76x02_configure_filter, From 5327b5ea13910df072772219e303a3d6cc5f992e Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Tue, 4 Sep 2018 16:41:07 +0200 Subject: [PATCH 140/276] mt76: unify sta_rate_tbl_update and related helpers Use common sta_rate_tbl_update on mt76x0 and mt76x2. mt76x0 do not have support TPC (transmision power control) implmented, msta->wcid.max_txpwr_adj is only set for mt76x2. Signed-off-by: Stanislaw Gruszka Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt76.h | 2 + .../net/wireless/mediatek/mt76/mt76x0/init.c | 1 + .../net/wireless/mediatek/mt76/mt76x0/mac.c | 63 +----------------- .../net/wireless/mediatek/mt76/mt76x0/mac.h | 59 ----------------- .../net/wireless/mediatek/mt76/mt76x0/main.c | 25 +------ .../net/wireless/mediatek/mt76/mt76x0/tx.c | 2 +- .../net/wireless/mediatek/mt76/mt76x02_mac.c | 61 +++++++++++++++++ .../net/wireless/mediatek/mt76/mt76x02_mac.h | 56 ++++++++++++++++ .../net/wireless/mediatek/mt76/mt76x02_util.c | 21 ++++++ .../net/wireless/mediatek/mt76/mt76x02_util.h | 3 + drivers/net/wireless/mediatek/mt76/mt76x2.h | 5 +- .../wireless/mediatek/mt76/mt76x2_common.c | 19 ------ .../net/wireless/mediatek/mt76/mt76x2_init.c | 1 + .../net/wireless/mediatek/mt76/mt76x2_mac.h | 53 --------------- .../mediatek/mt76/mt76x2_mac_common.c | 65 +------------------ .../net/wireless/mediatek/mt76/mt76x2_main.c | 2 +- .../wireless/mediatek/mt76/mt76x2_tx_common.c | 3 +- .../net/wireless/mediatek/mt76/mt76x2u_main.c | 2 +- 18 files changed, 155 insertions(+), 288 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h index 7a7d13b16508..cbd223c1c01a 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76.h +++ b/drivers/net/wireless/mediatek/mt76/mt76.h @@ -247,6 +247,8 @@ struct mt76_driver_ops { void (*sta_ps)(struct mt76_dev *dev, struct ieee80211_sta *sta, bool ps); + s8 (*get_max_txpwr_adj)(struct mt76_dev *dev, + const struct ieee80211_tx_rate *rate); }; struct mt76_channel_state { diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c index b5bf22184a69..84fc306d2cbf 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c @@ -493,6 +493,7 @@ struct mt76x0_dev *mt76x0_alloc_device(struct device *pdev) dev = hw->priv; dev->mt76.dev = pdev; dev->mt76.hw = hw; + dev->mt76.drv = NULL; mutex_init(&dev->usb_ctrl_mtx); mutex_init(&dev->reg_atomic_mutex); mutex_init(&dev->hw_atomic_mutex); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c b/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c index 4c4962bcca11..65b04e314621 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c @@ -116,67 +116,6 @@ mt76_mac_fill_tx_status(struct mt76x0_dev *dev, struct ieee80211_tx_info *info, info->flags |= IEEE80211_TX_STAT_ACK; } -u16 mt76x0_mac_tx_rate_val(struct mt76x0_dev *dev, - const struct ieee80211_tx_rate *rate, u8 *nss_val) -{ - u16 rateval; - u8 phy, rate_idx; - u8 nss = 1; - u8 bw = 0; - - if (rate->flags & IEEE80211_TX_RC_VHT_MCS) { - rate_idx = rate->idx; - nss = 1 + (rate->idx >> 4); - phy = MT_PHY_TYPE_VHT; - if (rate->flags & IEEE80211_TX_RC_80_MHZ_WIDTH) - bw = 2; - else if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) - bw = 1; - } else if (rate->flags & IEEE80211_TX_RC_MCS) { - rate_idx = rate->idx; - nss = 1 + (rate->idx >> 3); - phy = MT_PHY_TYPE_HT; - if (rate->flags & IEEE80211_TX_RC_GREEN_FIELD) - phy = MT_PHY_TYPE_HT_GF; - if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) - bw = 1; - } else { - const struct ieee80211_rate *r; - int band = dev->mt76.chandef.chan->band; - u16 val; - - r = &dev->mt76.hw->wiphy->bands[band]->bitrates[rate->idx]; - if (rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) - val = r->hw_value_short; - else - val = r->hw_value; - - phy = val >> 8; - rate_idx = val & 0xff; - bw = 0; - } - - rateval = FIELD_PREP(MT_RXWI_RATE_INDEX, rate_idx); - rateval |= FIELD_PREP(MT_RXWI_RATE_PHY, phy); - rateval |= FIELD_PREP(MT_RXWI_RATE_BW, bw); - if (rate->flags & IEEE80211_TX_RC_SHORT_GI) - rateval |= MT_RXWI_RATE_SGI; - - *nss_val = nss; - return cpu_to_le16(rateval); -} - -void mt76x0_mac_wcid_set_rate(struct mt76x0_dev *dev, struct mt76_wcid *wcid, - const struct ieee80211_tx_rate *rate) -{ - unsigned long flags; - - spin_lock_irqsave(&dev->mt76.lock, flags); - wcid->tx_rate = mt76x0_mac_tx_rate_val(dev, rate, &wcid->tx_rate_nss); - wcid->tx_rate_set = true; - spin_unlock_irqrestore(&dev->mt76.lock, flags); -} - struct mt76x02_tx_status mt76x0_mac_fetch_tx_status(struct mt76x0_dev *dev) { struct mt76x02_tx_status stat = {}; @@ -537,7 +476,7 @@ u32 mt76x0_mac_process_rx(struct mt76x0_dev *dev, struct sk_buff *skb, spin_lock_bh(&dev->con_mon_lock); if (mt76x0_rx_is_our_beacon(dev, data)) { mt76x0_rx_monitor_beacon(dev, rxwi, rate, rssi); - } else if (rxwi->rxinfo & cpu_to_le32(MT_RXINFO_U2M)) { + } else if (rxwi->rxinfo & cpu_to_le32(MT_RXINFO_UNICAST)) { if (dev->avg_rssi == 0) dev->avg_rssi = rssi; else diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mac.h b/drivers/net/wireless/mediatek/mt76/mt76x0/mac.h index a6153a1ae206..aee7dc8f258e 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mac.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mac.h @@ -32,60 +32,6 @@ struct mt76x0_rxwi { __le32 bbp_rxinfo[4]; } __packed __aligned(4); -#define MT_RXINFO_BA BIT(0) -#define MT_RXINFO_DATA BIT(1) -#define MT_RXINFO_NULL BIT(2) -#define MT_RXINFO_FRAG BIT(3) -#define MT_RXINFO_U2M BIT(4) -#define MT_RXINFO_MULTICAST BIT(5) -#define MT_RXINFO_BROADCAST BIT(6) -#define MT_RXINFO_MYBSS BIT(7) -#define MT_RXINFO_CRCERR BIT(8) -#define MT_RXINFO_ICVERR BIT(9) -#define MT_RXINFO_MICERR BIT(10) -#define MT_RXINFO_AMSDU BIT(11) -#define MT_RXINFO_HTC BIT(12) -#define MT_RXINFO_RSSI BIT(13) -#define MT_RXINFO_L2PAD BIT(14) -#define MT_RXINFO_AMPDU BIT(15) -#define MT_RXINFO_DECRYPT BIT(16) -#define MT_RXINFO_BSSIDX3 BIT(17) -#define MT_RXINFO_WAPI_KEY BIT(18) -#define MT_RXINFO_PN_LEN GENMASK(21, 19) -#define MT_RXINFO_SW_PKT_80211 BIT(22) -#define MT_RXINFO_TCP_SUM_BYPASS BIT(28) -#define MT_RXINFO_IP_SUM_BYPASS BIT(29) -#define MT_RXINFO_TCP_SUM_ERR BIT(30) -#define MT_RXINFO_IP_SUM_ERR BIT(31) - -#define MT_RXWI_CTL_WCID GENMASK(7, 0) -#define MT_RXWI_CTL_KEY_IDX GENMASK(9, 8) -#define MT_RXWI_CTL_BSS_IDX GENMASK(12, 10) -#define MT_RXWI_CTL_UDF GENMASK(15, 13) -#define MT_RXWI_CTL_MPDU_LEN GENMASK(27, 16) -#define MT_RXWI_CTL_TID GENMASK(31, 28) - -#define MT_RXWI_FRAG GENMASK(3, 0) -#define MT_RXWI_SN GENMASK(15, 4) - -#define MT_RXWI_RATE_INDEX GENMASK(5, 0) -#define MT_RXWI_RATE_LDPC BIT(6) -#define MT_RXWI_RATE_BW GENMASK(8, 7) -#define MT_RXWI_RATE_SGI BIT(9) -#define MT_RXWI_RATE_STBC BIT(10) -#define MT_RXWI_RATE_LDPC_ETXBF BIT(11) -#define MT_RXWI_RATE_SND BIT(12) -#define MT_RXWI_RATE_PHY GENMASK(15, 13) - -#define MT_RATE_INDEX_VHT_IDX GENMASK(3, 0) -#define MT_RATE_INDEX_VHT_NSS GENMASK(5, 4) - -#define MT_RXWI_GAIN_RSSI_VAL GENMASK(5, 0) -#define MT_RXWI_GAIN_RSSI_LNA_ID GENMASK(7, 6) -#define MT_RXWI_ANT_AUX_LNA BIT(7) - -#define MT_RXWI_EANT_ENC_ANT_ID GENMASK(7, 0) - enum mt76_phy_bandwidth { MT_PHY_BW_20, MT_PHY_BW_40, @@ -138,11 +84,6 @@ struct mt76_txwi { u32 mt76x0_mac_process_rx(struct mt76x0_dev *dev, struct sk_buff *skb, u8 *data, void *rxi); -void mt76x0_mac_wcid_set_rate(struct mt76x0_dev *dev, struct mt76_wcid *wcid, - const struct ieee80211_tx_rate *rate); - -u16 mt76x0_mac_tx_rate_val(struct mt76x0_dev *dev, - const struct ieee80211_tx_rate *rate, u8 *nss_val); struct mt76x02_tx_status mt76x0_mac_fetch_tx_status(struct mt76x0_dev *dev); void mt76x0_send_tx_status(struct mt76x0_dev *dev, struct mt76x02_tx_status *stat, u8 *update); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c index 809ee41e7121..a14f03b1ac54 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c @@ -156,29 +156,6 @@ static int mt76x0_set_rts_threshold(struct ieee80211_hw *hw, u32 value) return 0; } -static void -mt76_sta_rate_tbl_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - struct ieee80211_sta *sta) -{ - struct mt76x0_dev *dev = hw->priv; - struct mt76x02_sta *msta = (struct mt76x02_sta *) sta->drv_priv; - struct ieee80211_sta_rates *rates; - struct ieee80211_tx_rate rate = {}; - - rcu_read_lock(); - rates = rcu_dereference(sta->rates); - - if (!rates) - goto out; - - rate.idx = rates->rate[0].idx; - rate.flags = rates->rate[0].flags; - mt76x0_mac_wcid_set_rate(dev, &msta->wcid, &rate); - -out: - rcu_read_unlock(); -} - const struct ieee80211_ops mt76x0_ops = { .tx = mt76x0_tx, .start = mt76x0_start, @@ -195,6 +172,6 @@ const struct ieee80211_ops mt76x0_ops = { .sw_scan_start = mt76x0_sw_scan, .sw_scan_complete = mt76x0_sw_scan_complete, .ampdu_action = mt76x02_ampdu_action, - .sta_rate_tbl_update = mt76_sta_rate_tbl_update, + .sta_rate_tbl_update = mt76x02_sta_rate_tbl_update, .set_rts_threshold = mt76x0_set_rts_threshold, }; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c b/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c index ce80763ec557..eeb298719329 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c @@ -93,7 +93,7 @@ mt76x0_push_txwi(struct mt76x0_dev *dev, struct sk_buff *skb, rate_ctl = wcid->tx_rate; nss = wcid->tx_rate_nss; } else { - rate_ctl = mt76x0_mac_tx_rate_val(dev, rate, &nss); + rate_ctl = mt76x02_mac_tx_rate_val(&dev->mt76, rate, &nss); } spin_unlock_irqrestore(&dev->mt76.lock, flags); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c index 67c53089229e..d67e12bd23a7 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c @@ -155,3 +155,64 @@ void mt76x02_txq_init(struct mt76_dev *dev, struct ieee80211_txq *txq) mt76_txq_init(dev, txq); } EXPORT_SYMBOL_GPL(mt76x02_txq_init); + +__le16 +mt76x02_mac_tx_rate_val(struct mt76_dev *dev, + const struct ieee80211_tx_rate *rate, u8 *nss_val) +{ + u16 rateval; + u8 phy, rate_idx; + u8 nss = 1; + u8 bw = 0; + + if (rate->flags & IEEE80211_TX_RC_VHT_MCS) { + rate_idx = rate->idx; + nss = 1 + (rate->idx >> 4); + phy = MT_PHY_TYPE_VHT; + if (rate->flags & IEEE80211_TX_RC_80_MHZ_WIDTH) + bw = 2; + else if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) + bw = 1; + } else if (rate->flags & IEEE80211_TX_RC_MCS) { + rate_idx = rate->idx; + nss = 1 + (rate->idx >> 3); + phy = MT_PHY_TYPE_HT; + if (rate->flags & IEEE80211_TX_RC_GREEN_FIELD) + phy = MT_PHY_TYPE_HT_GF; + if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) + bw = 1; + } else { + const struct ieee80211_rate *r; + int band = dev->chandef.chan->band; + u16 val; + + r = &dev->hw->wiphy->bands[band]->bitrates[rate->idx]; + if (rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) + val = r->hw_value_short; + else + val = r->hw_value; + + phy = val >> 8; + rate_idx = val & 0xff; + bw = 0; + } + + rateval = FIELD_PREP(MT_RXWI_RATE_INDEX, rate_idx); + rateval |= FIELD_PREP(MT_RXWI_RATE_PHY, phy); + rateval |= FIELD_PREP(MT_RXWI_RATE_BW, bw); + if (rate->flags & IEEE80211_TX_RC_SHORT_GI) + rateval |= MT_RXWI_RATE_SGI; + + *nss_val = nss; + return cpu_to_le16(rateval); +} +EXPORT_SYMBOL_GPL(mt76x02_mac_tx_rate_val); + +void mt76x02_mac_wcid_set_rate(struct mt76_dev *dev, struct mt76_wcid *wcid, + const struct ieee80211_tx_rate *rate) +{ + spin_lock_bh(&dev->lock); + wcid->tx_rate = mt76x02_mac_tx_rate_val(dev, rate, &wcid->tx_rate_nss); + wcid->tx_rate_set = true; + spin_unlock_bh(&dev->lock); +} diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h index 551970da9025..fc880ffe3d8b 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h @@ -53,6 +53,57 @@ struct mt76x02_sta { int inactive_count; }; +#define MT_RXINFO_BA BIT(0) +#define MT_RXINFO_DATA BIT(1) +#define MT_RXINFO_NULL BIT(2) +#define MT_RXINFO_FRAG BIT(3) +#define MT_RXINFO_UNICAST BIT(4) +#define MT_RXINFO_MULTICAST BIT(5) +#define MT_RXINFO_BROADCAST BIT(6) +#define MT_RXINFO_MYBSS BIT(7) +#define MT_RXINFO_CRCERR BIT(8) +#define MT_RXINFO_ICVERR BIT(9) +#define MT_RXINFO_MICERR BIT(10) +#define MT_RXINFO_AMSDU BIT(11) +#define MT_RXINFO_HTC BIT(12) +#define MT_RXINFO_RSSI BIT(13) +#define MT_RXINFO_L2PAD BIT(14) +#define MT_RXINFO_AMPDU BIT(15) +#define MT_RXINFO_DECRYPT BIT(16) +#define MT_RXINFO_BSSIDX3 BIT(17) +#define MT_RXINFO_WAPI_KEY BIT(18) +#define MT_RXINFO_PN_LEN GENMASK(21, 19) +#define MT_RXINFO_SW_FTYPE0 BIT(22) +#define MT_RXINFO_SW_FTYPE1 BIT(23) +#define MT_RXINFO_PROBE_RESP BIT(24) +#define MT_RXINFO_BEACON BIT(25) +#define MT_RXINFO_DISASSOC BIT(26) +#define MT_RXINFO_DEAUTH BIT(27) +#define MT_RXINFO_ACTION BIT(28) +#define MT_RXINFO_TCP_SUM_ERR BIT(30) +#define MT_RXINFO_IP_SUM_ERR BIT(31) + +#define MT_RXWI_CTL_WCID GENMASK(7, 0) +#define MT_RXWI_CTL_KEY_IDX GENMASK(9, 8) +#define MT_RXWI_CTL_BSS_IDX GENMASK(12, 10) +#define MT_RXWI_CTL_UDF GENMASK(15, 13) +#define MT_RXWI_CTL_MPDU_LEN GENMASK(29, 16) +#define MT_RXWI_CTL_EOF BIT(31) + +#define MT_RXWI_TID GENMASK(3, 0) +#define MT_RXWI_SN GENMASK(15, 4) + +#define MT_RXWI_RATE_INDEX GENMASK(5, 0) +#define MT_RXWI_RATE_LDPC BIT(6) +#define MT_RXWI_RATE_BW GENMASK(8, 7) +#define MT_RXWI_RATE_SGI BIT(9) +#define MT_RXWI_RATE_STBC BIT(10) +#define MT_RXWI_RATE_LDPC_EXSYM BIT(11) +#define MT_RXWI_RATE_PHY GENMASK(15, 13) + +#define MT_RATE_INDEX_VHT_IDX GENMASK(3, 0) +#define MT_RATE_INDEX_VHT_NSS GENMASK(5, 4) + static inline bool mt76x02_wait_for_mac(struct mt76_dev *dev) { const u32 MAC_CSR0 = 0x1000; @@ -85,4 +136,9 @@ int mt76x02_mac_wcid_set_key(struct mt76_dev *dev, u8 idx, struct ieee80211_key_conf *key); void mt76x02_mac_wcid_setup(struct mt76_dev *dev, u8 idx, u8 vif_idx, u8 *mac); void mt76x02_mac_wcid_set_drop(struct mt76_dev *dev, u8 idx, bool drop); +void mt76x02_mac_wcid_set_rate(struct mt76_dev *dev, struct mt76_wcid *wcid, + const struct ieee80211_tx_rate *rate); +__le16 +mt76x02_mac_tx_rate_val(struct mt76_dev *dev, + const struct ieee80211_tx_rate *rate, u8 *nss_val); #endif diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c index 41406ba09296..2c80fe9a493c 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c @@ -327,4 +327,25 @@ int mt76x02_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, } EXPORT_SYMBOL_GPL(mt76x02_conf_tx); +void mt76x02_sta_rate_tbl_update(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta) +{ + struct mt76_dev *dev = hw->priv; + struct mt76x02_sta *msta = (struct mt76x02_sta *) sta->drv_priv; + struct ieee80211_sta_rates *rates = rcu_dereference(sta->rates); + struct ieee80211_tx_rate rate = {}; + + if (!rates) + return; + + rate.idx = rates->rate[0].idx; + rate.flags = rates->rate[0].flags; + mt76x02_mac_wcid_set_rate(dev, &msta->wcid, &rate); + + if (dev->drv && dev->drv->get_max_txpwr_adj) + msta->wcid.max_txpwr_adj = dev->drv->get_max_txpwr_adj(dev, &rate); +} +EXPORT_SYMBOL_GPL(mt76x02_sta_rate_tbl_update); + MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.h b/drivers/net/wireless/mediatek/mt76/mt76x02_util.h index f8890ab7b04e..cff3c8f6393c 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.h @@ -40,4 +40,7 @@ int mt76x02_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, struct ieee80211_key_conf *key); int mt76x02_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u16 queue, const struct ieee80211_tx_queue_params *params); +void mt76x02_sta_rate_tbl_update(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta); #endif diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2.h b/drivers/net/wireless/mediatek/mt76/mt76x2.h index ada01186d3c3..faf830585515 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x2.h @@ -234,7 +234,7 @@ void mt76x2_sta_ps(struct mt76_dev *dev, struct ieee80211_sta *sta, bool ps); void mt76x2_update_channel(struct mt76_dev *mdev); -s8 mt76x2_tx_get_max_txpwr_adj(struct mt76x2_dev *dev, +s8 mt76x2_tx_get_max_txpwr_adj(struct mt76_dev *dev, const struct ieee80211_tx_rate *rate); s8 mt76x2_tx_get_txpwr_adj(struct mt76x2_dev *dev, s8 txpwr, s8 max_txpwr_adj); void mt76x2_tx_set_txpwr_auto(struct mt76x2_dev *dev, s8 txpwr); @@ -259,9 +259,6 @@ void mt76x2_remove_interface(struct ieee80211_hw *hw, int mt76x2_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u16 queue, const struct ieee80211_tx_queue_params *params); void mt76x2_txq_init(struct mt76x2_dev *dev, struct ieee80211_txq *txq); -void mt76x2_sta_rate_tbl_update(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta); void mt76x2_phy_set_txpower_regs(struct mt76x2_dev *dev, enum nl80211_band band); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_common.c b/drivers/net/wireless/mediatek/mt76/mt76x2_common.c index be4e00fe7586..2db67f7a4bec 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_common.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_common.c @@ -18,25 +18,6 @@ #include "mt76x2.h" #include "mt76x02_mac.h" -void mt76x2_sta_rate_tbl_update(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta) -{ - struct mt76x2_dev *dev = hw->priv; - struct mt76x02_sta *msta = (struct mt76x02_sta *) sta->drv_priv; - struct ieee80211_sta_rates *rates = rcu_dereference(sta->rates); - struct ieee80211_tx_rate rate = {}; - - if (!rates) - return; - - rate.idx = rates->rate[0].idx; - rate.flags = rates->rate[0].flags; - mt76x2_mac_wcid_set_rate(dev, &msta->wcid, &rate); - msta->wcid.max_txpwr_adj = mt76x2_tx_get_max_txpwr_adj(dev, &rate); -} -EXPORT_SYMBOL_GPL(mt76x2_sta_rate_tbl_update); - void mt76x2_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q, struct sk_buff *skb) { diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_init.c b/drivers/net/wireless/mediatek/mt76/mt76x2_init.c index 1f397c5e64a3..e59af314712c 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_init.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_init.c @@ -424,6 +424,7 @@ struct mt76x2_dev *mt76x2_alloc_device(struct device *pdev) .rx_skb = mt76x2_queue_rx_skb, .rx_poll_complete = mt76x2_rx_poll_complete, .sta_ps = mt76x2_sta_ps, + .get_max_txpwr_adj = mt76x2_tx_get_max_txpwr_adj, }; struct mt76x2_dev *dev; struct mt76_dev *mdev; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.h b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.h index 14089e8e5a02..62cb34f4f362 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.h @@ -47,57 +47,6 @@ struct mt76x2_rxwi { __le32 bbp_rxinfo[4]; }; -#define MT_RXINFO_BA BIT(0) -#define MT_RXINFO_DATA BIT(1) -#define MT_RXINFO_NULL BIT(2) -#define MT_RXINFO_FRAG BIT(3) -#define MT_RXINFO_UNICAST BIT(4) -#define MT_RXINFO_MULTICAST BIT(5) -#define MT_RXINFO_BROADCAST BIT(6) -#define MT_RXINFO_MYBSS BIT(7) -#define MT_RXINFO_CRCERR BIT(8) -#define MT_RXINFO_ICVERR BIT(9) -#define MT_RXINFO_MICERR BIT(10) -#define MT_RXINFO_AMSDU BIT(11) -#define MT_RXINFO_HTC BIT(12) -#define MT_RXINFO_RSSI BIT(13) -#define MT_RXINFO_L2PAD BIT(14) -#define MT_RXINFO_AMPDU BIT(15) -#define MT_RXINFO_DECRYPT BIT(16) -#define MT_RXINFO_BSSIDX3 BIT(17) -#define MT_RXINFO_WAPI_KEY BIT(18) -#define MT_RXINFO_PN_LEN GENMASK(21, 19) -#define MT_RXINFO_SW_FTYPE0 BIT(22) -#define MT_RXINFO_SW_FTYPE1 BIT(23) -#define MT_RXINFO_PROBE_RESP BIT(24) -#define MT_RXINFO_BEACON BIT(25) -#define MT_RXINFO_DISASSOC BIT(26) -#define MT_RXINFO_DEAUTH BIT(27) -#define MT_RXINFO_ACTION BIT(28) -#define MT_RXINFO_TCP_SUM_ERR BIT(30) -#define MT_RXINFO_IP_SUM_ERR BIT(31) - -#define MT_RXWI_CTL_WCID GENMASK(7, 0) -#define MT_RXWI_CTL_KEY_IDX GENMASK(9, 8) -#define MT_RXWI_CTL_BSS_IDX GENMASK(12, 10) -#define MT_RXWI_CTL_UDF GENMASK(15, 13) -#define MT_RXWI_CTL_MPDU_LEN GENMASK(29, 16) -#define MT_RXWI_CTL_EOF BIT(31) - -#define MT_RXWI_TID GENMASK(3, 0) -#define MT_RXWI_SN GENMASK(15, 4) - -#define MT_RXWI_RATE_INDEX GENMASK(5, 0) -#define MT_RXWI_RATE_LDPC BIT(6) -#define MT_RXWI_RATE_BW GENMASK(8, 7) -#define MT_RXWI_RATE_SGI BIT(9) -#define MT_RXWI_RATE_STBC BIT(10) -#define MT_RXWI_RATE_LDPC_EXSYM BIT(11) -#define MT_RXWI_RATE_PHY GENMASK(15, 13) - -#define MT_RATE_INDEX_VHT_IDX GENMASK(3, 0) -#define MT_RATE_INDEX_VHT_NSS GENMASK(5, 4) - #define MT_TX_PWR_ADJ GENMASK(3, 0) enum mt76x2_phy_bandwidth { @@ -157,8 +106,6 @@ int mt76x2_mac_process_rx(struct mt76x2_dev *dev, struct sk_buff *skb, void mt76x2_mac_write_txwi(struct mt76x2_dev *dev, struct mt76x2_txwi *txwi, struct sk_buff *skb, struct mt76_wcid *wcid, struct ieee80211_sta *sta, int len); -void mt76x2_mac_wcid_set_rate(struct mt76x2_dev *dev, struct mt76_wcid *wcid, - const struct ieee80211_tx_rate *rate); int mt76x2_mac_set_beacon(struct mt76x2_dev *dev, u8 vif_idx, struct sk_buff *skb); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mac_common.c b/drivers/net/wireless/mediatek/mt76/mt76x2_mac_common.c index ec2326cd724b..85671244fdf9 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_mac_common.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mac_common.c @@ -229,67 +229,6 @@ void mt76x2_send_tx_status(struct mt76x2_dev *dev, } EXPORT_SYMBOL_GPL(mt76x2_send_tx_status); -static __le16 -mt76x2_mac_tx_rate_val(struct mt76x2_dev *dev, - const struct ieee80211_tx_rate *rate, u8 *nss_val) -{ - u16 rateval; - u8 phy, rate_idx; - u8 nss = 1; - u8 bw = 0; - - if (rate->flags & IEEE80211_TX_RC_VHT_MCS) { - rate_idx = rate->idx; - nss = 1 + (rate->idx >> 4); - phy = MT_PHY_TYPE_VHT; - if (rate->flags & IEEE80211_TX_RC_80_MHZ_WIDTH) - bw = 2; - else if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) - bw = 1; - } else if (rate->flags & IEEE80211_TX_RC_MCS) { - rate_idx = rate->idx; - nss = 1 + (rate->idx >> 3); - phy = MT_PHY_TYPE_HT; - if (rate->flags & IEEE80211_TX_RC_GREEN_FIELD) - phy = MT_PHY_TYPE_HT_GF; - if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) - bw = 1; - } else { - const struct ieee80211_rate *r; - int band = dev->mt76.chandef.chan->band; - u16 val; - - r = &mt76_hw(dev)->wiphy->bands[band]->bitrates[rate->idx]; - if (rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) - val = r->hw_value_short; - else - val = r->hw_value; - - phy = val >> 8; - rate_idx = val & 0xff; - bw = 0; - } - - rateval = FIELD_PREP(MT_RXWI_RATE_INDEX, rate_idx); - rateval |= FIELD_PREP(MT_RXWI_RATE_PHY, phy); - rateval |= FIELD_PREP(MT_RXWI_RATE_BW, bw); - if (rate->flags & IEEE80211_TX_RC_SHORT_GI) - rateval |= MT_RXWI_RATE_SGI; - - *nss_val = nss; - return cpu_to_le16(rateval); -} - -void mt76x2_mac_wcid_set_rate(struct mt76x2_dev *dev, struct mt76_wcid *wcid, - const struct ieee80211_tx_rate *rate) -{ - spin_lock_bh(&dev->mt76.lock); - wcid->tx_rate = mt76x2_mac_tx_rate_val(dev, rate, &wcid->tx_rate_nss); - wcid->tx_rate_set = true; - spin_unlock_bh(&dev->mt76.lock); -} -EXPORT_SYMBOL_GPL(mt76x2_mac_wcid_set_rate); - void mt76x2_mac_write_txwi(struct mt76x2_dev *dev, struct mt76x2_txwi *txwi, struct sk_buff *skb, struct mt76_wcid *wcid, struct ieee80211_sta *sta, int len) @@ -333,8 +272,8 @@ void mt76x2_mac_write_txwi(struct mt76x2_dev *dev, struct mt76x2_txwi *txwi, max_txpwr_adj = wcid->max_txpwr_adj; nss = wcid->tx_rate_nss; } else { - txwi->rate = mt76x2_mac_tx_rate_val(dev, rate, &nss); - max_txpwr_adj = mt76x2_tx_get_max_txpwr_adj(dev, rate); + txwi->rate = mt76x02_mac_tx_rate_val(&dev->mt76, rate, &nss); + max_txpwr_adj = mt76x2_tx_get_max_txpwr_adj(&dev->mt76, rate); } spin_unlock_bh(&dev->mt76.lock); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_main.c b/drivers/net/wireless/mediatek/mt76/mt76x2_main.c index 99d9033efa15..7f0a89be154c 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_main.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_main.c @@ -299,7 +299,7 @@ const struct ieee80211_ops mt76x2_ops = { .ampdu_action = mt76x02_ampdu_action, .get_txpower = mt76x2_get_txpower, .wake_tx_queue = mt76_wake_tx_queue, - .sta_rate_tbl_update = mt76x2_sta_rate_tbl_update, + .sta_rate_tbl_update = mt76x02_sta_rate_tbl_update, .release_buffered_frames = mt76_release_buffered_frames, .set_coverage_class = mt76x2_set_coverage_class, .get_survey = mt76_get_survey, diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_tx_common.c b/drivers/net/wireless/mediatek/mt76/mt76x2_tx_common.c index b6c6d657b2b7..17da4ae1032d 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_tx_common.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_tx_common.c @@ -63,9 +63,10 @@ int mt76x2_insert_hdr_pad(struct sk_buff *skb) } EXPORT_SYMBOL_GPL(mt76x2_insert_hdr_pad); -s8 mt76x2_tx_get_max_txpwr_adj(struct mt76x2_dev *dev, +s8 mt76x2_tx_get_max_txpwr_adj(struct mt76_dev *mdev, const struct ieee80211_tx_rate *rate) { + struct mt76x2_dev *dev = (struct mt76x2_dev *) mdev; s8 max_txpwr; if (rate->flags & IEEE80211_TX_RC_VHT_MCS) { diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2u_main.c b/drivers/net/wireless/mediatek/mt76/mt76x2u_main.c index 66a923a32e51..c6855549c312 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2u_main.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2u_main.c @@ -176,5 +176,5 @@ const struct ieee80211_ops mt76x2u_ops = { .conf_tx = mt76x02_conf_tx, .sw_scan_start = mt76x2u_sw_scan, .sw_scan_complete = mt76x2u_sw_scan_complete, - .sta_rate_tbl_update = mt76x2_sta_rate_tbl_update, + .sta_rate_tbl_update = mt76x02_sta_rate_tbl_update, }; From 5944cd02866f380680b556c7e8e89858d56d1391 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Tue, 4 Sep 2018 16:41:08 +0200 Subject: [PATCH 141/276] mt76: unify txwi and rxwi structures txwi and rxwi are the same for mt76x0 and mt76x2. Signed-off-by: Stanislaw Gruszka Signed-off-by: Felix Fietkau --- .../net/wireless/mediatek/mt76/mt76x0/dma.c | 12 ++-- .../net/wireless/mediatek/mt76/mt76x0/mac.c | 4 +- .../net/wireless/mediatek/mt76/mt76x0/mac.h | 67 ------------------- .../wireless/mediatek/mt76/mt76x0/mt76x0.h | 4 +- .../net/wireless/mediatek/mt76/mt76x0/phy.c | 2 +- .../net/wireless/mediatek/mt76/mt76x0/trace.h | 12 ++-- .../net/wireless/mediatek/mt76/mt76x0/tx.c | 18 ++--- .../net/wireless/mediatek/mt76/mt76x02_mac.h | 54 +++++++++++++++ .../wireless/mediatek/mt76/mt76x2_common.c | 2 +- .../net/wireless/mediatek/mt76/mt76x2_dma.c | 6 +- .../net/wireless/mediatek/mt76/mt76x2_init.c | 2 +- .../net/wireless/mediatek/mt76/mt76x2_mac.c | 6 +- .../net/wireless/mediatek/mt76/mt76x2_mac.h | 57 +--------------- .../mediatek/mt76/mt76x2_mac_common.c | 4 +- .../net/wireless/mediatek/mt76/mt76x2u_core.c | 8 +-- 15 files changed, 94 insertions(+), 164 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/dma.c b/drivers/net/wireless/mediatek/mt76/mt76x0/dma.c index 715c3734a307..05e577342a90 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/dma.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/dma.c @@ -34,7 +34,7 @@ static unsigned int ieee80211_get_hdrlen_from_buf(const u8 *data, unsigned len) } static struct sk_buff * -mt76x0_rx_skb_from_seg(struct mt76x0_dev *dev, struct mt76x0_rxwi *rxwi, +mt76x0_rx_skb_from_seg(struct mt76x0_dev *dev, struct mt76x02_rxwi *rxwi, void *data, u32 seg_len, u32 truesize, struct page *p) { struct sk_buff *skb; @@ -86,7 +86,7 @@ static void mt76x0_rx_process_seg(struct mt76x0_dev *dev, u8 *data, u32 seg_len, struct page *p) { struct sk_buff *skb; - struct mt76x0_rxwi *rxwi; + struct mt76x02_rxwi *rxwi; u32 fce_info, truesize = seg_len; /* DMA_INFO field at the beginning of the segment contains only some of @@ -98,9 +98,9 @@ static void mt76x0_rx_process_seg(struct mt76x0_dev *dev, u8 *data, data += MT_DMA_HDR_LEN; seg_len -= MT_DMA_HDR_LEN; - rxwi = (struct mt76x0_rxwi *) data; - data += sizeof(struct mt76x0_rxwi); - seg_len -= sizeof(struct mt76x0_rxwi); + rxwi = (struct mt76x02_rxwi *) data; + data += sizeof(struct mt76x02_rxwi); + seg_len -= sizeof(struct mt76x02_rxwi); if (unlikely(FIELD_GET(MT_RXD_INFO_TYPE, fce_info))) dev_err_once(dev->mt76.dev, "Error: RX path seen a non-pkt urb\n"); @@ -119,7 +119,7 @@ static void mt76x0_rx_process_seg(struct mt76x0_dev *dev, u8 *data, static u16 mt76x0_rx_next_seg_len(u8 *data, u32 data_len) { u32 min_seg_len = MT_DMA_HDR_LEN + MT_RX_INFO_LEN + - sizeof(struct mt76x0_rxwi) + MT_FCE_INFO_LEN; + sizeof(struct mt76x02_rxwi) + MT_FCE_INFO_LEN; u16 dma_len = get_unaligned_le16(data); if (data_len < min_seg_len || diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c b/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c index 65b04e314621..46646a7461bd 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c @@ -431,7 +431,7 @@ mt76_mac_process_rate(struct ieee80211_rx_status *status, u16 rate) } static void -mt76x0_rx_monitor_beacon(struct mt76x0_dev *dev, struct mt76x0_rxwi *rxwi, +mt76x0_rx_monitor_beacon(struct mt76x0_dev *dev, struct mt76x02_rxwi *rxwi, u16 rate, int rssi) { dev->bcn_phy_mode = FIELD_GET(MT_RXWI_RATE_PHY, rate); @@ -451,7 +451,7 @@ u32 mt76x0_mac_process_rx(struct mt76x0_dev *dev, struct sk_buff *skb, u8 *data, void *rxi) { struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); - struct mt76x0_rxwi *rxwi = rxi; + struct mt76x02_rxwi *rxwi = rxi; u32 len, ctl = le32_to_cpu(rxwi->ctl); u16 rate = le16_to_cpu(rxwi->rate); int rssi; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mac.h b/drivers/net/wireless/mediatek/mt76/mt76x0/mac.h index aee7dc8f258e..33b6e1e82eaa 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mac.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mac.h @@ -15,73 +15,6 @@ #ifndef __MT76_MAC_H #define __MT76_MAC_H -/* Note: values in original "RSSI" and "SNR" fields are not actually what they - * are called for MT76X0U, names used by this driver are educated guesses - * (see vendor mac/ral_omac.c). - */ -struct mt76x0_rxwi { - __le32 rxinfo; - - __le32 ctl; - - __le16 tid_sn; - __le16 rate; - - s8 rssi[4]; - - __le32 bbp_rxinfo[4]; -} __packed __aligned(4); - -enum mt76_phy_bandwidth { - MT_PHY_BW_20, - MT_PHY_BW_40, - MT_PHY_BW_80, -}; - -struct mt76_txwi { - __le16 flags; - __le16 rate_ctl; - u8 ack_ctl; - u8 wcid; - __le16 len_ctl; - __le32 iv; - __le32 eiv; - u8 aid; - u8 txstream; - u8 ctl2; - u8 pktid; -} __packed __aligned(4); - -#define MT_TXWI_FLAGS_FRAG BIT(0) -#define MT_TXWI_FLAGS_MMPS BIT(1) -#define MT_TXWI_FLAGS_CFACK BIT(2) -#define MT_TXWI_FLAGS_TS BIT(3) -#define MT_TXWI_FLAGS_AMPDU BIT(4) -#define MT_TXWI_FLAGS_MPDU_DENSITY GENMASK(7, 5) -#define MT_TXWI_FLAGS_TXOP GENMASK(9, 8) -#define MT_TXWI_FLAGS_CWMIN GENMASK(12, 10) -#define MT_TXWI_FLAGS_NO_RATE_FALLBACK BIT(13) -#define MT_TXWI_FLAGS_TX_RPT BIT(14) -#define MT_TXWI_FLAGS_TX_RATE_LUT BIT(15) - -#define MT_TXWI_RATE_MCS GENMASK(6, 0) -#define MT_TXWI_RATE_BW BIT(7) -#define MT_TXWI_RATE_SGI BIT(8) -#define MT_TXWI_RATE_STBC GENMASK(10, 9) -#define MT_TXWI_RATE_PHY_MODE GENMASK(15, 14) - -#define MT_TXWI_ACK_CTL_REQ BIT(0) -#define MT_TXWI_ACK_CTL_NSEQ BIT(1) -#define MT_TXWI_ACK_CTL_BA_WINDOW GENMASK(7, 2) - -#define MT_TXWI_LEN_BYTE_CNT GENMASK(11, 0) - -#define MT_TXWI_CTL_TX_POWER_ADJ GENMASK(3, 0) -#define MT_TXWI_CTL_CHAN_CHECK_PKT BIT(4) -#define MT_TXWI_CTL_PIFS_REV BIT(6) - -#define MT_TXWI_PKTID_PROBE BIT(7) - u32 mt76x0_mac_process_rx(struct mt76x0_dev *dev, struct sk_buff *skb, u8 *data, void *rxi); struct mt76x02_tx_status diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h index c3669735965b..7fbf379064f1 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h @@ -187,8 +187,6 @@ struct mt76x0_wcid { u8 tx_rate_nss; }; -struct mt76x0_rxwi; - extern const struct ieee80211_ops mt76x0_ops; static inline bool is_mt7610e(struct mt76x0_dev *dev) @@ -229,7 +227,7 @@ void mt76x0_agc_restore(struct mt76x0_dev *dev); int mt76x0_phy_set_channel(struct mt76x0_dev *dev, struct cfg80211_chan_def *chandef); void mt76x0_phy_recalibrate_after_assoc(struct mt76x0_dev *dev); -int mt76x0_phy_get_rssi(struct mt76x0_dev *dev, struct mt76x0_rxwi *rxwi); +int mt76x0_phy_get_rssi(struct mt76x0_dev *dev, struct mt76x02_rxwi *rxwi); void mt76x0_phy_con_cal_onoff(struct mt76x0_dev *dev, struct ieee80211_bss_conf *info); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c index 5da7bfbe907f..af30885b7e5e 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c @@ -225,7 +225,7 @@ mt76x0_bbp_set_ctrlch(struct mt76x0_dev *dev, enum nl80211_chan_width width, mt76_rmw_field(dev, MT_BBP(TXBE, 0), MT_BBP_TXBE_R0_CTRL_CHAN, ctrl); } -int mt76x0_phy_get_rssi(struct mt76x0_dev *dev, struct mt76x0_rxwi *rxwi) +int mt76x0_phy_get_rssi(struct mt76x0_dev *dev, struct mt76x02_rxwi *rxwi) { s8 lna_gain, rssi_offset; int val; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/trace.h b/drivers/net/wireless/mediatek/mt76/mt76x0/trace.h index d31ba71b9d5b..36bbdd585163 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/trace.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/trace.h @@ -178,11 +178,11 @@ DECLARE_EVENT_CLASS(dev_simple_evt, ); TRACE_EVENT(mt76x0_rx, - TP_PROTO(struct mt76_dev *dev, struct mt76x0_rxwi *rxwi, u32 f), + TP_PROTO(struct mt76_dev *dev, struct mt76x02_rxwi *rxwi, u32 f), TP_ARGS(dev, rxwi, f), TP_STRUCT__entry( DEV_ENTRY - __field_struct(struct mt76x0_rxwi, rxwi) + __field_struct(struct mt76x02_rxwi, rxwi) __field(u32, fce_info) ), TP_fast_assign( @@ -197,11 +197,11 @@ TRACE_EVENT(mt76x0_rx, TRACE_EVENT(mt76x0_tx, TP_PROTO(struct mt76_dev *dev, struct sk_buff *skb, - struct mt76x02_sta *sta, struct mt76_txwi *h), + struct mt76x02_sta *sta, struct mt76x02_txwi *h), TP_ARGS(dev, skb, sta, h), TP_STRUCT__entry( DEV_ENTRY - __field_struct(struct mt76_txwi, h) + __field_struct(struct mt76x02_txwi, h) __field(struct sk_buff *, skb) __field(struct mt76x02_sta *, sta) ), @@ -211,11 +211,11 @@ TRACE_EVENT(mt76x0_tx, __entry->skb = skb; __entry->sta = sta; ), - TP_printk(DEV_PR_FMT "skb:%p sta:%p flg:%04hx rate_ctl:%04hx " + TP_printk(DEV_PR_FMT "skb:%p sta:%p flg:%04hx rate:%04hx " "ack:%02hhx wcid:%02hhx len_ctl:%05hx", DEV_PR_ARG, __entry->skb, __entry->sta, le16_to_cpu(__entry->h.flags), - le16_to_cpu(__entry->h.rate_ctl), + le16_to_cpu(__entry->h.rate), __entry->h.ack_ctl, __entry->h.wcid, le16_to_cpu(__entry->h.len_ctl)) ); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c b/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c index eeb298719329..c94b9cf4231d 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c @@ -33,7 +33,7 @@ static void mt76x0_tx_skb_remove_dma_overhead(struct sk_buff *skb, { int pkt_len = (unsigned long)info->status.status_driver_data[0]; - skb_pull(skb, sizeof(struct mt76_txwi) + 4); + skb_pull(skb, sizeof(struct mt76x02_txwi) + 4); if (ieee80211_get_hdrlen_from_skb(skb) % 4) mt76x0_remove_hdr_pad(skb); @@ -60,28 +60,28 @@ static int mt76x0_skb_rooms(struct mt76x0_dev *dev, struct sk_buff *skb) int hdr_len = ieee80211_get_hdrlen_from_skb(skb); u32 need_head; - need_head = sizeof(struct mt76_txwi) + 4; + need_head = sizeof(struct mt76x02_txwi) + 4; if (hdr_len % 4) need_head += 2; return skb_cow(skb, need_head); } -static struct mt76_txwi * +static struct mt76x02_txwi * mt76x0_push_txwi(struct mt76x0_dev *dev, struct sk_buff *skb, struct ieee80211_sta *sta, struct mt76_wcid *wcid, int pkt_len) { struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct ieee80211_tx_rate *rate = &info->control.rates[0]; - struct mt76_txwi *txwi; + struct mt76x02_txwi *txwi; unsigned long flags; u16 txwi_flags = 0; u32 pkt_id; u16 rate_ctl; u8 nss; - txwi = (struct mt76_txwi *)skb_push(skb, sizeof(struct mt76_txwi)); + txwi = (struct mt76x02_txwi *)skb_push(skb, sizeof(struct mt76x02_txwi)); memset(txwi, 0, sizeof(*txwi)); if (!wcid->tx_rate_set) @@ -97,12 +97,12 @@ mt76x0_push_txwi(struct mt76x0_dev *dev, struct sk_buff *skb, } spin_unlock_irqrestore(&dev->mt76.lock, flags); - txwi->rate_ctl = cpu_to_le16(rate_ctl); + txwi->rate = cpu_to_le16(rate_ctl); if (info->flags & IEEE80211_TX_CTL_LDPC) - txwi->rate_ctl |= cpu_to_le16(MT_RXWI_RATE_LDPC); + txwi->rate |= cpu_to_le16(MT_RXWI_RATE_LDPC); if ((info->flags & IEEE80211_TX_CTL_STBC) && nss == 1) - txwi->rate_ctl |= cpu_to_le16(MT_RXWI_RATE_STBC); + txwi->rate |= cpu_to_le16(MT_RXWI_RATE_STBC); if (nss > 1 && sta && sta->smps_mode == IEEE80211_SMPS_DYNAMIC) txwi_flags |= MT_TXWI_FLAGS_MMPS; @@ -151,7 +151,7 @@ void mt76x0_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, struct ieee80211_sta *sta = control->sta; struct mt76x02_sta *msta = NULL; struct mt76_wcid *wcid = &dev->mt76.global_wcid; - struct mt76_txwi *txwi; + struct mt76x02_txwi *txwi; int pkt_len = skb->len; int hw_q = skb2q(skb); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h index fc880ffe3d8b..498b2b293d20 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h @@ -104,6 +104,60 @@ struct mt76x02_sta { #define MT_RATE_INDEX_VHT_IDX GENMASK(3, 0) #define MT_RATE_INDEX_VHT_NSS GENMASK(5, 4) +struct mt76x02_rxwi { + __le32 rxinfo; + + __le32 ctl; + + __le16 tid_sn; + __le16 rate; + + u8 rssi[4]; + + __le32 bbp_rxinfo[4]; +}; + +#define MT_TX_PWR_ADJ GENMASK(3, 0) + +enum mt76x2_phy_bandwidth { + MT_PHY_BW_20, + MT_PHY_BW_40, + MT_PHY_BW_80, +}; + +#define MT_TXWI_FLAGS_FRAG BIT(0) +#define MT_TXWI_FLAGS_MMPS BIT(1) +#define MT_TXWI_FLAGS_CFACK BIT(2) +#define MT_TXWI_FLAGS_TS BIT(3) +#define MT_TXWI_FLAGS_AMPDU BIT(4) +#define MT_TXWI_FLAGS_MPDU_DENSITY GENMASK(7, 5) +#define MT_TXWI_FLAGS_TXOP GENMASK(9, 8) +#define MT_TXWI_FLAGS_NDPS BIT(10) +#define MT_TXWI_FLAGS_RTSBWSIG BIT(11) +#define MT_TXWI_FLAGS_NDP_BW GENMASK(13, 12) +#define MT_TXWI_FLAGS_SOUND BIT(14) +#define MT_TXWI_FLAGS_TX_RATE_LUT BIT(15) + +#define MT_TXWI_ACK_CTL_REQ BIT(0) +#define MT_TXWI_ACK_CTL_NSEQ BIT(1) +#define MT_TXWI_ACK_CTL_BA_WINDOW GENMASK(7, 2) + +#define MT_TXWI_PKTID_PROBE BIT(7) + +struct mt76x02_txwi { + __le16 flags; + __le16 rate; + u8 ack_ctl; + u8 wcid; + __le16 len_ctl; + __le32 iv; + __le32 eiv; + u8 aid; + u8 txstream; + u8 ctl2; + u8 pktid; +} __packed __aligned(4); + static inline bool mt76x02_wait_for_mac(struct mt76_dev *dev) { const u32 MAC_CSR0 = 0x1000; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_common.c b/drivers/net/wireless/mediatek/mt76/mt76x2_common.c index 2db67f7a4bec..0f7f731ab285 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_common.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_common.c @@ -30,7 +30,7 @@ void mt76x2_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q, return; } - skb_pull(skb, sizeof(struct mt76x2_rxwi)); + skb_pull(skb, sizeof(struct mt76x02_rxwi)); if (mt76x2_mac_process_rx(dev, skb, rxwi)) { dev_kfree_skb(skb); return; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_dma.c b/drivers/net/wireless/mediatek/mt76/mt76x2_dma.c index 1c8e5d7be425..42cdccf481f7 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_dma.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_dma.c @@ -107,8 +107,8 @@ int mt76x2_dma_init(struct mt76x2_dev *dev) struct mt76_txwi_cache __maybe_unused *t; struct mt76_queue *q; - BUILD_BUG_ON(sizeof(t->txwi) < sizeof(struct mt76x2_txwi)); - BUILD_BUG_ON(sizeof(struct mt76x2_rxwi) > MT_RX_HEADROOM); + BUILD_BUG_ON(sizeof(t->txwi) < sizeof(struct mt76x02_txwi)); + BUILD_BUG_ON(sizeof(struct mt76x02_rxwi) > MT_RX_HEADROOM); mt76_dma_attach(&dev->mt76); @@ -142,7 +142,7 @@ int mt76x2_dma_init(struct mt76x2_dev *dev) return ret; q = &dev->mt76.q_rx[MT_RXQ_MAIN]; - q->buf_offset = MT_RX_HEADROOM - sizeof(struct mt76x2_rxwi); + q->buf_offset = MT_RX_HEADROOM - sizeof(struct mt76x02_rxwi); ret = mt76x2_init_rx_queue(dev, q, 0, MT76x2_RX_RING_SIZE, MT_RX_BUF_SIZE); if (ret) return ret; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_init.c b/drivers/net/wireless/mediatek/mt76/mt76x2_init.c index e59af314712c..c6d5e7db6edb 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_init.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_init.c @@ -417,7 +417,7 @@ void mt76x2_cleanup(struct mt76x2_dev *dev) struct mt76x2_dev *mt76x2_alloc_device(struct device *pdev) { static const struct mt76_driver_ops drv_ops = { - .txwi_size = sizeof(struct mt76x2_txwi), + .txwi_size = sizeof(struct mt76x02_txwi), .update_survey = mt76x2_update_channel, .tx_prepare_skb = mt76x2_tx_prepare_skb, .tx_complete_skb = mt76x2_tx_complete_skb, diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c index 71ab06050e23..0d37d0de0b84 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c @@ -64,7 +64,7 @@ mt76x2_mac_queue_txdone(struct mt76x2_dev *dev, struct sk_buff *skb, void *txwi_ptr) { struct mt76x2_tx_info *txi = mt76x2_skb_tx_info(skb); - struct mt76x2_txwi *txwi = txwi_ptr; + struct mt76x02_txwi *txwi = txwi_ptr; mt76x2_mac_poll_tx_status(dev, false); @@ -100,9 +100,9 @@ static int mt76_write_beacon(struct mt76x2_dev *dev, int offset, struct sk_buff *skb) { int beacon_len = dev->beacon_offsets[1] - dev->beacon_offsets[0]; - struct mt76x2_txwi txwi; + struct mt76x02_txwi txwi; - if (WARN_ON_ONCE(beacon_len < skb->len + sizeof(struct mt76x2_txwi))) + if (WARN_ON_ONCE(beacon_len < skb->len + sizeof(struct mt76x02_txwi))) return -ENOSPC; mt76x2_mac_write_txwi(dev, &txwi, skb, NULL, NULL, skb->len); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.h b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.h index 62cb34f4f362..66a57294fcfc 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.h @@ -23,7 +23,6 @@ struct mt76x2_dev; struct mt76x2_sta; struct mt76x02_vif; -struct mt76x2_txwi; struct mt76x2_tx_info { unsigned long jiffies; @@ -34,60 +33,6 @@ struct mt76x2_tx_info { u8 retry; }; -struct mt76x2_rxwi { - __le32 rxinfo; - - __le32 ctl; - - __le16 tid_sn; - __le16 rate; - - u8 rssi[4]; - - __le32 bbp_rxinfo[4]; -}; - -#define MT_TX_PWR_ADJ GENMASK(3, 0) - -enum mt76x2_phy_bandwidth { - MT_PHY_BW_20, - MT_PHY_BW_40, - MT_PHY_BW_80, -}; - -#define MT_TXWI_FLAGS_FRAG BIT(0) -#define MT_TXWI_FLAGS_MMPS BIT(1) -#define MT_TXWI_FLAGS_CFACK BIT(2) -#define MT_TXWI_FLAGS_TS BIT(3) -#define MT_TXWI_FLAGS_AMPDU BIT(4) -#define MT_TXWI_FLAGS_MPDU_DENSITY GENMASK(7, 5) -#define MT_TXWI_FLAGS_TXOP GENMASK(9, 8) -#define MT_TXWI_FLAGS_NDPS BIT(10) -#define MT_TXWI_FLAGS_RTSBWSIG BIT(11) -#define MT_TXWI_FLAGS_NDP_BW GENMASK(13, 12) -#define MT_TXWI_FLAGS_SOUND BIT(14) -#define MT_TXWI_FLAGS_TX_RATE_LUT BIT(15) - -#define MT_TXWI_ACK_CTL_REQ BIT(0) -#define MT_TXWI_ACK_CTL_NSEQ BIT(1) -#define MT_TXWI_ACK_CTL_BA_WINDOW GENMASK(7, 2) - -#define MT_TXWI_PKTID_PROBE BIT(7) - -struct mt76x2_txwi { - __le16 flags; - __le16 rate; - u8 ack_ctl; - u8 wcid; - __le16 len_ctl; - __le32 iv; - __le32 eiv; - u8 aid; - u8 txstream; - u8 ctl2; - u8 pktid; -} __packed __aligned(4); - static inline struct mt76x2_tx_info * mt76x2_skb_tx_info(struct sk_buff *skb) { @@ -103,7 +48,7 @@ void mt76x2_mac_set_bssid(struct mt76x2_dev *dev, u8 idx, const u8 *addr); int mt76x2_mac_process_rx(struct mt76x2_dev *dev, struct sk_buff *skb, void *rxi); -void mt76x2_mac_write_txwi(struct mt76x2_dev *dev, struct mt76x2_txwi *txwi, +void mt76x2_mac_write_txwi(struct mt76x2_dev *dev, struct mt76x02_txwi *txwi, struct sk_buff *skb, struct mt76_wcid *wcid, struct ieee80211_sta *sta, int len); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mac_common.c b/drivers/net/wireless/mediatek/mt76/mt76x2_mac_common.c index 85671244fdf9..3cd99d4debb8 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_mac_common.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mac_common.c @@ -229,7 +229,7 @@ void mt76x2_send_tx_status(struct mt76x2_dev *dev, } EXPORT_SYMBOL_GPL(mt76x2_send_tx_status); -void mt76x2_mac_write_txwi(struct mt76x2_dev *dev, struct mt76x2_txwi *txwi, +void mt76x2_mac_write_txwi(struct mt76x2_dev *dev, struct mt76x02_txwi *txwi, struct sk_buff *skb, struct mt76_wcid *wcid, struct ieee80211_sta *sta, int len) { @@ -443,7 +443,7 @@ int mt76x2_mac_process_rx(struct mt76x2_dev *dev, struct sk_buff *skb, void *rxi) { struct mt76_rx_status *status = (struct mt76_rx_status *) skb->cb; - struct mt76x2_rxwi *rxwi = rxi; + struct mt76x02_rxwi *rxwi = rxi; struct mt76x02_sta *sta; u32 rxinfo = le32_to_cpu(rxwi->rxinfo); u32 ctl = le32_to_cpu(rxwi->ctl); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2u_core.c b/drivers/net/wireless/mediatek/mt76/mt76x2u_core.c index 500d7db338aa..3bc37123ffd1 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2u_core.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2u_core.c @@ -21,7 +21,7 @@ static void mt76x2u_remove_dma_hdr(struct sk_buff *skb) { int hdr_len; - skb_pull(skb, sizeof(struct mt76x2_txwi) + MT_DMA_HDR_LEN); + skb_pull(skb, sizeof(struct mt76x02_txwi) + MT_DMA_HDR_LEN); hdr_len = ieee80211_get_hdrlen_from_skb(skb); if (hdr_len % 4) { memmove(skb->data + 2, skb->data, hdr_len); @@ -35,7 +35,7 @@ mt76x2u_check_skb_rooms(struct sk_buff *skb) int hdr_len = ieee80211_get_hdrlen_from_skb(skb); u32 need_head; - need_head = sizeof(struct mt76x2_txwi) + MT_DMA_HDR_LEN; + need_head = sizeof(struct mt76x02_txwi) + MT_DMA_HDR_LEN; if (hdr_len % 4) need_head += 2; return skb_cow(skb, need_head); @@ -82,7 +82,7 @@ int mt76x2u_tx_prepare_skb(struct mt76_dev *mdev, void *data, u32 *tx_info) { struct mt76x2_dev *dev = container_of(mdev, struct mt76x2_dev, mt76); - struct mt76x2_txwi *txwi; + struct mt76x02_txwi *txwi; int err, len = skb->len; err = mt76x2u_check_skb_rooms(skb); @@ -91,7 +91,7 @@ int mt76x2u_tx_prepare_skb(struct mt76_dev *mdev, void *data, mt76x2_insert_hdr_pad(skb); - txwi = skb_push(skb, sizeof(struct mt76x2_txwi)); + txwi = skb_push(skb, sizeof(struct mt76x02_txwi)); mt76x2_mac_write_txwi(dev, txwi, skb, wcid, sta, len); return mt76x2u_set_txinfo(skb, wcid, q2ep(q->hw_idx)); From b490b1df9a25d57a9499642fb7eaf9c4b58e67f7 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Tue, 4 Sep 2018 16:41:09 +0200 Subject: [PATCH 142/276] mt76: unify load_tx_status Unify load/fetch tx status from mt76x0 and mt76x2 Signed-off-by: Stanislaw Gruszka Signed-off-by: Felix Fietkau --- .../net/wireless/mediatek/mt76/mt76x0/mac.c | 21 ---------------- .../net/wireless/mediatek/mt76/mt76x0/tx.c | 3 +-- .../net/wireless/mediatek/mt76/mt76x02_mac.c | 25 +++++++++++++++++++ .../net/wireless/mediatek/mt76/mt76x02_mac.h | 2 ++ drivers/net/wireless/mediatek/mt76/mt76x2.h | 2 -- .../net/wireless/mediatek/mt76/mt76x2_mac.c | 2 +- .../mediatek/mt76/mt76x2_mac_common.c | 25 ------------------- .../net/wireless/mediatek/mt76/mt76x2u_core.c | 2 +- 8 files changed, 30 insertions(+), 52 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c b/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c index 46646a7461bd..41f681cfc5ef 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c @@ -116,27 +116,6 @@ mt76_mac_fill_tx_status(struct mt76x0_dev *dev, struct ieee80211_tx_info *info, info->flags |= IEEE80211_TX_STAT_ACK; } -struct mt76x02_tx_status mt76x0_mac_fetch_tx_status(struct mt76x0_dev *dev) -{ - struct mt76x02_tx_status stat = {}; - u32 stat2, stat1; - - stat2 = mt76_rr(dev, MT_TX_STAT_FIFO_EXT); - stat1 = mt76_rr(dev, MT_TX_STAT_FIFO); - - stat.valid = !!(stat1 & MT_TX_STAT_FIFO_VALID); - stat.success = !!(stat1 & MT_TX_STAT_FIFO_SUCCESS); - stat.aggr = !!(stat1 & MT_TX_STAT_FIFO_AGGR); - stat.ack_req = !!(stat1 & MT_TX_STAT_FIFO_ACKREQ); - stat.wcid = FIELD_GET(MT_TX_STAT_FIFO_WCID, stat1); - stat.rate = FIELD_GET(MT_TX_STAT_FIFO_RATE, stat1); - - stat.retry = FIELD_GET(MT_TX_STAT_FIFO_EXT_RETRY, stat2); - stat.pktid = FIELD_GET(MT_TX_STAT_FIFO_EXT_PKTID, stat2); - - return stat; -} - void mt76x0_send_tx_status(struct mt76x0_dev *dev, struct mt76x02_tx_status *stat, u8 *update) { struct ieee80211_tx_info info = {}; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c b/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c index c94b9cf4231d..9270469a580d 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c @@ -190,8 +190,7 @@ void mt76x0_tx_stat(struct work_struct *work) u8 update = 1; while (!test_bit(MT76_REMOVED, &dev->mt76.state)) { - stat = mt76x0_mac_fetch_tx_status(dev); - if (!stat.valid) + if (!mt76x02_mac_load_tx_status(&dev->mt76, &stat)) break; mt76x0_send_tx_status(dev, &stat, &update); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c index d67e12bd23a7..ea1f77579b7c 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c @@ -216,3 +216,28 @@ void mt76x02_mac_wcid_set_rate(struct mt76_dev *dev, struct mt76_wcid *wcid, wcid->tx_rate_set = true; spin_unlock_bh(&dev->lock); } + +bool mt76x02_mac_load_tx_status(struct mt76_dev *dev, + struct mt76x02_tx_status *stat) +{ + u32 stat1, stat2; + + stat2 = __mt76_rr(dev, MT_TX_STAT_FIFO_EXT); + stat1 = __mt76_rr(dev, MT_TX_STAT_FIFO); + + stat->valid = !!(stat1 & MT_TX_STAT_FIFO_VALID); + if (!stat->valid) + return false; + + stat->success = !!(stat1 & MT_TX_STAT_FIFO_SUCCESS); + stat->aggr = !!(stat1 & MT_TX_STAT_FIFO_AGGR); + stat->ack_req = !!(stat1 & MT_TX_STAT_FIFO_ACKREQ); + stat->wcid = FIELD_GET(MT_TX_STAT_FIFO_WCID, stat1); + stat->rate = FIELD_GET(MT_TX_STAT_FIFO_RATE, stat1); + + stat->retry = FIELD_GET(MT_TX_STAT_FIFO_EXT_RETRY, stat2); + stat->pktid = FIELD_GET(MT_TX_STAT_FIFO_EXT_PKTID, stat2); + + return true; +} +EXPORT_SYMBOL_GPL(mt76x02_mac_load_tx_status); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h index 498b2b293d20..0547f7db9d3d 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h @@ -195,4 +195,6 @@ void mt76x02_mac_wcid_set_rate(struct mt76_dev *dev, struct mt76_wcid *wcid, __le16 mt76x02_mac_tx_rate_val(struct mt76_dev *dev, const struct ieee80211_tx_rate *rate, u8 *nss_val); +bool mt76x02_mac_load_tx_status(struct mt76_dev *dev, + struct mt76x02_tx_status *stat); #endif diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2.h b/drivers/net/wireless/mediatek/mt76/mt76x2.h index faf830585515..0a29e7ae1a9d 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x2.h @@ -241,8 +241,6 @@ void mt76x2_tx_set_txpwr_auto(struct mt76x2_dev *dev, s8 txpwr); int mt76x2_insert_hdr_pad(struct sk_buff *skb); -bool mt76x2_mac_load_tx_status(struct mt76x2_dev *dev, - struct mt76x02_tx_status *stat); void mt76x2_send_tx_status(struct mt76x2_dev *dev, struct mt76x02_tx_status *stat, u8 *update); void mt76x2_reset_wlan(struct mt76x2_dev *dev, bool enable); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c index 0d37d0de0b84..b346f17e49d5 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c @@ -42,7 +42,7 @@ void mt76x2_mac_poll_tx_status(struct mt76x2_dev *dev, bool irq) while (!irq || !kfifo_is_full(&dev->txstatus_fifo)) { spin_lock_irqsave(&dev->irq_lock, flags); - ret = mt76x2_mac_load_tx_status(dev, &stat); + ret = mt76x02_mac_load_tx_status(&dev->mt76, &stat); spin_unlock_irqrestore(&dev->irq_lock, flags); if (!ret) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mac_common.c b/drivers/net/wireless/mediatek/mt76/mt76x2_mac_common.c index 3cd99d4debb8..4cd94bfc9dbc 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_mac_common.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mac_common.c @@ -53,31 +53,6 @@ void mt76x2_mac_stop(struct mt76x2_dev *dev, bool force) } EXPORT_SYMBOL_GPL(mt76x2_mac_stop); -bool mt76x2_mac_load_tx_status(struct mt76x2_dev *dev, - struct mt76x02_tx_status *stat) -{ - u32 stat1, stat2; - - stat2 = mt76_rr(dev, MT_TX_STAT_FIFO_EXT); - stat1 = mt76_rr(dev, MT_TX_STAT_FIFO); - - stat->valid = !!(stat1 & MT_TX_STAT_FIFO_VALID); - if (!stat->valid) - return false; - - stat->success = !!(stat1 & MT_TX_STAT_FIFO_SUCCESS); - stat->aggr = !!(stat1 & MT_TX_STAT_FIFO_AGGR); - stat->ack_req = !!(stat1 & MT_TX_STAT_FIFO_ACKREQ); - stat->wcid = FIELD_GET(MT_TX_STAT_FIFO_WCID, stat1); - stat->rate = FIELD_GET(MT_TX_STAT_FIFO_RATE, stat1); - - stat->retry = FIELD_GET(MT_TX_STAT_FIFO_EXT_RETRY, stat2); - stat->pktid = FIELD_GET(MT_TX_STAT_FIFO_EXT_PKTID, stat2); - - return true; -} -EXPORT_SYMBOL_GPL(mt76x2_mac_load_tx_status); - static int mt76x2_mac_process_tx_rate(struct ieee80211_tx_rate *txrate, u16 rate, enum nl80211_band band) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2u_core.c b/drivers/net/wireless/mediatek/mt76/mt76x2u_core.c index 3bc37123ffd1..ec434ad86cc0 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2u_core.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2u_core.c @@ -68,7 +68,7 @@ bool mt76x2u_tx_status_data(struct mt76_dev *mdev, u8 *update) struct mt76x2_dev *dev = container_of(mdev, struct mt76x2_dev, mt76); struct mt76x02_tx_status stat; - if (!mt76x2_mac_load_tx_status(dev, &stat)) + if (!mt76x02_mac_load_tx_status(&dev->mt76, &stat)) return false; mt76x2_send_tx_status(dev, &stat, update); From 7c1f888126909602954546bd926964abbe09b087 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Tue, 4 Sep 2018 16:41:10 +0200 Subject: [PATCH 143/276] mt76: unify send_tx_status and related helpers Merge send_tx_status and helper functions from mt76x0 and mt76x2. Signed-off-by: Stanislaw Gruszka Signed-off-by: Felix Fietkau --- .../net/wireless/mediatek/mt76/mt76x0/mac.c | 147 ----------------- .../net/wireless/mediatek/mt76/mt76x0/mac.h | 4 - .../net/wireless/mediatek/mt76/mt76x0/tx.c | 2 +- .../net/wireless/mediatek/mt76/mt76x02_mac.c | 151 ++++++++++++++++++ .../net/wireless/mediatek/mt76/mt76x02_mac.h | 2 + drivers/net/wireless/mediatek/mt76/mt76x2.h | 2 - .../net/wireless/mediatek/mt76/mt76x2_mac.c | 4 +- .../mediatek/mt76/mt76x2_mac_common.c | 151 ------------------ .../net/wireless/mediatek/mt76/mt76x2u_core.c | 2 +- 9 files changed, 157 insertions(+), 308 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c b/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c index 41f681cfc5ef..eecb9d015d70 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c @@ -17,153 +17,6 @@ #include "trace.h" #include -static void -mt76_mac_process_tx_rate(struct ieee80211_tx_rate *txrate, u16 rate, - enum nl80211_band band) -{ - u8 idx = FIELD_GET(MT_RXWI_RATE_INDEX, rate); - - txrate->idx = 0; - txrate->flags = 0; - txrate->count = 1; - - switch (FIELD_GET(MT_RXWI_RATE_PHY, rate)) { - case MT_PHY_TYPE_OFDM: - if (band == NL80211_BAND_2GHZ) - idx += 4; - - txrate->idx = idx; - return; - case MT_PHY_TYPE_CCK: - if (idx >= 8) - idx -= 8; - - txrate->idx = idx; - return; - case MT_PHY_TYPE_HT_GF: - txrate->flags |= IEEE80211_TX_RC_GREEN_FIELD; - /* fall through */ - case MT_PHY_TYPE_HT: - txrate->flags |= IEEE80211_TX_RC_MCS; - txrate->idx = idx; - break; - case MT_PHY_TYPE_VHT: - txrate->flags |= IEEE80211_TX_RC_VHT_MCS; - txrate->idx = idx; - break; - default: - WARN_ON(1); - return; - } - - switch (FIELD_GET(MT_RXWI_RATE_BW, rate)) { - case MT_PHY_BW_20: - break; - case MT_PHY_BW_40: - txrate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH; - break; - case MT_PHY_BW_80: - txrate->flags |= IEEE80211_TX_RC_80_MHZ_WIDTH; - break; - default: - WARN_ON(1); - return; - } - - if (rate & MT_RXWI_RATE_SGI) - txrate->flags |= IEEE80211_TX_RC_SHORT_GI; -} - -static void -mt76_mac_fill_tx_status(struct mt76x0_dev *dev, struct ieee80211_tx_info *info, - struct mt76x02_tx_status *st, int n_frames) -{ - struct ieee80211_tx_rate *rate = info->status.rates; - int cur_idx, last_rate; - int i; - - if (!n_frames) - return; - - last_rate = min_t(int, st->retry, IEEE80211_TX_MAX_RATES - 1); - mt76_mac_process_tx_rate(&rate[last_rate], st->rate, - dev->mt76.chandef.chan->band); - if (last_rate < IEEE80211_TX_MAX_RATES - 1) - rate[last_rate + 1].idx = -1; - - cur_idx = rate[last_rate].idx + last_rate; - for (i = 0; i <= last_rate; i++) { - rate[i].flags = rate[last_rate].flags; - rate[i].idx = max_t(int, 0, cur_idx - i); - rate[i].count = 1; - } - - rate[last_rate - 1].count = st->retry + 1 - last_rate; - - info->status.ampdu_len = n_frames; - info->status.ampdu_ack_len = st->success ? n_frames : 0; - - if (st->pktid & MT_TXWI_PKTID_PROBE) - info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE; - - if (st->aggr) - info->flags |= IEEE80211_TX_CTL_AMPDU | - IEEE80211_TX_STAT_AMPDU; - - if (!st->ack_req) - info->flags |= IEEE80211_TX_CTL_NO_ACK; - else if (st->success) - info->flags |= IEEE80211_TX_STAT_ACK; -} - -void mt76x0_send_tx_status(struct mt76x0_dev *dev, struct mt76x02_tx_status *stat, u8 *update) -{ - struct ieee80211_tx_info info = {}; - struct ieee80211_sta *sta = NULL; - struct mt76_wcid *wcid = NULL; - struct mt76x02_sta *msta = NULL; - - rcu_read_lock(); - if (stat->wcid < ARRAY_SIZE(dev->mt76.wcid)) - wcid = rcu_dereference(dev->mt76.wcid[stat->wcid]); - - if (wcid) { - void *priv; - priv = msta = container_of(wcid, struct mt76x02_sta, wcid); - sta = container_of(priv, struct ieee80211_sta, drv_priv); - } - - if (msta && stat->aggr) { - u32 stat_val, stat_cache; - - stat_val = stat->rate; - stat_val |= ((u32) stat->retry) << 16; - stat_cache = msta->status.rate; - stat_cache |= ((u32) msta->status.retry) << 16; - - if (*update == 0 && stat_val == stat_cache && - stat->wcid == msta->status.wcid && msta->n_frames < 32) { - msta->n_frames++; - goto out; - } - - mt76_mac_fill_tx_status(dev, &info, &msta->status, - msta->n_frames); - msta->status = *stat; - msta->n_frames = 1; - *update = 0; - } else { - mt76_mac_fill_tx_status(dev, &info, stat, 1); - *update = 1; - } - - spin_lock_bh(&dev->mac_lock); - ieee80211_tx_status_noskb(dev->mt76.hw, sta, &info); - spin_unlock_bh(&dev->mac_lock); -out: - rcu_read_unlock(); -} - void mt76x0_mac_set_protection(struct mt76x0_dev *dev, bool legacy_prot, int ht_mode) { diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mac.h b/drivers/net/wireless/mediatek/mt76/mt76x0/mac.h index 33b6e1e82eaa..abce22a51c87 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mac.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mac.h @@ -17,8 +17,4 @@ u32 mt76x0_mac_process_rx(struct mt76x0_dev *dev, struct sk_buff *skb, u8 *data, void *rxi); -struct mt76x02_tx_status -mt76x0_mac_fetch_tx_status(struct mt76x0_dev *dev); -void mt76x0_send_tx_status(struct mt76x0_dev *dev, struct mt76x02_tx_status *stat, u8 *update); - #endif diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c b/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c index 9270469a580d..fa902ac227ec 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c @@ -193,7 +193,7 @@ void mt76x0_tx_stat(struct work_struct *work) if (!mt76x02_mac_load_tx_status(&dev->mt76, &stat)) break; - mt76x0_send_tx_status(dev, &stat, &update); + mt76x02_send_tx_status(&dev->mt76, &stat, &update); cleaned++; } diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c index ea1f77579b7c..873e4701b403 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c @@ -241,3 +241,154 @@ bool mt76x02_mac_load_tx_status(struct mt76_dev *dev, return true; } EXPORT_SYMBOL_GPL(mt76x02_mac_load_tx_status); + +static int +mt76x02_mac_process_tx_rate(struct ieee80211_tx_rate *txrate, u16 rate, + enum nl80211_band band) +{ + u8 idx = FIELD_GET(MT_RXWI_RATE_INDEX, rate); + + txrate->idx = 0; + txrate->flags = 0; + txrate->count = 1; + + switch (FIELD_GET(MT_RXWI_RATE_PHY, rate)) { + case MT_PHY_TYPE_OFDM: + if (band == NL80211_BAND_2GHZ) + idx += 4; + + txrate->idx = idx; + return 0; + case MT_PHY_TYPE_CCK: + if (idx >= 8) + idx -= 8; + + txrate->idx = idx; + return 0; + case MT_PHY_TYPE_HT_GF: + txrate->flags |= IEEE80211_TX_RC_GREEN_FIELD; + /* fall through */ + case MT_PHY_TYPE_HT: + txrate->flags |= IEEE80211_TX_RC_MCS; + txrate->idx = idx; + break; + case MT_PHY_TYPE_VHT: + txrate->flags |= IEEE80211_TX_RC_VHT_MCS; + txrate->idx = idx; + break; + default: + return -EINVAL; + } + + switch (FIELD_GET(MT_RXWI_RATE_BW, rate)) { + case MT_PHY_BW_20: + break; + case MT_PHY_BW_40: + txrate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH; + break; + case MT_PHY_BW_80: + txrate->flags |= IEEE80211_TX_RC_80_MHZ_WIDTH; + break; + default: + return -EINVAL; + } + + if (rate & MT_RXWI_RATE_SGI) + txrate->flags |= IEEE80211_TX_RC_SHORT_GI; + + return 0; +} + +static void +mt76x02_mac_fill_tx_status(struct mt76_dev *dev, + struct ieee80211_tx_info *info, + struct mt76x02_tx_status *st, int n_frames) +{ + struct ieee80211_tx_rate *rate = info->status.rates; + int cur_idx, last_rate; + int i; + + if (!n_frames) + return; + + last_rate = min_t(int, st->retry, IEEE80211_TX_MAX_RATES - 1); + mt76x02_mac_process_tx_rate(&rate[last_rate], st->rate, + dev->chandef.chan->band); + if (last_rate < IEEE80211_TX_MAX_RATES - 1) + rate[last_rate + 1].idx = -1; + + cur_idx = rate[last_rate].idx + last_rate; + for (i = 0; i <= last_rate; i++) { + rate[i].flags = rate[last_rate].flags; + rate[i].idx = max_t(int, 0, cur_idx - i); + rate[i].count = 1; + } + rate[last_rate].count = st->retry + 1 - last_rate; + + info->status.ampdu_len = n_frames; + info->status.ampdu_ack_len = st->success ? n_frames : 0; + + if (st->pktid & MT_TXWI_PKTID_PROBE) + info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE; + + if (st->aggr) + info->flags |= IEEE80211_TX_CTL_AMPDU | + IEEE80211_TX_STAT_AMPDU; + + if (!st->ack_req) + info->flags |= IEEE80211_TX_CTL_NO_ACK; + else if (st->success) + info->flags |= IEEE80211_TX_STAT_ACK; +} + +void mt76x02_send_tx_status(struct mt76_dev *dev, + struct mt76x02_tx_status *stat, u8 *update) +{ + struct ieee80211_tx_info info = {}; + struct ieee80211_sta *sta = NULL; + struct mt76_wcid *wcid = NULL; + struct mt76x02_sta *msta = NULL; + + rcu_read_lock(); + if (stat->wcid < ARRAY_SIZE(dev->wcid)) + wcid = rcu_dereference(dev->wcid[stat->wcid]); + + if (wcid) { + void *priv; + + priv = msta = container_of(wcid, struct mt76x02_sta, wcid); + sta = container_of(priv, struct ieee80211_sta, + drv_priv); + } + + if (msta && stat->aggr) { + u32 stat_val, stat_cache; + + stat_val = stat->rate; + stat_val |= ((u32) stat->retry) << 16; + stat_cache = msta->status.rate; + stat_cache |= ((u32) msta->status.retry) << 16; + + if (*update == 0 && stat_val == stat_cache && + stat->wcid == msta->status.wcid && msta->n_frames < 32) { + msta->n_frames++; + goto out; + } + + mt76x02_mac_fill_tx_status(dev, &info, &msta->status, + msta->n_frames); + + msta->status = *stat; + msta->n_frames = 1; + *update = 0; + } else { + mt76x02_mac_fill_tx_status(dev, &info, stat, 1); + *update = 1; + } + + ieee80211_tx_status_noskb(dev->hw, sta, &info); + +out: + rcu_read_unlock(); +} +EXPORT_SYMBOL_GPL(mt76x02_send_tx_status); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h index 0547f7db9d3d..4ba38f2aa24c 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h @@ -197,4 +197,6 @@ mt76x02_mac_tx_rate_val(struct mt76_dev *dev, const struct ieee80211_tx_rate *rate, u8 *nss_val); bool mt76x02_mac_load_tx_status(struct mt76_dev *dev, struct mt76x02_tx_status *stat); +void mt76x02_send_tx_status(struct mt76_dev *dev, + struct mt76x02_tx_status *stat, u8 *update); #endif diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2.h b/drivers/net/wireless/mediatek/mt76/mt76x2.h index 0a29e7ae1a9d..b3a936edfb30 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x2.h @@ -241,8 +241,6 @@ void mt76x2_tx_set_txpwr_auto(struct mt76x2_dev *dev, s8 txpwr); int mt76x2_insert_hdr_pad(struct sk_buff *skb); -void mt76x2_send_tx_status(struct mt76x2_dev *dev, - struct mt76x02_tx_status *stat, u8 *update); void mt76x2_reset_wlan(struct mt76x2_dev *dev, bool enable); void mt76x2_init_txpower(struct mt76x2_dev *dev, struct ieee80211_supported_band *sband); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c index b346f17e49d5..3bb02b55f146 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c @@ -51,7 +51,7 @@ void mt76x2_mac_poll_tx_status(struct mt76x2_dev *dev, bool irq) trace_mac_txstat_fetch(dev, &stat); if (!irq) { - mt76x2_send_tx_status(dev, &stat, &update); + mt76x02_send_tx_status(&dev->mt76, &stat, &update); continue; } @@ -82,7 +82,7 @@ void mt76x2_mac_process_tx_status_fifo(struct mt76x2_dev *dev) u8 update = 1; while (kfifo_get(&dev->txstatus_fifo, &stat)) - mt76x2_send_tx_status(dev, &stat, &update); + mt76x02_send_tx_status(&dev->mt76, &stat, &update); } void mt76x2_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue *q, diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mac_common.c b/drivers/net/wireless/mediatek/mt76/mt76x2_mac_common.c index 4cd94bfc9dbc..1ebc3bfa9d6a 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_mac_common.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mac_common.c @@ -53,157 +53,6 @@ void mt76x2_mac_stop(struct mt76x2_dev *dev, bool force) } EXPORT_SYMBOL_GPL(mt76x2_mac_stop); -static int -mt76x2_mac_process_tx_rate(struct ieee80211_tx_rate *txrate, u16 rate, - enum nl80211_band band) -{ - u8 idx = FIELD_GET(MT_RXWI_RATE_INDEX, rate); - - txrate->idx = 0; - txrate->flags = 0; - txrate->count = 1; - - switch (FIELD_GET(MT_RXWI_RATE_PHY, rate)) { - case MT_PHY_TYPE_OFDM: - if (band == NL80211_BAND_2GHZ) - idx += 4; - - txrate->idx = idx; - return 0; - case MT_PHY_TYPE_CCK: - if (idx >= 8) - idx -= 8; - - txrate->idx = idx; - return 0; - case MT_PHY_TYPE_HT_GF: - txrate->flags |= IEEE80211_TX_RC_GREEN_FIELD; - /* fall through */ - case MT_PHY_TYPE_HT: - txrate->flags |= IEEE80211_TX_RC_MCS; - txrate->idx = idx; - break; - case MT_PHY_TYPE_VHT: - txrate->flags |= IEEE80211_TX_RC_VHT_MCS; - txrate->idx = idx; - break; - default: - return -EINVAL; - } - - switch (FIELD_GET(MT_RXWI_RATE_BW, rate)) { - case MT_PHY_BW_20: - break; - case MT_PHY_BW_40: - txrate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH; - break; - case MT_PHY_BW_80: - txrate->flags |= IEEE80211_TX_RC_80_MHZ_WIDTH; - break; - default: - return -EINVAL; - } - - if (rate & MT_RXWI_RATE_SGI) - txrate->flags |= IEEE80211_TX_RC_SHORT_GI; - - return 0; -} - -static void -mt76x2_mac_fill_tx_status(struct mt76x2_dev *dev, - struct ieee80211_tx_info *info, - struct mt76x02_tx_status *st, int n_frames) -{ - struct ieee80211_tx_rate *rate = info->status.rates; - int cur_idx, last_rate; - int i; - - if (!n_frames) - return; - - last_rate = min_t(int, st->retry, IEEE80211_TX_MAX_RATES - 1); - mt76x2_mac_process_tx_rate(&rate[last_rate], st->rate, - dev->mt76.chandef.chan->band); - if (last_rate < IEEE80211_TX_MAX_RATES - 1) - rate[last_rate + 1].idx = -1; - - cur_idx = rate[last_rate].idx + last_rate; - for (i = 0; i <= last_rate; i++) { - rate[i].flags = rate[last_rate].flags; - rate[i].idx = max_t(int, 0, cur_idx - i); - rate[i].count = 1; - } - rate[last_rate].count = st->retry + 1 - last_rate; - - info->status.ampdu_len = n_frames; - info->status.ampdu_ack_len = st->success ? n_frames : 0; - - if (st->pktid & MT_TXWI_PKTID_PROBE) - info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE; - - if (st->aggr) - info->flags |= IEEE80211_TX_CTL_AMPDU | - IEEE80211_TX_STAT_AMPDU; - - if (!st->ack_req) - info->flags |= IEEE80211_TX_CTL_NO_ACK; - else if (st->success) - info->flags |= IEEE80211_TX_STAT_ACK; -} - -void mt76x2_send_tx_status(struct mt76x2_dev *dev, - struct mt76x02_tx_status *stat, u8 *update) -{ - struct ieee80211_tx_info info = {}; - struct ieee80211_sta *sta = NULL; - struct mt76_wcid *wcid = NULL; - struct mt76x02_sta *msta = NULL; - - rcu_read_lock(); - if (stat->wcid < ARRAY_SIZE(dev->mt76.wcid)) - wcid = rcu_dereference(dev->mt76.wcid[stat->wcid]); - - if (wcid) { - void *priv; - - priv = msta = container_of(wcid, struct mt76x02_sta, wcid); - sta = container_of(priv, struct ieee80211_sta, - drv_priv); - } - - if (msta && stat->aggr) { - u32 stat_val, stat_cache; - - stat_val = stat->rate; - stat_val |= ((u32) stat->retry) << 16; - stat_cache = msta->status.rate; - stat_cache |= ((u32) msta->status.retry) << 16; - - if (*update == 0 && stat_val == stat_cache && - stat->wcid == msta->status.wcid && msta->n_frames < 32) { - msta->n_frames++; - goto out; - } - - mt76x2_mac_fill_tx_status(dev, &info, &msta->status, - msta->n_frames); - - msta->status = *stat; - msta->n_frames = 1; - *update = 0; - } else { - mt76x2_mac_fill_tx_status(dev, &info, stat, 1); - *update = 1; - } - - ieee80211_tx_status_noskb(mt76_hw(dev), sta, &info); - -out: - rcu_read_unlock(); -} -EXPORT_SYMBOL_GPL(mt76x2_send_tx_status); - void mt76x2_mac_write_txwi(struct mt76x2_dev *dev, struct mt76x02_txwi *txwi, struct sk_buff *skb, struct mt76_wcid *wcid, struct ieee80211_sta *sta, int len) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2u_core.c b/drivers/net/wireless/mediatek/mt76/mt76x2u_core.c index ec434ad86cc0..4aa781e852d7 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2u_core.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2u_core.c @@ -71,7 +71,7 @@ bool mt76x2u_tx_status_data(struct mt76_dev *mdev, u8 *update) if (!mt76x02_mac_load_tx_status(&dev->mt76, &stat)) return false; - mt76x2_send_tx_status(dev, &stat, update); + mt76x02_send_tx_status(&dev->mt76, &stat, update); return true; } From 82e1dd0f39bda541b529cf2676f63a0d0cb2cfea Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Tue, 4 Sep 2018 16:41:11 +0200 Subject: [PATCH 144/276] mt76: use mt76_rx_status in mt76x0 Make rx status processing similar to mt76x2. Signed-off-by: Stanislaw Gruszka Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mac80211.c | 3 ++- drivers/net/wireless/mediatek/mt76/mt76.h | 2 ++ drivers/net/wireless/mediatek/mt76/mt76x0/dma.c | 2 ++ drivers/net/wireless/mediatek/mt76/mt76x0/mac.c | 4 ++-- 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c b/drivers/net/wireless/mediatek/mt76/mac80211.c index 2bc386f4387c..639cbafc1d50 100644 --- a/drivers/net/wireless/mediatek/mt76/mac80211.c +++ b/drivers/net/wireless/mediatek/mt76/mac80211.c @@ -475,7 +475,7 @@ void mt76_wcid_key_setup(struct mt76_dev *dev, struct mt76_wcid *wcid, } EXPORT_SYMBOL(mt76_wcid_key_setup); -static struct ieee80211_sta *mt76_rx_convert(struct sk_buff *skb) +struct ieee80211_sta *mt76_rx_convert(struct sk_buff *skb) { struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); struct mt76_rx_status mstat; @@ -500,6 +500,7 @@ static struct ieee80211_sta *mt76_rx_convert(struct sk_buff *skb) return wcid_to_sta(mstat.wcid); } +EXPORT_SYMBOL(mt76_rx_convert); static int mt76_check_ccmp_pn(struct sk_buff *skb) diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h index cbd223c1c01a..8e33d7c53557 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76.h +++ b/drivers/net/wireless/mediatek/mt76/mt76.h @@ -573,6 +573,8 @@ void mt76_rx_aggr_stop(struct mt76_dev *dev, struct mt76_wcid *wcid, u8 tid); void mt76_wcid_key_setup(struct mt76_dev *dev, struct mt76_wcid *wcid, struct ieee80211_key_conf *key); +struct ieee80211_sta *mt76_rx_convert(struct sk_buff *skb); + /* internal */ void mt76_tx_free(struct mt76_dev *dev); struct mt76_txwi_cache *mt76_get_txwi(struct mt76_dev *dev); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/dma.c b/drivers/net/wireless/mediatek/mt76/mt76x0/dma.c index 05e577342a90..f29402861ced 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/dma.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/dma.c @@ -111,6 +111,8 @@ static void mt76x0_rx_process_seg(struct mt76x0_dev *dev, u8 *data, if (!skb) return; + mt76_rx_convert(skb); + spin_lock(&dev->mac_lock); ieee80211_rx(dev->mt76.hw, skb); spin_unlock(&dev->mac_lock); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c b/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c index eecb9d015d70..c1170d4800b4 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c @@ -196,7 +196,7 @@ void mt76x0_mac_set_ampdu_factor(struct mt76x0_dev *dev) } static void -mt76_mac_process_rate(struct ieee80211_rx_status *status, u16 rate) +mt76_mac_process_rate(struct mt76_rx_status *status, u16 rate) { u8 idx = FIELD_GET(MT_RXWI_RATE_INDEX, rate); @@ -282,7 +282,7 @@ mt76x0_rx_is_our_beacon(struct mt76x0_dev *dev, u8 *data) u32 mt76x0_mac_process_rx(struct mt76x0_dev *dev, struct sk_buff *skb, u8 *data, void *rxi) { - struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); + struct mt76_rx_status *status = (struct mt76_rx_status *) skb->cb; struct mt76x02_rxwi *rxwi = rxi; u32 len, ctl = le32_to_cpu(rxwi->ctl); u16 rate = le16_to_cpu(rxwi->rate); From 74ff45393bf866043eb31c5e9a7b528b6698710e Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Tue, 4 Sep 2018 16:41:12 +0200 Subject: [PATCH 145/276] mt76: unify mac_process_rate Merge mac_process_rate from mt76x0 and mt76x2. Signed-off-by: Stanislaw Gruszka Signed-off-by: Felix Fietkau --- .../net/wireless/mediatek/mt76/mt76x0/mac.c | 69 +------------------ .../net/wireless/mediatek/mt76/mt76x02_mac.c | 68 ++++++++++++++++++ .../net/wireless/mediatek/mt76/mt76x02_mac.h | 2 + .../mediatek/mt76/mt76x2_mac_common.c | 69 +------------------ 4 files changed, 72 insertions(+), 136 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c b/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c index c1170d4800b4..99e2e1225d55 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c @@ -195,73 +195,6 @@ void mt76x0_mac_set_ampdu_factor(struct mt76x0_dev *dev) FIELD_PREP(MT_MAX_LEN_CFG_AMPDU, min_factor)); } -static void -mt76_mac_process_rate(struct mt76_rx_status *status, u16 rate) -{ - u8 idx = FIELD_GET(MT_RXWI_RATE_INDEX, rate); - - switch (FIELD_GET(MT_RXWI_RATE_PHY, rate)) { - case MT_PHY_TYPE_OFDM: - if (idx >= 8) - idx = 0; - - if (status->band == NL80211_BAND_2GHZ) - idx += 4; - - status->rate_idx = idx; - return; - case MT_PHY_TYPE_CCK: - if (idx >= 8) { - idx -= 8; - status->enc_flags |= RX_ENC_FLAG_SHORTPRE; - } - - if (idx >= 4) - idx = 0; - - status->rate_idx = idx; - return; - case MT_PHY_TYPE_HT_GF: - status->enc_flags |= RX_ENC_FLAG_HT_GF; - /* fall through */ - case MT_PHY_TYPE_HT: - status->encoding = RX_ENC_HT; - status->rate_idx = idx; - break; - case MT_PHY_TYPE_VHT: - status->encoding = RX_ENC_VHT; - status->rate_idx = FIELD_GET(MT_RATE_INDEX_VHT_IDX, idx); - status->nss = FIELD_GET(MT_RATE_INDEX_VHT_NSS, idx) + 1; - break; - default: - WARN_ON(1); - return; - } - - if (rate & MT_RXWI_RATE_LDPC) - status->enc_flags |= RX_ENC_FLAG_LDPC; - - if (rate & MT_RXWI_RATE_SGI) - status->enc_flags |= RX_ENC_FLAG_SHORT_GI; - - if (rate & MT_RXWI_RATE_STBC) - status->enc_flags |= 1 << RX_ENC_FLAG_STBC_SHIFT; - - switch (FIELD_GET(MT_RXWI_RATE_BW, rate)) { - case MT_PHY_BW_20: - break; - case MT_PHY_BW_40: - status->bw = RATE_INFO_BW_40; - break; - case MT_PHY_BW_80: - status->bw = RATE_INFO_BW_80; - break; - default: - WARN_ON(1); - break; - } -} - static void mt76x0_rx_monitor_beacon(struct mt76x0_dev *dev, struct mt76x02_rxwi *rxwi, u16 rate, int rssi) @@ -303,7 +236,7 @@ u32 mt76x0_mac_process_rx(struct mt76x0_dev *dev, struct sk_buff *skb, status->freq = dev->mt76.chandef.chan->center_freq; status->band = dev->mt76.chandef.chan->band; - mt76_mac_process_rate(status, rate); + mt76x02_mac_process_rate(status, rate); spin_lock_bh(&dev->con_mon_lock); if (mt76x0_rx_is_our_beacon(dev, data)) { diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c index 873e4701b403..f80290d4442a 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c @@ -392,3 +392,71 @@ void mt76x02_send_tx_status(struct mt76_dev *dev, rcu_read_unlock(); } EXPORT_SYMBOL_GPL(mt76x02_send_tx_status); + +int +mt76x02_mac_process_rate(struct mt76_rx_status *status, u16 rate) +{ + u8 idx = FIELD_GET(MT_RXWI_RATE_INDEX, rate); + + switch (FIELD_GET(MT_RXWI_RATE_PHY, rate)) { + case MT_PHY_TYPE_OFDM: + if (idx >= 8) + idx = 0; + + if (status->band == NL80211_BAND_2GHZ) + idx += 4; + + status->rate_idx = idx; + return 0; + case MT_PHY_TYPE_CCK: + if (idx >= 8) { + idx -= 8; + status->enc_flags |= RX_ENC_FLAG_SHORTPRE; + } + + if (idx >= 4) + idx = 0; + + status->rate_idx = idx; + return 0; + case MT_PHY_TYPE_HT_GF: + status->enc_flags |= RX_ENC_FLAG_HT_GF; + /* fall through */ + case MT_PHY_TYPE_HT: + status->encoding = RX_ENC_HT; + status->rate_idx = idx; + break; + case MT_PHY_TYPE_VHT: + status->encoding = RX_ENC_VHT; + status->rate_idx = FIELD_GET(MT_RATE_INDEX_VHT_IDX, idx); + status->nss = FIELD_GET(MT_RATE_INDEX_VHT_NSS, idx) + 1; + break; + default: + return -EINVAL; + } + + if (rate & MT_RXWI_RATE_LDPC) + status->enc_flags |= RX_ENC_FLAG_LDPC; + + if (rate & MT_RXWI_RATE_SGI) + status->enc_flags |= RX_ENC_FLAG_SHORT_GI; + + if (rate & MT_RXWI_RATE_STBC) + status->enc_flags |= 1 << RX_ENC_FLAG_STBC_SHIFT; + + switch (FIELD_GET(MT_RXWI_RATE_BW, rate)) { + case MT_PHY_BW_20: + break; + case MT_PHY_BW_40: + status->bw = RATE_INFO_BW_40; + break; + case MT_PHY_BW_80: + status->bw = RATE_INFO_BW_80; + break; + default: + break; + } + + return 0; +} +EXPORT_SYMBOL_GPL(mt76x02_mac_process_rate); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h index 4ba38f2aa24c..61dd2efb5cbc 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h @@ -199,4 +199,6 @@ bool mt76x02_mac_load_tx_status(struct mt76_dev *dev, struct mt76x02_tx_status *stat); void mt76x02_send_tx_status(struct mt76_dev *dev, struct mt76x02_tx_status *stat, u8 *update); +int +mt76x02_mac_process_rate(struct mt76_rx_status *status, u16 rate); #endif diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mac_common.c b/drivers/net/wireless/mediatek/mt76/mt76x2_mac_common.c index 1ebc3bfa9d6a..039fce3d1daa 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_mac_common.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mac_common.c @@ -146,73 +146,6 @@ void mt76x2_mac_write_txwi(struct mt76x2_dev *dev, struct mt76x02_txwi *txwi, } EXPORT_SYMBOL_GPL(mt76x2_mac_write_txwi); -static int -mt76x2_mac_process_rate(struct mt76_rx_status *status, u16 rate) -{ - u8 idx = FIELD_GET(MT_RXWI_RATE_INDEX, rate); - - switch (FIELD_GET(MT_RXWI_RATE_PHY, rate)) { - case MT_PHY_TYPE_OFDM: - if (idx >= 8) - idx = 0; - - if (status->band == NL80211_BAND_2GHZ) - idx += 4; - - status->rate_idx = idx; - return 0; - case MT_PHY_TYPE_CCK: - if (idx >= 8) { - idx -= 8; - status->enc_flags |= RX_ENC_FLAG_SHORTPRE; - } - - if (idx >= 4) - idx = 0; - - status->rate_idx = idx; - return 0; - case MT_PHY_TYPE_HT_GF: - status->enc_flags |= RX_ENC_FLAG_HT_GF; - /* fall through */ - case MT_PHY_TYPE_HT: - status->encoding = RX_ENC_HT; - status->rate_idx = idx; - break; - case MT_PHY_TYPE_VHT: - status->encoding = RX_ENC_VHT; - status->rate_idx = FIELD_GET(MT_RATE_INDEX_VHT_IDX, idx); - status->nss = FIELD_GET(MT_RATE_INDEX_VHT_NSS, idx) + 1; - break; - default: - return -EINVAL; - } - - if (rate & MT_RXWI_RATE_LDPC) - status->enc_flags |= RX_ENC_FLAG_LDPC; - - if (rate & MT_RXWI_RATE_SGI) - status->enc_flags |= RX_ENC_FLAG_SHORT_GI; - - if (rate & MT_RXWI_RATE_STBC) - status->enc_flags |= 1 << RX_ENC_FLAG_STBC_SHIFT; - - switch (FIELD_GET(MT_RXWI_RATE_BW, rate)) { - case MT_PHY_BW_20: - break; - case MT_PHY_BW_40: - status->bw = RATE_INFO_BW_40; - break; - case MT_PHY_BW_80: - status->bw = RATE_INFO_BW_80; - break; - default: - break; - } - - return 0; -} - static void mt76x2_remove_hdr_pad(struct sk_buff *skb, int len) { int hdrlen; @@ -345,6 +278,6 @@ int mt76x2_mac_process_rx(struct mt76x2_dev *dev, struct sk_buff *skb, sta->inactive_count = 0; } - return mt76x2_mac_process_rate(status, rate); + return mt76x02_mac_process_rate(status, rate); } EXPORT_SYMBOL_GPL(mt76x2_mac_process_rx); From 493703aa9e3c861bcfd5f28ac1b0117e77d829fa Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Tue, 4 Sep 2018 16:41:13 +0200 Subject: [PATCH 146/276] mt76x0: reserve enough space in mac80211 Allocate skg with enough headroom by mac80211 , this eliminate need to add extra skb headroom by the mt76x0 driver. Signed-off-by: Stanislaw Gruszka Signed-off-by: Felix Fietkau --- .../net/wireless/mediatek/mt76/mt76x0/init.c | 1 + drivers/net/wireless/mediatek/mt76/mt76x0/tx.c | 17 +---------------- 2 files changed, 2 insertions(+), 16 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c index 84fc306d2cbf..45c9f1f7a89a 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c @@ -685,6 +685,7 @@ int mt76x0_register_device(struct mt76x0_dev *dev) hw->max_rates = 1; hw->max_report_rates = 7; hw->max_rate_tries = 1; + hw->extra_tx_headroom = sizeof(struct mt76x02_txwi) + 4 + 2; hw->sta_data_size = sizeof(struct mt76x02_sta); hw->vif_data_size = sizeof(struct mt76x02_vif); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c b/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c index fa902ac227ec..35db38523e3b 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c @@ -55,18 +55,6 @@ void mt76x0_tx_status(struct mt76x0_dev *dev, struct sk_buff *skb) spin_unlock(&dev->mac_lock); } -static int mt76x0_skb_rooms(struct mt76x0_dev *dev, struct sk_buff *skb) -{ - int hdr_len = ieee80211_get_hdrlen_from_skb(skb); - u32 need_head; - - need_head = sizeof(struct mt76x02_txwi) + 4; - if (hdr_len % 4) - need_head += 2; - - return skb_cow(skb, need_head); -} - static struct mt76x02_txwi * mt76x0_push_txwi(struct mt76x0_dev *dev, struct sk_buff *skb, struct ieee80211_sta *sta, struct mt76_wcid *wcid, @@ -158,10 +146,7 @@ void mt76x0_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, BUILD_BUG_ON(ARRAY_SIZE(info->status.status_driver_data) < 1); info->status.status_driver_data[0] = (void *)(unsigned long)pkt_len; - if (mt76x0_skb_rooms(dev, skb) || mt76x0_insert_hdr_pad(skb)) { - ieee80211_free_txskb(dev->mt76.hw, skb); - return; - } + mt76x0_insert_hdr_pad(skb); if (sta) { msta = (struct mt76x02_sta *) sta->drv_priv; From 0e59cba856049a227baac9da9b22ea1470a40fa0 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Tue, 4 Sep 2018 16:41:14 +0200 Subject: [PATCH 147/276] mt76: unify {insert/remove}_hdr_pad Merge insert/remove _hdr_pad from mt76x0 and mt76x2. Signed-off-by: Stanislaw Gruszka Signed-off-by: Felix Fietkau --- .../wireless/mediatek/mt76/mt76x0/Makefile | 2 +- .../wireless/mediatek/mt76/mt76x0/mt76x0.h | 4 -- .../net/wireless/mediatek/mt76/mt76x0/tx.c | 5 ++- .../net/wireless/mediatek/mt76/mt76x0/util.c | 42 ------------------- .../net/wireless/mediatek/mt76/mt76x02_util.c | 29 +++++++++++++ .../net/wireless/mediatek/mt76/mt76x02_util.h | 2 + drivers/net/wireless/mediatek/mt76/mt76x2.h | 1 - .../mediatek/mt76/mt76x2_mac_common.c | 15 +------ .../net/wireless/mediatek/mt76/mt76x2_tx.c | 3 +- .../wireless/mediatek/mt76/mt76x2_tx_common.c | 16 ------- .../net/wireless/mediatek/mt76/mt76x2u_core.c | 3 +- 11 files changed, 41 insertions(+), 81 deletions(-) delete mode 100644 drivers/net/wireless/mediatek/mt76/mt76x0/util.c diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/Makefile b/drivers/net/wireless/mediatek/mt76/mt76x0/Makefile index 2f1721263aa5..a4a446921d2f 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/Makefile +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/Makefile @@ -2,6 +2,6 @@ obj-$(CONFIG_MT76x0U) += mt76x0.o mt76x0-objs = \ usb.o init.o main.o mcu.o trace.o dma.o eeprom.o phy.o \ - mac.o util.o debugfs.o tx.o + mac.o debugfs.o tx.o # ccflags-y := -DDEBUG CFLAGS_trace.o := -I$(src) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h index 7fbf379064f1..8510f120a121 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h @@ -245,10 +245,6 @@ void mt76x0_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, void mt76x0_tx_status(struct mt76x0_dev *dev, struct sk_buff *skb); void mt76x0_tx_stat(struct work_struct *work); -/* util */ -void mt76x0_remove_hdr_pad(struct sk_buff *skb); -int mt76x0_insert_hdr_pad(struct sk_buff *skb); - int mt76x0_dma_init(struct mt76x0_dev *dev); void mt76x0_dma_cleanup(struct mt76x0_dev *dev); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c b/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c index 35db38523e3b..92d06cca0266 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c @@ -14,6 +14,7 @@ #include "mt76x0.h" #include "trace.h" +#include "../mt76x02_util.h" /* Take mac80211 Q id from the skb and translate it to hardware Q id */ static u8 skb2q(struct sk_buff *skb) @@ -35,7 +36,7 @@ static void mt76x0_tx_skb_remove_dma_overhead(struct sk_buff *skb, skb_pull(skb, sizeof(struct mt76x02_txwi) + 4); if (ieee80211_get_hdrlen_from_skb(skb) % 4) - mt76x0_remove_hdr_pad(skb); + mt76x02_remove_hdr_pad(skb, 2); skb_trim(skb, pkt_len); } @@ -146,7 +147,7 @@ void mt76x0_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, BUILD_BUG_ON(ARRAY_SIZE(info->status.status_driver_data) < 1); info->status.status_driver_data[0] = (void *)(unsigned long)pkt_len; - mt76x0_insert_hdr_pad(skb); + mt76x02_insert_hdr_pad(skb); if (sta) { msta = (struct mt76x02_sta *) sta->drv_priv; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/util.c b/drivers/net/wireless/mediatek/mt76/mt76x0/util.c deleted file mode 100644 index 7856dd760419..000000000000 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/util.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2014 Felix Fietkau - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include "mt76x0.h" - -void mt76x0_remove_hdr_pad(struct sk_buff *skb) -{ - int len = ieee80211_get_hdrlen_from_skb(skb); - - memmove(skb->data + 2, skb->data, len); - skb_pull(skb, 2); -} - -int mt76x0_insert_hdr_pad(struct sk_buff *skb) -{ - int len = ieee80211_get_hdrlen_from_skb(skb); - int ret; - - if (len % 4 == 0) - return 0; - - ret = skb_cow(skb, 2); - if (ret) - return ret; - - skb_push(skb, 2); - memmove(skb->data, skb->data + 2, len); - - skb->data[len] = 0; - skb->data[len + 1] = 0; - return 0; -} diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c index 2c80fe9a493c..7518c0bb63fa 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c @@ -348,4 +348,33 @@ void mt76x02_sta_rate_tbl_update(struct ieee80211_hw *hw, } EXPORT_SYMBOL_GPL(mt76x02_sta_rate_tbl_update); +int mt76x02_insert_hdr_pad(struct sk_buff *skb) +{ + int len = ieee80211_get_hdrlen_from_skb(skb); + + if (len % 4 == 0) + return 0; + + skb_push(skb, 2); + memmove(skb->data, skb->data + 2, len); + + skb->data[len] = 0; + skb->data[len + 1] = 0; + return 2; +} +EXPORT_SYMBOL_GPL(mt76x02_insert_hdr_pad); + +void mt76x02_remove_hdr_pad(struct sk_buff *skb, int len) +{ + int hdrlen; + + if (!len) + return; + + hdrlen = ieee80211_get_hdrlen_from_skb(skb); + memmove(skb->data + len, skb->data, hdrlen); + skb_pull(skb, len); +} +EXPORT_SYMBOL_GPL(mt76x02_remove_hdr_pad); + MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.h b/drivers/net/wireless/mediatek/mt76/mt76x02_util.h index cff3c8f6393c..953c4bea4051 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.h @@ -43,4 +43,6 @@ int mt76x02_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, void mt76x02_sta_rate_tbl_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta); +int mt76x02_insert_hdr_pad(struct sk_buff *skb); +void mt76x02_remove_hdr_pad(struct sk_buff *skb, int len); #endif diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2.h b/drivers/net/wireless/mediatek/mt76/mt76x2.h index b3a936edfb30..f275411f0e3d 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x2.h @@ -239,7 +239,6 @@ s8 mt76x2_tx_get_max_txpwr_adj(struct mt76_dev *dev, s8 mt76x2_tx_get_txpwr_adj(struct mt76x2_dev *dev, s8 txpwr, s8 max_txpwr_adj); void mt76x2_tx_set_txpwr_auto(struct mt76x2_dev *dev, s8 txpwr); -int mt76x2_insert_hdr_pad(struct sk_buff *skb); void mt76x2_reset_wlan(struct mt76x2_dev *dev, bool enable); void mt76x2_init_txpower(struct mt76x2_dev *dev, diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mac_common.c b/drivers/net/wireless/mediatek/mt76/mt76x2_mac_common.c index 039fce3d1daa..dbc0e3ef1258 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_mac_common.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mac_common.c @@ -16,6 +16,7 @@ */ #include "mt76x2.h" +#include "mt76x02_util.h" void mt76x2_mac_stop(struct mt76x2_dev *dev, bool force) { @@ -146,18 +147,6 @@ void mt76x2_mac_write_txwi(struct mt76x2_dev *dev, struct mt76x02_txwi *txwi, } EXPORT_SYMBOL_GPL(mt76x2_mac_write_txwi); -static void mt76x2_remove_hdr_pad(struct sk_buff *skb, int len) -{ - int hdrlen; - - if (!len) - return; - - hdrlen = ieee80211_get_hdrlen_from_skb(skb); - memmove(skb->data + len, skb->data, hdrlen); - skb_pull(skb, len); -} - int mt76x2_mac_get_rssi(struct mt76x2_dev *dev, s8 rssi, int chain) { struct mt76x2_rx_freq_cal *cal = &dev->cal.rx; @@ -254,7 +243,7 @@ int mt76x2_mac_process_rx(struct mt76x2_dev *dev, struct sk_buff *skb, } } - mt76x2_remove_hdr_pad(skb, pad_len); + mt76x02_remove_hdr_pad(skb, pad_len); if ((rxinfo & MT_RXINFO_BA) && !(rxinfo & MT_RXINFO_NULL)) status->aggr = true; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_tx.c b/drivers/net/wireless/mediatek/mt76/mt76x2_tx.c index 5338e8efa606..41bae90e5f6a 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_tx.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_tx.c @@ -16,6 +16,7 @@ #include "mt76x2.h" #include "mt76x2_dma.h" +#include "mt76x02_util.h" struct beacon_bc_data { struct mt76x2_dev *dev; @@ -38,7 +39,7 @@ int mt76x2_tx_prepare_skb(struct mt76_dev *mdev, void *txwi, mt76x2_mac_write_txwi(dev, txwi, skb, wcid, sta, skb->len); - ret = mt76x2_insert_hdr_pad(skb); + ret = mt76x02_insert_hdr_pad(skb); if (ret < 0) return ret; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_tx_common.c b/drivers/net/wireless/mediatek/mt76/mt76x2_tx_common.c index 17da4ae1032d..056a21b006df 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_tx_common.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_tx_common.c @@ -47,22 +47,6 @@ void mt76x2_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, } EXPORT_SYMBOL_GPL(mt76x2_tx); -int mt76x2_insert_hdr_pad(struct sk_buff *skb) -{ - int len = ieee80211_get_hdrlen_from_skb(skb); - - if (len % 4 == 0) - return 0; - - skb_push(skb, 2); - memmove(skb->data, skb->data + 2, len); - - skb->data[len] = 0; - skb->data[len + 1] = 0; - return 2; -} -EXPORT_SYMBOL_GPL(mt76x2_insert_hdr_pad); - s8 mt76x2_tx_get_max_txpwr_adj(struct mt76_dev *mdev, const struct ieee80211_tx_rate *rate) { diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2u_core.c b/drivers/net/wireless/mediatek/mt76/mt76x2u_core.c index 4aa781e852d7..1041c8416519 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2u_core.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2u_core.c @@ -16,6 +16,7 @@ #include "mt76x2u.h" #include "dma.h" +#include "mt76x02_util.h" static void mt76x2u_remove_dma_hdr(struct sk_buff *skb) { @@ -89,7 +90,7 @@ int mt76x2u_tx_prepare_skb(struct mt76_dev *mdev, void *data, if (err < 0) return -ENOMEM; - mt76x2_insert_hdr_pad(skb); + mt76x02_insert_hdr_pad(skb); txwi = skb_push(skb, sizeof(struct mt76x02_txwi)); mt76x2_mac_write_txwi(dev, txwi, skb, wcid, sta, len); From 0b7da311274664decc52afcbe6354d0350b3ef57 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Tue, 4 Sep 2018 16:41:15 +0200 Subject: [PATCH 148/276] mt76: partially unify filling txwi fields Merge code filing txwi fields the same way on mt76x0 and mt76x2. Signed-off-by: Stanislaw Gruszka Signed-off-by: Felix Fietkau --- .../net/wireless/mediatek/mt76/mt76x0/tx.c | 46 ++----------------- .../net/wireless/mediatek/mt76/mt76x02_mac.c | 42 +++++++++++++++++ .../net/wireless/mediatek/mt76/mt76x02_mac.h | 3 +- .../mediatek/mt76/mt76x2_mac_common.c | 35 +------------- 4 files changed, 49 insertions(+), 77 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c b/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c index 92d06cca0266..0dab1c6528f9 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c @@ -65,8 +65,6 @@ mt76x0_push_txwi(struct mt76x0_dev *dev, struct sk_buff *skb, struct ieee80211_tx_rate *rate = &info->control.rates[0]; struct mt76x02_txwi *txwi; unsigned long flags; - u16 txwi_flags = 0; - u32 pkt_id; u16 rate_ctl; u8 nss; @@ -86,47 +84,11 @@ mt76x0_push_txwi(struct mt76x0_dev *dev, struct sk_buff *skb, } spin_unlock_irqrestore(&dev->mt76.lock, flags); - txwi->rate = cpu_to_le16(rate_ctl); - - if (info->flags & IEEE80211_TX_CTL_LDPC) - txwi->rate |= cpu_to_le16(MT_RXWI_RATE_LDPC); - if ((info->flags & IEEE80211_TX_CTL_STBC) && nss == 1) - txwi->rate |= cpu_to_le16(MT_RXWI_RATE_STBC); - if (nss > 1 && sta && sta->smps_mode == IEEE80211_SMPS_DYNAMIC) - txwi_flags |= MT_TXWI_FLAGS_MMPS; - - if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) { - txwi->ack_ctl |= MT_TXWI_ACK_CTL_REQ; - pkt_id = 1; - } else { - pkt_id = 0; - } - - if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) - pkt_id |= MT_TXWI_PKTID_PROBE; - - if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) - txwi->ack_ctl |= MT_TXWI_ACK_CTL_NSEQ; - - if ((info->flags & IEEE80211_TX_CTL_AMPDU) && sta) { - u8 ba_size = IEEE80211_MIN_AMPDU_BUF; - - ba_size <<= sta->ht_cap.ampdu_factor; - ba_size = min_t(int, 7, ba_size - 1); - if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) { - ba_size = 0; - } else { - txwi_flags |= MT_TXWI_FLAGS_AMPDU; - txwi_flags |= FIELD_PREP(MT_TXWI_FLAGS_MPDU_DENSITY, - sta->ht_cap.ampdu_density); - } - txwi->ack_ctl |= FIELD_PREP(MT_TXWI_ACK_CTL_BA_WINDOW, ba_size); - } - txwi->wcid = wcid->idx; - txwi->flags |= cpu_to_le16(txwi_flags); - txwi->len_ctl = cpu_to_le16(pkt_len); - txwi->pktid = pkt_id; + txwi->rate = cpu_to_le16(rate_ctl); + txwi->pktid = (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) ? 1 : 0; + + mt76x02_mac_fill_txwi(txwi, skb, sta, pkt_len, nss); return txwi; } diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c index f80290d4442a..0b12299c7a41 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c @@ -156,6 +156,48 @@ void mt76x02_txq_init(struct mt76_dev *dev, struct ieee80211_txq *txq) } EXPORT_SYMBOL_GPL(mt76x02_txq_init); +void mt76x02_mac_fill_txwi(struct mt76x02_txwi *txwi, struct sk_buff *skb, + struct ieee80211_sta *sta, int len, u8 nss) +{ + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; + u16 txwi_flags = 0; + + if (info->flags & IEEE80211_TX_CTL_LDPC) + txwi->rate |= cpu_to_le16(MT_RXWI_RATE_LDPC); + if ((info->flags & IEEE80211_TX_CTL_STBC) && nss == 1) + txwi->rate |= cpu_to_le16(MT_RXWI_RATE_STBC); + if (nss > 1 && sta && sta->smps_mode == IEEE80211_SMPS_DYNAMIC) + txwi_flags |= MT_TXWI_FLAGS_MMPS; + if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) + txwi->ack_ctl |= MT_TXWI_ACK_CTL_REQ; + if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) + txwi->ack_ctl |= MT_TXWI_ACK_CTL_NSEQ; + if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) + txwi->pktid |= MT_TXWI_PKTID_PROBE; + if ((info->flags & IEEE80211_TX_CTL_AMPDU) && sta) { + u8 ba_size = IEEE80211_MIN_AMPDU_BUF; + + ba_size <<= sta->ht_cap.ampdu_factor; + ba_size = min_t(int, 63, ba_size - 1); + if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) + ba_size = 0; + txwi->ack_ctl |= FIELD_PREP(MT_TXWI_ACK_CTL_BA_WINDOW, ba_size); + + txwi_flags |= MT_TXWI_FLAGS_AMPDU | + FIELD_PREP(MT_TXWI_FLAGS_MPDU_DENSITY, + sta->ht_cap.ampdu_density); + } + + if (ieee80211_is_probe_resp(hdr->frame_control) || + ieee80211_is_beacon(hdr->frame_control)) + txwi_flags |= MT_TXWI_FLAGS_TS; + + txwi->flags |= cpu_to_le16(txwi_flags); + txwi->len_ctl = cpu_to_le16(len); +} +EXPORT_SYMBOL_GPL(mt76x02_mac_fill_txwi); + __le16 mt76x02_mac_tx_rate_val(struct mt76_dev *dev, const struct ieee80211_tx_rate *rate, u8 *nss_val) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h index 61dd2efb5cbc..1a5da35702e6 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h @@ -180,7 +180,8 @@ static inline bool mt76x02_wait_for_mac(struct mt76_dev *dev) } void mt76x02_txq_init(struct mt76_dev *dev, struct ieee80211_txq *txq); - +void mt76x02_mac_fill_txwi(struct mt76x02_txwi *txwi, struct sk_buff *skb, + struct ieee80211_sta *sta, int len, u8 nss); enum mt76x02_cipher_type mt76x02_mac_get_key_info(struct ieee80211_key_conf *key, u8 *key_data); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mac_common.c b/drivers/net/wireless/mediatek/mt76/mt76x2_mac_common.c index dbc0e3ef1258..126650742ba4 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_mac_common.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mac_common.c @@ -61,9 +61,7 @@ void mt76x2_mac_write_txwi(struct mt76x2_dev *dev, struct mt76x02_txwi *txwi, struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct ieee80211_tx_rate *rate = &info->control.rates[0]; struct ieee80211_key_conf *key = info->control.hw_key; - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; u16 rate_ht_mask = FIELD_PREP(MT_RXWI_RATE_PHY, BIT(1) | BIT(2)); - u16 txwi_flags = 0; u8 nss; s8 txpwr_adj, max_txpwr_adj; u8 ccmp_pn[8]; @@ -112,38 +110,7 @@ void mt76x2_mac_write_txwi(struct mt76x2_dev *dev, struct mt76x02_txwi *txwi, !(txwi->rate & cpu_to_le16(rate_ht_mask))) txwi->txstream = 0x93; - if (info->flags & IEEE80211_TX_CTL_LDPC) - txwi->rate |= cpu_to_le16(MT_RXWI_RATE_LDPC); - if ((info->flags & IEEE80211_TX_CTL_STBC) && nss == 1) - txwi->rate |= cpu_to_le16(MT_RXWI_RATE_STBC); - if (nss > 1 && sta && sta->smps_mode == IEEE80211_SMPS_DYNAMIC) - txwi_flags |= MT_TXWI_FLAGS_MMPS; - if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) - txwi->ack_ctl |= MT_TXWI_ACK_CTL_REQ; - if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) - txwi->ack_ctl |= MT_TXWI_ACK_CTL_NSEQ; - if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) - txwi->pktid |= MT_TXWI_PKTID_PROBE; - if ((info->flags & IEEE80211_TX_CTL_AMPDU) && sta) { - u8 ba_size = IEEE80211_MIN_AMPDU_BUF; - - ba_size <<= sta->ht_cap.ampdu_factor; - ba_size = min_t(int, 63, ba_size - 1); - if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) - ba_size = 0; - txwi->ack_ctl |= FIELD_PREP(MT_TXWI_ACK_CTL_BA_WINDOW, ba_size); - - txwi_flags |= MT_TXWI_FLAGS_AMPDU | - FIELD_PREP(MT_TXWI_FLAGS_MPDU_DENSITY, - sta->ht_cap.ampdu_density); - } - - if (ieee80211_is_probe_resp(hdr->frame_control) || - ieee80211_is_beacon(hdr->frame_control)) - txwi_flags |= MT_TXWI_FLAGS_TS; - - txwi->flags |= cpu_to_le16(txwi_flags); - txwi->len_ctl = cpu_to_le16(len); + mt76x02_mac_fill_txwi(txwi, skb, sta, len, nss); } EXPORT_SYMBOL_GPL(mt76x2_mac_write_txwi); From 5a69931cb768f19e6708832661dde63a8a14f453 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Thu, 6 Sep 2018 11:18:17 +0200 Subject: [PATCH 149/276] mt76x2: change mt76x2_tx_complete routine signature Use mt76_dev instead of mt76x2_dev in mt76x2_tx_complete signature in order to be reused in mt76x0 driver Signed-off-by: Lorenzo Bianconi Signed-off-by: Stanislaw Gruszka Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt76x2.h | 2 +- drivers/net/wireless/mediatek/mt76/mt76x2_mac.c | 2 +- drivers/net/wireless/mediatek/mt76/mt76x2_tx_common.c | 6 +++--- drivers/net/wireless/mediatek/mt76/mt76x2u_core.c | 4 +--- 4 files changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2.h b/drivers/net/wireless/mediatek/mt76/mt76x2.h index f275411f0e3d..9f495d4cfb6a 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x2.h @@ -215,7 +215,7 @@ int mt76x2_tx_queue_mcu(struct mt76x2_dev *dev, enum mt76_txq_id qid, struct sk_buff *skb, int cmd, int seq); void mt76x2_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, struct sk_buff *skb); -void mt76x2_tx_complete(struct mt76x2_dev *dev, struct sk_buff *skb); +void mt76x2_tx_complete(struct mt76_dev *dev, struct sk_buff *skb); int mt76x2_tx_prepare_skb(struct mt76_dev *mdev, void *txwi, struct sk_buff *skb, struct mt76_queue *q, struct mt76_wcid *wcid, struct ieee80211_sta *sta, diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c index 3bb02b55f146..db0cb4a2500b 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c @@ -73,7 +73,7 @@ mt76x2_mac_queue_txdone(struct mt76x2_dev *dev, struct sk_buff *skb, txi->wcid = txwi->wcid; txi->pktid = txwi->pktid; trace_mac_txdone_add(dev, txwi->wcid, txwi->pktid); - mt76x2_tx_complete(dev, skb); + mt76x2_tx_complete(&dev->mt76, skb); } void mt76x2_mac_process_tx_status_fifo(struct mt76x2_dev *dev) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_tx_common.c b/drivers/net/wireless/mediatek/mt76/mt76x2_tx_common.c index 056a21b006df..663229dc269d 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_tx_common.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_tx_common.c @@ -117,17 +117,17 @@ void mt76x2_tx_set_txpwr_auto(struct mt76x2_dev *dev, s8 txpwr) } EXPORT_SYMBOL_GPL(mt76x2_tx_set_txpwr_auto); -void mt76x2_tx_complete(struct mt76x2_dev *dev, struct sk_buff *skb) +void mt76x2_tx_complete(struct mt76_dev *dev, struct sk_buff *skb) { struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); if (info->flags & IEEE80211_TX_CTL_AMPDU) { - ieee80211_free_txskb(mt76_hw(dev), skb); + ieee80211_free_txskb(dev->hw, skb); } else { ieee80211_tx_info_clear_status(info); info->status.rates[0].idx = -1; info->flags |= IEEE80211_TX_STAT_ACK; - ieee80211_tx_status(mt76_hw(dev), skb); + ieee80211_tx_status(dev->hw, skb); } } EXPORT_SYMBOL_GPL(mt76x2_tx_complete); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2u_core.c b/drivers/net/wireless/mediatek/mt76/mt76x2u_core.c index 1041c8416519..e9fa126fce0f 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2u_core.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2u_core.c @@ -101,9 +101,7 @@ int mt76x2u_tx_prepare_skb(struct mt76_dev *mdev, void *data, void mt76x2u_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue *q, struct mt76_queue_entry *e, bool flush) { - struct mt76x2_dev *dev = container_of(mdev, struct mt76x2_dev, mt76); - mt76x2u_remove_dma_hdr(e->skb); - mt76x2_tx_complete(dev, e->skb); + mt76x2_tx_complete(mdev, e->skb); } From 2a45ad31aff71d0383df853feab416504c64a967 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Thu, 6 Sep 2018 11:18:18 +0200 Subject: [PATCH 150/276] mt76: move mt76x2_tx_complete routine in mt76x02-lib module Move mt76x2_tx_complete routine in mt76x02-lib module and rename it in mt76x02_tx_complete in order to be used in mt76x0 driver Signed-off-by: Lorenzo Bianconi Signed-off-by: Stanislaw Gruszka Signed-off-by: Felix Fietkau --- .../net/wireless/mediatek/mt76/mt76x02_util.c | 15 +++++++++++++++ .../net/wireless/mediatek/mt76/mt76x02_util.h | 1 + drivers/net/wireless/mediatek/mt76/mt76x2.h | 1 - drivers/net/wireless/mediatek/mt76/mt76x2_mac.c | 3 ++- .../wireless/mediatek/mt76/mt76x2_tx_common.c | 16 ---------------- .../net/wireless/mediatek/mt76/mt76x2u_core.c | 2 +- 6 files changed, 19 insertions(+), 19 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c index 7518c0bb63fa..d5af543b2ad1 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c @@ -377,4 +377,19 @@ void mt76x02_remove_hdr_pad(struct sk_buff *skb, int len) } EXPORT_SYMBOL_GPL(mt76x02_remove_hdr_pad); +void mt76x02_tx_complete(struct mt76_dev *dev, struct sk_buff *skb) +{ + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + + if (info->flags & IEEE80211_TX_CTL_AMPDU) { + ieee80211_free_txskb(dev->hw, skb); + } else { + ieee80211_tx_info_clear_status(info); + info->status.rates[0].idx = -1; + info->flags |= IEEE80211_TX_STAT_ACK; + ieee80211_tx_status(dev->hw, skb); + } +} +EXPORT_SYMBOL_GPL(mt76x02_tx_complete); + MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.h b/drivers/net/wireless/mediatek/mt76/mt76x02_util.h index 953c4bea4051..19fe42c40bed 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.h @@ -45,4 +45,5 @@ void mt76x02_sta_rate_tbl_update(struct ieee80211_hw *hw, struct ieee80211_sta *sta); int mt76x02_insert_hdr_pad(struct sk_buff *skb); void mt76x02_remove_hdr_pad(struct sk_buff *skb, int len); +void mt76x02_tx_complete(struct mt76_dev *dev, struct sk_buff *skb); #endif diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2.h b/drivers/net/wireless/mediatek/mt76/mt76x2.h index 9f495d4cfb6a..efed3c0a82ce 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x2.h @@ -215,7 +215,6 @@ int mt76x2_tx_queue_mcu(struct mt76x2_dev *dev, enum mt76_txq_id qid, struct sk_buff *skb, int cmd, int seq); void mt76x2_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, struct sk_buff *skb); -void mt76x2_tx_complete(struct mt76_dev *dev, struct sk_buff *skb); int mt76x2_tx_prepare_skb(struct mt76_dev *mdev, void *txwi, struct sk_buff *skb, struct mt76_queue *q, struct mt76_wcid *wcid, struct ieee80211_sta *sta, diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c index db0cb4a2500b..241ede98e6d3 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c @@ -19,6 +19,7 @@ #include "mt76x2_mcu.h" #include "mt76x2_eeprom.h" #include "mt76x2_trace.h" +#include "mt76x02_util.h" void mt76x2_mac_set_bssid(struct mt76x2_dev *dev, u8 idx, const u8 *addr) { @@ -73,7 +74,7 @@ mt76x2_mac_queue_txdone(struct mt76x2_dev *dev, struct sk_buff *skb, txi->wcid = txwi->wcid; txi->pktid = txwi->pktid; trace_mac_txdone_add(dev, txwi->wcid, txwi->pktid); - mt76x2_tx_complete(&dev->mt76, skb); + mt76x02_tx_complete(&dev->mt76, skb); } void mt76x2_mac_process_tx_status_fifo(struct mt76x2_dev *dev) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_tx_common.c b/drivers/net/wireless/mediatek/mt76/mt76x2_tx_common.c index 663229dc269d..c3c06e036832 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_tx_common.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_tx_common.c @@ -116,19 +116,3 @@ void mt76x2_tx_set_txpwr_auto(struct mt76x2_dev *dev, s8 txpwr) MT_PROT_AUTO_TX_CFG_AUTO_PADJ, txpwr_adj); } EXPORT_SYMBOL_GPL(mt76x2_tx_set_txpwr_auto); - -void mt76x2_tx_complete(struct mt76_dev *dev, struct sk_buff *skb) -{ - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - - if (info->flags & IEEE80211_TX_CTL_AMPDU) { - ieee80211_free_txskb(dev->hw, skb); - } else { - ieee80211_tx_info_clear_status(info); - info->status.rates[0].idx = -1; - info->flags |= IEEE80211_TX_STAT_ACK; - ieee80211_tx_status(dev->hw, skb); - } -} -EXPORT_SYMBOL_GPL(mt76x2_tx_complete); - diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2u_core.c b/drivers/net/wireless/mediatek/mt76/mt76x2u_core.c index e9fa126fce0f..7cadbce639d1 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2u_core.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2u_core.c @@ -102,6 +102,6 @@ void mt76x2u_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue *q, struct mt76_queue_entry *e, bool flush) { mt76x2u_remove_dma_hdr(e->skb); - mt76x2_tx_complete(mdev, e->skb); + mt76x02_tx_complete(mdev, e->skb); } From b38b8207bf80c8d3b86e92bb901f32e3e109d148 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Thu, 6 Sep 2018 11:18:19 +0200 Subject: [PATCH 151/276] mt76: move mt76x2u_remove_dma_hdr in mt76x02-lib module Move mt76x2u_remove_dma_hdr in mt76x02-lib module and rename it in mt76x02_remove_dma_hdr. Moreover use mt76x02_remove_hdr_pad routine in mt76x02_remove_dma_hdr function. Furthermore remove mt76x0_tx_skb_remove_dma_overhead routine Signed-off-by: Lorenzo Bianconi Signed-off-by: Stanislaw Gruszka Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt76x0/tx.c | 14 +------------- drivers/net/wireless/mediatek/mt76/mt76x02_util.c | 12 ++++++++++++ drivers/net/wireless/mediatek/mt76/mt76x02_util.h | 1 + drivers/net/wireless/mediatek/mt76/mt76x2u_core.c | 14 +------------- 4 files changed, 15 insertions(+), 26 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c b/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c index 0dab1c6528f9..de2643d54a1e 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c @@ -29,23 +29,11 @@ static u8 skb2q(struct sk_buff *skb) return mt76_ac_to_hwq(qid); } -static void mt76x0_tx_skb_remove_dma_overhead(struct sk_buff *skb, - struct ieee80211_tx_info *info) -{ - int pkt_len = (unsigned long)info->status.status_driver_data[0]; - - skb_pull(skb, sizeof(struct mt76x02_txwi) + 4); - if (ieee80211_get_hdrlen_from_skb(skb) % 4) - mt76x02_remove_hdr_pad(skb, 2); - - skb_trim(skb, pkt_len); -} - void mt76x0_tx_status(struct mt76x0_dev *dev, struct sk_buff *skb) { struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - mt76x0_tx_skb_remove_dma_overhead(skb, info); + mt76x02_remove_dma_hdr(skb); ieee80211_tx_info_clear_status(info); info->status.rates[0].idx = -1; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c index d5af543b2ad1..602b30d6915f 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c @@ -16,6 +16,7 @@ */ #include "mt76.h" +#include "dma.h" #include "mt76x02_regs.h" #include "mt76x02_mac.h" @@ -377,6 +378,17 @@ void mt76x02_remove_hdr_pad(struct sk_buff *skb, int len) } EXPORT_SYMBOL_GPL(mt76x02_remove_hdr_pad); +void mt76x02_remove_dma_hdr(struct sk_buff *skb) +{ + int hdr_len; + + skb_pull(skb, sizeof(struct mt76x02_txwi) + MT_DMA_HDR_LEN); + hdr_len = ieee80211_get_hdrlen_from_skb(skb); + if (hdr_len % 4) + mt76x02_remove_hdr_pad(skb, 2); +} +EXPORT_SYMBOL_GPL(mt76x02_remove_dma_hdr); + void mt76x02_tx_complete(struct mt76_dev *dev, struct sk_buff *skb) { struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.h b/drivers/net/wireless/mediatek/mt76/mt76x02_util.h index 19fe42c40bed..6b6e963454c8 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.h @@ -46,4 +46,5 @@ void mt76x02_sta_rate_tbl_update(struct ieee80211_hw *hw, int mt76x02_insert_hdr_pad(struct sk_buff *skb); void mt76x02_remove_hdr_pad(struct sk_buff *skb, int len); void mt76x02_tx_complete(struct mt76_dev *dev, struct sk_buff *skb); +void mt76x02_remove_dma_hdr(struct sk_buff *skb); #endif diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2u_core.c b/drivers/net/wireless/mediatek/mt76/mt76x2u_core.c index 7cadbce639d1..52b08b0ed6b9 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2u_core.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2u_core.c @@ -18,18 +18,6 @@ #include "dma.h" #include "mt76x02_util.h" -static void mt76x2u_remove_dma_hdr(struct sk_buff *skb) -{ - int hdr_len; - - skb_pull(skb, sizeof(struct mt76x02_txwi) + MT_DMA_HDR_LEN); - hdr_len = ieee80211_get_hdrlen_from_skb(skb); - if (hdr_len % 4) { - memmove(skb->data + 2, skb->data, hdr_len); - skb_pull(skb, 2); - } -} - static int mt76x2u_check_skb_rooms(struct sk_buff *skb) { @@ -101,7 +89,7 @@ int mt76x2u_tx_prepare_skb(struct mt76_dev *mdev, void *data, void mt76x2u_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue *q, struct mt76_queue_entry *e, bool flush) { - mt76x2u_remove_dma_hdr(e->skb); + mt76x02_remove_dma_hdr(e->skb); mt76x02_tx_complete(mdev, e->skb); } From f847e45a2db8301825c92a91d89f5190a9d50f83 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Thu, 6 Sep 2018 11:18:20 +0200 Subject: [PATCH 152/276] mt76: move mt76x2u_tx_complete_skb in mt76x02-lib moudule Move mt76x2u_tx_complete_skb routine in mt76x02-lib module and rename it in mt76x02_tx_complete_skb in order to be reused in mt76x0 driver Signed-off-by: Lorenzo Bianconi Signed-off-by: Stanislaw Gruszka Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt76x02_util.c | 8 ++++++++ drivers/net/wireless/mediatek/mt76/mt76x02_util.h | 2 ++ drivers/net/wireless/mediatek/mt76/mt76x2u.h | 2 -- drivers/net/wireless/mediatek/mt76/mt76x2u_core.c | 8 -------- drivers/net/wireless/mediatek/mt76/mt76x2u_init.c | 3 ++- 5 files changed, 12 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c index 602b30d6915f..64b7b0a47694 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c @@ -404,4 +404,12 @@ void mt76x02_tx_complete(struct mt76_dev *dev, struct sk_buff *skb) } EXPORT_SYMBOL_GPL(mt76x02_tx_complete); +void mt76x02_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue *q, + struct mt76_queue_entry *e, bool flush) +{ + mt76x02_remove_dma_hdr(e->skb); + mt76x02_tx_complete(mdev, e->skb); +} +EXPORT_SYMBOL_GPL(mt76x02_tx_complete_skb); + MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.h b/drivers/net/wireless/mediatek/mt76/mt76x02_util.h index 6b6e963454c8..a7c20e6fb4ab 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.h @@ -47,4 +47,6 @@ int mt76x02_insert_hdr_pad(struct sk_buff *skb); void mt76x02_remove_hdr_pad(struct sk_buff *skb, int len); void mt76x02_tx_complete(struct mt76_dev *dev, struct sk_buff *skb); void mt76x02_remove_dma_hdr(struct sk_buff *skb); +void mt76x02_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue *q, + struct mt76_queue_entry *e, bool flush); #endif diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2u.h b/drivers/net/wireless/mediatek/mt76/mt76x2u.h index a83c17cb6be5..6946123820e8 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2u.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x2u.h @@ -74,8 +74,6 @@ int mt76x2u_tx_prepare_skb(struct mt76_dev *mdev, void *data, struct sk_buff *skb, struct mt76_queue *q, struct mt76_wcid *wcid, struct ieee80211_sta *sta, u32 *tx_info); -void mt76x2u_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue *q, - struct mt76_queue_entry *e, bool flush); int mt76x2u_skb_dma_info(struct sk_buff *skb, enum dma_msg_port port, u32 flags); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2u_core.c b/drivers/net/wireless/mediatek/mt76/mt76x2u_core.c index 52b08b0ed6b9..f6372c509268 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2u_core.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2u_core.c @@ -85,11 +85,3 @@ int mt76x2u_tx_prepare_skb(struct mt76_dev *mdev, void *data, return mt76x2u_set_txinfo(skb, wcid, q2ep(q->hw_idx)); } - -void mt76x2u_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue *q, - struct mt76_queue_entry *e, bool flush) -{ - mt76x02_remove_dma_hdr(e->skb); - mt76x02_tx_complete(mdev, e->skb); -} - diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2u_init.c b/drivers/net/wireless/mediatek/mt76/mt76x2u_init.c index 53ace9d21fc8..f166246da002 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2u_init.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2u_init.c @@ -17,6 +17,7 @@ #include #include "mt76x2u.h" +#include "mt76x02_util.h" #include "mt76x2_eeprom.h" static void mt76x2u_init_dma(struct mt76x2_dev *dev) @@ -136,7 +137,7 @@ struct mt76x2_dev *mt76x2u_alloc_device(struct device *pdev) { static const struct mt76_driver_ops drv_ops = { .tx_prepare_skb = mt76x2u_tx_prepare_skb, - .tx_complete_skb = mt76x2u_tx_complete_skb, + .tx_complete_skb = mt76x02_tx_complete_skb, .tx_status_data = mt76x2u_tx_status_data, .rx_skb = mt76x2_queue_rx_skb, }; From 2251dd5d463c0b3e29a6b0ade4a9745c43c682ad Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Thu, 6 Sep 2018 11:18:21 +0200 Subject: [PATCH 153/276] mt76: move mt76_qsel definition in dma.h Move mt76_qsel definition in dma.h in order to be reused in mt76x0 driver. Moreover remove empty mt76x2_dma.h header file Signed-off-by: Lorenzo Bianconi Signed-off-by: Stanislaw Gruszka Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/dma.h | 7 +++++ .../net/wireless/mediatek/mt76/mt76x2_dma.c | 2 +- .../net/wireless/mediatek/mt76/mt76x2_dma.h | 29 ------------------- .../net/wireless/mediatek/mt76/mt76x2_mcu.c | 2 +- .../net/wireless/mediatek/mt76/mt76x2_tx.c | 2 +- .../wireless/mediatek/mt76/mt76x2_tx_common.c | 2 +- drivers/net/wireless/mediatek/mt76/mt76x2u.h | 2 +- 7 files changed, 12 insertions(+), 34 deletions(-) delete mode 100644 drivers/net/wireless/mediatek/mt76/mt76x2_dma.h diff --git a/drivers/net/wireless/mediatek/mt76/dma.h b/drivers/net/wireless/mediatek/mt76/dma.h index 828e52ae70e8..aa2faf19bf05 100644 --- a/drivers/net/wireless/mediatek/mt76/dma.h +++ b/drivers/net/wireless/mediatek/mt76/dma.h @@ -75,6 +75,13 @@ enum dma_msg_port { DISCARD, }; +enum mt76_qsel { + MT_QSEL_MGMT, + MT_QSEL_HCCA, + MT_QSEL_EDCA, + MT_QSEL_EDCA_2, +}; + enum mt76_mcu_evt_type { EVT_CMD_DONE, EVT_CMD_ERROR, diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_dma.c b/drivers/net/wireless/mediatek/mt76/mt76x2_dma.c index 42cdccf481f7..4b60e8a5239e 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_dma.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_dma.c @@ -15,7 +15,7 @@ */ #include "mt76x2.h" -#include "mt76x2_dma.h" +#include "dma.h" int mt76x2_tx_queue_mcu(struct mt76x2_dev *dev, enum mt76_txq_id qid, diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_dma.h b/drivers/net/wireless/mediatek/mt76/mt76x2_dma.h deleted file mode 100644 index da294558c268..000000000000 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_dma.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) 2016 Felix Fietkau - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef __MT76x2_DMA_H -#define __MT76x2_DMA_H - -#include "dma.h" - -enum mt76x2_qsel { - MT_QSEL_MGMT, - MT_QSEL_HCCA, - MT_QSEL_EDCA, - MT_QSEL_EDCA_2, -}; - -#endif diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.c index 743da57760dc..c90803334ef0 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.c @@ -20,8 +20,8 @@ #include "mt76x2.h" #include "mt76x2_mcu.h" -#include "mt76x2_dma.h" #include "mt76x2_eeprom.h" +#include "dma.h" static struct sk_buff *mt76x2_mcu_msg_alloc(const void *data, int len) { diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_tx.c b/drivers/net/wireless/mediatek/mt76/mt76x2_tx.c index 41bae90e5f6a..41d660991839 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_tx.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_tx.c @@ -15,8 +15,8 @@ */ #include "mt76x2.h" -#include "mt76x2_dma.h" #include "mt76x02_util.h" +#include "dma.h" struct beacon_bc_data { struct mt76x2_dev *dev; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_tx_common.c b/drivers/net/wireless/mediatek/mt76/mt76x2_tx_common.c index c3c06e036832..dbb3071bed1b 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_tx_common.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_tx_common.c @@ -16,7 +16,7 @@ */ #include "mt76x2.h" -#include "mt76x2_dma.h" +#include "dma.h" void mt76x2_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, struct sk_buff *skb) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2u.h b/drivers/net/wireless/mediatek/mt76/mt76x2u.h index 6946123820e8..180779bebaa2 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2u.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x2u.h @@ -20,8 +20,8 @@ #include #include "mt76x2.h" -#include "mt76x2_dma.h" #include "mt76x2_mcu.h" +#include "dma.h" #define MT7612U_EEPROM_SIZE 512 From 41868f984e71d4ff3100e0b3b81bfa747d05c273 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Thu, 6 Sep 2018 11:18:22 +0200 Subject: [PATCH 154/276] mt76: move mt76x2u_set_txinfo in mt76x02-lib module Move mt76x2u_set_txinfo routine in mt76x02-lib module and rename it in mt76x02_set_txinfo in order to be reused in mt76x0 driver Signed-off-by: Lorenzo Bianconi Signed-off-by: Stanislaw Gruszka Signed-off-by: Felix Fietkau --- .../net/wireless/mediatek/mt76/mt76x02_util.c | 21 ++++++++++++++++ .../net/wireless/mediatek/mt76/mt76x02_util.h | 1 + .../net/wireless/mediatek/mt76/mt76x2u_core.c | 24 +------------------ 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c index 64b7b0a47694..1b7168127d2a 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c @@ -412,4 +412,25 @@ void mt76x02_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue *q, } EXPORT_SYMBOL_GPL(mt76x02_tx_complete_skb); +int mt76x02_set_txinfo(struct sk_buff *skb, struct mt76_wcid *wcid, u8 ep) +{ + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + enum mt76_qsel qsel; + u32 flags; + + if ((info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) || + ep == MT_EP_OUT_HCCA) + qsel = MT_QSEL_MGMT; + else + qsel = MT_QSEL_EDCA; + + flags = FIELD_PREP(MT_TXD_INFO_QSEL, qsel) | + MT_TXD_INFO_80211; + if (!wcid || wcid->hw_key_idx == 0xff || wcid->sw_iv) + flags |= MT_TXD_INFO_WIV; + + return mt76u_skb_dma_info(skb, WLAN_PORT, flags); +} +EXPORT_SYMBOL_GPL(mt76x02_set_txinfo); + MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.h b/drivers/net/wireless/mediatek/mt76/mt76x02_util.h index a7c20e6fb4ab..ad4112cc7800 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.h @@ -49,4 +49,5 @@ void mt76x02_tx_complete(struct mt76_dev *dev, struct sk_buff *skb); void mt76x02_remove_dma_hdr(struct sk_buff *skb); void mt76x02_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue *q, struct mt76_queue_entry *e, bool flush); +int mt76x02_set_txinfo(struct sk_buff *skb, struct mt76_wcid *wcid, u8 ep); #endif diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2u_core.c b/drivers/net/wireless/mediatek/mt76/mt76x2u_core.c index f6372c509268..f0b0eb4e7e80 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2u_core.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2u_core.c @@ -30,28 +30,6 @@ mt76x2u_check_skb_rooms(struct sk_buff *skb) return skb_cow(skb, need_head); } -static int -mt76x2u_set_txinfo(struct sk_buff *skb, - struct mt76_wcid *wcid, u8 ep) -{ - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - enum mt76x2_qsel qsel; - u32 flags; - - if ((info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) || - ep == MT_EP_OUT_HCCA) - qsel = MT_QSEL_MGMT; - else - qsel = MT_QSEL_EDCA; - - flags = FIELD_PREP(MT_TXD_INFO_QSEL, qsel) | - MT_TXD_INFO_80211; - if (!wcid || wcid->hw_key_idx == 0xff || wcid->sw_iv) - flags |= MT_TXD_INFO_WIV; - - return mt76u_skb_dma_info(skb, WLAN_PORT, flags); -} - bool mt76x2u_tx_status_data(struct mt76_dev *mdev, u8 *update) { struct mt76x2_dev *dev = container_of(mdev, struct mt76x2_dev, mt76); @@ -83,5 +61,5 @@ int mt76x2u_tx_prepare_skb(struct mt76_dev *mdev, void *data, txwi = skb_push(skb, sizeof(struct mt76x02_txwi)); mt76x2_mac_write_txwi(dev, txwi, skb, wcid, sta, len); - return mt76x2u_set_txinfo(skb, wcid, q2ep(q->hw_idx)); + return mt76x02_set_txinfo(skb, wcid, q2ep(q->hw_idx)); } From 8c6adb7862d41297a58ad568197f2f535eb10d4b Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Thu, 6 Sep 2018 11:18:23 +0200 Subject: [PATCH 155/276] mt76x0: introduce mt76x0_tx_prepare_skb routine Add mt76x0_tx_prepare_skb routine as tx txwi handler. mt76x0_tx_prepare_skb will be used by mt76-usb layer Signed-off-by: Lorenzo Bianconi Signed-off-by: Stanislaw Gruszka Signed-off-by: Felix Fietkau --- .../net/wireless/mediatek/mt76/mt76x0/mt76x0.h | 5 ++++- drivers/net/wireless/mediatek/mt76/mt76x0/tx.c | 15 +++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h index 8510f120a121..8b0bef9a15e4 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h @@ -250,5 +250,8 @@ void mt76x0_dma_cleanup(struct mt76x0_dev *dev); int mt76x0_dma_enqueue_tx(struct mt76x0_dev *dev, struct sk_buff *skb, struct mt76_wcid *wcid, int hw_q); - +int mt76x0_tx_prepare_skb(struct mt76_dev *mdev, void *data, + struct sk_buff *skb, struct mt76_queue *q, + struct mt76_wcid *wcid, struct ieee80211_sta *sta, + u32 *tx_info); #endif diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c b/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c index de2643d54a1e..4cafd30d2c0a 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c @@ -116,6 +116,21 @@ void mt76x0_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, trace_mt76x0_tx(&dev->mt76, skb, msta, txwi); } +int mt76x0_tx_prepare_skb(struct mt76_dev *mdev, void *data, + struct sk_buff *skb, struct mt76_queue *q, + struct mt76_wcid *wcid, struct ieee80211_sta *sta, + u32 *tx_info) +{ + struct mt76x0_dev *dev = container_of(mdev, struct mt76x0_dev, mt76); + struct mt76x02_txwi *txwi; + int len = skb->len; + + mt76x02_insert_hdr_pad(skb); + txwi = mt76x0_push_txwi(dev, skb, sta, wcid, len); + + return mt76x02_set_txinfo(skb, wcid, q2ep(q->hw_idx)); +} + void mt76x0_tx_stat(struct work_struct *work) { struct mt76x0_dev *dev = container_of(work, struct mt76x0_dev, From 8f6c23a94e16d726de8fabe134c0a193d5fae2ce Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Thu, 6 Sep 2018 11:18:24 +0200 Subject: [PATCH 156/276] mt76: move mt76x2u_tx_status_data in mt76x02-lib module Move mt76x2u_tx_status_data routine in mt76x02-lib module and rename it in mt76x02_tx_status_data in order to be reused in mt76x0 driver Signed-off-by: Lorenzo Bianconi Signed-off-by: Stanislaw Gruszka Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt76x02_util.c | 13 +++++++++++++ drivers/net/wireless/mediatek/mt76/mt76x02_util.h | 1 + drivers/net/wireless/mediatek/mt76/mt76x2u.h | 1 - drivers/net/wireless/mediatek/mt76/mt76x2u_core.c | 13 ------------- drivers/net/wireless/mediatek/mt76/mt76x2u_init.c | 2 +- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c index 1b7168127d2a..e0d0d13152a7 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c @@ -433,4 +433,17 @@ int mt76x02_set_txinfo(struct sk_buff *skb, struct mt76_wcid *wcid, u8 ep) } EXPORT_SYMBOL_GPL(mt76x02_set_txinfo); +bool mt76x02_tx_status_data(struct mt76_dev *dev, u8 *update) +{ + struct mt76x02_tx_status stat; + + if (!mt76x02_mac_load_tx_status(dev, &stat)) + return false; + + mt76x02_send_tx_status(dev, &stat, update); + + return true; +} +EXPORT_SYMBOL_GPL(mt76x02_tx_status_data); + MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.h b/drivers/net/wireless/mediatek/mt76/mt76x02_util.h index ad4112cc7800..383031b9b6d8 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.h @@ -50,4 +50,5 @@ void mt76x02_remove_dma_hdr(struct sk_buff *skb); void mt76x02_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue *q, struct mt76_queue_entry *e, bool flush); int mt76x02_set_txinfo(struct sk_buff *skb, struct mt76_wcid *wcid, u8 ep); +bool mt76x02_tx_status_data(struct mt76_dev *dev, u8 *update); #endif diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2u.h b/drivers/net/wireless/mediatek/mt76/mt76x2u.h index 180779bebaa2..5a11217c03ed 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2u.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x2u.h @@ -69,7 +69,6 @@ int mt76x2u_mcu_fw_init(struct mt76x2_dev *dev); int mt76x2u_alloc_queues(struct mt76x2_dev *dev); void mt76x2u_queues_deinit(struct mt76x2_dev *dev); void mt76x2u_stop_queues(struct mt76x2_dev *dev); -bool mt76x2u_tx_status_data(struct mt76_dev *mdev, u8 *update); int mt76x2u_tx_prepare_skb(struct mt76_dev *mdev, void *data, struct sk_buff *skb, struct mt76_queue *q, struct mt76_wcid *wcid, struct ieee80211_sta *sta, diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2u_core.c b/drivers/net/wireless/mediatek/mt76/mt76x2u_core.c index f0b0eb4e7e80..4433cc7b150d 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2u_core.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2u_core.c @@ -30,19 +30,6 @@ mt76x2u_check_skb_rooms(struct sk_buff *skb) return skb_cow(skb, need_head); } -bool mt76x2u_tx_status_data(struct mt76_dev *mdev, u8 *update) -{ - struct mt76x2_dev *dev = container_of(mdev, struct mt76x2_dev, mt76); - struct mt76x02_tx_status stat; - - if (!mt76x02_mac_load_tx_status(&dev->mt76, &stat)) - return false; - - mt76x02_send_tx_status(&dev->mt76, &stat, update); - - return true; -} - int mt76x2u_tx_prepare_skb(struct mt76_dev *mdev, void *data, struct sk_buff *skb, struct mt76_queue *q, struct mt76_wcid *wcid, struct ieee80211_sta *sta, diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2u_init.c b/drivers/net/wireless/mediatek/mt76/mt76x2u_init.c index f166246da002..29f3ecaad979 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2u_init.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2u_init.c @@ -138,7 +138,7 @@ struct mt76x2_dev *mt76x2u_alloc_device(struct device *pdev) static const struct mt76_driver_ops drv_ops = { .tx_prepare_skb = mt76x2u_tx_prepare_skb, .tx_complete_skb = mt76x02_tx_complete_skb, - .tx_status_data = mt76x2u_tx_status_data, + .tx_status_data = mt76x02_tx_status_data, .rx_skb = mt76x2_queue_rx_skb, }; struct mt76x2_dev *dev; From 7fd3c60ccbc2a8c8937e41dc402032a87c01c66e Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Thu, 6 Sep 2018 11:18:27 +0200 Subject: [PATCH 157/276] mt76x0: disable usb rx bulk aggregation In order to use zero-copying, disable usb rx bulk aggregation Signed-off-by: Lorenzo Bianconi Signed-off-by: Stanislaw Gruszka Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt76x0/init.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c index 45c9f1f7a89a..f2d3ae93d643 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c @@ -109,17 +109,17 @@ static void mt76x0_reset_csr_bbp(struct mt76x0_dev *dev) static void mt76x0_init_usb_dma(struct mt76x0_dev *dev) { - struct mt76_usb *usb = &dev->mt76.usb; u32 val; val = mt76_rr(dev, MT_USB_DMA_CFG); - val |= FIELD_PREP(MT_USB_DMA_CFG_RX_BULK_AGG_TOUT, MT_USB_AGGR_TIMEOUT) | - FIELD_PREP(MT_USB_DMA_CFG_RX_BULK_AGG_LMT, MT_USB_AGGR_SIZE_LIMIT) | - MT_USB_DMA_CFG_RX_BULK_EN | + val |= MT_USB_DMA_CFG_RX_BULK_EN | MT_USB_DMA_CFG_TX_BULK_EN; - if (usb->in_max_packet == 512) - val |= MT_USB_DMA_CFG_RX_BULK_AGG_EN; + + /* disable AGGR_BULK_RX in order to receive one + * frame in each rx urb and avoid copies + */ + val &= ~MT_USB_DMA_CFG_RX_BULK_AGG_EN; mt76_wr(dev, MT_USB_DMA_CFG, val); val = mt76_rr(dev, MT_COM_REG0); From a4986909ec18d96d30850e574e2f18705a7e5c8f Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Thu, 6 Sep 2018 11:18:28 +0200 Subject: [PATCH 158/276] mt76x0: mark device as running in mt76x0_start Set MT76_STATE_RUNNING flag in mt76x0_start routine and clear it in mt76x0_stop one Signed-off-by: Lorenzo Bianconi Signed-off-by: Stanislaw Gruszka Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt76x0/main.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c index a14f03b1ac54..3ac8e36d1c24 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c @@ -33,6 +33,9 @@ static int mt76x0_start(struct ieee80211_hw *hw) MT_CALIBRATE_INTERVAL); ieee80211_queue_delayed_work(dev->mt76.hw, &dev->cal_work, MT_CALIBRATE_INTERVAL); + + set_bit(MT76_STATE_RUNNING, &dev->mt76.state); + out: mutex_unlock(&dev->mt76.mutex); return ret; @@ -44,6 +47,8 @@ static void mt76x0_stop(struct ieee80211_hw *hw) mutex_lock(&dev->mt76.mutex); + clear_bit(MT76_STATE_RUNNING, &dev->mt76.state); + cancel_delayed_work_sync(&dev->cal_work); cancel_delayed_work_sync(&dev->mac_work); mt76x0_mac_stop(dev); From 82aedcef17e4bdececd2e39ed581fed5ce767436 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Thu, 6 Sep 2018 11:18:29 +0200 Subject: [PATCH 159/276] mt76x0: simplify mt76_mac_process_rx signature Remove data pointer from mt76_mac_process_rx routine signature Signed-off-by: Lorenzo Bianconi Signed-off-by: Stanislaw Gruszka Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt76x0/dma.c | 2 +- drivers/net/wireless/mediatek/mt76/mt76x0/mac.c | 4 ++-- drivers/net/wireless/mediatek/mt76/mt76x0/mac.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/dma.c b/drivers/net/wireless/mediatek/mt76/mt76x0/dma.c index f29402861ced..82c2b37d0896 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/dma.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/dma.c @@ -44,7 +44,7 @@ mt76x0_rx_skb_from_seg(struct mt76x0_dev *dev, struct mt76x02_rxwi *rxwi, if (!skb) return NULL; - true_len = mt76x0_mac_process_rx(dev, skb, data, rxwi); + true_len = mt76x0_mac_process_rx(dev, skb, rxwi); if (!true_len || true_len > seg_len) goto bad_frame; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c b/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c index 99e2e1225d55..2d8abeb413ac 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c @@ -213,7 +213,7 @@ mt76x0_rx_is_our_beacon(struct mt76x0_dev *dev, u8 *data) } u32 mt76x0_mac_process_rx(struct mt76x0_dev *dev, struct sk_buff *skb, - u8 *data, void *rxi) + void *rxi) { struct mt76_rx_status *status = (struct mt76_rx_status *) skb->cb; struct mt76x02_rxwi *rxwi = rxi; @@ -239,7 +239,7 @@ u32 mt76x0_mac_process_rx(struct mt76x0_dev *dev, struct sk_buff *skb, mt76x02_mac_process_rate(status, rate); spin_lock_bh(&dev->con_mon_lock); - if (mt76x0_rx_is_our_beacon(dev, data)) { + if (mt76x0_rx_is_our_beacon(dev, skb->data)) { mt76x0_rx_monitor_beacon(dev, rxwi, rate, rssi); } else if (rxwi->rxinfo & cpu_to_le32(MT_RXINFO_UNICAST)) { if (dev->avg_rssi == 0) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mac.h b/drivers/net/wireless/mediatek/mt76/mt76x0/mac.h index abce22a51c87..b887693a56b6 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mac.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mac.h @@ -16,5 +16,5 @@ #define __MT76_MAC_H u32 mt76x0_mac_process_rx(struct mt76x0_dev *dev, struct sk_buff *skb, - u8 *data, void *rxi); + void *rxi); #endif From 4fcedad49cdcf82759ae54cb843f516ccd87944b Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Thu, 6 Sep 2018 11:18:30 +0200 Subject: [PATCH 160/276] mt76x0: add mt76x0_queue_rx_skb routine Introduce mt76x0_queue_rx_skb routine as mt76x0 driver frame rx handler. mt76x0_queue_rx_skb will be run by mt76-usb layer rx datapath Signed-off-by: Lorenzo Bianconi Signed-off-by: Stanislaw Gruszka Signed-off-by: Felix Fietkau --- .../net/wireless/mediatek/mt76/mt76x0/mt76x0.h | 3 +++ drivers/net/wireless/mediatek/mt76/mt76x0/tx.c | 15 +++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h index 8b0bef9a15e4..8a01efb8d499 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h @@ -245,6 +245,9 @@ void mt76x0_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, void mt76x0_tx_status(struct mt76x0_dev *dev, struct sk_buff *skb); void mt76x0_tx_stat(struct work_struct *work); +void mt76x0_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q, + struct sk_buff *skb); + int mt76x0_dma_init(struct mt76x0_dev *dev); void mt76x0_dma_cleanup(struct mt76x0_dev *dev); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c b/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c index 4cafd30d2c0a..5de454dac615 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c @@ -131,6 +131,21 @@ int mt76x0_tx_prepare_skb(struct mt76_dev *mdev, void *data, return mt76x02_set_txinfo(skb, wcid, q2ep(q->hw_idx)); } +void mt76x0_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q, + struct sk_buff *skb) +{ + struct mt76x0_dev *dev = container_of(mdev, struct mt76x0_dev, mt76); + void *rxwi = skb->data; + + skb_pull(skb, sizeof(struct mt76x02_rxwi)); + if (!mt76x0_mac_process_rx(dev, skb, rxwi)) { + dev_kfree_skb(skb); + return; + } + + mt76_rx(&dev->mt76, q, skb); +} + void mt76x0_tx_stat(struct work_struct *work) { struct mt76x0_dev *dev = container_of(work, struct mt76x0_dev, From f2653a4ee3f25baf8539f251de2e0093619d2460 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Thu, 6 Sep 2018 11:18:25 +0200 Subject: [PATCH 161/276] mt76x0: init mt76_driver_ops callbacks Init mt76_driver_ops callbacks in mt76x0_alloc_device. mt76_driver_ops callbacks will be used by mt76-usb module Signed-off-by: Lorenzo Bianconi Signed-off-by: Stanislaw Gruszka Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt76x0/init.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c index f2d3ae93d643..a92de35ef7fd 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c @@ -19,6 +19,7 @@ #include "trace.h" #include "mcu.h" #include "usb.h" +#include "../mt76x02_util.h" #include "initvals.h" @@ -483,6 +484,12 @@ void mt76x0_cleanup(struct mt76x0_dev *dev) struct mt76x0_dev *mt76x0_alloc_device(struct device *pdev) { + static const struct mt76_driver_ops drv_ops = { + .tx_prepare_skb = mt76x0_tx_prepare_skb, + .tx_complete_skb = mt76x02_tx_complete_skb, + .tx_status_data = mt76x02_tx_status_data, + .rx_skb = mt76x0_queue_rx_skb, + }; struct ieee80211_hw *hw; struct mt76x0_dev *dev; @@ -493,7 +500,7 @@ struct mt76x0_dev *mt76x0_alloc_device(struct device *pdev) dev = hw->priv; dev->mt76.dev = pdev; dev->mt76.hw = hw; - dev->mt76.drv = NULL; + dev->mt76.drv = &drv_ops; mutex_init(&dev->usb_ctrl_mtx); mutex_init(&dev->reg_atomic_mutex); mutex_init(&dev->hw_atomic_mutex); From 95e507d2f36654814db75b01b636aed34c0b436f Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Thu, 6 Sep 2018 11:18:26 +0200 Subject: [PATCH 162/276] mt76x0: use mt76_alloc_device for device allocation Use mt76_alloc_device utility routine for mt76x0_dev/mt76_dev allocation Signed-off-by: Lorenzo Bianconi Signed-off-by: Stanislaw Gruszka Signed-off-by: Felix Fietkau --- .../net/wireless/mediatek/mt76/mt76x0/init.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c index a92de35ef7fd..b28ea45a7282 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c @@ -490,24 +490,22 @@ struct mt76x0_dev *mt76x0_alloc_device(struct device *pdev) .tx_status_data = mt76x02_tx_status_data, .rx_skb = mt76x0_queue_rx_skb, }; - struct ieee80211_hw *hw; struct mt76x0_dev *dev; + struct mt76_dev *mdev; - hw = ieee80211_alloc_hw(sizeof(*dev), &mt76x0_ops); - if (!hw) + mdev = mt76_alloc_device(sizeof(*dev), &mt76x0_ops); + if (!mdev) return NULL; - dev = hw->priv; - dev->mt76.dev = pdev; - dev->mt76.hw = hw; - dev->mt76.drv = &drv_ops; + mdev->dev = pdev; + mdev->drv = &drv_ops; + + dev = container_of(mdev, struct mt76x0_dev, mt76); mutex_init(&dev->usb_ctrl_mtx); mutex_init(&dev->reg_atomic_mutex); mutex_init(&dev->hw_atomic_mutex); - mutex_init(&dev->mt76.mutex); spin_lock_init(&dev->tx_lock); spin_lock_init(&dev->rx_lock); - spin_lock_init(&dev->mt76.lock); spin_lock_init(&dev->mac_lock); spin_lock_init(&dev->con_mon_lock); atomic_set(&dev->avg_ampdu_len, 1); @@ -515,7 +513,7 @@ struct mt76x0_dev *mt76x0_alloc_device(struct device *pdev) dev->stat_wq = alloc_workqueue("mt76x0", WQ_UNBOUND, 0); if (!dev->stat_wq) { - ieee80211_free_hw(hw); + ieee80211_free_hw(mdev->hw); return NULL; } From 30ec915269c69cd8673ff3f99b024b05a5a27a0e Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Thu, 6 Sep 2018 11:18:31 +0200 Subject: [PATCH 163/276] mt76x0: unify tx/rx datapath with mt76x2u driver Use mt76/mt76-usb shared routine for tx/rx datapath. Initialize mt76-usb tx/rx queues in mt76x0_init_hardware and deallocate them in mt76x0_cleanup routine. Moreover remove data padding in mt76_mac_process_rx routine. Furthermore remove unused skb2q routine Signed-off-by: Lorenzo Bianconi Signed-off-by: Stanislaw Gruszka Signed-off-by: Felix Fietkau --- .../net/wireless/mediatek/mt76/mt76x0/init.c | 9 ++-- .../net/wireless/mediatek/mt76/mt76x0/mac.c | 8 +++- .../net/wireless/mediatek/mt76/mt76x0/tx.c | 46 ++++++------------- 3 files changed, 25 insertions(+), 38 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c index b28ea45a7282..33730c93c63f 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c @@ -417,8 +417,9 @@ int mt76x0_init_hardware(struct mt76x0_dev *dev) ret = mt76x0_mcu_cmd_init(dev); if (ret) goto err; - ret = mt76x0_dma_init(dev); - if (ret) + + ret = mt76u_alloc_queues(&dev->mt76); + if (ret < 0) goto err_mcu; mt76x0_init_mac_registers(dev); @@ -464,7 +465,7 @@ int mt76x0_init_hardware(struct mt76x0_dev *dev) return 0; err_rx: - mt76x0_dma_cleanup(dev); + mt76u_queues_deinit(&dev->mt76); err_mcu: mt76u_mcu_deinit(&dev->mt76); err: @@ -478,7 +479,7 @@ void mt76x0_cleanup(struct mt76x0_dev *dev) return; mt76x0_stop_hardware(dev); - mt76x0_dma_cleanup(dev); + mt76u_queues_deinit(&dev->mt76); mt76u_mcu_deinit(&dev->mt76); } diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c b/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c index 2d8abeb413ac..8fdc246964b9 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c @@ -15,6 +15,7 @@ #include "mt76x0.h" #include "trace.h" +#include "../mt76x02_util.h" #include void mt76x0_mac_set_protection(struct mt76x0_dev *dev, bool legacy_prot, @@ -219,7 +220,7 @@ u32 mt76x0_mac_process_rx(struct mt76x0_dev *dev, struct sk_buff *skb, struct mt76x02_rxwi *rxwi = rxi; u32 len, ctl = le32_to_cpu(rxwi->ctl); u16 rate = le16_to_cpu(rxwi->rate); - int rssi; + int rssi, pad_len = 0; len = FIELD_GET(MT_RXWI_CTL_MPDU_LEN, ctl); if (WARN_ON(len < 10)) @@ -230,6 +231,11 @@ u32 mt76x0_mac_process_rx(struct mt76x0_dev *dev, struct sk_buff *skb, status->flag |= RX_FLAG_IV_STRIPPED | RX_FLAG_MMIC_STRIPPED; } + if (rxwi->rxinfo & MT_RXINFO_L2PAD) + pad_len += 2; + + mt76x02_remove_hdr_pad(skb, pad_len); + status->chains = BIT(0); rssi = mt76x0_phy_get_rssi(dev, rxwi); status->chain_signal[0] = status->signal = rssi; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c b/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c index 5de454dac615..287e6c989447 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c @@ -16,19 +16,6 @@ #include "trace.h" #include "../mt76x02_util.h" -/* Take mac80211 Q id from the skb and translate it to hardware Q id */ -static u8 skb2q(struct sk_buff *skb) -{ - int qid = skb_get_queue_mapping(skb); - - if (WARN_ON(qid >= MT_TXQ_PSD)) { - qid = MT_TXQ_BE; - skb_set_queue_mapping(skb, qid); - } - - return mt76_ac_to_hwq(qid); -} - void mt76x0_tx_status(struct mt76x0_dev *dev, struct sk_buff *skb) { struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); @@ -82,38 +69,31 @@ mt76x0_push_txwi(struct mt76x0_dev *dev, struct sk_buff *skb, } void mt76x0_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, - struct sk_buff *skb) + struct sk_buff *skb) { struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct mt76x0_dev *dev = hw->priv; struct ieee80211_vif *vif = info->control.vif; - struct ieee80211_sta *sta = control->sta; - struct mt76x02_sta *msta = NULL; struct mt76_wcid *wcid = &dev->mt76.global_wcid; - struct mt76x02_txwi *txwi; - int pkt_len = skb->len; - int hw_q = skb2q(skb); - BUILD_BUG_ON(ARRAY_SIZE(info->status.status_driver_data) < 1); - info->status.status_driver_data[0] = (void *)(unsigned long)pkt_len; + if (control->sta) { + struct mt76x02_sta *msta; - mt76x02_insert_hdr_pad(skb); - - if (sta) { - msta = (struct mt76x02_sta *) sta->drv_priv; + msta = (struct mt76x02_sta *)control->sta->drv_priv; wcid = &msta->wcid; - } else if (vif && (!info->control.hw_key && wcid->hw_key_idx != 0xff)) { - struct mt76x02_vif *mvif = (struct mt76x02_vif *)vif->drv_priv; + /* sw encrypted frames */ + if (!info->control.hw_key && wcid->hw_key_idx != 0xff) + control->sta = NULL; + } + if (vif && !control->sta) { + struct mt76x02_vif *mvif; + + mvif = (struct mt76x02_vif *)vif->drv_priv; wcid = &mvif->group_wcid; } - txwi = mt76x0_push_txwi(dev, skb, sta, wcid, pkt_len); - - if (mt76x0_dma_enqueue_tx(dev, skb, wcid, hw_q)) - return; - - trace_mt76x0_tx(&dev->mt76, skb, msta, txwi); + mt76_tx(&dev->mt76, control->sta, wcid, skb); } int mt76x0_tx_prepare_skb(struct mt76_dev *mdev, void *data, From 1baa6e3a9b7df55ed7381828e81df0f91194c4ea Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Thu, 6 Sep 2018 11:18:32 +0200 Subject: [PATCH 164/276] mt76x0: stop stat workqueue at hw stop Cancel tx status workqueue during vif teardown Signed-off-by: Lorenzo Bianconi Signed-off-by: Stanislaw Gruszka Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt76x0/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c index 3ac8e36d1c24..b0a1f7a7209a 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c @@ -51,6 +51,7 @@ static void mt76x0_stop(struct ieee80211_hw *hw) cancel_delayed_work_sync(&dev->cal_work); cancel_delayed_work_sync(&dev->mac_work); + mt76u_stop_stat_wk(&dev->mt76); mt76x0_mac_stop(dev); mutex_unlock(&dev->mt76.mutex); From c6687464080608279260380142b45c0c0b88420e Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Thu, 6 Sep 2018 11:18:33 +0200 Subject: [PATCH 165/276] mt76x0: set max fragments size Set maximum number of tx fragments according to usb controller features Signed-off-by: Lorenzo Bianconi Signed-off-by: Stanislaw Gruszka Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt76x0/init.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c index 33730c93c63f..cd7cdf3d9731 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c @@ -722,6 +722,12 @@ int mt76x0_register_device(struct mt76x0_dev *dev) if (ret) return ret; + /* check hw sg support in order to enable AMSDU */ + if (mt76u_check_sg(&dev->mt76)) + hw->max_tx_fragments = MT_SG_MAX_SIZE; + else + hw->max_tx_fragments = 1; + mt76x0_init_debugfs(dev); return 0; From 37d363665ba11b12d818a48bf495ad132d66d4f4 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Thu, 6 Sep 2018 11:18:34 +0200 Subject: [PATCH 166/276] mt76x0: remove unused dma.c source file Remove unused dma.c source file since dma related routines are no longer used Signed-off-by: Lorenzo Bianconi Signed-off-by: Stanislaw Gruszka Signed-off-by: Felix Fietkau --- .../wireless/mediatek/mt76/mt76x0/Makefile | 2 +- .../net/wireless/mediatek/mt76/mt76x0/dma.c | 526 ------------------ .../net/wireless/mediatek/mt76/mt76x0/init.c | 1 - .../wireless/mediatek/mt76/mt76x0/mt76x0.h | 11 - 4 files changed, 1 insertion(+), 539 deletions(-) delete mode 100644 drivers/net/wireless/mediatek/mt76/mt76x0/dma.c diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/Makefile b/drivers/net/wireless/mediatek/mt76/mt76x0/Makefile index a4a446921d2f..df70690e3aff 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/Makefile +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/Makefile @@ -1,7 +1,7 @@ obj-$(CONFIG_MT76x0U) += mt76x0.o mt76x0-objs = \ - usb.o init.o main.o mcu.o trace.o dma.o eeprom.o phy.o \ + usb.o init.o main.o mcu.o trace.o eeprom.o phy.o \ mac.o debugfs.o tx.o # ccflags-y := -DDEBUG CFLAGS_trace.o := -I$(src) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/dma.c b/drivers/net/wireless/mediatek/mt76/mt76x0/dma.c deleted file mode 100644 index 82c2b37d0896..000000000000 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/dma.c +++ /dev/null @@ -1,526 +0,0 @@ -/* - * Copyright (C) 2015 Jakub Kicinski - * Copyright (C) 2018 Stanislaw Gruszka - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include "mt76x0.h" -#include "dma.h" -#include "usb.h" -#include "trace.h" - -static int mt76x0_submit_rx_buf(struct mt76x0_dev *dev, - struct mt76x0_dma_buf_rx *e, gfp_t gfp); - -static unsigned int ieee80211_get_hdrlen_from_buf(const u8 *data, unsigned len) -{ - const struct ieee80211_hdr *hdr = (const struct ieee80211_hdr *)data; - unsigned int hdrlen; - - if (unlikely(len < 10)) - return 0; - hdrlen = ieee80211_hdrlen(hdr->frame_control); - if (unlikely(hdrlen > len)) - return 0; - return hdrlen; -} - -static struct sk_buff * -mt76x0_rx_skb_from_seg(struct mt76x0_dev *dev, struct mt76x02_rxwi *rxwi, - void *data, u32 seg_len, u32 truesize, struct page *p) -{ - struct sk_buff *skb; - u32 true_len, hdr_len = 0, copy, frag; - - skb = alloc_skb(p ? 128 : seg_len, GFP_ATOMIC); - if (!skb) - return NULL; - - true_len = mt76x0_mac_process_rx(dev, skb, rxwi); - if (!true_len || true_len > seg_len) - goto bad_frame; - - hdr_len = ieee80211_get_hdrlen_from_buf(data, true_len); - if (!hdr_len) - goto bad_frame; - - if (rxwi->rxinfo & cpu_to_le32(MT_RXINFO_L2PAD)) { - memcpy(skb_put(skb, hdr_len), data, hdr_len); - - data += hdr_len + 2; - true_len -= hdr_len; - hdr_len = 0; - } - - /* If not doing paged RX allocated skb will always have enough space */ - copy = (true_len <= skb_tailroom(skb)) ? true_len : hdr_len + 8; - frag = true_len - copy; - - memcpy(skb_put(skb, copy), data, copy); - data += copy; - - if (frag) { - skb_add_rx_frag(skb, 0, p, data - page_address(p), - frag, truesize); - get_page(p); - } - - return skb; - -bad_frame: - dev_err_ratelimited(dev->mt76.dev, "Error: incorrect frame len:%u hdr:%u\n", - true_len, hdr_len); - dev_kfree_skb(skb); - return NULL; -} - -static void mt76x0_rx_process_seg(struct mt76x0_dev *dev, u8 *data, - u32 seg_len, struct page *p) -{ - struct sk_buff *skb; - struct mt76x02_rxwi *rxwi; - u32 fce_info, truesize = seg_len; - - /* DMA_INFO field at the beginning of the segment contains only some of - * the information, we need to read the FCE descriptor from the end. - */ - fce_info = get_unaligned_le32(data + seg_len - MT_FCE_INFO_LEN); - seg_len -= MT_FCE_INFO_LEN; - - data += MT_DMA_HDR_LEN; - seg_len -= MT_DMA_HDR_LEN; - - rxwi = (struct mt76x02_rxwi *) data; - data += sizeof(struct mt76x02_rxwi); - seg_len -= sizeof(struct mt76x02_rxwi); - - if (unlikely(FIELD_GET(MT_RXD_INFO_TYPE, fce_info))) - dev_err_once(dev->mt76.dev, "Error: RX path seen a non-pkt urb\n"); - - trace_mt76x0_rx(&dev->mt76, rxwi, fce_info); - - skb = mt76x0_rx_skb_from_seg(dev, rxwi, data, seg_len, truesize, p); - if (!skb) - return; - - mt76_rx_convert(skb); - - spin_lock(&dev->mac_lock); - ieee80211_rx(dev->mt76.hw, skb); - spin_unlock(&dev->mac_lock); -} - -static u16 mt76x0_rx_next_seg_len(u8 *data, u32 data_len) -{ - u32 min_seg_len = MT_DMA_HDR_LEN + MT_RX_INFO_LEN + - sizeof(struct mt76x02_rxwi) + MT_FCE_INFO_LEN; - u16 dma_len = get_unaligned_le16(data); - - if (data_len < min_seg_len || - WARN_ON(!dma_len) || - WARN_ON(dma_len + MT_DMA_HDRS > data_len) || - WARN_ON(dma_len & 0x3)) - return 0; - - return MT_DMA_HDRS + dma_len; -} - -static void -mt76x0_rx_process_entry(struct mt76x0_dev *dev, struct mt76x0_dma_buf_rx *e) -{ - u32 seg_len, data_len = e->urb->actual_length; - u8 *data = page_address(e->p); - struct page *new_p = NULL; - int cnt = 0; - - if (!test_bit(MT76_STATE_INITIALIZED, &dev->mt76.state)) - return; - - /* Copy if there is very little data in the buffer. */ - if (data_len > 512) - new_p = dev_alloc_pages(MT_RX_ORDER); - - while ((seg_len = mt76x0_rx_next_seg_len(data, data_len))) { - mt76x0_rx_process_seg(dev, data, seg_len, new_p ? e->p : NULL); - - data_len -= seg_len; - data += seg_len; - cnt++; - } - - if (cnt > 1) - trace_mt76x0_rx_dma_aggr(&dev->mt76, cnt, !!new_p); - - if (new_p) { - /* we have one extra ref from the allocator */ - __free_pages(e->p, MT_RX_ORDER); - - e->p = new_p; - } -} - -static struct mt76x0_dma_buf_rx * -mt76x0_rx_get_pending_entry(struct mt76x0_dev *dev) -{ - struct mt76x0_rx_queue *q = &dev->rx_q; - struct mt76x0_dma_buf_rx *buf = NULL; - unsigned long flags; - - spin_lock_irqsave(&dev->rx_lock, flags); - - if (!q->pending) - goto out; - - buf = &q->e[q->start]; - q->pending--; - q->start = (q->start + 1) % q->entries; -out: - spin_unlock_irqrestore(&dev->rx_lock, flags); - - return buf; -} - -static void mt76x0_complete_rx(struct urb *urb) -{ - struct mt76x0_dev *dev = urb->context; - struct mt76x0_rx_queue *q = &dev->rx_q; - unsigned long flags; - - spin_lock_irqsave(&dev->rx_lock, flags); - - if (mt76x0_urb_has_error(urb)) - dev_err(dev->mt76.dev, "Error: RX urb failed:%d\n", urb->status); - if (WARN_ONCE(q->e[q->end].urb != urb, "RX urb mismatch")) - goto out; - - q->end = (q->end + 1) % q->entries; - q->pending++; - tasklet_schedule(&dev->rx_tasklet); -out: - spin_unlock_irqrestore(&dev->rx_lock, flags); -} - -static void mt76x0_rx_tasklet(unsigned long data) -{ - struct mt76x0_dev *dev = (struct mt76x0_dev *) data; - struct mt76x0_dma_buf_rx *e; - - while ((e = mt76x0_rx_get_pending_entry(dev))) { - if (e->urb->status) - continue; - - mt76x0_rx_process_entry(dev, e); - mt76x0_submit_rx_buf(dev, e, GFP_ATOMIC); - } -} - -static void mt76x0_complete_tx(struct urb *urb) -{ - struct mt76x0_tx_queue *q = urb->context; - struct mt76x0_dev *dev = q->dev; - struct sk_buff *skb; - unsigned long flags; - - spin_lock_irqsave(&dev->tx_lock, flags); - - if (mt76x0_urb_has_error(urb)) - dev_err(dev->mt76.dev, "Error: TX urb failed:%d\n", urb->status); - if (WARN_ONCE(q->e[q->start].urb != urb, "TX urb mismatch")) - goto out; - - skb = q->e[q->start].skb; - trace_mt76x0_tx_dma_done(&dev->mt76, skb); - - __skb_queue_tail(&dev->tx_skb_done, skb); - tasklet_schedule(&dev->tx_tasklet); - - if (q->used == q->entries - q->entries / 8) - ieee80211_wake_queue(dev->mt76.hw, skb_get_queue_mapping(skb)); - - q->start = (q->start + 1) % q->entries; - q->used--; -out: - spin_unlock_irqrestore(&dev->tx_lock, flags); -} - -static void mt76x0_tx_tasklet(unsigned long data) -{ - struct mt76x0_dev *dev = (struct mt76x0_dev *) data; - struct sk_buff_head skbs; - unsigned long flags; - - __skb_queue_head_init(&skbs); - - spin_lock_irqsave(&dev->tx_lock, flags); - - set_bit(MT76_MORE_STATS, &dev->mt76.state); - if (!test_and_set_bit(MT76_READING_STATS, &dev->mt76.state)) - queue_delayed_work(dev->stat_wq, &dev->stat_work, - msecs_to_jiffies(10)); - - skb_queue_splice_init(&dev->tx_skb_done, &skbs); - - spin_unlock_irqrestore(&dev->tx_lock, flags); - - while (!skb_queue_empty(&skbs)) { - struct sk_buff *skb = __skb_dequeue(&skbs); - - mt76x0_tx_status(dev, skb); - } -} - -static int mt76x0_dma_submit_tx(struct mt76x0_dev *dev, - struct sk_buff *skb, u8 ep) -{ - struct usb_device *usb_dev = mt76x0_to_usb_dev(dev); - struct mt76_usb *usb = &dev->mt76.usb; - unsigned snd_pipe = usb_sndbulkpipe(usb_dev, usb->out_ep[ep]); - struct mt76x0_dma_buf_tx *e; - struct mt76x0_tx_queue *q = &dev->tx_q[ep]; - unsigned long flags; - int ret; - - spin_lock_irqsave(&dev->tx_lock, flags); - - if (WARN_ON_ONCE(q->entries <= q->used)) { - ret = -ENOSPC; - goto out; - } - - e = &q->e[q->end]; - e->skb = skb; - usb_fill_bulk_urb(e->urb, usb_dev, snd_pipe, skb->data, skb->len, - mt76x0_complete_tx, q); - ret = usb_submit_urb(e->urb, GFP_ATOMIC); - if (ret) { - /* Special-handle ENODEV from TX urb submission because it will - * often be the first ENODEV we see after device is removed. - */ - if (ret == -ENODEV) - set_bit(MT76_REMOVED, &dev->mt76.state); - else - dev_err(dev->mt76.dev, "Error: TX urb submit failed:%d\n", - ret); - goto out; - } - - q->end = (q->end + 1) % q->entries; - q->used++; - - if (q->used >= q->entries) - ieee80211_stop_queue(dev->mt76.hw, skb_get_queue_mapping(skb)); -out: - spin_unlock_irqrestore(&dev->tx_lock, flags); - - return ret; -} - -/* Map USB endpoint number to Q id in the DMA engine */ -static enum mt76_qsel ep2dmaq(u8 ep) -{ - if (ep == 5) - return MT_QSEL_MGMT; - return MT_QSEL_EDCA; -} - -int mt76x0_dma_enqueue_tx(struct mt76x0_dev *dev, struct sk_buff *skb, - struct mt76_wcid *wcid, int hw_q) -{ - u8 ep = q2ep(hw_q); - u32 dma_flags; - int ret; - - dma_flags = MT_TXD_PKT_INFO_80211; - if (wcid->hw_key_idx == 0xff) - dma_flags |= MT_TXD_PKT_INFO_WIV; - - ret = mt76x0_dma_skb_wrap_pkt(skb, ep2dmaq(ep), dma_flags); - if (ret) - return ret; - - ret = mt76x0_dma_submit_tx(dev, skb, ep); - - if (ret) { - ieee80211_free_txskb(dev->mt76.hw, skb); - return ret; - } - - return 0; -} - -static void mt76x0_kill_rx(struct mt76x0_dev *dev) -{ - int i; - unsigned long flags; - - spin_lock_irqsave(&dev->rx_lock, flags); - - for (i = 0; i < dev->rx_q.entries; i++) { - int next = dev->rx_q.end; - - spin_unlock_irqrestore(&dev->rx_lock, flags); - usb_poison_urb(dev->rx_q.e[next].urb); - spin_lock_irqsave(&dev->rx_lock, flags); - } - - spin_unlock_irqrestore(&dev->rx_lock, flags); -} - -static int mt76x0_submit_rx_buf(struct mt76x0_dev *dev, - struct mt76x0_dma_buf_rx *e, gfp_t gfp) -{ - struct usb_device *usb_dev = mt76x0_to_usb_dev(dev); - struct mt76_usb *usb = &dev->mt76.usb; - u8 *buf = page_address(e->p); - unsigned pipe; - int ret; - - pipe = usb_rcvbulkpipe(usb_dev, usb->in_ep[MT_EP_IN_PKT_RX]); - - usb_fill_bulk_urb(e->urb, usb_dev, pipe, buf, MT_RX_URB_SIZE, - mt76x0_complete_rx, dev); - - trace_mt76x0_submit_urb(&dev->mt76, e->urb); - ret = usb_submit_urb(e->urb, gfp); - if (ret) - dev_err(dev->mt76.dev, "Error: submit RX URB failed:%d\n", ret); - - return ret; -} - -static int mt76x0_submit_rx(struct mt76x0_dev *dev) -{ - int i, ret; - - for (i = 0; i < dev->rx_q.entries; i++) { - ret = mt76x0_submit_rx_buf(dev, &dev->rx_q.e[i], GFP_KERNEL); - if (ret) - return ret; - } - - return 0; -} - -static void mt76x0_free_rx(struct mt76x0_dev *dev) -{ - int i; - - for (i = 0; i < dev->rx_q.entries; i++) { - __free_pages(dev->rx_q.e[i].p, MT_RX_ORDER); - usb_free_urb(dev->rx_q.e[i].urb); - } -} - -static int mt76x0_alloc_rx(struct mt76x0_dev *dev) -{ - int i; - - memset(&dev->rx_q, 0, sizeof(dev->rx_q)); - dev->rx_q.dev = dev; - dev->rx_q.entries = N_RX_ENTRIES; - - for (i = 0; i < N_RX_ENTRIES; i++) { - dev->rx_q.e[i].urb = usb_alloc_urb(0, GFP_KERNEL); - dev->rx_q.e[i].p = dev_alloc_pages(MT_RX_ORDER); - - if (!dev->rx_q.e[i].urb || !dev->rx_q.e[i].p) - return -ENOMEM; - } - - return 0; -} - -static void mt76x0_free_tx_queue(struct mt76x0_tx_queue *q) -{ - int i; - - WARN_ON(q->used); - - for (i = 0; i < q->entries; i++) { - usb_poison_urb(q->e[i].urb); - usb_free_urb(q->e[i].urb); - } -} - -static void mt76x0_free_tx(struct mt76x0_dev *dev) -{ - int i; - - for (i = 0; i < __MT_EP_OUT_MAX; i++) - mt76x0_free_tx_queue(&dev->tx_q[i]); -} - -static int mt76x0_alloc_tx_queue(struct mt76x0_dev *dev, - struct mt76x0_tx_queue *q) -{ - int i; - - q->dev = dev; - q->entries = N_TX_ENTRIES; - - for (i = 0; i < N_TX_ENTRIES; i++) { - q->e[i].urb = usb_alloc_urb(0, GFP_KERNEL); - if (!q->e[i].urb) - return -ENOMEM; - } - - return 0; -} - -static int mt76x0_alloc_tx(struct mt76x0_dev *dev) -{ - int i; - - dev->tx_q = devm_kcalloc(dev->mt76.dev, __MT_EP_OUT_MAX, - sizeof(*dev->tx_q), GFP_KERNEL); - - for (i = 0; i < __MT_EP_OUT_MAX; i++) - if (mt76x0_alloc_tx_queue(dev, &dev->tx_q[i])) - return -ENOMEM; - - return 0; -} - -int mt76x0_dma_init(struct mt76x0_dev *dev) -{ - int ret = -ENOMEM; - - tasklet_init(&dev->tx_tasklet, mt76x0_tx_tasklet, (unsigned long) dev); - tasklet_init(&dev->rx_tasklet, mt76x0_rx_tasklet, (unsigned long) dev); - - ret = mt76x0_alloc_tx(dev); - if (ret) - goto err; - ret = mt76x0_alloc_rx(dev); - if (ret) - goto err; - - ret = mt76x0_submit_rx(dev); - if (ret) - goto err; - - return 0; -err: - mt76x0_dma_cleanup(dev); - return ret; -} - -void mt76x0_dma_cleanup(struct mt76x0_dev *dev) -{ - mt76x0_kill_rx(dev); - - tasklet_kill(&dev->rx_tasklet); - - mt76x0_free_rx(dev); - mt76x0_free_tx(dev); - - tasklet_kill(&dev->tx_tasklet); -} diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c index cd7cdf3d9731..9c4029b3d0ae 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c @@ -510,7 +510,6 @@ struct mt76x0_dev *mt76x0_alloc_device(struct device *pdev) spin_lock_init(&dev->mac_lock); spin_lock_init(&dev->con_mon_lock); atomic_set(&dev->avg_ampdu_len, 1); - skb_queue_head_init(&dev->tx_skb_done); dev->stat_wq = alloc_workqueue("mt76x0", WQ_UNBOUND, 0); if (!dev->stat_wq) { diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h index 8a01efb8d499..974ca932333c 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h @@ -39,8 +39,6 @@ #define MT_USB_AGGR_SIZE_LIMIT 21 /* * 1024B */ #define MT_USB_AGGR_TIMEOUT 0x80 /* * 33ns */ -#define MT_RX_ORDER 3 -#define MT_RX_URB_SIZE (PAGE_SIZE << MT_RX_ORDER) struct mt76x0_dma_buf { struct urb *urb; @@ -126,9 +124,6 @@ struct mt76x0_dev { struct mutex usb_ctrl_mtx; u8 data[32]; - struct tasklet_struct rx_tasklet; - struct tasklet_struct tx_tasklet; - u8 out_ep[__MT_EP_OUT_MAX]; u16 out_max_packet; u8 in_ep[__MT_EP_IN_MAX]; @@ -155,7 +150,6 @@ struct mt76x0_dev { /* TX */ spinlock_t tx_lock; struct mt76x0_tx_queue *tx_q; - struct sk_buff_head tx_skb_done; atomic_t avg_ampdu_len; @@ -248,11 +242,6 @@ void mt76x0_tx_stat(struct work_struct *work); void mt76x0_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q, struct sk_buff *skb); -int mt76x0_dma_init(struct mt76x0_dev *dev); -void mt76x0_dma_cleanup(struct mt76x0_dev *dev); - -int mt76x0_dma_enqueue_tx(struct mt76x0_dev *dev, struct sk_buff *skb, - struct mt76_wcid *wcid, int hw_q); int mt76x0_tx_prepare_skb(struct mt76_dev *mdev, void *data, struct sk_buff *skb, struct mt76_queue *q, struct mt76_wcid *wcid, struct ieee80211_sta *sta, From 4220878b6e1d34d565e31973bce45699326ab53a Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Thu, 6 Sep 2018 11:18:35 +0200 Subject: [PATCH 167/276] mt76x0: remove unused stat work_queue Remove unused tx_status workqueue since now tx feedbacks are processed by mt76-usb layer Signed-off-by: Lorenzo Bianconi Signed-off-by: Stanislaw Gruszka Signed-off-by: Felix Fietkau --- .../net/wireless/mediatek/mt76/mt76x0/init.c | 7 ----- .../wireless/mediatek/mt76/mt76x0/mt76x0.h | 2 -- .../net/wireless/mediatek/mt76/mt76x0/tx.c | 30 ------------------- .../net/wireless/mediatek/mt76/mt76x0/usb.c | 2 -- 4 files changed, 41 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c index 9c4029b3d0ae..5be4c48936e4 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c @@ -511,12 +511,6 @@ struct mt76x0_dev *mt76x0_alloc_device(struct device *pdev) spin_lock_init(&dev->con_mon_lock); atomic_set(&dev->avg_ampdu_len, 1); - dev->stat_wq = alloc_workqueue("mt76x0", WQ_UNBOUND, 0); - if (!dev->stat_wq) { - ieee80211_free_hw(mdev->hw); - return NULL; - } - return dev; } @@ -715,7 +709,6 @@ int mt76x0_register_device(struct mt76x0_dev *dev) dev->mt76.chandef.chan = &dev->mt76.sband_2g.sband.channels[0]; INIT_DELAYED_WORK(&dev->mac_work, mt76x0_mac_work); - INIT_DELAYED_WORK(&dev->stat_work, mt76x0_tx_stat); ret = ieee80211_register_hw(hw); if (ret) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h index 974ca932333c..f63c44999bdd 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h @@ -132,7 +132,6 @@ struct mt76x0_dev { struct delayed_work cal_work; struct delayed_work mac_work; - struct workqueue_struct *stat_wq; struct delayed_work stat_work; spinlock_t mac_lock; @@ -237,7 +236,6 @@ void mt76x0_mac_set_ampdu_factor(struct mt76x0_dev *dev); void mt76x0_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, struct sk_buff *skb); void mt76x0_tx_status(struct mt76x0_dev *dev, struct sk_buff *skb); -void mt76x0_tx_stat(struct work_struct *work); void mt76x0_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q, struct sk_buff *skb); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c b/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c index 287e6c989447..c0ecb57fc9e6 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c @@ -126,33 +126,3 @@ void mt76x0_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q, mt76_rx(&dev->mt76, q, skb); } -void mt76x0_tx_stat(struct work_struct *work) -{ - struct mt76x0_dev *dev = container_of(work, struct mt76x0_dev, - stat_work.work); - struct mt76x02_tx_status stat; - unsigned long flags; - int cleaned = 0; - u8 update = 1; - - while (!test_bit(MT76_REMOVED, &dev->mt76.state)) { - if (!mt76x02_mac_load_tx_status(&dev->mt76, &stat)) - break; - - mt76x02_send_tx_status(&dev->mt76, &stat, &update); - - cleaned++; - } - trace_mt76x0_tx_status_cleaned(&dev->mt76, cleaned); - - spin_lock_irqsave(&dev->tx_lock, flags); - if (cleaned) - queue_delayed_work(dev->stat_wq, &dev->stat_work, - msecs_to_jiffies(10)); - else if (test_and_clear_bit(MT76_MORE_STATS, &dev->mt76.state)) - queue_delayed_work(dev->stat_wq, &dev->stat_work, - msecs_to_jiffies(20)); - else - clear_bit(MT76_READING_STATS, &dev->mt76.state); - spin_unlock_irqrestore(&dev->tx_lock, flags); -} diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c index a5ca74594290..219524c233ee 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c @@ -107,7 +107,6 @@ static int mt76x0_probe(struct usb_interface *usb_intf, usb_set_intfdata(usb_intf, NULL); usb_put_dev(interface_to_usbdev(usb_intf)); - destroy_workqueue(dev->stat_wq); ieee80211_free_hw(dev->mt76.hw); return ret; } @@ -126,7 +125,6 @@ static void mt76x0_disconnect(struct usb_interface *usb_intf) usb_set_intfdata(usb_intf, NULL); usb_put_dev(interface_to_usbdev(usb_intf)); - destroy_workqueue(dev->stat_wq); ieee80211_free_hw(dev->mt76.hw); } From 6d449d12a041f6ce42422d65b6759c1649e5515e Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Thu, 6 Sep 2018 11:18:36 +0200 Subject: [PATCH 168/276] mt76x0: remove unused {tx/rx}_queue definitions Remove unused tx_queue and rx_queue definitions since now mt76x0 driver uses mt76-usb {tx/rx}_queues Signed-off-by: Lorenzo Bianconi Signed-off-by: Stanislaw Gruszka Signed-off-by: Felix Fietkau --- .../net/wireless/mediatek/mt76/mt76x0/init.c | 2 - .../wireless/mediatek/mt76/mt76x0/mt76x0.h | 50 ------------------- 2 files changed, 52 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c index 5be4c48936e4..a7d6e747f221 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c @@ -505,8 +505,6 @@ struct mt76x0_dev *mt76x0_alloc_device(struct device *pdev) mutex_init(&dev->usb_ctrl_mtx); mutex_init(&dev->reg_atomic_mutex); mutex_init(&dev->hw_atomic_mutex); - spin_lock_init(&dev->tx_lock); - spin_lock_init(&dev->rx_lock); spin_lock_init(&dev->mac_lock); spin_lock_init(&dev->con_mon_lock); atomic_set(&dev->avg_ampdu_len, 1); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h index f63c44999bdd..6ba5e9ba2c7f 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h @@ -40,13 +40,6 @@ #define MT_USB_AGGR_SIZE_LIMIT 21 /* * 1024B */ #define MT_USB_AGGR_TIMEOUT 0x80 /* * 33ns */ -struct mt76x0_dma_buf { - struct urb *urb; - void *buf; - dma_addr_t dma; - size_t len; -}; - struct mac_stats { u64 rx_stat[6]; u64 tx_stat[6]; @@ -55,38 +48,6 @@ struct mac_stats { u64 zero_len_del[2]; }; -#define N_RX_ENTRIES 16 -struct mt76x0_rx_queue { - struct mt76x0_dev *dev; - - struct mt76x0_dma_buf_rx { - struct urb *urb; - struct page *p; - } e[N_RX_ENTRIES]; - - unsigned int start; - unsigned int end; - unsigned int entries; - unsigned int pending; -}; - -#define N_TX_ENTRIES 64 - -struct mt76x0_tx_queue { - struct mt76x0_dev *dev; - - struct mt76x0_dma_buf_tx { - struct urb *urb; - struct sk_buff *skb; - } e[N_TX_ENTRIES]; - - unsigned int start; - unsigned int end; - unsigned int entries; - unsigned int used; - unsigned int fifo_seq; -}; - struct mt76x0_eeprom_params; #define MT_EE_TEMPERATURE_SLOPE 39 @@ -108,9 +69,6 @@ enum mt_bw { * struct mt76x0_dev - adapter structure * @lock: protects @wcid->tx_rate. * @mac_lock: locks out mac80211's tx status and rx paths. - * @tx_lock: protects @tx_q and changes of MT76_STATE_*_STATS - * flags in @state. - * @rx_lock: protects @rx_q. * @con_mon_lock: protects @ap_bssid, @bcn_*, @avg_rssi. * @mutex: ensures exclusive access from mac80211 callbacks. * @reg_atomic_mutex: ensures atomicity of indirect register accesses @@ -146,16 +104,8 @@ struct mt76x0_dev { u32 debugfs_reg; - /* TX */ - spinlock_t tx_lock; - struct mt76x0_tx_queue *tx_q; - atomic_t avg_ampdu_len; - /* RX */ - spinlock_t rx_lock; - struct mt76x0_rx_queue rx_q; - /* Connection monitoring things */ spinlock_t con_mon_lock; u8 ap_bssid[ETH_ALEN]; From f79fdf7652dffa660a3caba46713a36387fd25b8 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Thu, 6 Sep 2018 11:18:37 +0200 Subject: [PATCH 169/276] mt76x0: remove unused mt76x0_tx_status routine Remove no longer used mt76x0_tx_status routine since mt76x0 driver uses mt76-usb utility routines to report tx-feedbacks Signed-off-by: Lorenzo Bianconi Signed-off-by: Stanislaw Gruszka Signed-off-by: Felix Fietkau --- .../net/wireless/mediatek/mt76/mt76x0/mt76x0.h | 1 - drivers/net/wireless/mediatek/mt76/mt76x0/tx.c | 15 --------------- 2 files changed, 16 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h index 6ba5e9ba2c7f..24712ac924ef 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h @@ -185,7 +185,6 @@ void mt76x0_mac_set_ampdu_factor(struct mt76x0_dev *dev); /* TX */ void mt76x0_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, struct sk_buff *skb); -void mt76x0_tx_status(struct mt76x0_dev *dev, struct sk_buff *skb); void mt76x0_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q, struct sk_buff *skb); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c b/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c index c0ecb57fc9e6..4058dae1368f 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c @@ -16,21 +16,6 @@ #include "trace.h" #include "../mt76x02_util.h" -void mt76x0_tx_status(struct mt76x0_dev *dev, struct sk_buff *skb) -{ - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - - mt76x02_remove_dma_hdr(skb); - - ieee80211_tx_info_clear_status(info); - info->status.rates[0].idx = -1; - info->flags |= IEEE80211_TX_STAT_ACK; - - spin_lock(&dev->mac_lock); - ieee80211_tx_status(dev->mt76.hw, skb); - spin_unlock(&dev->mac_lock); -} - static struct mt76x02_txwi * mt76x0_push_txwi(struct mt76x0_dev *dev, struct sk_buff *skb, struct ieee80211_sta *sta, struct mt76_wcid *wcid, From c1b6325d5105789b77e5b40ada9fc7c9455f8c81 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Thu, 6 Sep 2018 11:18:38 +0200 Subject: [PATCH 170/276] mt76x0: remove unused endpoint definitions remove unused usb endpoint definitions since mt76x0 uses mt76-usb ones. Moreover remove unused usb_ctrl mutex Signed-off-by: Lorenzo Bianconi Signed-off-by: Stanislaw Gruszka Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt76x0/init.c | 1 - drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h | 6 ------ 2 files changed, 7 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c index a7d6e747f221..75597b5a2427 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c @@ -502,7 +502,6 @@ struct mt76x0_dev *mt76x0_alloc_device(struct device *pdev) mdev->drv = &drv_ops; dev = container_of(mdev, struct mt76x0_dev, mt76); - mutex_init(&dev->usb_ctrl_mtx); mutex_init(&dev->reg_atomic_mutex); mutex_init(&dev->hw_atomic_mutex); spin_lock_init(&dev->mac_lock); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h index 24712ac924ef..0bcf54c0a06f 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h @@ -79,14 +79,8 @@ enum mt_bw { struct mt76x0_dev { struct mt76_dev mt76; /* must be first */ - struct mutex usb_ctrl_mtx; u8 data[32]; - u8 out_ep[__MT_EP_OUT_MAX]; - u16 out_max_packet; - u8 in_ep[__MT_EP_IN_MAX]; - u16 in_max_packet; - struct delayed_work cal_work; struct delayed_work mac_work; From 7cbe4c7607043d46accb7e6069a62691d276fbf9 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Thu, 6 Sep 2018 11:18:39 +0200 Subject: [PATCH 171/276] mt76x0: remove unused stat_work Remove unused definition of stat_work delayed_work definition and related flush/cancel routines Signed-off-by: Lorenzo Bianconi Signed-off-by: Stanislaw Gruszka Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt76x0/init.c | 2 -- drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h | 2 -- 2 files changed, 4 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c index 75597b5a2427..1f4a0fff684b 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c @@ -362,8 +362,6 @@ static void mt76x0_mac_stop_hw(struct mt76x0_dev *dev) void mt76x0_mac_stop(struct mt76x0_dev *dev) { mt76x0_mac_stop_hw(dev); - flush_delayed_work(&dev->stat_work); - cancel_delayed_work_sync(&dev->stat_work); } static void mt76x0_stop_hardware(struct mt76x0_dev *dev) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h index 0bcf54c0a06f..cd260317de27 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h @@ -84,8 +84,6 @@ struct mt76x0_dev { struct delayed_work cal_work; struct delayed_work mac_work; - struct delayed_work stat_work; - spinlock_t mac_lock; const u16 *beacon_offsets; From 67f5e7a794bcc1ccdc3679baf19ecb3f39cc20ab Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Thu, 6 Sep 2018 11:18:40 +0200 Subject: [PATCH 172/276] mt76x0: enable per-sta tx queueing Initialize wake_tx_queue function pointer in ieee80211_ops in order to enable per-sta tx queueing. Moreover set driver private txq size Signed-off-by: Lorenzo Bianconi Signed-off-by: Stanislaw Gruszka Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt76x0/init.c | 3 +++ drivers/net/wireless/mediatek/mt76/mt76x0/main.c | 1 + 2 files changed, 4 insertions(+) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c index 1f4a0fff684b..7cd939c97efe 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c @@ -684,6 +684,9 @@ int mt76x0_register_device(struct mt76x0_dev *dev) hw->sta_data_size = sizeof(struct mt76x02_sta); hw->vif_data_size = sizeof(struct mt76x02_vif); + hw->txq_data_size = sizeof(struct mt76_txq); + hw->max_tx_fragments = 16; + SET_IEEE80211_PERM_ADDR(hw, dev->macaddr); wiphy->features |= NL80211_FEATURE_ACTIVE_MONITOR; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c index b0a1f7a7209a..8c8a0f676228 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c @@ -180,4 +180,5 @@ const struct ieee80211_ops mt76x0_ops = { .ampdu_action = mt76x02_ampdu_action, .sta_rate_tbl_update = mt76x02_sta_rate_tbl_update, .set_rts_threshold = mt76x0_set_rts_threshold, + .wake_tx_queue = mt76_wake_tx_queue, }; From 0ae976a11b4fb5704b597e103b5189237641c1a1 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Thu, 6 Sep 2018 11:18:41 +0200 Subject: [PATCH 173/276] mt76x0: init hw capabilities Enable hw capabilities supported by mt76-usb layer - fast_xmit - tx/rx amsdu - MFP - non-linear tx skbs Signed-off-by: Lorenzo Bianconi Signed-off-by: Stanislaw Gruszka Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt76x0/init.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c index 7cd939c97efe..418e1918086d 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c @@ -676,6 +676,13 @@ int mt76x0_register_device(struct mt76x0_dev *dev) ieee80211_hw_set(hw, SUPPORTS_HT_CCK_RATES); ieee80211_hw_set(hw, AMPDU_AGGREGATION); ieee80211_hw_set(hw, SUPPORTS_RC_TABLE); + ieee80211_hw_set(hw, SUPPORT_FAST_XMIT); + ieee80211_hw_set(hw, SUPPORTS_CLONED_SKBS); + ieee80211_hw_set(hw, SUPPORTS_AMSDU_IN_AMPDU); + ieee80211_hw_set(hw, TX_AMSDU); + ieee80211_hw_set(hw, TX_FRAG_LIST); + ieee80211_hw_set(hw, MFP_CAPABLE); + hw->max_rates = 1; hw->max_report_rates = 7; hw->max_rate_tries = 1; From 242516caabdb03aee47bebf9ed94070444e44894 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Thu, 6 Sep 2018 11:18:42 +0200 Subject: [PATCH 174/276] mt76x0: trim rx skb to proper length We need to truncate skb to proper length. This fix below message: wlan0: associating with AP with corrupt beacon and probe response Fixes: 9d87d9fad47e ("mt76x0: unify tx/rx datapath with mt76x2u driver") Signed-off-by: Stanislaw Gruszka Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt76x0/mac.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c b/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c index 8fdc246964b9..f55734a922aa 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c @@ -236,6 +236,7 @@ u32 mt76x0_mac_process_rx(struct mt76x0_dev *dev, struct sk_buff *skb, mt76x02_remove_hdr_pad(skb, pad_len); + pskb_trim(skb, len); status->chains = BIT(0); rssi = mt76x0_phy_get_rssi(dev, rxwi); status->chain_signal[0] = status->signal = rssi; From 23ea0e7efbc978d7d2923667ff4402426869cec6 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Thu, 6 Sep 2018 11:18:43 +0200 Subject: [PATCH 175/276] mt76: remove unused MT76_MORE_STATS state Remove no longer used hw state Signed-off-by: Lorenzo Bianconi Signed-off-by: Stanislaw Gruszka Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt76.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h index 8e33d7c53557..2d74a2c3d93c 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76.h +++ b/drivers/net/wireless/mediatek/mt76/mt76.h @@ -217,7 +217,6 @@ enum { MT76_OFFCHANNEL, MT76_REMOVED, MT76_READING_STATS, - MT76_MORE_STATS, }; struct mt76_hw_cap { From 7c7b13941eda19be57c0d88660cd219cb917906c Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Thu, 6 Sep 2018 11:18:44 +0200 Subject: [PATCH 176/276] mt76x0: remove mt76x0_stop_hardware routine Since it is actually used in a single place and it just runs mt76x0_chip_onoff routine, remove mt76x0_stop_hardware and use mt76x0_chip_onoff directly Signed-off-by: Lorenzo Bianconi Signed-off-by: Stanislaw Gruszka Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt76x0/init.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c index 418e1918086d..5b819a224d33 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c @@ -364,11 +364,6 @@ void mt76x0_mac_stop(struct mt76x0_dev *dev) mt76x0_mac_stop_hw(dev); } -static void mt76x0_stop_hardware(struct mt76x0_dev *dev) -{ - mt76x0_chip_onoff(dev, false, false); -} - int mt76x0_init_hardware(struct mt76x0_dev *dev) { static const u16 beacon_offsets[16] = { @@ -476,7 +471,7 @@ void mt76x0_cleanup(struct mt76x0_dev *dev) if (!test_and_clear_bit(MT76_STATE_INITIALIZED, &dev->mt76.state)) return; - mt76x0_stop_hardware(dev); + mt76x0_chip_onoff(dev, false, false); mt76u_queues_deinit(&dev->mt76); mt76u_mcu_deinit(&dev->mt76); } From 58b5eb8c44ead87ebbd056fb60f0b257370d2a55 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Thu, 6 Sep 2018 11:18:45 +0200 Subject: [PATCH 177/276] mt76: move mt76 rate definitions in mt76x02-lib module Move mt76x2_rate definition in mt76x02-lib module and rename it in mt76x02_rates in order to be reused in mt76x0 driver. Moreover remove unused mt76_rate definition Signed-off-by: Lorenzo Bianconi Signed-off-by: Stanislaw Gruszka Signed-off-by: Felix Fietkau --- .../net/wireless/mediatek/mt76/mt76x0/init.c | 32 ++----------------- .../net/wireless/mediatek/mt76/mt76x02_util.c | 29 +++++++++++++++++ .../net/wireless/mediatek/mt76/mt76x02_util.h | 2 ++ drivers/net/wireless/mediatek/mt76/mt76x2.h | 2 -- .../net/wireless/mediatek/mt76/mt76x2_init.c | 5 +-- .../mediatek/mt76/mt76x2_init_common.c | 29 ----------------- .../net/wireless/mediatek/mt76/mt76x2u_init.c | 4 +-- 7 files changed, 38 insertions(+), 65 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c index 5b819a224d33..ca70b62442a1 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c @@ -559,34 +559,6 @@ static const struct ieee80211_channel mt76_channels_5ghz[] = { CHAN5G(140, 5700), }; -#define CCK_RATE(_idx, _rate) { \ - .bitrate = _rate, \ - .flags = IEEE80211_RATE_SHORT_PREAMBLE, \ - .hw_value = (MT_PHY_TYPE_CCK << 8) | _idx, \ - .hw_value_short = (MT_PHY_TYPE_CCK << 8) | (8 + _idx), \ -} - -#define OFDM_RATE(_idx, _rate) { \ - .bitrate = _rate, \ - .hw_value = (MT_PHY_TYPE_OFDM << 8) | _idx, \ - .hw_value_short = (MT_PHY_TYPE_OFDM << 8) | _idx, \ -} - -static struct ieee80211_rate mt76_rates[] = { - CCK_RATE(0, 10), - CCK_RATE(1, 20), - CCK_RATE(2, 55), - CCK_RATE(3, 110), - OFDM_RATE(0, 60), - OFDM_RATE(1, 90), - OFDM_RATE(2, 120), - OFDM_RATE(3, 180), - OFDM_RATE(4, 240), - OFDM_RATE(5, 360), - OFDM_RATE(6, 480), - OFDM_RATE(7, 540), -}; - static int mt76_init_sband(struct mt76x0_dev *dev, struct ieee80211_supported_band *sband, const struct ieee80211_channel *chan, int n_chan, @@ -634,7 +606,7 @@ mt76_init_sband_2g(struct mt76x0_dev *dev) return mt76_init_sband(dev, &dev->mt76.sband_2g.sband, mt76_channels_2ghz, ARRAY_SIZE(mt76_channels_2ghz), - mt76_rates, ARRAY_SIZE(mt76_rates)); + mt76x02_rates, ARRAY_SIZE(mt76x02_rates)); } static int @@ -644,7 +616,7 @@ mt76_init_sband_5g(struct mt76x0_dev *dev) return mt76_init_sband(dev, &dev->mt76.sband_5g.sband, mt76_channels_5ghz, ARRAY_SIZE(mt76_channels_5ghz), - mt76_rates + 4, ARRAY_SIZE(mt76_rates) - 4); + mt76x02_rates + 4, ARRAY_SIZE(mt76x02_rates) - 4); } diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c index e0d0d13152a7..d0480e42b4a7 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c @@ -20,6 +20,35 @@ #include "mt76x02_regs.h" #include "mt76x02_mac.h" +#define CCK_RATE(_idx, _rate) { \ + .bitrate = _rate, \ + .flags = IEEE80211_RATE_SHORT_PREAMBLE, \ + .hw_value = (MT_PHY_TYPE_CCK << 8) | _idx, \ + .hw_value_short = (MT_PHY_TYPE_CCK << 8) | (8 + _idx), \ +} + +#define OFDM_RATE(_idx, _rate) { \ + .bitrate = _rate, \ + .hw_value = (MT_PHY_TYPE_OFDM << 8) | _idx, \ + .hw_value_short = (MT_PHY_TYPE_OFDM << 8) | _idx, \ +} + +struct ieee80211_rate mt76x02_rates[] = { + CCK_RATE(0, 10), + CCK_RATE(1, 20), + CCK_RATE(2, 55), + CCK_RATE(3, 110), + OFDM_RATE(0, 60), + OFDM_RATE(1, 90), + OFDM_RATE(2, 120), + OFDM_RATE(3, 180), + OFDM_RATE(4, 240), + OFDM_RATE(5, 360), + OFDM_RATE(6, 480), + OFDM_RATE(7, 540), +}; +EXPORT_SYMBOL_GPL(mt76x02_rates); + void mt76x02_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags, unsigned int *total_flags, u64 multicast) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.h b/drivers/net/wireless/mediatek/mt76/mt76x02_util.h index 383031b9b6d8..b6ba7e6c2748 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.h @@ -18,6 +18,8 @@ #ifndef __MT76X02_UTIL_H #define __MT76X02_UTIL_H +extern struct ieee80211_rate mt76x02_rates[12]; + void mt76x02_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags, unsigned int *total_flags, u64 multicast); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2.h b/drivers/net/wireless/mediatek/mt76/mt76x2.h index efed3c0a82ce..87b805637ff8 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x2.h @@ -175,8 +175,6 @@ static inline bool wait_for_wpdma(struct mt76x2_dev *dev) extern const struct ieee80211_ops mt76x2_ops; -extern struct ieee80211_rate mt76x2_rates[12]; - struct mt76x2_dev *mt76x2_alloc_device(struct device *pdev); int mt76x2_register_device(struct mt76x2_dev *dev); void mt76x2_init_debugfs(struct mt76x2_dev *dev); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_init.c b/drivers/net/wireless/mediatek/mt76/mt76x2_init.c index c6d5e7db6edb..56a4b86bb665 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_init.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_init.c @@ -18,6 +18,7 @@ #include "mt76x2.h" #include "mt76x2_eeprom.h" #include "mt76x2_mcu.h" +#include "mt76x02_util.h" static void mt76x2_mac_pbf_init(struct mt76x2_dev *dev) @@ -584,8 +585,8 @@ int mt76x2_register_device(struct mt76x2_dev *dev) dev->mt76.led_cdev.brightness_set = mt76x2_led_set_brightness; dev->mt76.led_cdev.blink_set = mt76x2_led_set_blink; - ret = mt76_register_device(&dev->mt76, true, mt76x2_rates, - ARRAY_SIZE(mt76x2_rates)); + ret = mt76_register_device(&dev->mt76, true, mt76x02_rates, + ARRAY_SIZE(mt76x02_rates)); if (ret) goto fail; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_init_common.c b/drivers/net/wireless/mediatek/mt76/mt76x2_init_common.c index 424d77a82f06..31de3365cdb8 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_init_common.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_init_common.c @@ -18,35 +18,6 @@ #include "mt76x2.h" #include "mt76x2_eeprom.h" -#define CCK_RATE(_idx, _rate) { \ - .bitrate = _rate, \ - .flags = IEEE80211_RATE_SHORT_PREAMBLE, \ - .hw_value = (MT_PHY_TYPE_CCK << 8) | _idx, \ - .hw_value_short = (MT_PHY_TYPE_CCK << 8) | (8 + _idx), \ -} - -#define OFDM_RATE(_idx, _rate) { \ - .bitrate = _rate, \ - .hw_value = (MT_PHY_TYPE_OFDM << 8) | _idx, \ - .hw_value_short = (MT_PHY_TYPE_OFDM << 8) | _idx, \ -} - -struct ieee80211_rate mt76x2_rates[] = { - CCK_RATE(0, 10), - CCK_RATE(1, 20), - CCK_RATE(2, 55), - CCK_RATE(3, 110), - OFDM_RATE(0, 60), - OFDM_RATE(1, 90), - OFDM_RATE(2, 120), - OFDM_RATE(3, 180), - OFDM_RATE(4, 240), - OFDM_RATE(5, 360), - OFDM_RATE(6, 480), - OFDM_RATE(7, 540), -}; -EXPORT_SYMBOL_GPL(mt76x2_rates); - static void mt76x2_set_wlan_state(struct mt76x2_dev *dev, bool enable) { diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2u_init.c b/drivers/net/wireless/mediatek/mt76/mt76x2u_init.c index 29f3ecaad979..2f828658f566 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2u_init.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2u_init.c @@ -277,8 +277,8 @@ int mt76x2u_register_device(struct mt76x2_dev *dev) wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); - err = mt76_register_device(&dev->mt76, true, mt76x2_rates, - ARRAY_SIZE(mt76x2_rates)); + err = mt76_register_device(&dev->mt76, true, mt76x02_rates, + ARRAY_SIZE(mt76x02_rates)); if (err) goto fail; From d1b6eec235972e11da3564c4b55cb2b2b30d19bb Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Thu, 6 Sep 2018 11:18:46 +0200 Subject: [PATCH 178/276] mt76x0: alloc mcu buffers first in mt76x0_mcu_cmd_init swap mt76u_mcu_init_rx and mt76x0_mcu_function_select in mt76x0_mcu_cmd_init routine in order to allocate mcu buffers first and then send mcu commands Signed-off-by: Lorenzo Bianconi Signed-off-by: Stanislaw Gruszka Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c index 0a0deaf1c65d..7be2835f3b4f 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c @@ -387,9 +387,11 @@ int mt76x0_mcu_init(struct mt76x0_dev *dev) int mt76x0_mcu_cmd_init(struct mt76x0_dev *dev) { - int ret = mt76x0_mcu_function_select(dev, Q_SELECT, 1); + int ret; + + ret = mt76u_mcu_init_rx(&dev->mt76); if (ret) return ret; - return mt76u_mcu_init_rx(&dev->mt76); + return mt76x0_mcu_function_select(dev, Q_SELECT, 1); } From cb722aeddcfdab852a06a0477ac197174ea44051 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Thu, 6 Sep 2018 11:18:47 +0200 Subject: [PATCH 179/276] mt76x0: fix memory leak during hw probe Fix memory leak during hw probe if mt76x0_register_device fails since MT76_STATE_INITIALIZED has not set yet and mt76x0_cleanup does not free tx/rx queues and mcu buffers Signed-off-by: Lorenzo Bianconi Signed-off-by: Stanislaw Gruszka Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt76x0/init.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c index ca70b62442a1..d186f509b5a8 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c @@ -468,9 +468,7 @@ int mt76x0_init_hardware(struct mt76x0_dev *dev) void mt76x0_cleanup(struct mt76x0_dev *dev) { - if (!test_and_clear_bit(MT76_STATE_INITIALIZED, &dev->mt76.state)) - return; - + clear_bit(MT76_STATE_INITIALIZED, &dev->mt76.state); mt76x0_chip_onoff(dev, false, false); mt76u_queues_deinit(&dev->mt76); mt76u_mcu_deinit(&dev->mt76); From b680d7fbfbff01ead47a54d7bb50567a7ceeedde Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Thu, 6 Sep 2018 11:18:48 +0200 Subject: [PATCH 180/276] mt76x0: move stop related routines in mt76x0_mac_stop Move tear-down routines in mt76x0_mac_stop function. mt76x0_mac_stop routines will be reused in mt76x0_suspend Signed-off-by: Lorenzo Bianconi Signed-off-by: Stanislaw Gruszka Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt76x0/init.c | 3 +++ drivers/net/wireless/mediatek/mt76/mt76x0/main.c | 4 ---- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c index d186f509b5a8..b1d5f647eac5 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c @@ -361,6 +361,9 @@ static void mt76x0_mac_stop_hw(struct mt76x0_dev *dev) void mt76x0_mac_stop(struct mt76x0_dev *dev) { + cancel_delayed_work_sync(&dev->cal_work); + cancel_delayed_work_sync(&dev->mac_work); + mt76u_stop_stat_wk(&dev->mt76); mt76x0_mac_stop_hw(dev); } diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c index 8c8a0f676228..0d3c7accb4f8 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c @@ -48,10 +48,6 @@ static void mt76x0_stop(struct ieee80211_hw *hw) mutex_lock(&dev->mt76.mutex); clear_bit(MT76_STATE_RUNNING, &dev->mt76.state); - - cancel_delayed_work_sync(&dev->cal_work); - cancel_delayed_work_sync(&dev->mac_work); - mt76u_stop_stat_wk(&dev->mt76); mt76x0_mac_stop(dev); mutex_unlock(&dev->mt76.mutex); From e30a655ef13806765c335c33452bc5f0e7256f36 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Thu, 6 Sep 2018 11:18:49 +0200 Subject: [PATCH 181/276] mt76x0: move mt76x0_init_hardware in mt76x0_register_device Move mt76x0_init_hardware routine in mt76x0_register_device during hw probe. This is a preliminary patch to avoid {tx/rx} buffer allocation during resume/suspend Signed-off-by: Lorenzo Bianconi Signed-off-by: Stanislaw Gruszka Signed-off-by: Felix Fietkau --- .../net/wireless/mediatek/mt76/mt76x0/init.c | 55 ++++++++----------- .../net/wireless/mediatek/mt76/mt76x0/usb.c | 8 +-- 2 files changed, 26 insertions(+), 37 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c index b1d5f647eac5..deceece52492 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c @@ -382,27 +382,21 @@ int mt76x0_init_hardware(struct mt76x0_dev *dev) mt76x0_chip_onoff(dev, true, true); - if (!mt76x02_wait_for_mac(&dev->mt76)) { - ret = -ETIMEDOUT; - goto err; - } + if (!mt76x02_wait_for_mac(&dev->mt76)) + return -ETIMEDOUT; ret = mt76x0_mcu_init(dev); if (ret) - goto err; + return ret; if (!mt76_poll_msec(dev, MT_WPDMA_GLO_CFG, MT_WPDMA_GLO_CFG_TX_DMA_BUSY | - MT_WPDMA_GLO_CFG_RX_DMA_BUSY, 0, 100)) { - ret = -EIO; - goto err; - } + MT_WPDMA_GLO_CFG_RX_DMA_BUSY, 0, 100)) + return -EIO; /* Wait for ASIC ready after FW load. */ - if (!mt76x02_wait_for_mac(&dev->mt76)) { - ret = -ETIMEDOUT; - goto err; - } + if (!mt76x02_wait_for_mac(&dev->mt76)) + return -ETIMEDOUT; mt76x0_reset_csr_bbp(dev); mt76x0_init_usb_dma(dev); @@ -412,33 +406,33 @@ int mt76x0_init_hardware(struct mt76x0_dev *dev) ret = mt76x0_mcu_cmd_init(dev); if (ret) - goto err; + return ret; ret = mt76u_alloc_queues(&dev->mt76); if (ret < 0) - goto err_mcu; + return ret; mt76x0_init_mac_registers(dev); if (!mt76_poll_msec(dev, MT_MAC_STATUS, - MT_MAC_STATUS_TX | MT_MAC_STATUS_RX, 0, 1000)) { - ret = -EIO; - goto err_rx; - } + MT_MAC_STATUS_TX | MT_MAC_STATUS_RX, 0, 1000)) + return -EIO; ret = mt76x0_init_bbp(dev); if (ret) - goto err_rx; + return ret; ret = mt76x0_init_wcid_mem(dev); if (ret) - goto err_rx; + return ret; + ret = mt76x0_init_key_mem(dev); if (ret) - goto err_rx; + return ret; + ret = mt76x0_init_wcid_attr_mem(dev); if (ret) - goto err_rx; + return ret; mt76_clear(dev, MT_BEACON_TIME_CFG, (MT_BEACON_TIME_CFG_TIMER_EN | MT_BEACON_TIME_CFG_SYNC_MODE | @@ -455,18 +449,11 @@ int mt76x0_init_hardware(struct mt76x0_dev *dev) ret = mt76x0_eeprom_init(dev); if (ret) - goto err_rx; + return ret; mt76x0_phy_init(dev); - return 0; -err_rx: - mt76u_queues_deinit(&dev->mt76); -err_mcu: - mt76u_mcu_deinit(&dev->mt76); -err: - mt76x0_chip_onoff(dev, false, false); - return ret; + return 0; } void mt76x0_cleanup(struct mt76x0_dev *dev) @@ -627,6 +614,10 @@ int mt76x0_register_device(struct mt76x0_dev *dev) struct wiphy *wiphy = hw->wiphy; int ret; + ret = mt76x0_init_hardware(dev); + if (ret) + return ret; + /* Reserve WCID 0 for mcast - thanks to this APs WCID will go to * entry no. 1 like it does in the vendor driver. */ diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c index 219524c233ee..09b544890450 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c @@ -90,10 +90,6 @@ static int mt76x0_probe(struct usb_interface *usb_intf, if (!(mt76_rr(dev, MT_EFUSE_CTRL) & MT_EFUSE_CTRL_SEL)) dev_warn(dev->mt76.dev, "Warning: eFUSE not present\n"); - ret = mt76x0_init_hardware(dev); - if (ret) - goto err; - ret = mt76x0_register_device(dev); if (ret) goto err_hw; @@ -143,8 +139,10 @@ static int mt76x0_resume(struct usb_interface *usb_intf) int ret; ret = mt76x0_init_hardware(dev); - if (ret) + if (ret) { + mt76x0_cleanup(dev); return ret; + } set_bit(MT76_STATE_INITIALIZED, &dev->mt76.state); From 6f15ed16f17890c53ff0ad763c7e9c2c04a153b2 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Thu, 6 Sep 2018 11:18:50 +0200 Subject: [PATCH 182/276] mt76x0: do not free/alloc buffers during suspend/resume Do not free/alloc {tx,rx} buffers during suspend/resume phases but use the ones previously allocated during hw probe. Move {tx,rx}/mcu buffers allocation from mt76x0_init_hardware routine to mt76x0_register_device Signed-off-by: Lorenzo Bianconi Signed-off-by: Stanislaw Gruszka Signed-off-by: Felix Fietkau --- .../net/wireless/mediatek/mt76/mt76x0/init.c | 12 ++++-- .../net/wireless/mediatek/mt76/mt76x0/mcu.c | 6 --- .../net/wireless/mediatek/mt76/mt76x0/usb.c | 38 ++++++++++++++----- 3 files changed, 37 insertions(+), 19 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c index deceece52492..8f4b3197ab95 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c @@ -408,10 +408,6 @@ int mt76x0_init_hardware(struct mt76x0_dev *dev) if (ret) return ret; - ret = mt76u_alloc_queues(&dev->mt76); - if (ret < 0) - return ret; - mt76x0_init_mac_registers(dev); if (!mt76_poll_msec(dev, MT_MAC_STATUS, @@ -614,6 +610,14 @@ int mt76x0_register_device(struct mt76x0_dev *dev) struct wiphy *wiphy = hw->wiphy; int ret; + ret = mt76u_mcu_init_rx(mdev); + if (ret < 0) + return ret; + + ret = mt76u_alloc_queues(mdev); + if (ret < 0) + return ret; + ret = mt76x0_init_hardware(dev); if (ret) return ret; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c index 7be2835f3b4f..29c0b3978af7 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c @@ -387,11 +387,5 @@ int mt76x0_mcu_init(struct mt76x0_dev *dev) int mt76x0_mcu_cmd_init(struct mt76x0_dev *dev) { - int ret; - - ret = mt76u_mcu_init_rx(&dev->mt76); - if (ret) - return ret; - return mt76x0_mcu_function_select(dev, Q_SELECT, 1); } diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c index 09b544890450..fc8884c38f7e 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c @@ -124,29 +124,49 @@ static void mt76x0_disconnect(struct usb_interface *usb_intf) ieee80211_free_hw(dev->mt76.hw); } -static int mt76x0_suspend(struct usb_interface *usb_intf, pm_message_t state) +static int __maybe_unused mt76x0_suspend(struct usb_interface *usb_intf, + pm_message_t state) { struct mt76x0_dev *dev = usb_get_intfdata(usb_intf); + struct mt76_usb *usb = &dev->mt76.usb; - mt76x0_cleanup(dev); + mt76u_stop_queues(&dev->mt76); + mt76x0_mac_stop(dev); + usb_kill_urb(usb->mcu.res.urb); return 0; } -static int mt76x0_resume(struct usb_interface *usb_intf) +static int __maybe_unused mt76x0_resume(struct usb_interface *usb_intf) { struct mt76x0_dev *dev = usb_get_intfdata(usb_intf); + struct mt76_usb *usb = &dev->mt76.usb; int ret; - ret = mt76x0_init_hardware(dev); - if (ret) { - mt76x0_cleanup(dev); - return ret; - } + reinit_completion(&usb->mcu.cmpl); + ret = mt76u_submit_buf(&dev->mt76, USB_DIR_IN, + MT_EP_IN_CMD_RESP, + &usb->mcu.res, GFP_KERNEL, + mt76u_mcu_complete_urb, + &usb->mcu.cmpl); + if (ret < 0) + goto err; - set_bit(MT76_STATE_INITIALIZED, &dev->mt76.state); + ret = mt76u_submit_rx_buffers(&dev->mt76); + if (ret < 0) + goto err; + + tasklet_enable(&usb->rx_tasklet); + tasklet_enable(&usb->tx_tasklet); + + ret = mt76x0_init_hardware(dev); + if (ret) + goto err; return 0; +err: + mt76x0_cleanup(dev); + return ret; } MODULE_DEVICE_TABLE(usb, mt76x0_device_table); From 540399d5fb79154f51f9ce33f7512485e7c26e0c Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Thu, 6 Sep 2018 11:18:51 +0200 Subject: [PATCH 183/276] mt76x0: remove has_{2,5}ghz fields of mt76x0_eeprom_params Remove has_2ghz/has_5ghz fields of mt76x0_eeprom_params data structure and use mt76_dev ones. This is a preliminary patch to use shared routines for device allocation Signed-off-by: Lorenzo Bianconi Signed-off-by: Stanislaw Gruszka Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.c | 11 ++++++----- drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.h | 3 --- drivers/net/wireless/mediatek/mt76/mt76x0/init.c | 4 ++-- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.c b/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.c index 36da1e6bc21a..0fd178d84277 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.c @@ -123,18 +123,19 @@ mt76x0_set_chip_cap(struct mt76x0_dev *dev, u8 *eeprom) switch (FIELD_GET(MT_EE_NIC_CONF_0_BOARD_TYPE, nic_conf0)) { case BOARD_TYPE_5GHZ: - dev->ee->has_5ghz = true; + dev->mt76.cap.has_5ghz = true; break; case BOARD_TYPE_2GHZ: - dev->ee->has_2ghz = true; + dev->mt76.cap.has_2ghz = true; break; default: - dev->ee->has_2ghz = true; - dev->ee->has_5ghz = true; + dev->mt76.cap.has_2ghz = true; + dev->mt76.cap.has_5ghz = true; break; } - dev_dbg(dev->mt76.dev, "Has 2GHZ %d 5GHZ %d\n", dev->ee->has_2ghz, dev->ee->has_5ghz); + dev_dbg(dev->mt76.dev, "Has 2GHZ %d 5GHZ %d\n", + dev->mt76.cap.has_2ghz, dev->mt76.cap.has_5ghz); if (!field_valid(nic_conf1 & 0xff)) nic_conf1 &= 0xff00; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.h b/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.h index e37b573aed7b..cd0f14361405 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.h @@ -112,9 +112,6 @@ struct mt76x0_eeprom_params { u8 tx_pwr_per_chan[58]; struct reg_channel_bounds reg; - - bool has_2ghz; - bool has_5ghz; }; int mt76x0_eeprom_init(struct mt76x0_dev *dev); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c index 8f4b3197ab95..d075b29977e3 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c @@ -662,13 +662,13 @@ int mt76x0_register_device(struct mt76x0_dev *dev) wiphy->features |= NL80211_FEATURE_ACTIVE_MONITOR; wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); - if (dev->ee->has_2ghz) { + if (dev->mt76.cap.has_2ghz) { ret = mt76_init_sband_2g(dev); if (ret) return ret; } - if (dev->ee->has_5ghz) { + if (dev->mt76.cap.has_5ghz) { ret = mt76_init_sband_5g(dev); if (ret) return ret; From 1bee323a85208366406b8fc4490930d1dc046b13 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Thu, 6 Sep 2018 11:18:52 +0200 Subject: [PATCH 184/276] mt76x0: use mt76_register_device for device registration Use mt76_register_device routine for device registration. mt76_register_device allows to enable VHT support on 5GHz band. Overwrite unsupported vht features with mt76x0_vht_cap_mask routine. Remove macaddr field of mt76x0_dev data structure and use the mt76_dev one. Moreover remove following unused routines: - mt76_init_sband - mt76_init_sband_2g - mt76_init_sband_5g Signed-off-by: Lorenzo Bianconi Signed-off-by: Stanislaw Gruszka Signed-off-by: Felix Fietkau --- .../wireless/mediatek/mt76/mt76x0/eeprom.c | 13 +- .../net/wireless/mediatek/mt76/mt76x0/init.c | 187 +++--------------- .../wireless/mediatek/mt76/mt76x0/mt76x0.h | 1 - 3 files changed, 39 insertions(+), 162 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.c b/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.c index 0fd178d84277..2ce27de511f5 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.c @@ -160,18 +160,19 @@ static int mt76x0_set_macaddr(struct mt76x0_dev *dev, const u8 *eeprom) { const void *src = eeprom + MT_EE_MAC_ADDR; + u8 *dst = dev->mt76.macaddr; - ether_addr_copy(dev->macaddr, src); + ether_addr_copy(dev->mt76.macaddr, src); - if (!is_valid_ether_addr(dev->macaddr)) { - eth_random_addr(dev->macaddr); + if (!is_valid_ether_addr(dst)) { + eth_random_addr(dst); dev_info(dev->mt76.dev, "Invalid MAC address, using random address %pM\n", - dev->macaddr); + dst); } - mt76_wr(dev, MT_MAC_ADDR_DW0, get_unaligned_le32(dev->macaddr)); - mt76_wr(dev, MT_MAC_ADDR_DW1, get_unaligned_le16(dev->macaddr + 4) | + mt76_wr(dev, MT_MAC_ADDR_DW0, get_unaligned_le32(dst)); + mt76_wr(dev, MT_MAC_ADDR_DW1, get_unaligned_le16(dst + 4) | FIELD_PREP(MT_MAC_ADDR_DW1_U2ME_MASK, 0xff)); return 0; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c index d075b29977e3..44fcad2315a7 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c @@ -23,6 +23,24 @@ #include "initvals.h" +static void mt76x0_vht_cap_mask(struct ieee80211_supported_band *sband) +{ + struct ieee80211_sta_vht_cap *vht_cap = &sband->vht_cap; + u16 mcs_map = 0; + int i; + + vht_cap->cap &= ~IEEE80211_VHT_CAP_RXLDPC; + for (i = 0; i < 8; i++) { + if (!i) + mcs_map |= (IEEE80211_VHT_MCS_SUPPORT_0_7 << (i * 2)); + else + mcs_map |= + (IEEE80211_VHT_MCS_NOT_SUPPORTED << (i * 2)); + } + vht_cap->vht_mcs.rx_mcs_map = cpu_to_le16(mcs_map); + vht_cap->vht_mcs.tx_mcs_map = cpu_to_le16(mcs_map); +} + static void mt76x0_set_wlan_state(struct mt76x0_dev *dev, u32 val, bool enable) { @@ -488,125 +506,10 @@ struct mt76x0_dev *mt76x0_alloc_device(struct device *pdev) return dev; } -#define CHAN2G(_idx, _freq) { \ - .band = NL80211_BAND_2GHZ, \ - .center_freq = (_freq), \ - .hw_value = (_idx), \ - .max_power = 30, \ -} - -static const struct ieee80211_channel mt76_channels_2ghz[] = { - CHAN2G(1, 2412), - CHAN2G(2, 2417), - CHAN2G(3, 2422), - CHAN2G(4, 2427), - CHAN2G(5, 2432), - CHAN2G(6, 2437), - CHAN2G(7, 2442), - CHAN2G(8, 2447), - CHAN2G(9, 2452), - CHAN2G(10, 2457), - CHAN2G(11, 2462), - CHAN2G(12, 2467), - CHAN2G(13, 2472), - CHAN2G(14, 2484), -}; - -#define CHAN5G(_idx, _freq) { \ - .band = NL80211_BAND_5GHZ, \ - .center_freq = (_freq), \ - .hw_value = (_idx), \ - .max_power = 30, \ -} - -static const struct ieee80211_channel mt76_channels_5ghz[] = { - CHAN5G(36, 5180), - CHAN5G(40, 5200), - CHAN5G(44, 5220), - CHAN5G(46, 5230), - CHAN5G(48, 5240), - CHAN5G(52, 5260), - CHAN5G(56, 5280), - CHAN5G(60, 5300), - CHAN5G(64, 5320), - - CHAN5G(100, 5500), - CHAN5G(104, 5520), - CHAN5G(108, 5540), - CHAN5G(112, 5560), - CHAN5G(116, 5580), - CHAN5G(120, 5600), - CHAN5G(124, 5620), - CHAN5G(128, 5640), - CHAN5G(132, 5660), - CHAN5G(136, 5680), - CHAN5G(140, 5700), -}; - -static int -mt76_init_sband(struct mt76x0_dev *dev, struct ieee80211_supported_band *sband, - const struct ieee80211_channel *chan, int n_chan, - struct ieee80211_rate *rates, int n_rates) -{ - struct ieee80211_sta_ht_cap *ht_cap; - void *chanlist; - int size; - - size = n_chan * sizeof(*chan); - chanlist = devm_kmemdup(dev->mt76.dev, chan, size, GFP_KERNEL); - if (!chanlist) - return -ENOMEM; - - sband->channels = chanlist; - sband->n_channels = n_chan; - sband->bitrates = rates; - sband->n_bitrates = n_rates; - - ht_cap = &sband->ht_cap; - ht_cap->ht_supported = true; - ht_cap->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 | - IEEE80211_HT_CAP_GRN_FLD | - IEEE80211_HT_CAP_SGI_20 | - IEEE80211_HT_CAP_SGI_40 | - (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT); - - ht_cap->mcs.rx_mask[0] = 0xff; - ht_cap->mcs.rx_mask[4] = 0x1; - ht_cap->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; - ht_cap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; - ht_cap->ampdu_density = IEEE80211_HT_MPDU_DENSITY_2; - - return 0; -} - -static int -mt76_init_sband_2g(struct mt76x0_dev *dev) -{ - dev->mt76.hw->wiphy->bands[NL80211_BAND_2GHZ] = &dev->mt76.sband_2g.sband; - - WARN_ON(dev->ee->reg.start - 1 + dev->ee->reg.num > - ARRAY_SIZE(mt76_channels_2ghz)); - - - return mt76_init_sband(dev, &dev->mt76.sband_2g.sband, - mt76_channels_2ghz, ARRAY_SIZE(mt76_channels_2ghz), - mt76x02_rates, ARRAY_SIZE(mt76x02_rates)); -} - -static int -mt76_init_sband_5g(struct mt76x0_dev *dev) -{ - dev->mt76.hw->wiphy->bands[NL80211_BAND_5GHZ] = &dev->mt76.sband_5g.sband; - - return mt76_init_sband(dev, &dev->mt76.sband_5g.sband, - mt76_channels_5ghz, ARRAY_SIZE(mt76_channels_5ghz), - mt76x02_rates + 4, ARRAY_SIZE(mt76x02_rates) - 4); -} - - int mt76x0_register_device(struct mt76x0_dev *dev) { - struct ieee80211_hw *hw = dev->mt76.hw; + struct mt76_dev *mdev = &dev->mt76; + struct ieee80211_hw *hw = mdev->hw; struct wiphy *wiphy = hw->wiphy; int ret; @@ -625,27 +528,16 @@ int mt76x0_register_device(struct mt76x0_dev *dev) /* Reserve WCID 0 for mcast - thanks to this APs WCID will go to * entry no. 1 like it does in the vendor driver. */ - dev->mt76.wcid_mask[0] |= 1; + mdev->wcid_mask[0] |= 1; /* init fake wcid for monitor interfaces */ - dev->mt76.global_wcid.idx = 0xff; - dev->mt76.global_wcid.hw_key_idx = -1; + mdev->global_wcid.idx = 0xff; + mdev->global_wcid.hw_key_idx = -1; - SET_IEEE80211_DEV(hw, dev->mt76.dev); + /* init antenna configuration */ + mdev->antenna_mask = 1; hw->queues = 4; - ieee80211_hw_set(hw, SIGNAL_DBM); - ieee80211_hw_set(hw, PS_NULLFUNC_STACK); - ieee80211_hw_set(hw, SUPPORTS_HT_CCK_RATES); - ieee80211_hw_set(hw, AMPDU_AGGREGATION); - ieee80211_hw_set(hw, SUPPORTS_RC_TABLE); - ieee80211_hw_set(hw, SUPPORT_FAST_XMIT); - ieee80211_hw_set(hw, SUPPORTS_CLONED_SKBS); - ieee80211_hw_set(hw, SUPPORTS_AMSDU_IN_AMPDU); - ieee80211_hw_set(hw, TX_AMSDU); - ieee80211_hw_set(hw, TX_FRAG_LIST); - ieee80211_hw_set(hw, MFP_CAPABLE); - hw->max_rates = 1; hw->max_report_rates = 7; hw->max_rate_tries = 1; @@ -654,36 +546,21 @@ int mt76x0_register_device(struct mt76x0_dev *dev) hw->sta_data_size = sizeof(struct mt76x02_sta); hw->vif_data_size = sizeof(struct mt76x02_vif); - hw->txq_data_size = sizeof(struct mt76_txq); - hw->max_tx_fragments = 16; - - SET_IEEE80211_PERM_ADDR(hw, dev->macaddr); - - wiphy->features |= NL80211_FEATURE_ACTIVE_MONITOR; wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); - if (dev->mt76.cap.has_2ghz) { - ret = mt76_init_sband_2g(dev); - if (ret) - return ret; - } - - if (dev->mt76.cap.has_5ghz) { - ret = mt76_init_sband_5g(dev); - if (ret) - return ret; - } - - dev->mt76.chandef.chan = &dev->mt76.sband_2g.sband.channels[0]; - INIT_DELAYED_WORK(&dev->mac_work, mt76x0_mac_work); - ret = ieee80211_register_hw(hw); + ret = mt76_register_device(mdev, true, mt76x02_rates, + ARRAY_SIZE(mt76x02_rates)); if (ret) return ret; + /* overwrite unsupported features */ + if (mdev->cap.has_5ghz) + mt76x0_vht_cap_mask(&dev->mt76.sband_5g.sband); + /* check hw sg support in order to enable AMSDU */ - if (mt76u_check_sg(&dev->mt76)) + if (mt76u_check_sg(mdev)) hw->max_tx_fragments = MT_SG_MAX_SIZE; else hw->max_tx_fragments = 1; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h index cd260317de27..2918abc95c71 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h @@ -88,7 +88,6 @@ struct mt76x0_dev { const u16 *beacon_offsets; - u8 macaddr[ETH_ALEN]; struct mt76x0_eeprom_params *ee; struct mutex reg_atomic_mutex; From c2a4d9fbabfb9de8259c9467efc74ac85fcce838 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Thu, 6 Sep 2018 11:18:53 +0200 Subject: [PATCH 185/276] mt76x0: inital split between pci and usb For now pci driver can read ASIC version from the device :-) Signed-off-by: Stanislaw Gruszka Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/Kconfig | 23 ++++-- drivers/net/wireless/mediatek/mt76/Makefile | 2 +- .../wireless/mediatek/mt76/mt76x0/Makefile | 11 ++- .../wireless/mediatek/mt76/mt76x0/eeprom.c | 2 + .../net/wireless/mediatek/mt76/mt76x0/init.c | 6 ++ .../net/wireless/mediatek/mt76/mt76x0/main.c | 7 ++ .../wireless/mediatek/mt76/mt76x0/mt76x0.h | 1 - .../net/wireless/mediatek/mt76/mt76x0/pci.c | 81 +++++++++++++++++++ .../net/wireless/mediatek/mt76/mt76x0/usb.c | 6 -- 9 files changed, 121 insertions(+), 18 deletions(-) create mode 100644 drivers/net/wireless/mediatek/mt76/mt76x0/pci.c diff --git a/drivers/net/wireless/mediatek/mt76/Kconfig b/drivers/net/wireless/mediatek/mt76/Kconfig index 6a270e759006..e460a3a5e763 100644 --- a/drivers/net/wireless/mediatek/mt76/Kconfig +++ b/drivers/net/wireless/mediatek/mt76/Kconfig @@ -7,25 +7,35 @@ config MT76_USB config MT76x02_LIB tristate - depends on MT76_CORE + select MT76_CORE + +config MT76x0_COMMON + tristate + select MT76x02_LIB config MT76x2_COMMON tristate select MT76x02_LIB - depends on MT76_CORE config MT76x0U tristate "MediaTek MT76x0U (USB) support" - select MT76_CORE + select MT76x0_COMMON + select MT76_USB depends on MAC80211 depends on USB - select MT76x02_LIB help This adds support for MT7610U-based wireless USB dongles. +config MT76x0E + tristate "MediaTek MT76x0E (PCIe) support" + select MT76x0_COMMON + depends on MAC80211 + depends on PCI + help + This adds support for MT7610/MT7630-based wireless PCIe devices. + config MT76x2E tristate "MediaTek MT76x2E (PCIe) support" - select MT76_CORE select MT76x2_COMMON depends on MAC80211 depends on PCI @@ -34,9 +44,8 @@ config MT76x2E config MT76x2U tristate "MediaTek MT76x2U (USB) support" - select MT76_CORE - select MT76_USB select MT76x2_COMMON + select MT76_USB depends on MAC80211 depends on USB help diff --git a/drivers/net/wireless/mediatek/mt76/Makefile b/drivers/net/wireless/mediatek/mt76/Makefile index a7fe5d6da857..129ac71446d6 100644 --- a/drivers/net/wireless/mediatek/mt76/Makefile +++ b/drivers/net/wireless/mediatek/mt76/Makefile @@ -1,6 +1,6 @@ obj-$(CONFIG_MT76_CORE) += mt76.o obj-$(CONFIG_MT76_USB) += mt76-usb.o -obj-$(CONFIG_MT76x0U) += mt76x0/ +obj-$(CONFIG_MT76x0_COMMON) += mt76x0/ obj-$(CONFIG_MT76x02_LIB) += mt76x02-lib.o obj-$(CONFIG_MT76x2_COMMON) += mt76x2-common.o obj-$(CONFIG_MT76x2E) += mt76x2e.o diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/Makefile b/drivers/net/wireless/mediatek/mt76/mt76x0/Makefile index df70690e3aff..644c867c107a 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/Makefile +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/Makefile @@ -1,7 +1,12 @@ -obj-$(CONFIG_MT76x0U) += mt76x0.o +obj-$(CONFIG_MT76x0U) += mt76x0u.o +obj-$(CONFIG_MT76x0E) += mt76x0e.o +obj-$(CONFIG_MT76x0_COMMON) += mt76x0-common.o -mt76x0-objs = \ - usb.o init.o main.o mcu.o trace.o eeprom.o phy.o \ +mt76x0-common-y := \ + init.o main.o mcu.o trace.o eeprom.o phy.o \ mac.o debugfs.o tx.o +mt76x0u-y := usb.o +mt76x0e-y := pci.o + # ccflags-y := -DDEBUG CFLAGS_trace.o := -I$(src) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.c b/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.c index 2ce27de511f5..79856bde1632 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.c @@ -445,3 +445,5 @@ mt76x0_eeprom_init(struct mt76x0_dev *dev) kfree(eeprom); return ret; } + +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c index 44fcad2315a7..0e4a13fa42cb 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c @@ -111,6 +111,7 @@ void mt76x0_chip_onoff(struct mt76x0_dev *dev, bool enable, bool reset) mutex_unlock(&dev->hw_atomic_mutex); } +EXPORT_SYMBOL_GPL(mt76x0_chip_onoff); static void mt76x0_reset_csr_bbp(struct mt76x0_dev *dev) { @@ -384,6 +385,7 @@ void mt76x0_mac_stop(struct mt76x0_dev *dev) mt76u_stop_stat_wk(&dev->mt76); mt76x0_mac_stop_hw(dev); } +EXPORT_SYMBOL_GPL(mt76x0_mac_stop); int mt76x0_init_hardware(struct mt76x0_dev *dev) { @@ -469,6 +471,7 @@ int mt76x0_init_hardware(struct mt76x0_dev *dev) return 0; } +EXPORT_SYMBOL_GPL(mt76x0_init_hardware); void mt76x0_cleanup(struct mt76x0_dev *dev) { @@ -477,6 +480,7 @@ void mt76x0_cleanup(struct mt76x0_dev *dev) mt76u_queues_deinit(&dev->mt76); mt76u_mcu_deinit(&dev->mt76); } +EXPORT_SYMBOL_GPL(mt76x0_cleanup); struct mt76x0_dev *mt76x0_alloc_device(struct device *pdev) { @@ -505,6 +509,7 @@ struct mt76x0_dev *mt76x0_alloc_device(struct device *pdev) return dev; } +EXPORT_SYMBOL_GPL(mt76x0_alloc_device); int mt76x0_register_device(struct mt76x0_dev *dev) { @@ -569,3 +574,4 @@ int mt76x0_register_device(struct mt76x0_dev *dev) return 0; } +EXPORT_SYMBOL_GPL(mt76x0_register_device); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c index 0d3c7accb4f8..c84e00abfac9 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c @@ -71,6 +71,13 @@ static int mt76x0_config(struct ieee80211_hw *hw, u32 changed) return ret; } +static void +mt76x0_addr_wr(struct mt76x0_dev *dev, const u32 offset, const u8 *addr) +{ + mt76_wr(dev, offset, get_unaligned_le32(addr)); + mt76_wr(dev, offset + 4, addr[4] | addr[5] << 8); +} + static void mt76x0_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_bss_conf *info, u32 changed) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h index 2918abc95c71..d775d9951695 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h @@ -141,7 +141,6 @@ int mt76x0_read_reg_pairs(struct mt76x0_dev *dev, u32 base, struct mt76_reg_pair *data, int len); int mt76x0_burst_write_regs(struct mt76x0_dev *dev, u32 offset, const u32 *data, int n); -void mt76x0_addr_wr(struct mt76x0_dev *dev, const u32 offset, const u8 *addr); /* Init */ struct mt76x0_dev *mt76x0_alloc_device(struct device *dev); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c b/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c new file mode 100644 index 000000000000..244ab64560a6 --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2016 Felix Fietkau + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include + +#include "mt76x0.h" + +static int +mt76x0e_probe(struct pci_dev *pdev, const struct pci_device_id *id) +{ + struct mt76x0_dev *dev; + int ret = -ENODEV; + + ret = pcim_enable_device(pdev); + if (ret) + return ret; + + ret = pcim_iomap_regions(pdev, BIT(0), pci_name(pdev)); + if (ret) + return ret; + + pci_set_master(pdev); + + ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); + if (ret) + return ret; + + dev = mt76x0_alloc_device(&pdev->dev); + if (!dev) + return -ENOMEM; + + mt76_mmio_init(&dev->mt76, pcim_iomap_table(pdev)[0]); + + dev->mt76.rev = mt76_rr(dev, MT_ASIC_VERSION); + dev_info(dev->mt76.dev, "ASIC revision: %08x\n", dev->mt76.rev); + +/* error: */ + ieee80211_free_hw(mt76_hw(dev)); + return ret; +} + +static void +mt76x0e_remove(struct pci_dev *pdev) +{ + struct mt76_dev *mdev = pci_get_drvdata(pdev); + + mt76_unregister_device(mdev); + ieee80211_free_hw(mdev->hw); +} + +static const struct pci_device_id mt76x0e_device_table[] = { + { PCI_DEVICE(0x14c3, 0x7630) }, + { }, +}; + +MODULE_DEVICE_TABLE(pci, mt76x0e_device_table); +MODULE_LICENSE("Dual BSD/GPL"); + +static struct pci_driver mt76x0e_driver = { + .name = KBUILD_MODNAME, + .id_table = mt76x0e_device_table, + .probe = mt76x0e_probe, + .remove = mt76x0e_remove, +}; + +module_pci_driver(mt76x0e_driver); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c index fc8884c38f7e..b9382092f47f 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c @@ -46,12 +46,6 @@ static struct usb_device_id mt76x0_device_table[] = { { 0, } }; -void mt76x0_addr_wr(struct mt76x0_dev *dev, const u32 offset, const u8 *addr) -{ - mt76_wr(dev, offset, get_unaligned_le32(addr)); - mt76_wr(dev, offset + 4, addr[4] | addr[5] << 8); -} - static int mt76x0_probe(struct usb_interface *usb_intf, const struct usb_device_id *id) { From c0eb79ab33b952adaf0633aacea5775ba5d44614 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Thu, 6 Sep 2018 11:18:56 +0200 Subject: [PATCH 186/276] mt76x0: remove unused mt76x0_wcid We do not use mt76x0_wcid any longer. Signed-off-by: Stanislaw Gruszka Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h | 9 --------- 1 file changed, 9 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h index d775d9951695..31267a180573 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h @@ -112,15 +112,6 @@ struct mt76x0_dev { struct mac_stats stats; }; -struct mt76x0_wcid { - u8 idx; - u8 hw_key_idx; - - u16 tx_rate; - bool tx_rate_set; - u8 tx_rate_nss; -}; - extern const struct ieee80211_ops mt76x0_ops; static inline bool is_mt7610e(struct mt76x0_dev *dev) From 6d1bced1495d1431d26854367a0d0d38a87cea9e Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Thu, 6 Sep 2018 11:18:57 +0200 Subject: [PATCH 187/276] mt76x0: remove some usb specific code from mt76x0_register_device Initial effort to make mt76x0_register_device bus neutral. Signed-off-by: Stanislaw Gruszka Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt76x0/init.c | 8 -------- drivers/net/wireless/mediatek/mt76/mt76x0/usb.c | 12 ++++++++++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c index 0e4a13fa42cb..4a899904d518 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c @@ -518,14 +518,6 @@ int mt76x0_register_device(struct mt76x0_dev *dev) struct wiphy *wiphy = hw->wiphy; int ret; - ret = mt76u_mcu_init_rx(mdev); - if (ret < 0) - return ret; - - ret = mt76u_alloc_queues(mdev); - if (ret < 0) - return ret; - ret = mt76x0_init_hardware(dev); if (ret) return ret; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c index b9382092f47f..9a803fb0cd5d 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c @@ -46,7 +46,7 @@ static struct usb_device_id mt76x0_device_table[] = { { 0, } }; -static int mt76x0_probe(struct usb_interface *usb_intf, +static int mt76x0u_probe(struct usb_interface *usb_intf, const struct usb_device_id *id) { struct usb_device *usb_dev = interface_to_usbdev(usb_intf); @@ -84,6 +84,14 @@ static int mt76x0_probe(struct usb_interface *usb_intf, if (!(mt76_rr(dev, MT_EFUSE_CTRL) & MT_EFUSE_CTRL_SEL)) dev_warn(dev->mt76.dev, "Warning: eFUSE not present\n"); + ret = mt76u_mcu_init_rx(&dev->mt76); + if (ret < 0) + goto err; + + ret = mt76u_alloc_queues(&dev->mt76); + if (ret < 0) + goto err; + ret = mt76x0_register_device(dev); if (ret) goto err_hw; @@ -170,7 +178,7 @@ MODULE_LICENSE("GPL"); static struct usb_driver mt76x0_driver = { .name = KBUILD_MODNAME, .id_table = mt76x0_device_table, - .probe = mt76x0_probe, + .probe = mt76x0u_probe, .disconnect = mt76x0_disconnect, .suspend = mt76x0_suspend, .resume = mt76x0_resume, From 835123b7e14cc328608197897db28e9b4d09d987 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Thu, 6 Sep 2018 11:18:58 +0200 Subject: [PATCH 188/276] mt76x0: make device allocation bus neutral Remove some USB specific code form mt76x0_alloc_device. Signed-off-by: Stanislaw Gruszka Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt76x0/init.c | 11 +++-------- drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h | 3 ++- drivers/net/wireless/mediatek/mt76/mt76x0/pci.c | 2 +- drivers/net/wireless/mediatek/mt76/mt76x0/tx.c | 3 ++- drivers/net/wireless/mediatek/mt76/mt76x0/usb.c | 9 ++++++++- 5 files changed, 16 insertions(+), 12 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c index 4a899904d518..9c720906ea13 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c @@ -482,14 +482,9 @@ void mt76x0_cleanup(struct mt76x0_dev *dev) } EXPORT_SYMBOL_GPL(mt76x0_cleanup); -struct mt76x0_dev *mt76x0_alloc_device(struct device *pdev) +struct mt76x0_dev * +mt76x0_alloc_device(struct device *pdev, const struct mt76_driver_ops *drv_ops) { - static const struct mt76_driver_ops drv_ops = { - .tx_prepare_skb = mt76x0_tx_prepare_skb, - .tx_complete_skb = mt76x02_tx_complete_skb, - .tx_status_data = mt76x02_tx_status_data, - .rx_skb = mt76x0_queue_rx_skb, - }; struct mt76x0_dev *dev; struct mt76_dev *mdev; @@ -498,7 +493,7 @@ struct mt76x0_dev *mt76x0_alloc_device(struct device *pdev) return NULL; mdev->dev = pdev; - mdev->drv = &drv_ops; + mdev->drv = drv_ops; dev = container_of(mdev, struct mt76x0_dev, mt76); mutex_init(&dev->reg_atomic_mutex); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h index 31267a180573..87eb084bd270 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h @@ -134,7 +134,8 @@ int mt76x0_burst_write_regs(struct mt76x0_dev *dev, u32 offset, const u32 *data, int n); /* Init */ -struct mt76x0_dev *mt76x0_alloc_device(struct device *dev); +struct mt76x0_dev * +mt76x0_alloc_device(struct device *pdev, const struct mt76_driver_ops *drv_ops); int mt76x0_init_hardware(struct mt76x0_dev *dev); int mt76x0_register_device(struct mt76x0_dev *dev); void mt76x0_cleanup(struct mt76x0_dev *dev); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c b/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c index 244ab64560a6..eb383f96ec9a 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c @@ -40,7 +40,7 @@ mt76x0e_probe(struct pci_dev *pdev, const struct pci_device_id *id) if (ret) return ret; - dev = mt76x0_alloc_device(&pdev->dev); + dev = mt76x0_alloc_device(&pdev->dev, NULL); if (!dev) return -ENOMEM; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c b/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c index 4058dae1368f..3618f92662f8 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c @@ -95,6 +95,7 @@ int mt76x0_tx_prepare_skb(struct mt76_dev *mdev, void *data, return mt76x02_set_txinfo(skb, wcid, q2ep(q->hw_idx)); } +EXPORT_SYMBOL_GPL(mt76x0_tx_prepare_skb); void mt76x0_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q, struct sk_buff *skb) @@ -110,4 +111,4 @@ void mt76x0_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q, mt76_rx(&dev->mt76, q, skb); } - +EXPORT_SYMBOL_GPL(mt76x0_queue_rx_skb); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c index 9a803fb0cd5d..89e856745fec 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c @@ -18,6 +18,7 @@ #include "mt76x0.h" #include "usb.h" #include "trace.h" +#include "../mt76x02_util.h" static struct usb_device_id mt76x0_device_table[] = { { USB_DEVICE(0x148F, 0x7610) }, /* MT7610U */ @@ -49,12 +50,18 @@ static struct usb_device_id mt76x0_device_table[] = { static int mt76x0u_probe(struct usb_interface *usb_intf, const struct usb_device_id *id) { + static const struct mt76_driver_ops drv_ops = { + .tx_prepare_skb = mt76x0_tx_prepare_skb, + .tx_complete_skb = mt76x02_tx_complete_skb, + .tx_status_data = mt76x02_tx_status_data, + .rx_skb = mt76x0_queue_rx_skb, + }; struct usb_device *usb_dev = interface_to_usbdev(usb_intf); struct mt76x0_dev *dev; u32 asic_rev, mac_rev; int ret; - dev = mt76x0_alloc_device(&usb_intf->dev); + dev = mt76x0_alloc_device(&usb_intf->dev, &drv_ops); if (!dev) return -ENOMEM; From 473f0a763d2c7cd68a6dedf51e7d81e8f58f78ac Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Fri, 7 Sep 2018 23:13:12 +0200 Subject: [PATCH 189/276] mt76x0: run vco calibration for each channel configuration According to vendor sdk, vco calibration has to be executed for each channel configuration whereas mcu calibration has to be performed during channel scanning. This patch fixes the mt76x0 monitor mode issue since in that configuration vco calibration was never executed Fixes: 10de7a8b4ab9 ("mt76x0: phy files") Tested-by: Sid Hayn Signed-off-by: Lorenzo Bianconi Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt76x0/phy.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c index af30885b7e5e..1176a288b2c6 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c @@ -757,10 +757,10 @@ __mt76x0_phy_set_channel(struct mt76x0_dev *dev, /* Vendor driver don't do it */ /* mt76x0_phy_set_tx_power(dev, channel, rf_bw_band); */ + mt76x0_vco_cal(dev, channel); if (scan) - mt76x0_vco_cal(dev, channel); + mt76x0_mcu_calibrate(dev, MCU_CAL_RXDCOC, 1); - mt76x0_mcu_calibrate(dev, MCU_CAL_RXDCOC, 1); mt76x0_phy_set_chan_pwr(dev, channel); dev->mt76.chandef = *chandef; From dce9dc8d571b916bb55e08b66fb7bc4c5abd9ae5 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Sun, 9 Sep 2018 22:32:36 +0200 Subject: [PATCH 190/276] mt76: move mt76x0 and mt76x2 mcu shared defs in mt76x02_mcu.h Move mt76x0 and mt76x2 mcu shared definition in mt76x02_mcu.h and remove duplicated code Signed-off-by: Lorenzo Bianconi Signed-off-by: Felix Fietkau --- .../net/wireless/mediatek/mt76/mt76x0/mcu.c | 8 +-- .../net/wireless/mediatek/mt76/mt76x0/mcu.h | 51 +------------ .../net/wireless/mediatek/mt76/mt76x02_mcu.h | 71 +++++++++++++++++++ .../net/wireless/mediatek/mt76/mt76x2_mcu.h | 49 +------------ .../net/wireless/mediatek/mt76/mt76x2u_mcu.c | 2 - 5 files changed, 79 insertions(+), 102 deletions(-) create mode 100644 drivers/net/wireless/mediatek/mt76/mt76x02_mcu.h diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c index 29c0b3978af7..a9314753a2dc 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c @@ -81,7 +81,7 @@ mt76x0_mcu_calibrate(struct mt76x0_dev *dev, enum mcu_calibrate cal, u32 val) int mt76x0_write_reg_pairs(struct mt76x0_dev *dev, u32 base, const struct mt76_reg_pair *data, int n) { - const int max_vals_per_cmd = INBAND_PACKET_MAX_LEN / 8; + const int max_vals_per_cmd = MT_INBAND_PACKET_MAX_LEN / 8; struct sk_buff *skb; int cnt, i, ret; @@ -111,7 +111,7 @@ int mt76x0_write_reg_pairs(struct mt76x0_dev *dev, u32 base, int mt76x0_read_reg_pairs(struct mt76x0_dev *dev, u32 base, struct mt76_reg_pair *data, int n) { - const int max_vals_per_cmd = INBAND_PACKET_MAX_LEN / 8; + const int max_vals_per_cmd = MT_INBAND_PACKET_MAX_LEN / 8; struct mt76_usb *usb = &dev->mt76.usb; struct sk_buff *skb; int cnt, i, ret; @@ -154,7 +154,7 @@ int mt76x0_read_reg_pairs(struct mt76x0_dev *dev, u32 base, int mt76x0_burst_write_regs(struct mt76x0_dev *dev, u32 offset, const u32 *data, int n) { - const int max_regs_per_cmd = INBAND_PACKET_MAX_LEN / 4 - 1; + const int max_regs_per_cmd = MT_INBAND_PACKET_MAX_LEN / 4 - 1; struct sk_buff *skb; int cnt, i, ret; @@ -185,7 +185,7 @@ int mt76x0_burst_write_regs(struct mt76x0_dev *dev, u32 offset, static int mt76x0_burst_read_regs(struct mt76x0_dev *dev, u32 base, struct mt76_reg_pair *data, int n) { - const int max_vals_per_cmd = INBAND_PACKET_MAX_LEN / 4 - 1; + const int max_vals_per_cmd = MT_INBAND_PACKET_MAX_LEN / 4 - 1; struct mt76_usb *usb = &dev->mt76.usb; struct sk_buff *skb; int cnt, ret; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.h b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.h index 010a7f2bbae9..a551ad5e3af4 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.h @@ -15,65 +15,18 @@ #ifndef __MT76X0U_MCU_H #define __MT76X0U_MCU_H -struct mt76x0_dev; +#include "../mt76x02_mcu.h" -/* Register definitions */ -#define MT_MCU_RESET_CTL 0x070C -#define MT_MCU_INT_LEVEL 0x0718 -#define MT_MCU_COM_REG0 0x0730 -#define MT_MCU_COM_REG1 0x0734 -#define MT_MCU_COM_REG2 0x0738 -#define MT_MCU_COM_REG3 0x073C +struct mt76x0_dev; #define MT_MCU_IVB_SIZE 0x40 #define MT_MCU_DLM_OFFSET 0x80000 -#define MT_MCU_MEMMAP_WLAN 0x00410000 /* We use same space for BBP as for MAC regs * #define MT_MCU_MEMMAP_BBP 0x40000000 */ #define MT_MCU_MEMMAP_RF 0x80000000 -#define INBAND_PACKET_MAX_LEN 192 - -enum mcu_cmd { - CMD_FUN_SET_OP = 1, - CMD_LOAD_CR = 2, - CMD_INIT_GAIN_OP = 3, - CMD_DYNC_VGA_OP = 6, - CMD_TDLS_CH_SW = 7, - CMD_BURST_WRITE = 8, - CMD_READ_MODIFY_WRITE = 9, - CMD_RANDOM_READ = 10, - CMD_BURST_READ = 11, - CMD_RANDOM_WRITE = 12, - CMD_LED_MODE_OP = 16, - CMD_POWER_SAVING_OP = 20, - CMD_WOW_CONFIG = 21, - CMD_WOW_QUERY = 22, - CMD_WOW_FEATURE = 24, - CMD_CARRIER_DETECT_OP = 28, - CMD_RADOR_DETECT_OP = 29, - CMD_SWITCH_CHANNEL_OP = 30, - CMD_CALIBRATION_OP = 31, - CMD_BEACON_OP = 32, - CMD_ANTENNA_OP = 33, -}; - -enum mcu_function { - Q_SELECT = 1, - BW_SETTING = 2, - ATOMIC_TSSI_SETTING = 5, -}; - -enum mcu_power_mode { - RADIO_OFF = 0x30, - RADIO_ON = 0x31, - RADIO_OFF_AUTO_WAKEUP = 0x32, - RADIO_OFF_ADVANCE = 0x33, - RADIO_ON_ADVANCE = 0x34, -}; - enum mcu_calibrate { MCU_CAL_R = 1, MCU_CAL_RXDCOC, diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mcu.h b/drivers/net/wireless/mediatek/mt76/mt76x02_mcu.h new file mode 100644 index 000000000000..21181fddee98 --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mcu.h @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2018 Lorenzo Bianconi + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef __MT76x02_MCU_H +#define __MT76x0x_MCU_H + +#define MT_MCU_RESET_CTL 0x070C +#define MT_MCU_INT_LEVEL 0x0718 +#define MT_MCU_COM_REG0 0x0730 +#define MT_MCU_COM_REG1 0x0734 +#define MT_MCU_COM_REG2 0x0738 +#define MT_MCU_COM_REG3 0x073C + +#define MT_INBAND_PACKET_MAX_LEN 192 +#define MT_MCU_MEMMAP_WLAN 0x410000 + +enum mcu_cmd { + CMD_FUN_SET_OP = 1, + CMD_LOAD_CR = 2, + CMD_INIT_GAIN_OP = 3, + CMD_DYNC_VGA_OP = 6, + CMD_TDLS_CH_SW = 7, + CMD_BURST_WRITE = 8, + CMD_READ_MODIFY_WRITE = 9, + CMD_RANDOM_READ = 10, + CMD_BURST_READ = 11, + CMD_RANDOM_WRITE = 12, + CMD_LED_MODE_OP = 16, + CMD_POWER_SAVING_OP = 20, + CMD_WOW_CONFIG = 21, + CMD_WOW_QUERY = 22, + CMD_WOW_FEATURE = 24, + CMD_CARRIER_DETECT_OP = 28, + CMD_RADOR_DETECT_OP = 29, + CMD_SWITCH_CHANNEL_OP = 30, + CMD_CALIBRATION_OP = 31, + CMD_BEACON_OP = 32, + CMD_ANTENNA_OP = 33, +}; + +enum mcu_power_mode { + RADIO_OFF = 0x30, + RADIO_ON = 0x31, + RADIO_OFF_AUTO_WAKEUP = 0x32, + RADIO_OFF_ADVANCE = 0x33, + RADIO_ON_ADVANCE = 0x34, +}; + +enum mcu_function { + Q_SELECT = 1, + BW_SETTING = 2, + USB2_SW_DISCONNECT = 2, + USB3_SW_DISCONNECT = 3, + LOG_FW_DEBUG_MSG = 4, + GET_FW_VERSION = 5, +}; + +#endif /* __MT76x02_MCU_H */ diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.h b/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.h index e40293f21417..564bcac27401 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.h @@ -17,15 +17,11 @@ #ifndef __MT76x2_MCU_H #define __MT76x2_MCU_H +#include "mt76x02_mcu.h" + /* Register definitions */ #define MT_MCU_CPU_CTL 0x0704 #define MT_MCU_CLOCK_CTL 0x0708 -#define MT_MCU_RESET_CTL 0x070C -#define MT_MCU_INT_LEVEL 0x0718 -#define MT_MCU_COM_REG0 0x0730 -#define MT_MCU_COM_REG1 0x0734 -#define MT_MCU_COM_REG2 0x0738 -#define MT_MCU_COM_REG3 0x073C #define MT_MCU_PCIE_REMAP_BASE1 0x0740 #define MT_MCU_PCIE_REMAP_BASE2 0x0744 #define MT_MCU_PCIE_REMAP_BASE3 0x0748 @@ -69,47 +65,6 @@ #define MT_MCU_DLM_ADDR 0x90000 #define MT_MCU_DLM_ADDR_E3 0x90800 -enum mcu_cmd { - CMD_FUN_SET_OP = 1, - CMD_LOAD_CR = 2, - CMD_INIT_GAIN_OP = 3, - CMD_DYNC_VGA_OP = 6, - CMD_TDLS_CH_SW = 7, - CMD_BURST_WRITE = 8, - CMD_READ_MODIFY_WRITE = 9, - CMD_RANDOM_READ = 10, - CMD_BURST_READ = 11, - CMD_RANDOM_WRITE = 12, - CMD_LED_MODE_OP = 16, - CMD_POWER_SAVING_OP = 20, - CMD_WOW_CONFIG = 21, - CMD_WOW_QUERY = 22, - CMD_WOW_FEATURE = 24, - CMD_CARRIER_DETECT_OP = 28, - CMD_RADOR_DETECT_OP = 29, - CMD_SWITCH_CHANNEL_OP = 30, - CMD_CALIBRATION_OP = 31, - CMD_BEACON_OP = 32, - CMD_ANTENNA_OP = 33, -}; - -enum mcu_function { - Q_SELECT = 1, - BW_SETTING = 2, - USB2_SW_DISCONNECT = 2, - USB3_SW_DISCONNECT = 3, - LOG_FW_DEBUG_MSG = 4, - GET_FW_VERSION = 5, -}; - -enum mcu_power_mode { - RADIO_OFF = 0x30, - RADIO_ON = 0x31, - RADIO_OFF_AUTO_WAKEUP = 0x32, - RADIO_OFF_ADVANCE = 0x33, - RADIO_ON_ADVANCE = 0x34, -}; - enum mcu_calibration { MCU_CAL_R = 1, MCU_CAL_TEMP_SENSOR, diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2u_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x2u_mcu.c index 31677e898427..a4302457cf5c 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2u_mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2u_mcu.c @@ -20,8 +20,6 @@ #include "mt76x2_eeprom.h" #define MT_CMD_HDR_LEN 4 -#define MT_INBAND_PACKET_MAX_LEN 192 -#define MT_MCU_MEMMAP_WLAN 0x410000 #define MCU_FW_URB_MAX_PAYLOAD 0x3900 #define MCU_ROM_PATCH_MAX_PAYLOAD 2048 From db0f04f324b3a9a317af2f050397c1dfa903eefa Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Sun, 9 Sep 2018 22:32:37 +0200 Subject: [PATCH 191/276] mt76: add mt76_mcu_ops data structure for mcu related pointers Introduce mt76_mcu_ops data structure to contain mcu related function pointers. This is a preliminary patch to move mt76x02 usb mcu code in mt76x02-usb module Acked-by: Stanislaw Gruszka Signed-off-by: Lorenzo Bianconi Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt76.h | 11 +++++++++++ drivers/net/wireless/mediatek/mt76/usb.c | 1 + drivers/net/wireless/mediatek/mt76/usb_mcu.c | 10 ++++++++++ 3 files changed, 22 insertions(+) diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h index 2d74a2c3d93c..bff03470ccbc 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76.h +++ b/drivers/net/wireless/mediatek/mt76/mt76.h @@ -119,6 +119,12 @@ struct mt76_queue { struct sk_buff *rx_head; }; +struct mt76_mcu_ops { + struct sk_buff *(*mcu_msg_alloc)(const void *data, int len); + int (*mcu_send_msg)(struct mt76_dev *dev, struct sk_buff *skb, + int cmd, bool wait_resp); +}; + struct mt76_queue_ops { int (*init)(struct mt76_dev *dev); @@ -336,6 +342,7 @@ struct mt76_dev { const struct mt76_bus_ops *bus; const struct mt76_driver_ops *drv; + const struct mt76_mcu_ops *mcu_ops; void __iomem *regs; struct device *dev; @@ -436,6 +443,9 @@ struct mt76_rx_status { #define mt76_rmw(dev, ...) (dev)->mt76.bus->rmw(&((dev)->mt76), __VA_ARGS__) #define mt76_wr_copy(dev, ...) (dev)->mt76.bus->copy(&((dev)->mt76), __VA_ARGS__) +#define mt76_mcu_msg_alloc(dev, ...) (dev)->mt76.mcu_ops->mcu_msg_alloc(__VA_ARGS__) +#define mt76_mcu_send_msg(dev, ...) (dev)->mt76.mcu_ops->mcu_send_msg(&((dev)->mt76), __VA_ARGS__) + #define mt76_set(dev, offset, val) mt76_rmw(dev, offset, 0, val) #define mt76_clear(dev, offset, val) mt76_rmw(dev, offset, val, 0) @@ -643,5 +653,6 @@ int mt76u_mcu_send_msg(struct mt76_dev *dev, struct sk_buff *skb, void mt76u_mcu_fw_reset(struct mt76_dev *dev); int mt76u_mcu_init_rx(struct mt76_dev *dev); void mt76u_mcu_deinit(struct mt76_dev *dev); +void mt76u_init_mcu_ops(struct mt76_dev *dev); #endif diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c index 333b2c8ca7a4..1259a2b8e205 100644 --- a/drivers/net/wireless/mediatek/mt76/usb.c +++ b/drivers/net/wireless/mediatek/mt76/usb.c @@ -836,6 +836,7 @@ int mt76u_init(struct mt76_dev *dev, mutex_init(&usb->usb_ctrl_mtx); dev->bus = &mt76u_ops; dev->queue_ops = &usb_queue_ops; + mt76u_init_mcu_ops(dev); return mt76u_set_endpoints(intf, usb); } diff --git a/drivers/net/wireless/mediatek/mt76/usb_mcu.c b/drivers/net/wireless/mediatek/mt76/usb_mcu.c index d80dbfafba6d..4cce807ec24e 100644 --- a/drivers/net/wireless/mediatek/mt76/usb_mcu.c +++ b/drivers/net/wireless/mediatek/mt76/usb_mcu.c @@ -296,3 +296,13 @@ void mt76u_mcu_deinit(struct mt76_dev *dev) mt76u_buf_free(&usb->mcu.res); } EXPORT_SYMBOL_GPL(mt76u_mcu_deinit); + +void mt76u_init_mcu_ops(struct mt76_dev *dev) +{ + static const struct mt76_mcu_ops mt76u_mcu_ops = { + .mcu_msg_alloc = mt76u_mcu_msg_alloc, + .mcu_send_msg = mt76u_mcu_send_msg, + }; + + dev->mcu_ops = &mt76u_mcu_ops; +} From f1638c7cd686c22620030da8ebb7c973dfc768e1 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Sun, 9 Sep 2018 22:32:38 +0200 Subject: [PATCH 192/276] mt76: add usb implementation of {wr,rd}_rp Add USB implementation for read and write reg pair routines. The actual implementation can use mcu related routines according to MCU state Signed-off-by: Stanislaw Gruszka Signed-off-by: Lorenzo Bianconi Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt76.h | 8 ++ .../net/wireless/mediatek/mt76/mt76x0/init.c | 5 +- .../net/wireless/mediatek/mt76/mt76x0/mcu.c | 73 ----------------- .../wireless/mediatek/mt76/mt76x0/mt76x0.h | 4 - .../net/wireless/mediatek/mt76/mt76x0/phy.c | 9 ++- drivers/net/wireless/mediatek/mt76/usb.c | 54 +++++++++++++ drivers/net/wireless/mediatek/mt76/usb_mcu.c | 79 +++++++++++++++++++ 7 files changed, 149 insertions(+), 83 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h index bff03470ccbc..3576418f696c 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76.h +++ b/drivers/net/wireless/mediatek/mt76/mt76.h @@ -650,6 +650,14 @@ int __mt76u_mcu_send_msg(struct mt76_dev *dev, struct sk_buff *skb, int cmd, bool wait_resp); int mt76u_mcu_send_msg(struct mt76_dev *dev, struct sk_buff *skb, int cmd, bool wait_resp); +int mt76u_mcu_wr_rp(struct mt76_dev *dev, u32 base, + const struct mt76_reg_pair *data, int n); +int mt76u_mcu_rd_rp(struct mt76_dev *dev, u32 base, + struct mt76_reg_pair *data, int n); +int mt76u_wr_rp(struct mt76_dev *dev, u32 base, + const struct mt76_reg_pair *data, int n); +int mt76u_rd_rp(struct mt76_dev *dev, u32 base, + struct mt76_reg_pair *data, int n); void mt76u_mcu_fw_reset(struct mt76_dev *dev); int mt76u_mcu_init_rx(struct mt76_dev *dev); void mt76u_mcu_deinit(struct mt76_dev *dev); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c index 9c720906ea13..007036e35063 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c @@ -154,8 +154,9 @@ static void mt76x0_init_usb_dma(struct mt76x0_dev *dev) mt76_wr(dev, MT_USB_DMA_CFG, val); } -#define RANDOM_WRITE(dev, tab) \ - mt76x0_write_reg_pairs(dev, MT_MCU_MEMMAP_WLAN, tab, ARRAY_SIZE(tab)); +#define RANDOM_WRITE(dev, tab) \ + mt76u_wr_rp(&(dev)->mt76, MT_MCU_MEMMAP_WLAN, \ + tab, ARRAY_SIZE(tab)) static int mt76x0_init_bbp(struct mt76x0_dev *dev) { diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c index a9314753a2dc..b8f85668c447 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c @@ -78,79 +78,6 @@ mt76x0_mcu_calibrate(struct mt76x0_dev *dev, enum mcu_calibrate cal, u32 val) true); } -int mt76x0_write_reg_pairs(struct mt76x0_dev *dev, u32 base, - const struct mt76_reg_pair *data, int n) -{ - const int max_vals_per_cmd = MT_INBAND_PACKET_MAX_LEN / 8; - struct sk_buff *skb; - int cnt, i, ret; - - if (!n) - return 0; - - cnt = min(max_vals_per_cmd, n); - - skb = alloc_skb(cnt * 8 + MT_DMA_HDR_LEN + 4, GFP_KERNEL); - if (!skb) - return -ENOMEM; - skb_reserve(skb, MT_DMA_HDR_LEN); - - for (i = 0; i < cnt; i++) { - skb_put_le32(skb, base + data[i].reg); - skb_put_le32(skb, data[i].value); - } - - ret = mt76u_mcu_send_msg(&dev->mt76, skb, CMD_RANDOM_WRITE, - cnt == n); - if (ret) - return ret; - - return mt76x0_write_reg_pairs(dev, base, data + cnt, n - cnt); -} - -int mt76x0_read_reg_pairs(struct mt76x0_dev *dev, u32 base, - struct mt76_reg_pair *data, int n) -{ - const int max_vals_per_cmd = MT_INBAND_PACKET_MAX_LEN / 8; - struct mt76_usb *usb = &dev->mt76.usb; - struct sk_buff *skb; - int cnt, i, ret; - - if (!n) - return 0; - - cnt = min(max_vals_per_cmd, n); - if (cnt != n) - return -EINVAL; - - skb = alloc_skb(cnt * 8 + MT_DMA_HDR_LEN + 4, GFP_KERNEL); - if (!skb) - return -ENOMEM; - skb_reserve(skb, MT_DMA_HDR_LEN); - - for (i = 0; i < cnt; i++) { - skb_put_le32(skb, base + data[i].reg); - skb_put_le32(skb, data[i].value); - } - - mutex_lock(&usb->mcu.mutex); - - usb->mcu.rp = data; - usb->mcu.rp_len = n; - usb->mcu.base = base; - usb->mcu.burst = false; - - ret = __mt76u_mcu_send_msg(&dev->mt76, skb, CMD_RANDOM_READ, - true); - - usb->mcu.rp = NULL; - - mutex_unlock(&usb->mcu.mutex); - - return ret; - -} - int mt76x0_burst_write_regs(struct mt76x0_dev *dev, u32 offset, const u32 *data, int n) { diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h index 87eb084bd270..92ecf4e8bda1 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h @@ -126,10 +126,6 @@ void mt76x0_init_debugfs(struct mt76x0_dev *dev); #define mt76_rmw_field(_dev, _reg, _field, _val) \ mt76_rmw(_dev, _reg, _field, FIELD_PREP(_field, _val)) -int mt76x0_write_reg_pairs(struct mt76x0_dev *dev, u32 base, - const struct mt76_reg_pair *data, int len); -int mt76x0_read_reg_pairs(struct mt76x0_dev *dev, u32 base, - struct mt76_reg_pair *data, int len); int mt76x0_burst_write_regs(struct mt76x0_dev *dev, u32 offset, const u32 *data, int n); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c index 1176a288b2c6..27dd8388a6ae 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c @@ -117,7 +117,7 @@ rf_wr(struct mt76x0_dev *dev, u32 offset, u8 val) .value = val, }; - return mt76x0_write_reg_pairs(dev, MT_MCU_MEMMAP_RF, &pair, 1); + return mt76u_wr_rp(&dev->mt76, MT_MCU_MEMMAP_RF, &pair, 1); } else { WARN_ON_ONCE(1); return mt76x0_rf_csr_wr(dev, offset, val); @@ -135,7 +135,7 @@ rf_rr(struct mt76x0_dev *dev, u32 offset) .reg = offset, }; - ret = mt76x0_read_reg_pairs(dev, MT_MCU_MEMMAP_RF, &pair, 1); + ret = mt76u_rd_rp(&dev->mt76, MT_MCU_MEMMAP_RF, &pair, 1); val = pair.value; } else { WARN_ON_ONCE(1); @@ -175,8 +175,9 @@ rf_clear(struct mt76x0_dev *dev, u32 offset, u8 mask) } #endif -#define RF_RANDOM_WRITE(dev, tab) \ - mt76x0_write_reg_pairs(dev, MT_MCU_MEMMAP_RF, tab, ARRAY_SIZE(tab)); +#define RF_RANDOM_WRITE(dev, tab) \ + mt76u_wr_rp(&(dev)->mt76, MT_MCU_MEMMAP_RF, \ + tab, ARRAY_SIZE(tab)) int mt76x0_wait_bbp_ready(struct mt76x0_dev *dev) { diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c index 1259a2b8e205..cd4d48594aaf 100644 --- a/drivers/net/wireless/mediatek/mt76/usb.c +++ b/drivers/net/wireless/mediatek/mt76/usb.c @@ -186,6 +186,60 @@ void mt76u_single_wr(struct mt76_dev *dev, const u8 req, } EXPORT_SYMBOL_GPL(mt76u_single_wr); +static int +mt76u_req_wr_rp(struct mt76_dev *dev, u32 base, + const struct mt76_reg_pair *data, int len) +{ + struct mt76_usb *usb = &dev->usb; + + mutex_lock(&usb->usb_ctrl_mtx); + while (len > 0) { + __mt76u_wr(dev, base + data->reg, data->value); + len--; + data++; + } + mutex_unlock(&usb->usb_ctrl_mtx); + + return 0; +} + +int mt76u_wr_rp(struct mt76_dev *dev, u32 base, + const struct mt76_reg_pair *data, int n) +{ + if (test_bit(MT76_STATE_MCU_RUNNING, &dev->state)) + return mt76u_mcu_wr_rp(dev, base, data, n); + else + return mt76u_req_wr_rp(dev, base, data, n); +} +EXPORT_SYMBOL_GPL(mt76u_wr_rp); + +static int +mt76u_req_rd_rp(struct mt76_dev *dev, u32 base, struct mt76_reg_pair *data, + int len) +{ + struct mt76_usb *usb = &dev->usb; + + mutex_lock(&usb->usb_ctrl_mtx); + while (len > 0) { + data->value = __mt76u_rr(dev, base + data->reg); + len--; + data++; + } + mutex_unlock(&usb->usb_ctrl_mtx); + + return 0; +} + +int mt76u_rd_rp(struct mt76_dev *dev, u32 base, + struct mt76_reg_pair *data, int n) +{ + if (test_bit(MT76_STATE_MCU_RUNNING, &dev->state)) + return mt76u_mcu_rd_rp(dev, base, data, n); + else + return mt76u_req_rd_rp(dev, base, data, n); +} +EXPORT_SYMBOL_GPL(mt76u_rd_rp); + static int mt76u_set_endpoints(struct usb_interface *intf, struct mt76_usb *usb) diff --git a/drivers/net/wireless/mediatek/mt76/usb_mcu.c b/drivers/net/wireless/mediatek/mt76/usb_mcu.c index 4cce807ec24e..622d7d6da32e 100644 --- a/drivers/net/wireless/mediatek/mt76/usb_mcu.c +++ b/drivers/net/wireless/mediatek/mt76/usb_mcu.c @@ -26,6 +26,8 @@ #define MT_TX_CPU_FROM_FCE_CPU_DESC_IDX 0x09a8 +#define MT_INBAND_PACKET_MAX_LEN 192 + struct sk_buff *mt76u_mcu_msg_alloc(const void *data, int len) { struct sk_buff *skb; @@ -178,6 +180,83 @@ int mt76u_mcu_send_msg(struct mt76_dev *dev, struct sk_buff *skb, } EXPORT_SYMBOL_GPL(mt76u_mcu_send_msg); +static inline void skb_put_le32(struct sk_buff *skb, u32 val) +{ + put_unaligned_le32(val, skb_put(skb, 4)); +} + +int mt76u_mcu_wr_rp(struct mt76_dev *dev, u32 base, + const struct mt76_reg_pair *data, int n) +{ + const int CMD_RANDOM_WRITE = 12; + const int max_vals_per_cmd = MT_INBAND_PACKET_MAX_LEN / 8; + struct sk_buff *skb; + int cnt, i, ret; + + if (!n) + return 0; + + cnt = min(max_vals_per_cmd, n); + + skb = alloc_skb(cnt * 8 + MT_DMA_HDR_LEN + 4, GFP_KERNEL); + if (!skb) + return -ENOMEM; + skb_reserve(skb, MT_DMA_HDR_LEN); + + for (i = 0; i < cnt; i++) { + skb_put_le32(skb, base + data[i].reg); + skb_put_le32(skb, data[i].value); + } + + ret = mt76u_mcu_send_msg(dev, skb, CMD_RANDOM_WRITE, cnt == n); + if (ret) + return ret; + + return mt76u_mcu_wr_rp(dev, base, data + cnt, n - cnt); +} + +int mt76u_mcu_rd_rp(struct mt76_dev *dev, u32 base, + struct mt76_reg_pair *data, int n) +{ + const int CMD_RANDOM_READ = 10; + const int max_vals_per_cmd = MT_INBAND_PACKET_MAX_LEN / 8; + struct mt76_usb *usb = &dev->usb; + struct sk_buff *skb; + int cnt, i, ret; + + if (!n) + return 0; + + cnt = min(max_vals_per_cmd, n); + if (cnt != n) + return -EINVAL; + + skb = alloc_skb(cnt * 8 + MT_DMA_HDR_LEN + 4, GFP_KERNEL); + if (!skb) + return -ENOMEM; + skb_reserve(skb, MT_DMA_HDR_LEN); + + for (i = 0; i < cnt; i++) { + skb_put_le32(skb, base + data[i].reg); + skb_put_le32(skb, data[i].value); + } + + mutex_lock(&usb->mcu.mutex); + + usb->mcu.rp = data; + usb->mcu.rp_len = n; + usb->mcu.base = base; + usb->mcu.burst = false; + + ret = __mt76u_mcu_send_msg(dev, skb, CMD_RANDOM_READ, true); + + usb->mcu.rp = NULL; + + mutex_unlock(&usb->mcu.mutex); + + return ret; +} + void mt76u_mcu_fw_reset(struct mt76_dev *dev) { mt76u_vendor_request(dev, MT_VEND_DEV_MODE, From 6da5a2911634e68ae52a384e24cbdf8bb0b55fa4 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Sun, 9 Sep 2018 22:32:39 +0200 Subject: [PATCH 193/276] mt76: add rd_rp and wr_rp to bus_ops/mcu_ops Add callbacks for reading and writing reg pairs tables. Signed-off-by: Stanislaw Gruszka Signed-off-by: Lorenzo Bianconi Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt76.h | 20 +++++++++++++++----- drivers/net/wireless/mediatek/mt76/usb.c | 2 ++ drivers/net/wireless/mediatek/mt76/usb_mcu.c | 2 ++ 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h index 3576418f696c..1d70be8dec32 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76.h +++ b/drivers/net/wireless/mediatek/mt76/mt76.h @@ -33,12 +33,21 @@ struct mt76_dev; struct mt76_wcid; +struct mt76_reg_pair { + u32 reg; + u32 value; +}; + struct mt76_bus_ops { u32 (*rr)(struct mt76_dev *dev, u32 offset); void (*wr)(struct mt76_dev *dev, u32 offset, u32 val); u32 (*rmw)(struct mt76_dev *dev, u32 offset, u32 mask, u32 val); void (*copy)(struct mt76_dev *dev, u32 offset, const void *data, int len); + int (*wr_rp)(struct mt76_dev *dev, u32 base, + const struct mt76_reg_pair *rp, int len); + int (*rd_rp)(struct mt76_dev *dev, u32 base, + struct mt76_reg_pair *rp, int len); }; enum mt76_txq_id { @@ -53,11 +62,6 @@ enum mt76_txq_id { __MT_TXQ_MAX }; -struct mt76_reg_pair { - u32 reg; - u32 value; -}; - enum mt76_rxq_id { MT_RXQ_MAIN, MT_RXQ_MCU, @@ -123,6 +127,10 @@ struct mt76_mcu_ops { struct sk_buff *(*mcu_msg_alloc)(const void *data, int len); int (*mcu_send_msg)(struct mt76_dev *dev, struct sk_buff *skb, int cmd, bool wait_resp); + int (*mcu_wr_rp)(struct mt76_dev *dev, u32 base, + const struct mt76_reg_pair *rp, int len); + int (*mcu_rd_rp)(struct mt76_dev *dev, u32 base, + struct mt76_reg_pair *rp, int len); }; struct mt76_queue_ops { @@ -442,6 +450,8 @@ struct mt76_rx_status { #define mt76_wr(dev, ...) (dev)->mt76.bus->wr(&((dev)->mt76), __VA_ARGS__) #define mt76_rmw(dev, ...) (dev)->mt76.bus->rmw(&((dev)->mt76), __VA_ARGS__) #define mt76_wr_copy(dev, ...) (dev)->mt76.bus->copy(&((dev)->mt76), __VA_ARGS__) +#define mt76_wr_rp(dev, ...) (dev)->mt76.bus->wr_rp(&((dev)->mt76), __VA_ARGS__) +#define mt76_rd_rp(dev, ...) (dev)->mt76.bus->rd_rp(&((dev)->mt76), __VA_ARGS__) #define mt76_mcu_msg_alloc(dev, ...) (dev)->mt76.mcu_ops->mcu_msg_alloc(__VA_ARGS__) #define mt76_mcu_send_msg(dev, ...) (dev)->mt76.mcu_ops->mcu_send_msg(&((dev)->mt76), __VA_ARGS__) diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c index cd4d48594aaf..fe36c4adbd38 100644 --- a/drivers/net/wireless/mediatek/mt76/usb.c +++ b/drivers/net/wireless/mediatek/mt76/usb.c @@ -876,6 +876,8 @@ int mt76u_init(struct mt76_dev *dev, .wr = mt76u_wr, .rmw = mt76u_rmw, .copy = mt76u_copy, + .wr_rp = mt76u_wr_rp, + .rd_rp = mt76u_rd_rp, }; struct mt76_usb *usb = &dev->usb; diff --git a/drivers/net/wireless/mediatek/mt76/usb_mcu.c b/drivers/net/wireless/mediatek/mt76/usb_mcu.c index 622d7d6da32e..7cbc02d8ec35 100644 --- a/drivers/net/wireless/mediatek/mt76/usb_mcu.c +++ b/drivers/net/wireless/mediatek/mt76/usb_mcu.c @@ -381,6 +381,8 @@ void mt76u_init_mcu_ops(struct mt76_dev *dev) static const struct mt76_mcu_ops mt76u_mcu_ops = { .mcu_msg_alloc = mt76u_mcu_msg_alloc, .mcu_send_msg = mt76u_mcu_send_msg, + .mcu_wr_rp = mt76u_mcu_wr_rp, + .mcu_rd_rp = mt76u_mcu_rd_rp, }; dev->mcu_ops = &mt76u_mcu_ops; From 1750715726c6663a0ee202adbe1badef741d8004 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Sun, 9 Sep 2018 22:32:40 +0200 Subject: [PATCH 194/276] mt76: usb: use common helpers for mcu_alloc_msg()/mcu_send_msg() Use mcu common helpers instead of usb specific routines. Add static qualifier to the following functions: - mt76u_mcu_msg_alloc - __mt76u_mcu_send_msg - mt76u_mcu_send_msg - mt76u_mcu_wr_rp - mt76u_mcu_rd_rp - mt76u_wr_rp - mt76u_rd_rp This is a preliminary patch to move mt76x02 usb mcu code in mt76x02-usb module Acked-by: Stanislaw Gruszka Signed-off-by: Lorenzo Bianconi Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt76.h | 13 ------ .../net/wireless/mediatek/mt76/mt76x0/init.c | 6 +-- .../net/wireless/mediatek/mt76/mt76x0/mcu.c | 13 +++--- .../net/wireless/mediatek/mt76/mt76x0/phy.c | 10 ++--- .../net/wireless/mediatek/mt76/mt76x2u_mcu.c | 40 +++++++++---------- drivers/net/wireless/mediatek/mt76/usb.c | 16 ++++---- drivers/net/wireless/mediatek/mt76/usb_mcu.c | 26 ++++++------ 7 files changed, 55 insertions(+), 69 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h index 1d70be8dec32..b7c63bfaf581 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76.h +++ b/drivers/net/wireless/mediatek/mt76/mt76.h @@ -655,19 +655,6 @@ int mt76u_skb_dma_info(struct sk_buff *skb, int port, u32 flags); int mt76u_mcu_fw_send_data(struct mt76_dev *dev, const void *data, int data_len, u32 max_payload, u32 offset); void mt76u_mcu_complete_urb(struct urb *urb); -struct sk_buff *mt76u_mcu_msg_alloc(const void *data, int len); -int __mt76u_mcu_send_msg(struct mt76_dev *dev, struct sk_buff *skb, - int cmd, bool wait_resp); -int mt76u_mcu_send_msg(struct mt76_dev *dev, struct sk_buff *skb, - int cmd, bool wait_resp); -int mt76u_mcu_wr_rp(struct mt76_dev *dev, u32 base, - const struct mt76_reg_pair *data, int n); -int mt76u_mcu_rd_rp(struct mt76_dev *dev, u32 base, - struct mt76_reg_pair *data, int n); -int mt76u_wr_rp(struct mt76_dev *dev, u32 base, - const struct mt76_reg_pair *data, int n); -int mt76u_rd_rp(struct mt76_dev *dev, u32 base, - struct mt76_reg_pair *data, int n); void mt76u_mcu_fw_reset(struct mt76_dev *dev); int mt76u_mcu_init_rx(struct mt76_dev *dev); void mt76u_mcu_deinit(struct mt76_dev *dev); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c index 007036e35063..a68161e1a2bf 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c @@ -154,9 +154,9 @@ static void mt76x0_init_usb_dma(struct mt76x0_dev *dev) mt76_wr(dev, MT_USB_DMA_CFG, val); } -#define RANDOM_WRITE(dev, tab) \ - mt76u_wr_rp(&(dev)->mt76, MT_MCU_MEMMAP_WLAN, \ - tab, ARRAY_SIZE(tab)) +#define RANDOM_WRITE(dev, tab) \ + mt76_wr_rp(dev, MT_MCU_MEMMAP_WLAN, \ + tab, ARRAY_SIZE(tab)) static int mt76x0_init_bbp(struct mt76x0_dev *dev) { diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c index b8f85668c447..17ec9189ac50 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c @@ -52,11 +52,10 @@ int mt76x0_mcu_function_select(struct mt76x0_dev *dev, .value = cpu_to_le32(val), }; - skb = mt76u_mcu_msg_alloc(&msg, sizeof(msg)); + skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg)); if (!skb) return -ENOMEM; - return mt76u_mcu_send_msg(&dev->mt76, skb, CMD_FUN_SET_OP, - func == 5); + return mt76_mcu_send_msg(dev, skb, CMD_FUN_SET_OP, func == 5); } int @@ -71,11 +70,10 @@ mt76x0_mcu_calibrate(struct mt76x0_dev *dev, enum mcu_calibrate cal, u32 val) .value = cpu_to_le32(val), }; - skb = mt76u_mcu_msg_alloc(&msg, sizeof(msg)); + skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg)); if (!skb) return -ENOMEM; - return mt76u_mcu_send_msg(&dev->mt76, skb, CMD_CALIBRATION_OP, - true); + return mt76_mcu_send_msg(dev, skb, CMD_CALIBRATION_OP, true); } int mt76x0_burst_write_regs(struct mt76x0_dev *dev, u32 offset, @@ -99,8 +97,7 @@ int mt76x0_burst_write_regs(struct mt76x0_dev *dev, u32 offset, for (i = 0; i < cnt; i++) skb_put_le32(skb, data[i]); - ret = mt76u_mcu_send_msg(&dev->mt76, skb, CMD_BURST_WRITE, - cnt == n); + ret = mt76_mcu_send_msg(dev, skb, CMD_BURST_WRITE, cnt == n); if (ret) return ret; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c index 27dd8388a6ae..0e9cf354cbec 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c @@ -117,7 +117,7 @@ rf_wr(struct mt76x0_dev *dev, u32 offset, u8 val) .value = val, }; - return mt76u_wr_rp(&dev->mt76, MT_MCU_MEMMAP_RF, &pair, 1); + return mt76_wr_rp(dev, MT_MCU_MEMMAP_RF, &pair, 1); } else { WARN_ON_ONCE(1); return mt76x0_rf_csr_wr(dev, offset, val); @@ -135,7 +135,7 @@ rf_rr(struct mt76x0_dev *dev, u32 offset) .reg = offset, }; - ret = mt76u_rd_rp(&dev->mt76, MT_MCU_MEMMAP_RF, &pair, 1); + ret = mt76_rd_rp(dev, MT_MCU_MEMMAP_RF, &pair, 1); val = pair.value; } else { WARN_ON_ONCE(1); @@ -175,9 +175,9 @@ rf_clear(struct mt76x0_dev *dev, u32 offset, u8 mask) } #endif -#define RF_RANDOM_WRITE(dev, tab) \ - mt76u_wr_rp(&(dev)->mt76, MT_MCU_MEMMAP_RF, \ - tab, ARRAY_SIZE(tab)) +#define RF_RANDOM_WRITE(dev, tab) \ + mt76_wr_rp(dev, MT_MCU_MEMMAP_RF, \ + tab, ARRAY_SIZE(tab)) int mt76x0_wait_bbp_ready(struct mt76x0_dev *dev) { diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2u_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x2u_mcu.c index a4302457cf5c..9d73bdc785b2 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2u_mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2u_mcu.c @@ -41,11 +41,11 @@ mt76x2u_mcu_function_select(struct mt76x2_dev *dev, enum mcu_function func, }; struct sk_buff *skb; - skb = mt76u_mcu_msg_alloc(&msg, sizeof(msg)); + skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg)); if (!skb) return -ENOMEM; - return mt76u_mcu_send_msg(&dev->mt76, skb, CMD_FUN_SET_OP, - func != Q_SELECT); + return mt76_mcu_send_msg(dev, skb, CMD_FUN_SET_OP, + func != Q_SELECT); } int mt76x2u_mcu_set_radio_state(struct mt76x2_dev *dev, bool val) @@ -59,11 +59,11 @@ int mt76x2u_mcu_set_radio_state(struct mt76x2_dev *dev, bool val) }; struct sk_buff *skb; - skb = mt76u_mcu_msg_alloc(&msg, sizeof(msg)); + skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg)); if (!skb) return -ENOMEM; - return mt76u_mcu_send_msg(&dev->mt76, skb, CMD_POWER_SAVING_OP, - false); + return mt76_mcu_send_msg(dev, skb, CMD_POWER_SAVING_OP, + false); } int mt76x2u_mcu_load_cr(struct mt76x2_dev *dev, u8 type, u8 temp_level, @@ -89,10 +89,10 @@ int mt76x2u_mcu_load_cr(struct mt76x2_dev *dev, u8 type, u8 temp_level, msg.cfg = cpu_to_le32(val); /* first set the channel without the extension channel info */ - skb = mt76u_mcu_msg_alloc(&msg, sizeof(msg)); + skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg)); if (!skb) return -ENOMEM; - return mt76u_mcu_send_msg(&dev->mt76, skb, CMD_LOAD_CR, true); + return mt76_mcu_send_msg(dev, skb, CMD_LOAD_CR, true); } int mt76x2u_mcu_set_channel(struct mt76x2_dev *dev, u8 channel, u8 bw, @@ -117,20 +117,20 @@ int mt76x2u_mcu_set_channel(struct mt76x2_dev *dev, u8 channel, u8 bw, struct sk_buff *skb; /* first set the channel without the extension channel info */ - skb = mt76u_mcu_msg_alloc(&msg, sizeof(msg)); + skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg)); if (!skb) return -ENOMEM; - mt76u_mcu_send_msg(&dev->mt76, skb, CMD_SWITCH_CHANNEL_OP, true); + mt76_mcu_send_msg(dev, skb, CMD_SWITCH_CHANNEL_OP, true); usleep_range(5000, 10000); msg.ext_chan = 0xe0 + bw_index; - skb = mt76u_mcu_msg_alloc(&msg, sizeof(msg)); + skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg)); if (!skb) return -ENOMEM; - return mt76u_mcu_send_msg(&dev->mt76, skb, CMD_SWITCH_CHANNEL_OP, true); + return mt76_mcu_send_msg(dev, skb, CMD_SWITCH_CHANNEL_OP, true); } int mt76x2u_mcu_calibrate(struct mt76x2_dev *dev, enum mcu_calibration type, @@ -145,10 +145,10 @@ int mt76x2u_mcu_calibrate(struct mt76x2_dev *dev, enum mcu_calibration type, }; struct sk_buff *skb; - skb = mt76u_mcu_msg_alloc(&msg, sizeof(msg)); + skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg)); if (!skb) return -ENOMEM; - return mt76u_mcu_send_msg(&dev->mt76, skb, CMD_CALIBRATION_OP, true); + return mt76_mcu_send_msg(dev, skb, CMD_CALIBRATION_OP, true); } int mt76x2u_mcu_init_gain(struct mt76x2_dev *dev, u8 channel, u32 gain, @@ -166,10 +166,10 @@ int mt76x2u_mcu_init_gain(struct mt76x2_dev *dev, u8 channel, u32 gain, if (force) msg.channel |= cpu_to_le32(BIT(31)); - skb = mt76u_mcu_msg_alloc(&msg, sizeof(msg)); + skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg)); if (!skb) return -ENOMEM; - return mt76u_mcu_send_msg(&dev->mt76, skb, CMD_INIT_GAIN_OP, true); + return mt76_mcu_send_msg(dev, skb, CMD_INIT_GAIN_OP, true); } int mt76x2u_mcu_set_dynamic_vga(struct mt76x2_dev *dev, u8 channel, bool ap, @@ -192,10 +192,10 @@ int mt76x2u_mcu_set_dynamic_vga(struct mt76x2_dev *dev, u8 channel, bool ap, val |= BIT(30); msg.channel = cpu_to_le32(val); - skb = mt76u_mcu_msg_alloc(&msg, sizeof(msg)); + skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg)); if (!skb) return -ENOMEM; - return mt76u_mcu_send_msg(&dev->mt76, skb, CMD_DYNC_VGA_OP, true); + return mt76_mcu_send_msg(dev, skb, CMD_DYNC_VGA_OP, true); } int mt76x2u_mcu_tssi_comp(struct mt76x2_dev *dev, @@ -210,10 +210,10 @@ int mt76x2u_mcu_tssi_comp(struct mt76x2_dev *dev, }; struct sk_buff *skb; - skb = mt76u_mcu_msg_alloc(&msg, sizeof(msg)); + skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg)); if (!skb) return -ENOMEM; - return mt76u_mcu_send_msg(&dev->mt76, skb, CMD_CALIBRATION_OP, true); + return mt76_mcu_send_msg(dev, skb, CMD_CALIBRATION_OP, true); } static void mt76x2u_mcu_load_ivb(struct mt76x2_dev *dev) diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c index fe36c4adbd38..981518dae48c 100644 --- a/drivers/net/wireless/mediatek/mt76/usb.c +++ b/drivers/net/wireless/mediatek/mt76/usb.c @@ -203,15 +203,15 @@ mt76u_req_wr_rp(struct mt76_dev *dev, u32 base, return 0; } -int mt76u_wr_rp(struct mt76_dev *dev, u32 base, - const struct mt76_reg_pair *data, int n) +static int +mt76u_wr_rp(struct mt76_dev *dev, u32 base, + const struct mt76_reg_pair *data, int n) { if (test_bit(MT76_STATE_MCU_RUNNING, &dev->state)) - return mt76u_mcu_wr_rp(dev, base, data, n); + return dev->mcu_ops->mcu_wr_rp(dev, base, data, n); else return mt76u_req_wr_rp(dev, base, data, n); } -EXPORT_SYMBOL_GPL(mt76u_wr_rp); static int mt76u_req_rd_rp(struct mt76_dev *dev, u32 base, struct mt76_reg_pair *data, @@ -230,15 +230,15 @@ mt76u_req_rd_rp(struct mt76_dev *dev, u32 base, struct mt76_reg_pair *data, return 0; } -int mt76u_rd_rp(struct mt76_dev *dev, u32 base, - struct mt76_reg_pair *data, int n) +static int +mt76u_rd_rp(struct mt76_dev *dev, u32 base, + struct mt76_reg_pair *data, int n) { if (test_bit(MT76_STATE_MCU_RUNNING, &dev->state)) - return mt76u_mcu_rd_rp(dev, base, data, n); + return dev->mcu_ops->mcu_rd_rp(dev, base, data, n); else return mt76u_req_rd_rp(dev, base, data, n); } -EXPORT_SYMBOL_GPL(mt76u_rd_rp); static int mt76u_set_endpoints(struct usb_interface *intf, diff --git a/drivers/net/wireless/mediatek/mt76/usb_mcu.c b/drivers/net/wireless/mediatek/mt76/usb_mcu.c index 7cbc02d8ec35..362a6de73fc1 100644 --- a/drivers/net/wireless/mediatek/mt76/usb_mcu.c +++ b/drivers/net/wireless/mediatek/mt76/usb_mcu.c @@ -28,7 +28,8 @@ #define MT_INBAND_PACKET_MAX_LEN 192 -struct sk_buff *mt76u_mcu_msg_alloc(const void *data, int len) +static struct sk_buff * +mt76u_mcu_msg_alloc(const void *data, int len) { struct sk_buff *skb; @@ -41,7 +42,6 @@ struct sk_buff *mt76u_mcu_msg_alloc(const void *data, int len) return skb; } -EXPORT_SYMBOL_GPL(mt76u_mcu_msg_alloc); void mt76u_mcu_complete_urb(struct urb *urb) { @@ -125,8 +125,9 @@ static int mt76u_mcu_wait_resp(struct mt76_dev *dev, u8 seq) return -ETIMEDOUT; } -int __mt76u_mcu_send_msg(struct mt76_dev *dev, struct sk_buff *skb, - int cmd, bool wait_resp) +static int +__mt76u_mcu_send_msg(struct mt76_dev *dev, struct sk_buff *skb, + int cmd, bool wait_resp) { struct usb_interface *intf = to_usb_interface(dev->dev); struct usb_device *udev = interface_to_usbdev(intf); @@ -164,10 +165,10 @@ int __mt76u_mcu_send_msg(struct mt76_dev *dev, struct sk_buff *skb, return ret; } -EXPORT_SYMBOL_GPL(__mt76u_mcu_send_msg); -int mt76u_mcu_send_msg(struct mt76_dev *dev, struct sk_buff *skb, - int cmd, bool wait_resp) +static int +mt76u_mcu_send_msg(struct mt76_dev *dev, struct sk_buff *skb, + int cmd, bool wait_resp) { struct mt76_usb *usb = &dev->usb; int err; @@ -178,15 +179,15 @@ int mt76u_mcu_send_msg(struct mt76_dev *dev, struct sk_buff *skb, return err; } -EXPORT_SYMBOL_GPL(mt76u_mcu_send_msg); static inline void skb_put_le32(struct sk_buff *skb, u32 val) { put_unaligned_le32(val, skb_put(skb, 4)); } -int mt76u_mcu_wr_rp(struct mt76_dev *dev, u32 base, - const struct mt76_reg_pair *data, int n) +static int +mt76u_mcu_wr_rp(struct mt76_dev *dev, u32 base, + const struct mt76_reg_pair *data, int n) { const int CMD_RANDOM_WRITE = 12; const int max_vals_per_cmd = MT_INBAND_PACKET_MAX_LEN / 8; @@ -215,8 +216,9 @@ int mt76u_mcu_wr_rp(struct mt76_dev *dev, u32 base, return mt76u_mcu_wr_rp(dev, base, data + cnt, n - cnt); } -int mt76u_mcu_rd_rp(struct mt76_dev *dev, u32 base, - struct mt76_reg_pair *data, int n) +static int +mt76u_mcu_rd_rp(struct mt76_dev *dev, u32 base, + struct mt76_reg_pair *data, int n) { const int CMD_RANDOM_READ = 10; const int max_vals_per_cmd = MT_INBAND_PACKET_MAX_LEN / 8; From 905db7470199a39d7a48643df0559ffee26b989e Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Sun, 9 Sep 2018 22:32:41 +0200 Subject: [PATCH 195/276] mt76: usb: move mt76x02 mcu code in mt76x02-usb module Introduce mt76x02_usb_mcu.c in order to contain mt76x02u mcu related code. Add mt76x02-usb module as a container for mt76x02 usb code. This is a preliminary patch to move MT_TXD_INFO, MT_MCU_MSG and MT_RX_FCE_INFO defs in mt76x02-lib module since other chipsets (e.g. mt7603) use different dma definitions Acked-by: Stanislaw Gruszka Signed-off-by: Lorenzo Bianconi Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/Kconfig | 8 +- drivers/net/wireless/mediatek/mt76/Makefile | 3 + drivers/net/wireless/mediatek/mt76/mt76.h | 4 - .../net/wireless/mediatek/mt76/mt76x0/mcu.c | 15 +- .../net/wireless/mediatek/mt76/mt76x0/usb.c | 2 + .../net/wireless/mediatek/mt76/mt76x02_usb.h | 27 ++ .../wireless/mediatek/mt76/mt76x02_usb_mcu.c | 358 ++++++++++++++++++ .../net/wireless/mediatek/mt76/mt76x2_usb.c | 2 + .../net/wireless/mediatek/mt76/mt76x2u_mcu.c | 27 +- drivers/net/wireless/mediatek/mt76/usb.c | 3 +- drivers/net/wireless/mediatek/mt76/usb_mcu.c | 335 ---------------- 11 files changed, 422 insertions(+), 362 deletions(-) create mode 100644 drivers/net/wireless/mediatek/mt76/mt76x02_usb.h create mode 100644 drivers/net/wireless/mediatek/mt76/mt76x02_usb_mcu.c diff --git a/drivers/net/wireless/mediatek/mt76/Kconfig b/drivers/net/wireless/mediatek/mt76/Kconfig index e460a3a5e763..7f24aad94efd 100644 --- a/drivers/net/wireless/mediatek/mt76/Kconfig +++ b/drivers/net/wireless/mediatek/mt76/Kconfig @@ -9,6 +9,10 @@ config MT76x02_LIB tristate select MT76_CORE +config MT76x02_USB + tristate + select MT76_USB + config MT76x0_COMMON tristate select MT76x02_LIB @@ -20,7 +24,7 @@ config MT76x2_COMMON config MT76x0U tristate "MediaTek MT76x0U (USB) support" select MT76x0_COMMON - select MT76_USB + select MT76x02_USB depends on MAC80211 depends on USB help @@ -45,7 +49,7 @@ config MT76x2E config MT76x2U tristate "MediaTek MT76x2U (USB) support" select MT76x2_COMMON - select MT76_USB + select MT76x02_USB depends on MAC80211 depends on USB help diff --git a/drivers/net/wireless/mediatek/mt76/Makefile b/drivers/net/wireless/mediatek/mt76/Makefile index 129ac71446d6..64a32b4bb127 100644 --- a/drivers/net/wireless/mediatek/mt76/Makefile +++ b/drivers/net/wireless/mediatek/mt76/Makefile @@ -2,6 +2,7 @@ obj-$(CONFIG_MT76_CORE) += mt76.o obj-$(CONFIG_MT76_USB) += mt76-usb.o obj-$(CONFIG_MT76x0_COMMON) += mt76x0/ obj-$(CONFIG_MT76x02_LIB) += mt76x02-lib.o +obj-$(CONFIG_MT76x02_USB) += mt76x02-usb.o obj-$(CONFIG_MT76x2_COMMON) += mt76x2-common.o obj-$(CONFIG_MT76x2E) += mt76x2e.o obj-$(CONFIG_MT76x2U) += mt76x2u.o @@ -16,6 +17,8 @@ CFLAGS_usb_trace.o := -I$(src) mt76x02-lib-y := mt76x02_util.o mt76x02_mac.o +mt76x02-usb-y := mt76x02_usb_mcu.o + mt76x2-common-y := \ mt76x2_eeprom.o mt76x2_tx_common.o mt76x2_mac_common.o \ mt76x2_init_common.o mt76x2_common.o mt76x2_phy_common.o \ diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h index b7c63bfaf581..2a84ddc338af 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76.h +++ b/drivers/net/wireless/mediatek/mt76/mt76.h @@ -652,12 +652,8 @@ void mt76u_stop_stat_wk(struct mt76_dev *dev); void mt76u_queues_deinit(struct mt76_dev *dev); int mt76u_skb_dma_info(struct sk_buff *skb, int port, u32 flags); -int mt76u_mcu_fw_send_data(struct mt76_dev *dev, const void *data, - int data_len, u32 max_payload, u32 offset); void mt76u_mcu_complete_urb(struct urb *urb); -void mt76u_mcu_fw_reset(struct mt76_dev *dev); int mt76u_mcu_init_rx(struct mt76_dev *dev); void mt76u_mcu_deinit(struct mt76_dev *dev); -void mt76u_init_mcu_ops(struct mt76_dev *dev); #endif diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c index 17ec9189ac50..7baa9a45bd84 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c @@ -25,6 +25,7 @@ #include "mcu.h" #include "usb.h" #include "trace.h" +#include "../mt76x02_usb.h" #define MCU_FW_URB_MAX_PAYLOAD 0x38f8 #define MCU_FW_URB_SIZE (MCU_FW_URB_MAX_PAYLOAD + 12) @@ -177,17 +178,17 @@ mt76x0_upload_firmware(struct mt76x0_dev *dev, const struct mt76_fw *fw) ilm_len = le32_to_cpu(fw->hdr.ilm_len) - sizeof(fw->ivb); dev_dbg(dev->mt76.dev, "loading FW - ILM %u + IVB %zu\n", ilm_len, sizeof(fw->ivb)); - ret = mt76u_mcu_fw_send_data(&dev->mt76, fw->ilm, ilm_len, - MCU_FW_URB_MAX_PAYLOAD, - sizeof(fw->ivb)); + ret = mt76x02u_mcu_fw_send_data(&dev->mt76, fw->ilm, ilm_len, + MCU_FW_URB_MAX_PAYLOAD, + sizeof(fw->ivb)); if (ret) goto error; dlm_len = le32_to_cpu(fw->hdr.dlm_len); dev_dbg(dev->mt76.dev, "loading FW - DLM %u\n", dlm_len); - ret = mt76u_mcu_fw_send_data(&dev->mt76, fw->ilm + ilm_len, - dlm_len, MCU_FW_URB_MAX_PAYLOAD, - MT_MCU_DLM_OFFSET); + ret = mt76x02u_mcu_fw_send_data(&dev->mt76, fw->ilm + ilm_len, + dlm_len, MCU_FW_URB_MAX_PAYLOAD, + MT_MCU_DLM_OFFSET); if (ret) goto error; @@ -257,7 +258,7 @@ static int mt76x0_load_firmware(struct mt76x0_dev *dev) mt76_set(dev, MT_USB_DMA_CFG, (MT_USB_DMA_CFG_RX_BULK_EN | MT_USB_DMA_CFG_TX_BULK_EN) | FIELD_PREP(MT_USB_DMA_CFG_RX_BULK_AGG_TOUT, 0x20)); - mt76u_mcu_fw_reset(&dev->mt76); + mt76x02u_mcu_fw_reset(&dev->mt76); msleep(5); /* mt76x0_rmw(dev, MT_PBF_CFG, 0, (MT_PBF_CFG_TX0Q_EN | diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c index 89e856745fec..2f05f7383117 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c @@ -19,6 +19,7 @@ #include "usb.h" #include "trace.h" #include "../mt76x02_util.h" +#include "../mt76x02_usb.h" static struct usb_device_id mt76x0_device_table[] = { { USB_DEVICE(0x148F, 0x7610) }, /* MT7610U */ @@ -70,6 +71,7 @@ static int mt76x0u_probe(struct usb_interface *usb_intf, usb_set_intfdata(usb_intf, dev); + mt76x02u_init_mcu(&dev->mt76); ret = mt76u_init(&dev->mt76, usb_intf); if (ret) goto err; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_usb.h b/drivers/net/wireless/mediatek/mt76/mt76x02_usb.h new file mode 100644 index 000000000000..798354be54ec --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_usb.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2018 Lorenzo Bianconi + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef __MT76x02_USB_H +#define __MT76x0x_USB_H + +#include "mt76.h" + +void mt76x02u_init_mcu(struct mt76_dev *dev); +void mt76x02u_mcu_fw_reset(struct mt76_dev *dev); +int mt76x02u_mcu_fw_send_data(struct mt76_dev *dev, const void *data, + int data_len, u32 max_payload, u32 offset); + +#endif /* __MT76x02_USB_H */ diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_mcu.c new file mode 100644 index 000000000000..3072be3e0dde --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_mcu.c @@ -0,0 +1,358 @@ +/* + * Copyright (C) 2018 Lorenzo Bianconi + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include "mt76.h" +#include "dma.h" +#include "mt76x02_mcu.h" + +#define MT_CMD_HDR_LEN 4 + +#define MT_FCE_DMA_ADDR 0x0230 +#define MT_FCE_DMA_LEN 0x0234 + +#define MT_TX_CPU_FROM_FCE_CPU_DESC_IDX 0x09a8 + +static struct sk_buff * +mt76x02u_mcu_msg_alloc(const void *data, int len) +{ + struct sk_buff *skb; + + skb = alloc_skb(MT_CMD_HDR_LEN + len + 8, GFP_KERNEL); + if (!skb) + return NULL; + + skb_reserve(skb, MT_CMD_HDR_LEN); + skb_put_data(skb, data, len); + + return skb; +} + +static void +mt76x02u_multiple_mcu_reads(struct mt76_dev *dev, u8 *data, int len) +{ + struct mt76_usb *usb = &dev->usb; + u32 reg, val; + int i; + + if (usb->mcu.burst) { + WARN_ON_ONCE(len / 4 != usb->mcu.rp_len); + + reg = usb->mcu.rp[0].reg - usb->mcu.base; + for (i = 0; i < usb->mcu.rp_len; i++) { + val = get_unaligned_le32(data + 4 * i); + usb->mcu.rp[i].reg = reg++; + usb->mcu.rp[i].value = val; + } + } else { + WARN_ON_ONCE(len / 8 != usb->mcu.rp_len); + + for (i = 0; i < usb->mcu.rp_len; i++) { + reg = get_unaligned_le32(data + 8 * i) - + usb->mcu.base; + val = get_unaligned_le32(data + 8 * i + 4); + + WARN_ON_ONCE(usb->mcu.rp[i].reg != reg); + usb->mcu.rp[i].value = val; + } + } +} + +static int mt76x02u_mcu_wait_resp(struct mt76_dev *dev, u8 seq) +{ + struct mt76_usb *usb = &dev->usb; + struct mt76u_buf *buf = &usb->mcu.res; + struct urb *urb = buf->urb; + int i, ret; + u32 rxfce; + u8 *data; + + for (i = 0; i < 5; i++) { + if (!wait_for_completion_timeout(&usb->mcu.cmpl, + msecs_to_jiffies(300))) + continue; + + if (urb->status) + return -EIO; + + data = sg_virt(&urb->sg[0]); + if (usb->mcu.rp) + mt76x02u_multiple_mcu_reads(dev, data + 4, + urb->actual_length - 8); + + rxfce = get_unaligned_le32(data); + ret = mt76u_submit_buf(dev, USB_DIR_IN, + MT_EP_IN_CMD_RESP, + buf, GFP_KERNEL, + mt76u_mcu_complete_urb, + &usb->mcu.cmpl); + if (ret) + return ret; + + if (seq == FIELD_GET(MT_RX_FCE_INFO_CMD_SEQ, rxfce) && + FIELD_GET(MT_RX_FCE_INFO_EVT_TYPE, rxfce) == EVT_CMD_DONE) + return 0; + + dev_err(dev->dev, "error: MCU resp evt:%lx seq:%hhx-%lx\n", + FIELD_GET(MT_RX_FCE_INFO_EVT_TYPE, rxfce), + seq, FIELD_GET(MT_RX_FCE_INFO_CMD_SEQ, rxfce)); + } + + dev_err(dev->dev, "error: %s timed out\n", __func__); + return -ETIMEDOUT; +} + +static int +__mt76x02u_mcu_send_msg(struct mt76_dev *dev, struct sk_buff *skb, + int cmd, bool wait_resp) +{ + struct usb_interface *intf = to_usb_interface(dev->dev); + struct usb_device *udev = interface_to_usbdev(intf); + struct mt76_usb *usb = &dev->usb; + unsigned int pipe; + int ret, sent; + u8 seq = 0; + u32 info; + + if (!skb) + return -EINVAL; + + if (test_bit(MT76_REMOVED, &dev->state)) + return 0; + + pipe = usb_sndbulkpipe(udev, usb->out_ep[MT_EP_OUT_INBAND_CMD]); + if (wait_resp) { + seq = ++usb->mcu.msg_seq & 0xf; + if (!seq) + seq = ++usb->mcu.msg_seq & 0xf; + } + + info = FIELD_PREP(MT_MCU_MSG_CMD_SEQ, seq) | + FIELD_PREP(MT_MCU_MSG_CMD_TYPE, cmd) | + MT_MCU_MSG_TYPE_CMD; + ret = mt76u_skb_dma_info(skb, CPU_TX_PORT, info); + if (ret) + return ret; + + ret = usb_bulk_msg(udev, pipe, skb->data, skb->len, &sent, 500); + if (ret) + return ret; + + if (wait_resp) + ret = mt76x02u_mcu_wait_resp(dev, seq); + + consume_skb(skb); + + return ret; +} + +static int +mt76x02u_mcu_send_msg(struct mt76_dev *dev, struct sk_buff *skb, + int cmd, bool wait_resp) +{ + struct mt76_usb *usb = &dev->usb; + int err; + + mutex_lock(&usb->mcu.mutex); + err = __mt76x02u_mcu_send_msg(dev, skb, cmd, wait_resp); + mutex_unlock(&usb->mcu.mutex); + + return err; +} + +static inline void skb_put_le32(struct sk_buff *skb, u32 val) +{ + put_unaligned_le32(val, skb_put(skb, 4)); +} + +static int +mt76x02u_mcu_wr_rp(struct mt76_dev *dev, u32 base, + const struct mt76_reg_pair *data, int n) +{ + const int CMD_RANDOM_WRITE = 12; + const int max_vals_per_cmd = MT_INBAND_PACKET_MAX_LEN / 8; + struct sk_buff *skb; + int cnt, i, ret; + + if (!n) + return 0; + + cnt = min(max_vals_per_cmd, n); + + skb = alloc_skb(cnt * 8 + MT_DMA_HDR_LEN + 4, GFP_KERNEL); + if (!skb) + return -ENOMEM; + skb_reserve(skb, MT_DMA_HDR_LEN); + + for (i = 0; i < cnt; i++) { + skb_put_le32(skb, base + data[i].reg); + skb_put_le32(skb, data[i].value); + } + + ret = mt76x02u_mcu_send_msg(dev, skb, CMD_RANDOM_WRITE, cnt == n); + if (ret) + return ret; + + return mt76x02u_mcu_wr_rp(dev, base, data + cnt, n - cnt); +} + +static int +mt76x02u_mcu_rd_rp(struct mt76_dev *dev, u32 base, + struct mt76_reg_pair *data, int n) +{ + const int CMD_RANDOM_READ = 10; + const int max_vals_per_cmd = MT_INBAND_PACKET_MAX_LEN / 8; + struct mt76_usb *usb = &dev->usb; + struct sk_buff *skb; + int cnt, i, ret; + + if (!n) + return 0; + + cnt = min(max_vals_per_cmd, n); + if (cnt != n) + return -EINVAL; + + skb = alloc_skb(cnt * 8 + MT_DMA_HDR_LEN + 4, GFP_KERNEL); + if (!skb) + return -ENOMEM; + skb_reserve(skb, MT_DMA_HDR_LEN); + + for (i = 0; i < cnt; i++) { + skb_put_le32(skb, base + data[i].reg); + skb_put_le32(skb, data[i].value); + } + + mutex_lock(&usb->mcu.mutex); + + usb->mcu.rp = data; + usb->mcu.rp_len = n; + usb->mcu.base = base; + usb->mcu.burst = false; + + ret = __mt76x02u_mcu_send_msg(dev, skb, CMD_RANDOM_READ, true); + + usb->mcu.rp = NULL; + + mutex_unlock(&usb->mcu.mutex); + + return ret; +} + +void mt76x02u_mcu_fw_reset(struct mt76_dev *dev) +{ + mt76u_vendor_request(dev, MT_VEND_DEV_MODE, + USB_DIR_OUT | USB_TYPE_VENDOR, + 0x1, 0, NULL, 0); +} +EXPORT_SYMBOL_GPL(mt76x02u_mcu_fw_reset); + +static int +__mt76x02u_mcu_fw_send_data(struct mt76_dev *dev, struct mt76u_buf *buf, + const void *fw_data, int len, u32 dst_addr) +{ + u8 *data = sg_virt(&buf->urb->sg[0]); + DECLARE_COMPLETION_ONSTACK(cmpl); + __le32 info; + u32 val; + int err; + + info = cpu_to_le32(FIELD_PREP(MT_MCU_MSG_PORT, CPU_TX_PORT) | + FIELD_PREP(MT_MCU_MSG_LEN, len) | + MT_MCU_MSG_TYPE_CMD); + + memcpy(data, &info, sizeof(info)); + memcpy(data + sizeof(info), fw_data, len); + memset(data + sizeof(info) + len, 0, 4); + + mt76u_single_wr(dev, MT_VEND_WRITE_FCE, + MT_FCE_DMA_ADDR, dst_addr); + len = roundup(len, 4); + mt76u_single_wr(dev, MT_VEND_WRITE_FCE, + MT_FCE_DMA_LEN, len << 16); + + buf->len = MT_CMD_HDR_LEN + len + sizeof(info); + err = mt76u_submit_buf(dev, USB_DIR_OUT, + MT_EP_OUT_INBAND_CMD, + buf, GFP_KERNEL, + mt76u_mcu_complete_urb, &cmpl); + if (err < 0) + return err; + + if (!wait_for_completion_timeout(&cmpl, + msecs_to_jiffies(1000))) { + dev_err(dev->dev, "firmware upload timed out\n"); + usb_kill_urb(buf->urb); + return -ETIMEDOUT; + } + + if (mt76u_urb_error(buf->urb)) { + dev_err(dev->dev, "firmware upload failed: %d\n", + buf->urb->status); + return buf->urb->status; + } + + val = mt76u_rr(dev, MT_TX_CPU_FROM_FCE_CPU_DESC_IDX); + val++; + mt76u_wr(dev, MT_TX_CPU_FROM_FCE_CPU_DESC_IDX, val); + + return 0; +} + +int mt76x02u_mcu_fw_send_data(struct mt76_dev *dev, const void *data, + int data_len, u32 max_payload, u32 offset) +{ + int err, len, pos = 0, max_len = max_payload - 8; + struct mt76u_buf buf; + + err = mt76u_buf_alloc(dev, &buf, 1, max_payload, max_payload, + GFP_KERNEL); + if (err < 0) + return err; + + while (data_len > 0) { + len = min_t(int, data_len, max_len); + err = __mt76x02u_mcu_fw_send_data(dev, &buf, data + pos, + len, offset + pos); + if (err < 0) + break; + + data_len -= len; + pos += len; + usleep_range(5000, 10000); + } + mt76u_buf_free(&buf); + + return err; +} +EXPORT_SYMBOL_GPL(mt76x02u_mcu_fw_send_data); + +void mt76x02u_init_mcu(struct mt76_dev *dev) +{ + static const struct mt76_mcu_ops mt76x02u_mcu_ops = { + .mcu_msg_alloc = mt76x02u_mcu_msg_alloc, + .mcu_send_msg = mt76x02u_mcu_send_msg, + .mcu_wr_rp = mt76x02u_mcu_wr_rp, + .mcu_rd_rp = mt76x02u_mcu_rd_rp, + }; + + dev->mcu_ops = &mt76x02u_mcu_ops; +} +EXPORT_SYMBOL_GPL(mt76x02u_init_mcu); + +MODULE_AUTHOR("Lorenzo Bianconi "); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_usb.c b/drivers/net/wireless/mediatek/mt76/mt76x2_usb.c index 2a465c4e1009..feb5cec66c67 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_usb.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_usb.c @@ -17,6 +17,7 @@ #include #include +#include "mt76x02_usb.h" #include "mt76x2u.h" static const struct usb_device_id mt76x2u_device_table[] = { @@ -46,6 +47,7 @@ static int mt76x2u_probe(struct usb_interface *intf, udev = usb_get_dev(udev); usb_reset_device(udev); + mt76x02u_init_mcu(&dev->mt76); err = mt76u_init(&dev->mt76, intf); if (err < 0) goto err; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2u_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x2u_mcu.c index 9d73bdc785b2..09afb8c5d851 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2u_mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2u_mcu.c @@ -18,6 +18,7 @@ #include "mt76x2u.h" #include "mt76x2_eeprom.h" +#include "mt76x02_usb.h" #define MT_CMD_HDR_LEN 4 @@ -300,7 +301,7 @@ static int mt76x2u_mcu_load_rom_patch(struct mt76x2_dev *dev) mt76_wr(dev, MT_VEND_ADDR(CFG, MT_USB_U3DMA_CFG), val); /* vendor reset */ - mt76u_mcu_fw_reset(&dev->mt76); + mt76x02u_mcu_fw_reset(&dev->mt76); usleep_range(5000, 10000); /* enable FCE to send in-band cmd */ @@ -314,10 +315,10 @@ static int mt76x2u_mcu_load_rom_patch(struct mt76x2_dev *dev) /* FCE skip_fs_en */ mt76_wr(dev, MT_FCE_SKIP_FS, 0x3); - err = mt76u_mcu_fw_send_data(&dev->mt76, fw->data + sizeof(*hdr), - fw->size - sizeof(*hdr), - MCU_ROM_PATCH_MAX_PAYLOAD, - MT76U_MCU_ROM_PATCH_OFFSET); + err = mt76x02u_mcu_fw_send_data(&dev->mt76, fw->data + sizeof(*hdr), + fw->size - sizeof(*hdr), + MCU_ROM_PATCH_MAX_PAYLOAD, + MT76U_MCU_ROM_PATCH_OFFSET); if (err < 0) { err = -EIO; goto out; @@ -373,7 +374,7 @@ static int mt76x2u_mcu_load_firmware(struct mt76x2_dev *dev) dev_info(dev->mt76.dev, "Build Time: %.16s\n", hdr->build_time); /* vendor reset */ - mt76u_mcu_fw_reset(&dev->mt76); + mt76x02u_mcu_fw_reset(&dev->mt76); usleep_range(5000, 10000); /* enable USB_DMA_CFG */ @@ -393,9 +394,9 @@ static int mt76x2u_mcu_load_firmware(struct mt76x2_dev *dev) mt76_wr(dev, MT_FCE_SKIP_FS, 0x3); /* load ILM */ - err = mt76u_mcu_fw_send_data(&dev->mt76, fw->data + sizeof(*hdr), - ilm_len, MCU_FW_URB_MAX_PAYLOAD, - MT76U_MCU_ILM_OFFSET); + err = mt76x02u_mcu_fw_send_data(&dev->mt76, fw->data + sizeof(*hdr), + ilm_len, MCU_FW_URB_MAX_PAYLOAD, + MT76U_MCU_ILM_OFFSET); if (err < 0) { err = -EIO; goto out; @@ -404,10 +405,10 @@ static int mt76x2u_mcu_load_firmware(struct mt76x2_dev *dev) /* load DLM */ if (mt76xx_rev(dev) >= MT76XX_REV_E3) dlm_offset += 0x800; - err = mt76u_mcu_fw_send_data(&dev->mt76, - fw->data + sizeof(*hdr) + ilm_len, - dlm_len, MCU_FW_URB_MAX_PAYLOAD, - dlm_offset); + err = mt76x02u_mcu_fw_send_data(&dev->mt76, + fw->data + sizeof(*hdr) + ilm_len, + dlm_len, MCU_FW_URB_MAX_PAYLOAD, + dlm_offset); if (err < 0) { err = -EIO; goto out; diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c index 981518dae48c..bc56bd4850bc 100644 --- a/drivers/net/wireless/mediatek/mt76/usb.c +++ b/drivers/net/wireless/mediatek/mt76/usb.c @@ -109,6 +109,7 @@ u32 mt76u_rr(struct mt76_dev *dev, u32 addr) return ret; } +EXPORT_SYMBOL_GPL(mt76u_rr); /* should be called with usb_ctrl_mtx locked */ static void __mt76u_wr(struct mt76_dev *dev, u32 addr, u32 val) @@ -140,6 +141,7 @@ void mt76u_wr(struct mt76_dev *dev, u32 addr, u32 val) __mt76u_wr(dev, addr, val); mutex_unlock(&dev->usb.usb_ctrl_mtx); } +EXPORT_SYMBOL_GPL(mt76u_wr); static u32 mt76u_rmw(struct mt76_dev *dev, u32 addr, u32 mask, u32 val) @@ -892,7 +894,6 @@ int mt76u_init(struct mt76_dev *dev, mutex_init(&usb->usb_ctrl_mtx); dev->bus = &mt76u_ops; dev->queue_ops = &usb_queue_ops; - mt76u_init_mcu_ops(dev); return mt76u_set_endpoints(intf, usb); } diff --git a/drivers/net/wireless/mediatek/mt76/usb_mcu.c b/drivers/net/wireless/mediatek/mt76/usb_mcu.c index 362a6de73fc1..036be4163e69 100644 --- a/drivers/net/wireless/mediatek/mt76/usb_mcu.c +++ b/drivers/net/wireless/mediatek/mt76/usb_mcu.c @@ -14,34 +14,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include - #include "mt76.h" -#include "dma.h" - -#define MT_CMD_HDR_LEN 4 - -#define MT_FCE_DMA_ADDR 0x0230 -#define MT_FCE_DMA_LEN 0x0234 - -#define MT_TX_CPU_FROM_FCE_CPU_DESC_IDX 0x09a8 - -#define MT_INBAND_PACKET_MAX_LEN 192 - -static struct sk_buff * -mt76u_mcu_msg_alloc(const void *data, int len) -{ - struct sk_buff *skb; - - skb = alloc_skb(MT_CMD_HDR_LEN + len + 8, GFP_KERNEL); - if (!skb) - return NULL; - - skb_reserve(skb, MT_CMD_HDR_LEN); - skb_put_data(skb, data, len); - - return skb; -} void mt76u_mcu_complete_urb(struct urb *urb) { @@ -51,302 +24,6 @@ void mt76u_mcu_complete_urb(struct urb *urb) } EXPORT_SYMBOL_GPL(mt76u_mcu_complete_urb); -static void -mt76u_multiple_mcu_reads(struct mt76_dev *dev, u8 *data, - int len) -{ - struct mt76_usb *usb = &dev->usb; - u32 reg, val; - int i; - - if (usb->mcu.burst) { - WARN_ON_ONCE(len / 4 != usb->mcu.rp_len); - - reg = usb->mcu.rp[0].reg - usb->mcu.base; - for (i = 0; i < usb->mcu.rp_len; i++) { - val = get_unaligned_le32(data + 4 * i); - usb->mcu.rp[i].reg = reg++; - usb->mcu.rp[i].value = val; - } - } else { - WARN_ON_ONCE(len / 8 != usb->mcu.rp_len); - - for (i = 0; i < usb->mcu.rp_len; i++) { - reg = get_unaligned_le32(data + 8 * i) - - usb->mcu.base; - val = get_unaligned_le32(data + 8 * i + 4); - - WARN_ON_ONCE(usb->mcu.rp[i].reg != reg); - usb->mcu.rp[i].value = val; - } - } -} - -static int mt76u_mcu_wait_resp(struct mt76_dev *dev, u8 seq) -{ - struct mt76_usb *usb = &dev->usb; - struct mt76u_buf *buf = &usb->mcu.res; - int i, ret; - u32 rxfce; - u8 *data; - - for (i = 0; i < 5; i++) { - if (!wait_for_completion_timeout(&usb->mcu.cmpl, - msecs_to_jiffies(300))) - continue; - - if (buf->urb->status) - return -EIO; - - data = sg_virt(&buf->urb->sg[0]); - if (usb->mcu.rp) - mt76u_multiple_mcu_reads(dev, data + 4, - buf->urb->actual_length - 8); - - rxfce = get_unaligned_le32(data); - ret = mt76u_submit_buf(dev, USB_DIR_IN, - MT_EP_IN_CMD_RESP, - buf, GFP_KERNEL, - mt76u_mcu_complete_urb, - &usb->mcu.cmpl); - if (ret) - return ret; - - if (seq == FIELD_GET(MT_RX_FCE_INFO_CMD_SEQ, rxfce) && - FIELD_GET(MT_RX_FCE_INFO_EVT_TYPE, rxfce) == EVT_CMD_DONE) - return 0; - - dev_err(dev->dev, "error: MCU resp evt:%lx seq:%hhx-%lx\n", - FIELD_GET(MT_RX_FCE_INFO_EVT_TYPE, rxfce), - seq, FIELD_GET(MT_RX_FCE_INFO_CMD_SEQ, rxfce)); - } - - dev_err(dev->dev, "error: %s timed out\n", __func__); - return -ETIMEDOUT; -} - -static int -__mt76u_mcu_send_msg(struct mt76_dev *dev, struct sk_buff *skb, - int cmd, bool wait_resp) -{ - struct usb_interface *intf = to_usb_interface(dev->dev); - struct usb_device *udev = interface_to_usbdev(intf); - struct mt76_usb *usb = &dev->usb; - unsigned int pipe; - int ret, sent; - u8 seq = 0; - u32 info; - - if (test_bit(MT76_REMOVED, &dev->state)) - return 0; - - pipe = usb_sndbulkpipe(udev, usb->out_ep[MT_EP_OUT_INBAND_CMD]); - if (wait_resp) { - seq = ++usb->mcu.msg_seq & 0xf; - if (!seq) - seq = ++usb->mcu.msg_seq & 0xf; - } - - info = FIELD_PREP(MT_MCU_MSG_CMD_SEQ, seq) | - FIELD_PREP(MT_MCU_MSG_CMD_TYPE, cmd) | - MT_MCU_MSG_TYPE_CMD; - ret = mt76u_skb_dma_info(skb, CPU_TX_PORT, info); - if (ret) - return ret; - - ret = usb_bulk_msg(udev, pipe, skb->data, skb->len, &sent, 500); - if (ret) - return ret; - - if (wait_resp) - ret = mt76u_mcu_wait_resp(dev, seq); - - consume_skb(skb); - - return ret; -} - -static int -mt76u_mcu_send_msg(struct mt76_dev *dev, struct sk_buff *skb, - int cmd, bool wait_resp) -{ - struct mt76_usb *usb = &dev->usb; - int err; - - mutex_lock(&usb->mcu.mutex); - err = __mt76u_mcu_send_msg(dev, skb, cmd, wait_resp); - mutex_unlock(&usb->mcu.mutex); - - return err; -} - -static inline void skb_put_le32(struct sk_buff *skb, u32 val) -{ - put_unaligned_le32(val, skb_put(skb, 4)); -} - -static int -mt76u_mcu_wr_rp(struct mt76_dev *dev, u32 base, - const struct mt76_reg_pair *data, int n) -{ - const int CMD_RANDOM_WRITE = 12; - const int max_vals_per_cmd = MT_INBAND_PACKET_MAX_LEN / 8; - struct sk_buff *skb; - int cnt, i, ret; - - if (!n) - return 0; - - cnt = min(max_vals_per_cmd, n); - - skb = alloc_skb(cnt * 8 + MT_DMA_HDR_LEN + 4, GFP_KERNEL); - if (!skb) - return -ENOMEM; - skb_reserve(skb, MT_DMA_HDR_LEN); - - for (i = 0; i < cnt; i++) { - skb_put_le32(skb, base + data[i].reg); - skb_put_le32(skb, data[i].value); - } - - ret = mt76u_mcu_send_msg(dev, skb, CMD_RANDOM_WRITE, cnt == n); - if (ret) - return ret; - - return mt76u_mcu_wr_rp(dev, base, data + cnt, n - cnt); -} - -static int -mt76u_mcu_rd_rp(struct mt76_dev *dev, u32 base, - struct mt76_reg_pair *data, int n) -{ - const int CMD_RANDOM_READ = 10; - const int max_vals_per_cmd = MT_INBAND_PACKET_MAX_LEN / 8; - struct mt76_usb *usb = &dev->usb; - struct sk_buff *skb; - int cnt, i, ret; - - if (!n) - return 0; - - cnt = min(max_vals_per_cmd, n); - if (cnt != n) - return -EINVAL; - - skb = alloc_skb(cnt * 8 + MT_DMA_HDR_LEN + 4, GFP_KERNEL); - if (!skb) - return -ENOMEM; - skb_reserve(skb, MT_DMA_HDR_LEN); - - for (i = 0; i < cnt; i++) { - skb_put_le32(skb, base + data[i].reg); - skb_put_le32(skb, data[i].value); - } - - mutex_lock(&usb->mcu.mutex); - - usb->mcu.rp = data; - usb->mcu.rp_len = n; - usb->mcu.base = base; - usb->mcu.burst = false; - - ret = __mt76u_mcu_send_msg(dev, skb, CMD_RANDOM_READ, true); - - usb->mcu.rp = NULL; - - mutex_unlock(&usb->mcu.mutex); - - return ret; -} - -void mt76u_mcu_fw_reset(struct mt76_dev *dev) -{ - mt76u_vendor_request(dev, MT_VEND_DEV_MODE, - USB_DIR_OUT | USB_TYPE_VENDOR, - 0x1, 0, NULL, 0); -} -EXPORT_SYMBOL_GPL(mt76u_mcu_fw_reset); - -static int -__mt76u_mcu_fw_send_data(struct mt76_dev *dev, struct mt76u_buf *buf, - const void *fw_data, int len, u32 dst_addr) -{ - u8 *data = sg_virt(&buf->urb->sg[0]); - DECLARE_COMPLETION_ONSTACK(cmpl); - __le32 info; - u32 val; - int err; - - info = cpu_to_le32(FIELD_PREP(MT_MCU_MSG_PORT, CPU_TX_PORT) | - FIELD_PREP(MT_MCU_MSG_LEN, len) | - MT_MCU_MSG_TYPE_CMD); - - memcpy(data, &info, sizeof(info)); - memcpy(data + sizeof(info), fw_data, len); - memset(data + sizeof(info) + len, 0, 4); - - mt76u_single_wr(dev, MT_VEND_WRITE_FCE, - MT_FCE_DMA_ADDR, dst_addr); - len = roundup(len, 4); - mt76u_single_wr(dev, MT_VEND_WRITE_FCE, - MT_FCE_DMA_LEN, len << 16); - - buf->len = MT_CMD_HDR_LEN + len + sizeof(info); - err = mt76u_submit_buf(dev, USB_DIR_OUT, - MT_EP_OUT_INBAND_CMD, - buf, GFP_KERNEL, - mt76u_mcu_complete_urb, &cmpl); - if (err < 0) - return err; - - if (!wait_for_completion_timeout(&cmpl, - msecs_to_jiffies(1000))) { - dev_err(dev->dev, "firmware upload timed out\n"); - usb_kill_urb(buf->urb); - return -ETIMEDOUT; - } - - if (mt76u_urb_error(buf->urb)) { - dev_err(dev->dev, "firmware upload failed: %d\n", - buf->urb->status); - return buf->urb->status; - } - - val = mt76u_rr(dev, MT_TX_CPU_FROM_FCE_CPU_DESC_IDX); - val++; - mt76u_wr(dev, MT_TX_CPU_FROM_FCE_CPU_DESC_IDX, val); - - return 0; -} - -int mt76u_mcu_fw_send_data(struct mt76_dev *dev, const void *data, - int data_len, u32 max_payload, u32 offset) -{ - int err, len, pos = 0, max_len = max_payload - 8; - struct mt76u_buf buf; - - err = mt76u_buf_alloc(dev, &buf, 1, max_payload, max_payload, - GFP_KERNEL); - if (err < 0) - return err; - - while (data_len > 0) { - len = min_t(int, data_len, max_len); - err = __mt76u_mcu_fw_send_data(dev, &buf, data + pos, - len, offset + pos); - if (err < 0) - break; - - data_len -= len; - pos += len; - usleep_range(5000, 10000); - } - mt76u_buf_free(&buf); - - return err; -} -EXPORT_SYMBOL_GPL(mt76u_mcu_fw_send_data); - int mt76u_mcu_init_rx(struct mt76_dev *dev) { struct mt76_usb *usb = &dev->usb; @@ -377,15 +54,3 @@ void mt76u_mcu_deinit(struct mt76_dev *dev) mt76u_buf_free(&usb->mcu.res); } EXPORT_SYMBOL_GPL(mt76u_mcu_deinit); - -void mt76u_init_mcu_ops(struct mt76_dev *dev) -{ - static const struct mt76_mcu_ops mt76u_mcu_ops = { - .mcu_msg_alloc = mt76u_mcu_msg_alloc, - .mcu_send_msg = mt76u_mcu_send_msg, - .mcu_wr_rp = mt76u_mcu_wr_rp, - .mcu_rd_rp = mt76u_mcu_rd_rp, - }; - - dev->mcu_ops = &mt76u_mcu_ops; -} From c2db13ac7b2b0d4337bf43f18806111c09de26e1 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Sun, 9 Sep 2018 22:32:42 +0200 Subject: [PATCH 196/276] mt76: usb: move mt76u_skb_dma_info in mt76x02_usb_core.c Move mt76u_skb_dma_info routine in mt76x02-usb module and rename it in mt76x02u_skb_dma_info. Moreover move mt76x02u_set_txinfo in mt76x02_usb_core.c. This is a preliminary patch to move MT_TXD_INFO, MT_MCU_MSG and MT_RX_FCE_INFO defs in mt76x02-lib module since other chipsets (e.g. mt7603) use different dma definitions Acked-by: Stanislaw Gruszka Signed-off-by: Lorenzo Bianconi Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/Makefile | 2 +- drivers/net/wireless/mediatek/mt76/mt76.h | 1 - .../net/wireless/mediatek/mt76/mt76x0/tx.c | 3 +- .../net/wireless/mediatek/mt76/mt76x02_usb.h | 2 + .../wireless/mediatek/mt76/mt76x02_usb_core.c | 72 +++++++++++++++++++ .../wireless/mediatek/mt76/mt76x02_usb_mcu.c | 3 +- .../net/wireless/mediatek/mt76/mt76x02_util.c | 21 ------ .../net/wireless/mediatek/mt76/mt76x02_util.h | 1 - .../net/wireless/mediatek/mt76/mt76x2u_core.c | 3 +- drivers/net/wireless/mediatek/mt76/usb.c | 34 --------- 10 files changed, 81 insertions(+), 61 deletions(-) create mode 100644 drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c diff --git a/drivers/net/wireless/mediatek/mt76/Makefile b/drivers/net/wireless/mediatek/mt76/Makefile index 64a32b4bb127..e8bd26923d73 100644 --- a/drivers/net/wireless/mediatek/mt76/Makefile +++ b/drivers/net/wireless/mediatek/mt76/Makefile @@ -17,7 +17,7 @@ CFLAGS_usb_trace.o := -I$(src) mt76x02-lib-y := mt76x02_util.o mt76x02_mac.o -mt76x02-usb-y := mt76x02_usb_mcu.o +mt76x02-usb-y := mt76x02_usb_mcu.o mt76x02_usb_core.o mt76x2-common-y := \ mt76x2_eeprom.o mt76x2_tx_common.o mt76x2_mac_common.o \ diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h index 2a84ddc338af..34d111a61235 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76.h +++ b/drivers/net/wireless/mediatek/mt76/mt76.h @@ -650,7 +650,6 @@ int mt76u_alloc_queues(struct mt76_dev *dev); void mt76u_stop_queues(struct mt76_dev *dev); void mt76u_stop_stat_wk(struct mt76_dev *dev); void mt76u_queues_deinit(struct mt76_dev *dev); -int mt76u_skb_dma_info(struct sk_buff *skb, int port, u32 flags); void mt76u_mcu_complete_urb(struct urb *urb); int mt76u_mcu_init_rx(struct mt76_dev *dev); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c b/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c index 3618f92662f8..c6d8ba01feb1 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/tx.c @@ -15,6 +15,7 @@ #include "mt76x0.h" #include "trace.h" #include "../mt76x02_util.h" +#include "../mt76x02_usb.h" static struct mt76x02_txwi * mt76x0_push_txwi(struct mt76x0_dev *dev, struct sk_buff *skb, @@ -93,7 +94,7 @@ int mt76x0_tx_prepare_skb(struct mt76_dev *mdev, void *data, mt76x02_insert_hdr_pad(skb); txwi = mt76x0_push_txwi(dev, skb, sta, wcid, len); - return mt76x02_set_txinfo(skb, wcid, q2ep(q->hw_idx)); + return mt76x02u_set_txinfo(skb, wcid, q2ep(q->hw_idx)); } EXPORT_SYMBOL_GPL(mt76x0_tx_prepare_skb); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_usb.h b/drivers/net/wireless/mediatek/mt76/mt76x02_usb.h index 798354be54ec..2482f9761fcd 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_usb.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_usb.h @@ -24,4 +24,6 @@ void mt76x02u_mcu_fw_reset(struct mt76_dev *dev); int mt76x02u_mcu_fw_send_data(struct mt76_dev *dev, const void *data, int data_len, u32 max_payload, u32 offset); +int mt76x02u_skb_dma_info(struct sk_buff *skb, int port, u32 flags); +int mt76x02u_set_txinfo(struct sk_buff *skb, struct mt76_wcid *wcid, u8 ep); #endif /* __MT76x02_USB_H */ diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c new file mode 100644 index 000000000000..9ca9e3d414d3 --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2018 Lorenzo Bianconi + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "mt76.h" +#include "dma.h" + +int mt76x02u_skb_dma_info(struct sk_buff *skb, int port, u32 flags) +{ + struct sk_buff *iter, *last = skb; + u32 info, pad; + + /* Buffer layout: + * | 4B | xfer len | pad | 4B | + * | TXINFO | pkt/cmd | zero pad to 4B | zero | + * + * length field of TXINFO should be set to 'xfer len'. + */ + info = FIELD_PREP(MT_TXD_INFO_LEN, round_up(skb->len, 4)) | + FIELD_PREP(MT_TXD_INFO_DPORT, port) | flags; + put_unaligned_le32(info, skb_push(skb, sizeof(info))); + + pad = round_up(skb->len, 4) + 4 - skb->len; + skb_walk_frags(skb, iter) { + last = iter; + if (!iter->next) { + skb->data_len += pad; + skb->len += pad; + break; + } + } + + if (unlikely(pad)) { + if (__skb_pad(last, pad, true)) + return -ENOMEM; + __skb_put(last, pad); + } + return 0; +} + +int mt76x02u_set_txinfo(struct sk_buff *skb, struct mt76_wcid *wcid, u8 ep) +{ + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + enum mt76_qsel qsel; + u32 flags; + + if ((info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) || + ep == MT_EP_OUT_HCCA) + qsel = MT_QSEL_MGMT; + else + qsel = MT_QSEL_EDCA; + + flags = FIELD_PREP(MT_TXD_INFO_QSEL, qsel) | + MT_TXD_INFO_80211; + if (!wcid || wcid->hw_key_idx == 0xff || wcid->sw_iv) + flags |= MT_TXD_INFO_WIV; + + return mt76x02u_skb_dma_info(skb, WLAN_PORT, flags); +} +EXPORT_SYMBOL_GPL(mt76x02u_set_txinfo); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_mcu.c index 3072be3e0dde..cc63efa16634 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_mcu.c @@ -19,6 +19,7 @@ #include "mt76.h" #include "dma.h" #include "mt76x02_mcu.h" +#include "mt76x02_usb.h" #define MT_CMD_HDR_LEN 4 @@ -144,7 +145,7 @@ __mt76x02u_mcu_send_msg(struct mt76_dev *dev, struct sk_buff *skb, info = FIELD_PREP(MT_MCU_MSG_CMD_SEQ, seq) | FIELD_PREP(MT_MCU_MSG_CMD_TYPE, cmd) | MT_MCU_MSG_TYPE_CMD; - ret = mt76u_skb_dma_info(skb, CPU_TX_PORT, info); + ret = mt76x02u_skb_dma_info(skb, CPU_TX_PORT, info); if (ret) return ret; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c index d0480e42b4a7..d3f35551413d 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c @@ -441,27 +441,6 @@ void mt76x02_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue *q, } EXPORT_SYMBOL_GPL(mt76x02_tx_complete_skb); -int mt76x02_set_txinfo(struct sk_buff *skb, struct mt76_wcid *wcid, u8 ep) -{ - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - enum mt76_qsel qsel; - u32 flags; - - if ((info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) || - ep == MT_EP_OUT_HCCA) - qsel = MT_QSEL_MGMT; - else - qsel = MT_QSEL_EDCA; - - flags = FIELD_PREP(MT_TXD_INFO_QSEL, qsel) | - MT_TXD_INFO_80211; - if (!wcid || wcid->hw_key_idx == 0xff || wcid->sw_iv) - flags |= MT_TXD_INFO_WIV; - - return mt76u_skb_dma_info(skb, WLAN_PORT, flags); -} -EXPORT_SYMBOL_GPL(mt76x02_set_txinfo); - bool mt76x02_tx_status_data(struct mt76_dev *dev, u8 *update) { struct mt76x02_tx_status stat; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.h b/drivers/net/wireless/mediatek/mt76/mt76x02_util.h index b6ba7e6c2748..48307ef2c380 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.h @@ -51,6 +51,5 @@ void mt76x02_tx_complete(struct mt76_dev *dev, struct sk_buff *skb); void mt76x02_remove_dma_hdr(struct sk_buff *skb); void mt76x02_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue *q, struct mt76_queue_entry *e, bool flush); -int mt76x02_set_txinfo(struct sk_buff *skb, struct mt76_wcid *wcid, u8 ep); bool mt76x02_tx_status_data(struct mt76_dev *dev, u8 *update); #endif diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2u_core.c b/drivers/net/wireless/mediatek/mt76/mt76x2u_core.c index 4433cc7b150d..c2ccdebca470 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2u_core.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2u_core.c @@ -17,6 +17,7 @@ #include "mt76x2u.h" #include "dma.h" #include "mt76x02_util.h" +#include "mt76x02_usb.h" static int mt76x2u_check_skb_rooms(struct sk_buff *skb) @@ -48,5 +49,5 @@ int mt76x2u_tx_prepare_skb(struct mt76_dev *mdev, void *data, txwi = skb_push(skb, sizeof(struct mt76x02_txwi)); mt76x2_mac_write_txwi(dev, txwi, skb, wcid, sta, len); - return mt76x02_set_txinfo(skb, wcid, q2ep(q->hw_idx)); + return mt76x02u_set_txinfo(skb, wcid, q2ep(q->hw_idx)); } diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c index bc56bd4850bc..16a9682d5452 100644 --- a/drivers/net/wireless/mediatek/mt76/usb.c +++ b/drivers/net/wireless/mediatek/mt76/usb.c @@ -565,40 +565,6 @@ static void mt76u_stop_rx(struct mt76_dev *dev) usb_kill_urb(q->entry[i].ubuf.urb); } -int mt76u_skb_dma_info(struct sk_buff *skb, int port, u32 flags) -{ - struct sk_buff *iter, *last = skb; - u32 info, pad; - - /* Buffer layout: - * | 4B | xfer len | pad | 4B | - * | TXINFO | pkt/cmd | zero pad to 4B | zero | - * - * length field of TXINFO should be set to 'xfer len'. - */ - info = FIELD_PREP(MT_TXD_INFO_LEN, round_up(skb->len, 4)) | - FIELD_PREP(MT_TXD_INFO_DPORT, port) | flags; - put_unaligned_le32(info, skb_push(skb, sizeof(info))); - - pad = round_up(skb->len, 4) + 4 - skb->len; - skb_walk_frags(skb, iter) { - last = iter; - if (!iter->next) { - skb->data_len += pad; - skb->len += pad; - break; - } - } - - if (unlikely(pad)) { - if (__skb_pad(last, pad, true)) - return -ENOMEM; - __skb_put(last, pad); - } - return 0; -} -EXPORT_SYMBOL_GPL(mt76u_skb_dma_info); - static void mt76u_tx_tasklet(unsigned long data) { struct mt76_dev *dev = (struct mt76_dev *)data; From 6181bf2a1124a2b0afb3fe0f4ce0021db70b774f Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Sun, 9 Sep 2018 22:32:43 +0200 Subject: [PATCH 197/276] mt76x02: move TXD/RXD/MCU definitions in mt76x02_dma.h Introduce mt76x02_dma.h header file to contain mt76x02 dma related definitions Signed-off-by: Lorenzo Bianconi Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/dma.h | 38 ------------ .../net/wireless/mediatek/mt76/mt76x02_dma.h | 60 +++++++++++++++++++ .../wireless/mediatek/mt76/mt76x02_usb_core.c | 2 +- .../wireless/mediatek/mt76/mt76x02_usb_mcu.c | 2 +- .../net/wireless/mediatek/mt76/mt76x02_util.c | 2 +- .../net/wireless/mediatek/mt76/mt76x2_dma.c | 2 +- .../net/wireless/mediatek/mt76/mt76x2_mcu.c | 2 +- .../net/wireless/mediatek/mt76/mt76x2_tx.c | 2 +- drivers/net/wireless/mediatek/mt76/mt76x2u.h | 2 +- 9 files changed, 67 insertions(+), 45 deletions(-) create mode 100644 drivers/net/wireless/mediatek/mt76/mt76x02_dma.h diff --git a/drivers/net/wireless/mediatek/mt76/dma.h b/drivers/net/wireless/mediatek/mt76/dma.h index aa2faf19bf05..357cc356342d 100644 --- a/drivers/net/wireless/mediatek/mt76/dma.h +++ b/drivers/net/wireless/mediatek/mt76/dma.h @@ -25,34 +25,6 @@ #define MT_DMA_CTL_LAST_SEC0 BIT(30) #define MT_DMA_CTL_DMA_DONE BIT(31) -#define MT_TXD_INFO_LEN GENMASK(15, 0) -#define MT_TXD_INFO_NEXT_VLD BIT(16) -#define MT_TXD_INFO_TX_BURST BIT(17) -#define MT_TXD_INFO_80211 BIT(19) -#define MT_TXD_INFO_TSO BIT(20) -#define MT_TXD_INFO_CSO BIT(21) -#define MT_TXD_INFO_WIV BIT(24) -#define MT_TXD_INFO_QSEL GENMASK(26, 25) -#define MT_TXD_INFO_DPORT GENMASK(29, 27) -#define MT_TXD_INFO_TYPE GENMASK(31, 30) - -#define MT_RX_FCE_INFO_LEN GENMASK(13, 0) -#define MT_RX_FCE_INFO_SELF_GEN BIT(15) -#define MT_RX_FCE_INFO_CMD_SEQ GENMASK(19, 16) -#define MT_RX_FCE_INFO_EVT_TYPE GENMASK(23, 20) -#define MT_RX_FCE_INFO_PCIE_INTR BIT(24) -#define MT_RX_FCE_INFO_QSEL GENMASK(26, 25) -#define MT_RX_FCE_INFO_D_PORT GENMASK(29, 27) -#define MT_RX_FCE_INFO_TYPE GENMASK(31, 30) - -/* MCU request message header */ -#define MT_MCU_MSG_LEN GENMASK(15, 0) -#define MT_MCU_MSG_CMD_SEQ GENMASK(19, 16) -#define MT_MCU_MSG_CMD_TYPE GENMASK(26, 20) -#define MT_MCU_MSG_PORT GENMASK(29, 27) -#define MT_MCU_MSG_TYPE GENMASK(31, 30) -#define MT_MCU_MSG_TYPE_CMD BIT(30) - #define MT_DMA_HDR_LEN 4 #define MT_RX_INFO_LEN 4 #define MT_FCE_INFO_LEN 4 @@ -65,16 +37,6 @@ struct mt76_desc { __le32 info; } __packed __aligned(4); -enum dma_msg_port { - WLAN_PORT, - CPU_RX_PORT, - CPU_TX_PORT, - HOST_PORT, - VIRTUAL_CPU_RX_PORT, - VIRTUAL_CPU_TX_PORT, - DISCARD, -}; - enum mt76_qsel { MT_QSEL_MGMT, MT_QSEL_HCCA, diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_dma.h b/drivers/net/wireless/mediatek/mt76/mt76x02_dma.h new file mode 100644 index 000000000000..32a323ebc6a7 --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_dma.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2018 Lorenzo Bianconi + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef __MT76x02_DMA_H +#define __MT76x02_DMA_H + +#include "dma.h" + +#define MT_TXD_INFO_LEN GENMASK(15, 0) +#define MT_TXD_INFO_NEXT_VLD BIT(16) +#define MT_TXD_INFO_TX_BURST BIT(17) +#define MT_TXD_INFO_80211 BIT(19) +#define MT_TXD_INFO_TSO BIT(20) +#define MT_TXD_INFO_CSO BIT(21) +#define MT_TXD_INFO_WIV BIT(24) +#define MT_TXD_INFO_QSEL GENMASK(26, 25) +#define MT_TXD_INFO_DPORT GENMASK(29, 27) +#define MT_TXD_INFO_TYPE GENMASK(31, 30) + +#define MT_RX_FCE_INFO_LEN GENMASK(13, 0) +#define MT_RX_FCE_INFO_SELF_GEN BIT(15) +#define MT_RX_FCE_INFO_CMD_SEQ GENMASK(19, 16) +#define MT_RX_FCE_INFO_EVT_TYPE GENMASK(23, 20) +#define MT_RX_FCE_INFO_PCIE_INTR BIT(24) +#define MT_RX_FCE_INFO_QSEL GENMASK(26, 25) +#define MT_RX_FCE_INFO_D_PORT GENMASK(29, 27) +#define MT_RX_FCE_INFO_TYPE GENMASK(31, 30) + +/* MCU request message header */ +#define MT_MCU_MSG_LEN GENMASK(15, 0) +#define MT_MCU_MSG_CMD_SEQ GENMASK(19, 16) +#define MT_MCU_MSG_CMD_TYPE GENMASK(26, 20) +#define MT_MCU_MSG_PORT GENMASK(29, 27) +#define MT_MCU_MSG_TYPE GENMASK(31, 30) +#define MT_MCU_MSG_TYPE_CMD BIT(30) + +enum dma_msg_port { + WLAN_PORT, + CPU_RX_PORT, + CPU_TX_PORT, + HOST_PORT, + VIRTUAL_CPU_RX_PORT, + VIRTUAL_CPU_TX_PORT, + DISCARD, +}; + +#endif /* __MT76x02_DMA_H */ diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c index 9ca9e3d414d3..235b1bc5a367 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c @@ -15,7 +15,7 @@ */ #include "mt76.h" -#include "dma.h" +#include "mt76x02_dma.h" int mt76x02u_skb_dma_info(struct sk_buff *skb, int port, u32 flags) { diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_mcu.c index cc63efa16634..b39a4d7d71cc 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_mcu.c @@ -17,7 +17,7 @@ #include #include "mt76.h" -#include "dma.h" +#include "mt76x02_dma.h" #include "mt76x02_mcu.h" #include "mt76x02_usb.h" diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c index d3f35551413d..52b175bd40e2 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c @@ -16,7 +16,7 @@ */ #include "mt76.h" -#include "dma.h" +#include "mt76x02_dma.h" #include "mt76x02_regs.h" #include "mt76x02_mac.h" diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_dma.c b/drivers/net/wireless/mediatek/mt76/mt76x2_dma.c index 4b60e8a5239e..304869961f69 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_dma.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_dma.c @@ -15,7 +15,7 @@ */ #include "mt76x2.h" -#include "dma.h" +#include "mt76x02_dma.h" int mt76x2_tx_queue_mcu(struct mt76x2_dev *dev, enum mt76_txq_id qid, diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.c index c90803334ef0..9a174db5a23a 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.c @@ -21,7 +21,7 @@ #include "mt76x2.h" #include "mt76x2_mcu.h" #include "mt76x2_eeprom.h" -#include "dma.h" +#include "mt76x02_dma.h" static struct sk_buff *mt76x2_mcu_msg_alloc(const void *data, int len) { diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_tx.c b/drivers/net/wireless/mediatek/mt76/mt76x2_tx.c index 41d660991839..fcdf1879162e 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_tx.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_tx.c @@ -16,7 +16,7 @@ #include "mt76x2.h" #include "mt76x02_util.h" -#include "dma.h" +#include "mt76x02_dma.h" struct beacon_bc_data { struct mt76x2_dev *dev; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2u.h b/drivers/net/wireless/mediatek/mt76/mt76x2u.h index 5a11217c03ed..83abbafc0c1a 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2u.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x2u.h @@ -21,7 +21,7 @@ #include "mt76x2.h" #include "mt76x2_mcu.h" -#include "dma.h" +#include "mt76x02_dma.h" #define MT7612U_EEPROM_SIZE 512 From 6d6631fd788dcead846ccdc89f3c83e768a98580 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Sun, 9 Sep 2018 22:32:44 +0200 Subject: [PATCH 198/276] mt76x02: add static qualifier to mt76x02_remove_dma_hdr Add static qualifier to mt76x02_remove_dma_hdr routine and do not export the symbol since it is only used in mt76x02_util.c Signed-off-by: Lorenzo Bianconi Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt76x02_util.c | 3 +-- drivers/net/wireless/mediatek/mt76/mt76x02_util.h | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c index 52b175bd40e2..4ecfb75f3f7d 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c @@ -407,7 +407,7 @@ void mt76x02_remove_hdr_pad(struct sk_buff *skb, int len) } EXPORT_SYMBOL_GPL(mt76x02_remove_hdr_pad); -void mt76x02_remove_dma_hdr(struct sk_buff *skb) +static void mt76x02_remove_dma_hdr(struct sk_buff *skb) { int hdr_len; @@ -416,7 +416,6 @@ void mt76x02_remove_dma_hdr(struct sk_buff *skb) if (hdr_len % 4) mt76x02_remove_hdr_pad(skb, 2); } -EXPORT_SYMBOL_GPL(mt76x02_remove_dma_hdr); void mt76x02_tx_complete(struct mt76_dev *dev, struct sk_buff *skb) { diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.h b/drivers/net/wireless/mediatek/mt76/mt76x02_util.h index 48307ef2c380..2ea9e68bfa3f 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.h @@ -48,7 +48,6 @@ void mt76x02_sta_rate_tbl_update(struct ieee80211_hw *hw, int mt76x02_insert_hdr_pad(struct sk_buff *skb); void mt76x02_remove_hdr_pad(struct sk_buff *skb, int len); void mt76x02_tx_complete(struct mt76_dev *dev, struct sk_buff *skb); -void mt76x02_remove_dma_hdr(struct sk_buff *skb); void mt76x02_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue *q, struct mt76_queue_entry *e, bool flush); bool mt76x02_tx_status_data(struct mt76_dev *dev, u8 *update); From fd0c6e189d2315294bbd29107ae8e7b1b4ed2e4a Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Sun, 9 Sep 2018 22:32:45 +0200 Subject: [PATCH 199/276] mt76x0: remove unused mt76x0_burst_read_regs mt76x0_burst_read_regs is not used, but keep it for eventual use. Since we have this function now in the driver git history, we can remove it and eventually revert this commit it the function will be needed. Signed-off-by: Stanislaw Gruszka Signed-off-by: Lorenzo Bianconi Signed-off-by: Felix Fietkau --- .../net/wireless/mediatek/mt76/mt76x0/mcu.c | 43 ------------------- 1 file changed, 43 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c index 7baa9a45bd84..c14ae6c3e863 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c @@ -106,49 +106,6 @@ int mt76x0_burst_write_regs(struct mt76x0_dev *dev, u32 offset, data + cnt, n - cnt); } -#if 0 -static int mt76x0_burst_read_regs(struct mt76x0_dev *dev, u32 base, - struct mt76_reg_pair *data, int n) -{ - const int max_vals_per_cmd = MT_INBAND_PACKET_MAX_LEN / 4 - 1; - struct mt76_usb *usb = &dev->mt76.usb; - struct sk_buff *skb; - int cnt, ret; - - if (!n) - return 0; - - cnt = min(max_vals_per_cmd, n); - if (cnt != n) - return -EINVAL; - - skb = alloc_skb(cnt * 4 + MT_DMA_HDR_LEN + 4, GFP_KERNEL); - if (!skb) - return -ENOMEM; - skb_reserve(skb, MT_DMA_HDR_LEN); - - skb_put_le32(skb, base + data[0].reg); - skb_put_le32(skb, n); - - mutex_lock(&usb->mcu.mutex); - - usb->mcu.rp = data; - usb->mcu.rp_len = n; - usb->mcu.base = base; - usb->mcu.burst = false; - - ret = __mt76u_mcu_send_msg(&dev->mt76, skb, CMD_BURST_READ, true); - - usb->mcu.rp = NULL; - - mutex_unlock(&usb->mcu.mutex); - - consume_skb(skb); - - return ret; -} -#endif - struct mt76_fw_header { __le32 ilm_len; __le32 dlm_len; From 331419b2ce6eb97c6a042d34bbacd79ff5fb5cf1 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Sun, 9 Sep 2018 22:32:46 +0200 Subject: [PATCH 200/276] mt76x0: remove mt76x0_burst_write_regs() We don't need to use custom burst write regs via MCU, we can use generic mt76_wr_copy() for the same purpose. Signed-off-by: Stanislaw Gruszka Signed-off-by: Lorenzo Bianconi Signed-off-by: Felix Fietkau --- .../net/wireless/mediatek/mt76/mt76x0/init.c | 25 ++++++---------- .../net/wireless/mediatek/mt76/mt76x0/mcu.c | 29 ------------------- .../wireless/mediatek/mt76/mt76x0/mt76x0.h | 3 -- 3 files changed, 9 insertions(+), 48 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c index a68161e1a2bf..7e415b361ad1 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c @@ -249,7 +249,7 @@ static void mt76x0_init_mac_registers(struct mt76x0_dev *dev) static int mt76x0_init_wcid_mem(struct mt76x0_dev *dev) { u32 *vals; - int i, ret; + int i; vals = kmalloc(sizeof(*vals) * MT76_N_WCIDS * 2, GFP_KERNEL); if (!vals) @@ -260,25 +260,22 @@ static int mt76x0_init_wcid_mem(struct mt76x0_dev *dev) vals[i * 2 + 1] = 0x00ffffff; } - ret = mt76x0_burst_write_regs(dev, MT_WCID_ADDR_BASE, - vals, MT76_N_WCIDS * 2); + mt76_wr_copy(dev, MT_WCID_ADDR_BASE, vals, MT76_N_WCIDS * 2); kfree(vals); - - return ret; + return 0; } -static int mt76x0_init_key_mem(struct mt76x0_dev *dev) +static void mt76x0_init_key_mem(struct mt76x0_dev *dev) { u32 vals[4] = {}; - return mt76x0_burst_write_regs(dev, MT_SKEY_MODE_BASE_0, - vals, ARRAY_SIZE(vals)); + mt76_wr_copy(dev, MT_SKEY_MODE_BASE_0, vals, ARRAY_SIZE(vals)); } static int mt76x0_init_wcid_attr_mem(struct mt76x0_dev *dev) { u32 *vals; - int i, ret; + int i; vals = kmalloc(sizeof(*vals) * MT76_N_WCIDS * 2, GFP_KERNEL); if (!vals) @@ -287,11 +284,9 @@ static int mt76x0_init_wcid_attr_mem(struct mt76x0_dev *dev) for (i = 0; i < MT76_N_WCIDS * 2; i++) vals[i] = 1; - ret = mt76x0_burst_write_regs(dev, MT_WCID_ATTR_BASE, - vals, MT76_N_WCIDS * 2); + mt76_wr_copy(dev, MT_WCID_ATTR_BASE, vals, MT76_N_WCIDS * 2); kfree(vals); - - return ret; + return 0; } static void mt76x0_reset_counters(struct mt76x0_dev *dev) @@ -443,9 +438,7 @@ int mt76x0_init_hardware(struct mt76x0_dev *dev) if (ret) return ret; - ret = mt76x0_init_key_mem(dev); - if (ret) - return ret; + mt76x0_init_key_mem(dev); ret = mt76x0_init_wcid_attr_mem(dev); if (ret) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c index c14ae6c3e863..4a5739e056a7 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c @@ -77,35 +77,6 @@ mt76x0_mcu_calibrate(struct mt76x0_dev *dev, enum mcu_calibrate cal, u32 val) return mt76_mcu_send_msg(dev, skb, CMD_CALIBRATION_OP, true); } -int mt76x0_burst_write_regs(struct mt76x0_dev *dev, u32 offset, - const u32 *data, int n) -{ - const int max_regs_per_cmd = MT_INBAND_PACKET_MAX_LEN / 4 - 1; - struct sk_buff *skb; - int cnt, i, ret; - - if (!n) - return 0; - - cnt = min(max_regs_per_cmd, n); - - skb = alloc_skb(cnt * 4 + MT_DMA_HDR_LEN + 4, GFP_KERNEL); - if (!skb) - return -ENOMEM; - skb_reserve(skb, MT_DMA_HDR_LEN); - - skb_put_le32(skb, MT_MCU_MEMMAP_WLAN + offset); - for (i = 0; i < cnt; i++) - skb_put_le32(skb, data[i]); - - ret = mt76_mcu_send_msg(dev, skb, CMD_BURST_WRITE, cnt == n); - if (ret) - return ret; - - return mt76x0_burst_write_regs(dev, offset + cnt * 4, - data + cnt, n - cnt); -} - struct mt76_fw_header { __le32 ilm_len; __le32 dlm_len; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h index 92ecf4e8bda1..6aaa9a5b51db 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h @@ -126,9 +126,6 @@ void mt76x0_init_debugfs(struct mt76x0_dev *dev); #define mt76_rmw_field(_dev, _reg, _field, _val) \ mt76_rmw(_dev, _reg, _field, FIELD_PREP(_field, _val)) -int mt76x0_burst_write_regs(struct mt76x0_dev *dev, u32 offset, - const u32 *data, int n); - /* Init */ struct mt76x0_dev * mt76x0_alloc_device(struct device *pdev, const struct mt76_driver_ops *drv_ops); From 8799b624fe744f1cc8a48835c9b6469166ef5188 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Sun, 9 Sep 2018 23:57:54 +0200 Subject: [PATCH 201/276] mt76: usb: remove skb check in mt76x{0,2}u mcu routines Remove mt76_mcu_msg_alloc return value check since it is already evaluated in __mt76x02u_mcu_send_msg Signed-off-by: Lorenzo Bianconi Signed-off-by: Felix Fietkau --- .../net/wireless/mediatek/mt76/mt76x0/mcu.c | 4 ---- .../net/wireless/mediatek/mt76/mt76x2u_mcu.c | 20 ------------------- 2 files changed, 24 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c index 4a5739e056a7..d757cde33f74 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c @@ -54,8 +54,6 @@ int mt76x0_mcu_function_select(struct mt76x0_dev *dev, }; skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg)); - if (!skb) - return -ENOMEM; return mt76_mcu_send_msg(dev, skb, CMD_FUN_SET_OP, func == 5); } @@ -72,8 +70,6 @@ mt76x0_mcu_calibrate(struct mt76x0_dev *dev, enum mcu_calibrate cal, u32 val) }; skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg)); - if (!skb) - return -ENOMEM; return mt76_mcu_send_msg(dev, skb, CMD_CALIBRATION_OP, true); } diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2u_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x2u_mcu.c index 09afb8c5d851..e93123e4a395 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2u_mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2u_mcu.c @@ -43,8 +43,6 @@ mt76x2u_mcu_function_select(struct mt76x2_dev *dev, enum mcu_function func, struct sk_buff *skb; skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg)); - if (!skb) - return -ENOMEM; return mt76_mcu_send_msg(dev, skb, CMD_FUN_SET_OP, func != Q_SELECT); } @@ -61,8 +59,6 @@ int mt76x2u_mcu_set_radio_state(struct mt76x2_dev *dev, bool val) struct sk_buff *skb; skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg)); - if (!skb) - return -ENOMEM; return mt76_mcu_send_msg(dev, skb, CMD_POWER_SAVING_OP, false); } @@ -91,8 +87,6 @@ int mt76x2u_mcu_load_cr(struct mt76x2_dev *dev, u8 type, u8 temp_level, /* first set the channel without the extension channel info */ skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg)); - if (!skb) - return -ENOMEM; return mt76_mcu_send_msg(dev, skb, CMD_LOAD_CR, true); } @@ -119,18 +113,12 @@ int mt76x2u_mcu_set_channel(struct mt76x2_dev *dev, u8 channel, u8 bw, /* first set the channel without the extension channel info */ skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg)); - if (!skb) - return -ENOMEM; - mt76_mcu_send_msg(dev, skb, CMD_SWITCH_CHANNEL_OP, true); usleep_range(5000, 10000); msg.ext_chan = 0xe0 + bw_index; skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg)); - if (!skb) - return -ENOMEM; - return mt76_mcu_send_msg(dev, skb, CMD_SWITCH_CHANNEL_OP, true); } @@ -147,8 +135,6 @@ int mt76x2u_mcu_calibrate(struct mt76x2_dev *dev, enum mcu_calibration type, struct sk_buff *skb; skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg)); - if (!skb) - return -ENOMEM; return mt76_mcu_send_msg(dev, skb, CMD_CALIBRATION_OP, true); } @@ -168,8 +154,6 @@ int mt76x2u_mcu_init_gain(struct mt76x2_dev *dev, u8 channel, u32 gain, msg.channel |= cpu_to_le32(BIT(31)); skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg)); - if (!skb) - return -ENOMEM; return mt76_mcu_send_msg(dev, skb, CMD_INIT_GAIN_OP, true); } @@ -194,8 +178,6 @@ int mt76x2u_mcu_set_dynamic_vga(struct mt76x2_dev *dev, u8 channel, bool ap, msg.channel = cpu_to_le32(val); skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg)); - if (!skb) - return -ENOMEM; return mt76_mcu_send_msg(dev, skb, CMD_DYNC_VGA_OP, true); } @@ -212,8 +194,6 @@ int mt76x2u_mcu_tssi_comp(struct mt76x2_dev *dev, struct sk_buff *skb; skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg)); - if (!skb) - return -ENOMEM; return mt76_mcu_send_msg(dev, skb, CMD_CALIBRATION_OP, true); } From d5c4261357ce7e0fd40564875e39fdc16893f686 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Sun, 9 Sep 2018 23:57:55 +0200 Subject: [PATCH 202/276] mt76x2: use mt76_dev instead of mt76x2_dev in mt76x2_tx_queue_mcu Use mt76_dev data structure instead of mt76x2_dev one in mt76x2_tx_queue_mcu routine. This is a preliminary patch to share mcu code between mt76x2e and mt76x0e Signed-off-by: Lorenzo Bianconi Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt76x2.h | 2 +- drivers/net/wireless/mediatek/mt76/mt76x2_dma.c | 12 ++++++------ drivers/net/wireless/mediatek/mt76/mt76x2_mcu.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2.h b/drivers/net/wireless/mediatek/mt76/mt76x2.h index 87b805637ff8..978477d1ff08 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x2.h @@ -209,7 +209,7 @@ void mt76x2_dma_cleanup(struct mt76x2_dev *dev); void mt76x2_cleanup(struct mt76x2_dev *dev); -int mt76x2_tx_queue_mcu(struct mt76x2_dev *dev, enum mt76_txq_id qid, +int mt76x2_tx_queue_mcu(struct mt76_dev *dev, enum mt76_txq_id qid, struct sk_buff *skb, int cmd, int seq); void mt76x2_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, struct sk_buff *skb); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_dma.c b/drivers/net/wireless/mediatek/mt76/mt76x2_dma.c index 304869961f69..9198c3d19d98 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_dma.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_dma.c @@ -18,10 +18,10 @@ #include "mt76x02_dma.h" int -mt76x2_tx_queue_mcu(struct mt76x2_dev *dev, enum mt76_txq_id qid, +mt76x2_tx_queue_mcu(struct mt76_dev *dev, enum mt76_txq_id qid, struct sk_buff *skb, int cmd, int seq) { - struct mt76_queue *q = &dev->mt76.q_tx[qid]; + struct mt76_queue *q = &dev->q_tx[qid]; struct mt76_queue_buf buf; dma_addr_t addr; u32 tx_info; @@ -32,16 +32,16 @@ mt76x2_tx_queue_mcu(struct mt76x2_dev *dev, enum mt76_txq_id qid, FIELD_PREP(MT_MCU_MSG_PORT, CPU_TX_PORT) | FIELD_PREP(MT_MCU_MSG_LEN, skb->len); - addr = dma_map_single(dev->mt76.dev, skb->data, skb->len, + addr = dma_map_single(dev->dev, skb->data, skb->len, DMA_TO_DEVICE); - if (dma_mapping_error(dev->mt76.dev, addr)) + if (dma_mapping_error(dev->dev, addr)) return -ENOMEM; buf.addr = addr; buf.len = skb->len; spin_lock_bh(&q->lock); - mt76_queue_add_buf(dev, q, &buf, 1, tx_info, skb, NULL); - mt76_queue_kick(dev, q); + dev->queue_ops->add_buf(dev, q, &buf, 1, tx_info, skb, NULL); + dev->queue_ops->kick(dev, q); spin_unlock_bh(&q->lock); return 0; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.c index 9a174db5a23a..27b2d7b3d856 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.c @@ -66,7 +66,7 @@ mt76x2_mcu_msg_send(struct mt76x2_dev *dev, struct sk_buff *skb, if (!seq) seq = ++dev->mcu.msg_seq & 0xf; - ret = mt76x2_tx_queue_mcu(dev, MT_TXQ_MCU, skb, cmd, seq); + ret = mt76x2_tx_queue_mcu(&dev->mt76, MT_TXQ_MCU, skb, cmd, seq); if (ret) goto out; From 8db5ec77de216cd136a678f24ac7a804a1c79192 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Sun, 9 Sep 2018 23:57:56 +0200 Subject: [PATCH 203/276] mt76x2: remove leftover mt76u_buf data structure in mt76x2_mcu Remove unused usb buffer in mt76x2_mcu data structure Signed-off-by: Lorenzo Bianconi Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt76x2.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2.h b/drivers/net/wireless/mediatek/mt76/mt76x2.h index 978477d1ff08..5449d38d2f35 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x2.h @@ -52,7 +52,6 @@ struct mt76x2_mcu { wait_queue_head_t wait; struct sk_buff_head res_q; - struct mt76u_buf res_u; u32 msg_seq; }; From f7bbb80f22166387248b26353336a8300f05e555 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Sun, 9 Sep 2018 23:57:57 +0200 Subject: [PATCH 204/276] mt76: introduce mmio data structure in mt76_dev Introduce mt76_mmio data structure in mt76_dev and move mt76x2_mcu in mt76_mmio. This is a preliminary patch to unify mcu code between mt76x02{e,u} drivers Signed-off-by: Lorenzo Bianconi Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mmio.c | 4 ++++ drivers/net/wireless/mediatek/mt76/mt76.h | 16 +++++++++++++++- drivers/net/wireless/mediatek/mt76/mt76x2.h | 10 ---------- .../net/wireless/mediatek/mt76/mt76x2_common.c | 5 +++-- drivers/net/wireless/mediatek/mt76/mt76x2_dma.c | 3 --- drivers/net/wireless/mediatek/mt76/mt76x2_mcu.c | 17 ++++++++--------- 6 files changed, 30 insertions(+), 25 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mmio.c b/drivers/net/wireless/mediatek/mt76/mmio.c index 09a14dead6e3..11a74c3eb957 100644 --- a/drivers/net/wireless/mediatek/mt76/mmio.c +++ b/drivers/net/wireless/mediatek/mt76/mmio.c @@ -57,5 +57,9 @@ void mt76_mmio_init(struct mt76_dev *dev, void __iomem *regs) dev->bus = &mt76_mmio_ops; dev->regs = regs; + + skb_queue_head_init(&dev->mmio.mcu.res_q); + init_waitqueue_head(&dev->mmio.mcu.wait); + mutex_init(&dev->mmio.mcu.mutex); } EXPORT_SYMBOL_GPL(mt76_mmio_init); diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h index 34d111a61235..8c9b78d53705 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76.h +++ b/drivers/net/wireless/mediatek/mt76/mt76.h @@ -338,6 +338,17 @@ struct mt76_usb { } mcu; }; +struct mt76_mmio { + struct mt76e_mcu { + struct mutex mutex; + + wait_queue_head_t wait; + struct sk_buff_head res_q; + + u32 msg_seq; + } mcu; +}; + struct mt76_dev { struct ieee80211_hw *hw; struct cfg80211_chan_def chandef; @@ -392,7 +403,10 @@ struct mt76_dev { u32 rxfilter; - struct mt76_usb usb; + union { + struct mt76_mmio mmio; + struct mt76_usb usb; + }; }; enum mt76_phy_type { diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2.h b/drivers/net/wireless/mediatek/mt76/mt76x2.h index 5449d38d2f35..07400d9aba3f 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x2.h @@ -47,15 +47,6 @@ #include "mt76x2_mac.h" #include "mt76x2_dfs.h" -struct mt76x2_mcu { - struct mutex mutex; - - wait_queue_head_t wait; - struct sk_buff_head res_q; - - u32 msg_seq; -}; - struct mt76x2_rx_freq_cal { s8 high_gain[MT_MAX_CHAINS]; s8 rssi_offset[MT_MAX_CHAINS]; @@ -97,7 +88,6 @@ struct mt76x2_dev { u8 txdone_seq; DECLARE_KFIFO_PTR(txstatus_fifo, struct mt76x02_tx_status); - struct mt76x2_mcu mcu; struct sk_buff *rx_head; struct tasklet_struct tx_tasklet; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_common.c b/drivers/net/wireless/mediatek/mt76/mt76x2_common.c index 0f7f731ab285..3e667d8c0ee7 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_common.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_common.c @@ -25,8 +25,9 @@ void mt76x2_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q, void *rxwi = skb->data; if (q == MT_RXQ_MCU) { - skb_queue_tail(&dev->mcu.res_q, skb); - wake_up(&dev->mcu.wait); + /* this is used just by mmio code */ + skb_queue_tail(&mdev->mmio.mcu.res_q, skb); + wake_up(&mdev->mmio.mcu.wait); return; } diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_dma.c b/drivers/net/wireless/mediatek/mt76/mt76x2_dma.c index 9198c3d19d98..3c6bbb7df837 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_dma.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_dma.c @@ -112,9 +112,6 @@ int mt76x2_dma_init(struct mt76x2_dev *dev) mt76_dma_attach(&dev->mt76); - init_waitqueue_head(&dev->mcu.wait); - skb_queue_head_init(&dev->mcu.res_q); - tasklet_init(&dev->tx_tasklet, mt76x2_tx_tasklet, (unsigned long) dev); mt76_wr(dev, MT_WPDMA_RST_IDX, ~0); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.c index 27b2d7b3d856..fc1c0800170c 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.c @@ -44,9 +44,10 @@ mt76x2_mcu_get_response(struct mt76x2_dev *dev, unsigned long expires) return NULL; timeout = expires - jiffies; - wait_event_timeout(dev->mcu.wait, !skb_queue_empty(&dev->mcu.res_q), + wait_event_timeout(dev->mt76.mmio.mcu.wait, + !skb_queue_empty(&dev->mt76.mmio.mcu.res_q), timeout); - return skb_dequeue(&dev->mcu.res_q); + return skb_dequeue(&dev->mt76.mmio.mcu.res_q); } static int @@ -60,11 +61,11 @@ mt76x2_mcu_msg_send(struct mt76x2_dev *dev, struct sk_buff *skb, if (!skb) return -EINVAL; - mutex_lock(&dev->mcu.mutex); + mutex_lock(&dev->mt76.mmio.mcu.mutex); - seq = ++dev->mcu.msg_seq & 0xf; + seq = ++dev->mt76.mmio.mcu.msg_seq & 0xf; if (!seq) - seq = ++dev->mcu.msg_seq & 0xf; + seq = ++dev->mt76.mmio.mcu.msg_seq & 0xf; ret = mt76x2_tx_queue_mcu(&dev->mt76, MT_TXQ_MCU, skb, cmd, seq); if (ret) @@ -94,7 +95,7 @@ mt76x2_mcu_msg_send(struct mt76x2_dev *dev, struct sk_buff *skb, } out: - mutex_unlock(&dev->mcu.mutex); + mutex_unlock(&dev->mt76.mmio.mcu.mutex); return ret; } @@ -399,8 +400,6 @@ int mt76x2_mcu_init(struct mt76x2_dev *dev) { int ret; - mutex_init(&dev->mcu.mutex); - ret = mt76pci_load_rom_patch(dev); if (ret) return ret; @@ -420,7 +419,7 @@ int mt76x2_mcu_cleanup(struct mt76x2_dev *dev) mt76_wr(dev, MT_MCU_INT_LEVEL, 1); usleep_range(20000, 30000); - while ((skb = skb_dequeue(&dev->mcu.res_q)) != NULL) + while ((skb = skb_dequeue(&dev->mt76.mmio.mcu.res_q)) != NULL) dev_kfree_skb(skb); return 0; From 27db1ad10f2e6fdb22bb7c6200c57e35076b684d Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Sun, 9 Sep 2018 23:57:58 +0200 Subject: [PATCH 205/276] mt76: move __iomem regs in mt76_mmio Move __iomem regs pointer in mt76_mmio data structure Signed-off-by: Lorenzo Bianconi Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mmio.c | 8 ++++---- drivers/net/wireless/mediatek/mt76/mt76.h | 2 +- drivers/net/wireless/mediatek/mt76/mt76x2_dma.c | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mmio.c b/drivers/net/wireless/mediatek/mt76/mmio.c index 11a74c3eb957..2f09f451a9b6 100644 --- a/drivers/net/wireless/mediatek/mt76/mmio.c +++ b/drivers/net/wireless/mediatek/mt76/mmio.c @@ -21,7 +21,7 @@ static u32 mt76_mmio_rr(struct mt76_dev *dev, u32 offset) { u32 val; - val = ioread32(dev->regs + offset); + val = ioread32(dev->mmio.regs + offset); trace_reg_rr(dev, offset, val); return val; @@ -30,7 +30,7 @@ static u32 mt76_mmio_rr(struct mt76_dev *dev, u32 offset) static void mt76_mmio_wr(struct mt76_dev *dev, u32 offset, u32 val) { trace_reg_wr(dev, offset, val); - iowrite32(val, dev->regs + offset); + iowrite32(val, dev->mmio.regs + offset); } static u32 mt76_mmio_rmw(struct mt76_dev *dev, u32 offset, u32 mask, u32 val) @@ -43,7 +43,7 @@ static u32 mt76_mmio_rmw(struct mt76_dev *dev, u32 offset, u32 mask, u32 val) static void mt76_mmio_copy(struct mt76_dev *dev, u32 offset, const void *data, int len) { - __iowrite32_copy(dev->regs + offset, data, len >> 2); + __iowrite32_copy(dev->mmio.regs + offset, data, len >> 2); } void mt76_mmio_init(struct mt76_dev *dev, void __iomem *regs) @@ -56,7 +56,7 @@ void mt76_mmio_init(struct mt76_dev *dev, void __iomem *regs) }; dev->bus = &mt76_mmio_ops; - dev->regs = regs; + dev->mmio.regs = regs; skb_queue_head_init(&dev->mmio.mcu.res_q); init_waitqueue_head(&dev->mmio.mcu.wait); diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h index 8c9b78d53705..56983213093f 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76.h +++ b/drivers/net/wireless/mediatek/mt76/mt76.h @@ -347,6 +347,7 @@ struct mt76_mmio { u32 msg_seq; } mcu; + void __iomem *regs; }; struct mt76_dev { @@ -362,7 +363,6 @@ struct mt76_dev { const struct mt76_bus_ops *bus; const struct mt76_driver_ops *drv; const struct mt76_mcu_ops *mcu_ops; - void __iomem *regs; struct device *dev; struct net_device napi_dev; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_dma.c b/drivers/net/wireless/mediatek/mt76/mt76x2_dma.c index 3c6bbb7df837..b1d6937c1e5f 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_dma.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_dma.c @@ -53,7 +53,7 @@ mt76x2_init_tx_queue(struct mt76x2_dev *dev, struct mt76_queue *q, { int ret; - q->regs = dev->mt76.regs + MT_TX_RING_BASE + idx * MT_RING_SIZE; + q->regs = dev->mt76.mmio.regs + MT_TX_RING_BASE + idx * MT_RING_SIZE; q->ndesc = n_desc; q->hw_idx = idx; @@ -72,7 +72,7 @@ mt76x2_init_rx_queue(struct mt76x2_dev *dev, struct mt76_queue *q, { int ret; - q->regs = dev->mt76.regs + MT_RX_RING_BASE + idx * MT_RING_SIZE; + q->regs = dev->mt76.mmio.regs + MT_RX_RING_BASE + idx * MT_RING_SIZE; q->ndesc = n_desc; q->buf_size = bufsize; From 0ed821bbbb0382770ae74a1fa21f51eded9ae895 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Sun, 9 Sep 2018 23:57:59 +0200 Subject: [PATCH 206/276] mt76x2: use mt76_dev instead of mt76x2_dev in mt76x2_mcu_msg_send Use mt76_dev data structure instead of mt76x2_dev one in mt76x2_mcu_msg_send and mt76x2_mcu_get_response routines. Moreover add wait_resp parameter to mt76x2_mcu_msg_send signature. This is a preliminary patch in order to unify mcu_msg_alloc()/mcu_msg_send() between pcie and usb code Signed-off-by: Lorenzo Bianconi Signed-off-by: Felix Fietkau --- .../net/wireless/mediatek/mt76/mt76x2_mcu.c | 47 ++++++++++--------- 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.c index fc1c0800170c..0c5a0f8bfd53 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.c @@ -36,7 +36,7 @@ static struct sk_buff *mt76x2_mcu_msg_alloc(const void *data, int len) } static struct sk_buff * -mt76x2_mcu_get_response(struct mt76x2_dev *dev, unsigned long expires) +mt76x2_mcu_get_response(struct mt76_dev *dev, unsigned long expires) { unsigned long timeout; @@ -44,15 +44,15 @@ mt76x2_mcu_get_response(struct mt76x2_dev *dev, unsigned long expires) return NULL; timeout = expires - jiffies; - wait_event_timeout(dev->mt76.mmio.mcu.wait, - !skb_queue_empty(&dev->mt76.mmio.mcu.res_q), + wait_event_timeout(dev->mmio.mcu.wait, + !skb_queue_empty(&dev->mmio.mcu.res_q), timeout); - return skb_dequeue(&dev->mt76.mmio.mcu.res_q); + return skb_dequeue(&dev->mmio.mcu.res_q); } static int -mt76x2_mcu_msg_send(struct mt76x2_dev *dev, struct sk_buff *skb, - enum mcu_cmd cmd) +mt76x2_mcu_msg_send(struct mt76_dev *dev, struct sk_buff *skb, + int cmd, bool wait_resp) { unsigned long expires = jiffies + HZ; int ret; @@ -61,23 +61,23 @@ mt76x2_mcu_msg_send(struct mt76x2_dev *dev, struct sk_buff *skb, if (!skb) return -EINVAL; - mutex_lock(&dev->mt76.mmio.mcu.mutex); + mutex_lock(&dev->mmio.mcu.mutex); - seq = ++dev->mt76.mmio.mcu.msg_seq & 0xf; + seq = ++dev->mmio.mcu.msg_seq & 0xf; if (!seq) - seq = ++dev->mt76.mmio.mcu.msg_seq & 0xf; + seq = ++dev->mmio.mcu.msg_seq & 0xf; - ret = mt76x2_tx_queue_mcu(&dev->mt76, MT_TXQ_MCU, skb, cmd, seq); + ret = mt76x2_tx_queue_mcu(dev, MT_TXQ_MCU, skb, cmd, seq); if (ret) goto out; - while (1) { + while (wait_resp) { u32 *rxfce; bool check_seq = false; skb = mt76x2_mcu_get_response(dev, expires); if (!skb) { - dev_err(dev->mt76.dev, + dev_err(dev->dev, "MCU message %d (seq %d) timed out\n", cmd, seq); ret = -ETIMEDOUT; @@ -95,7 +95,7 @@ mt76x2_mcu_msg_send(struct mt76x2_dev *dev, struct sk_buff *skb, } out: - mutex_unlock(&dev->mt76.mmio.mcu.mutex); + mutex_unlock(&dev->mmio.mcu.mutex); return ret; } @@ -256,7 +256,7 @@ mt76x2_mcu_function_select(struct mt76x2_dev *dev, enum mcu_function func, }; skb = mt76x2_mcu_msg_alloc(&msg, sizeof(msg)); - return mt76x2_mcu_msg_send(dev, skb, CMD_FUN_SET_OP); + return mt76x2_mcu_msg_send(&dev->mt76, skb, CMD_FUN_SET_OP, true); } int mt76x2_mcu_load_cr(struct mt76x2_dev *dev, u8 type, u8 temp_level, @@ -284,7 +284,7 @@ int mt76x2_mcu_load_cr(struct mt76x2_dev *dev, u8 type, u8 temp_level, /* first set the channel without the extension channel info */ skb = mt76x2_mcu_msg_alloc(&msg, sizeof(msg)); - return mt76x2_mcu_msg_send(dev, skb, CMD_LOAD_CR); + return mt76x2_mcu_msg_send(&dev->mt76, skb, CMD_LOAD_CR, true); } int mt76x2_mcu_set_channel(struct mt76x2_dev *dev, u8 channel, u8 bw, @@ -310,13 +310,14 @@ int mt76x2_mcu_set_channel(struct mt76x2_dev *dev, u8 channel, u8 bw, /* first set the channel without the extension channel info */ skb = mt76x2_mcu_msg_alloc(&msg, sizeof(msg)); - mt76x2_mcu_msg_send(dev, skb, CMD_SWITCH_CHANNEL_OP); + mt76x2_mcu_msg_send(&dev->mt76, skb, CMD_SWITCH_CHANNEL_OP, true); usleep_range(5000, 10000); msg.ext_chan = 0xe0 + bw_index; skb = mt76x2_mcu_msg_alloc(&msg, sizeof(msg)); - return mt76x2_mcu_msg_send(dev, skb, CMD_SWITCH_CHANNEL_OP); + return mt76x2_mcu_msg_send(&dev->mt76, skb, CMD_SWITCH_CHANNEL_OP, + true); } int mt76x2_mcu_set_radio_state(struct mt76x2_dev *dev, bool on) @@ -331,7 +332,8 @@ int mt76x2_mcu_set_radio_state(struct mt76x2_dev *dev, bool on) }; skb = mt76x2_mcu_msg_alloc(&msg, sizeof(msg)); - return mt76x2_mcu_msg_send(dev, skb, CMD_POWER_SAVING_OP); + return mt76x2_mcu_msg_send(&dev->mt76, skb, CMD_POWER_SAVING_OP, + true); } int mt76x2_mcu_calibrate(struct mt76x2_dev *dev, enum mcu_calibration type, @@ -350,7 +352,8 @@ int mt76x2_mcu_calibrate(struct mt76x2_dev *dev, enum mcu_calibration type, mt76_clear(dev, MT_MCU_COM_REG0, BIT(31)); skb = mt76x2_mcu_msg_alloc(&msg, sizeof(msg)); - ret = mt76x2_mcu_msg_send(dev, skb, CMD_CALIBRATION_OP); + ret = mt76x2_mcu_msg_send(&dev->mt76, skb, CMD_CALIBRATION_OP, + true); if (ret) return ret; @@ -374,7 +377,8 @@ int mt76x2_mcu_tssi_comp(struct mt76x2_dev *dev, }; skb = mt76x2_mcu_msg_alloc(&msg, sizeof(msg)); - return mt76x2_mcu_msg_send(dev, skb, CMD_CALIBRATION_OP); + return mt76x2_mcu_msg_send(&dev->mt76, skb, CMD_CALIBRATION_OP, + true); } int mt76x2_mcu_init_gain(struct mt76x2_dev *dev, u8 channel, u32 gain, @@ -393,7 +397,8 @@ int mt76x2_mcu_init_gain(struct mt76x2_dev *dev, u8 channel, u32 gain, msg.channel |= cpu_to_le32(BIT(31)); skb = mt76x2_mcu_msg_alloc(&msg, sizeof(msg)); - return mt76x2_mcu_msg_send(dev, skb, CMD_INIT_GAIN_OP); + return mt76x2_mcu_msg_send(&dev->mt76, skb, CMD_INIT_GAIN_OP, + true); } int mt76x2_mcu_init(struct mt76x2_dev *dev) From 8cff12371b33555630014ae7bf80850574a491de Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Sun, 9 Sep 2018 23:58:00 +0200 Subject: [PATCH 207/276] mt76x2: use common helpers for mcu_alloc_msg()/mcu_send_msg() Use mcu common helpers instead of mt76x2 specific routines for mcu_alloc_msg()/mcu_send_msg(). This is a preliminary patch to unify mt76e and mt76u mcu code Signed-off-by: Lorenzo Bianconi Signed-off-by: Felix Fietkau --- .../net/wireless/mediatek/mt76/mt76x2_mcu.c | 43 ++++++++++--------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.c index 0c5a0f8bfd53..d067ad48c397 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.c @@ -255,8 +255,8 @@ mt76x2_mcu_function_select(struct mt76x2_dev *dev, enum mcu_function func, .value = cpu_to_le32(val), }; - skb = mt76x2_mcu_msg_alloc(&msg, sizeof(msg)); - return mt76x2_mcu_msg_send(&dev->mt76, skb, CMD_FUN_SET_OP, true); + skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg)); + return mt76_mcu_send_msg(dev, skb, CMD_FUN_SET_OP, true); } int mt76x2_mcu_load_cr(struct mt76x2_dev *dev, u8 type, u8 temp_level, @@ -283,8 +283,8 @@ int mt76x2_mcu_load_cr(struct mt76x2_dev *dev, u8 type, u8 temp_level, msg.cfg = cpu_to_le32(val); /* first set the channel without the extension channel info */ - skb = mt76x2_mcu_msg_alloc(&msg, sizeof(msg)); - return mt76x2_mcu_msg_send(&dev->mt76, skb, CMD_LOAD_CR, true); + skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg)); + return mt76_mcu_send_msg(dev, skb, CMD_LOAD_CR, true); } int mt76x2_mcu_set_channel(struct mt76x2_dev *dev, u8 channel, u8 bw, @@ -309,15 +309,14 @@ int mt76x2_mcu_set_channel(struct mt76x2_dev *dev, u8 channel, u8 bw, }; /* first set the channel without the extension channel info */ - skb = mt76x2_mcu_msg_alloc(&msg, sizeof(msg)); - mt76x2_mcu_msg_send(&dev->mt76, skb, CMD_SWITCH_CHANNEL_OP, true); + skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg)); + mt76_mcu_send_msg(dev, skb, CMD_SWITCH_CHANNEL_OP, true); usleep_range(5000, 10000); msg.ext_chan = 0xe0 + bw_index; - skb = mt76x2_mcu_msg_alloc(&msg, sizeof(msg)); - return mt76x2_mcu_msg_send(&dev->mt76, skb, CMD_SWITCH_CHANNEL_OP, - true); + skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg)); + return mt76_mcu_send_msg(dev, skb, CMD_SWITCH_CHANNEL_OP, true); } int mt76x2_mcu_set_radio_state(struct mt76x2_dev *dev, bool on) @@ -331,9 +330,8 @@ int mt76x2_mcu_set_radio_state(struct mt76x2_dev *dev, bool on) .level = cpu_to_le32(0), }; - skb = mt76x2_mcu_msg_alloc(&msg, sizeof(msg)); - return mt76x2_mcu_msg_send(&dev->mt76, skb, CMD_POWER_SAVING_OP, - true); + skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg)); + return mt76_mcu_send_msg(dev, skb, CMD_POWER_SAVING_OP, true); } int mt76x2_mcu_calibrate(struct mt76x2_dev *dev, enum mcu_calibration type, @@ -351,9 +349,8 @@ int mt76x2_mcu_calibrate(struct mt76x2_dev *dev, enum mcu_calibration type, mt76_clear(dev, MT_MCU_COM_REG0, BIT(31)); - skb = mt76x2_mcu_msg_alloc(&msg, sizeof(msg)); - ret = mt76x2_mcu_msg_send(&dev->mt76, skb, CMD_CALIBRATION_OP, - true); + skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg)); + ret = mt76_mcu_send_msg(dev, skb, CMD_CALIBRATION_OP, true); if (ret) return ret; @@ -376,9 +373,8 @@ int mt76x2_mcu_tssi_comp(struct mt76x2_dev *dev, .data = *tssi_data, }; - skb = mt76x2_mcu_msg_alloc(&msg, sizeof(msg)); - return mt76x2_mcu_msg_send(&dev->mt76, skb, CMD_CALIBRATION_OP, - true); + skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg)); + return mt76_mcu_send_msg(dev, skb, CMD_CALIBRATION_OP, true); } int mt76x2_mcu_init_gain(struct mt76x2_dev *dev, u8 channel, u32 gain, @@ -396,15 +392,20 @@ int mt76x2_mcu_init_gain(struct mt76x2_dev *dev, u8 channel, u32 gain, if (force) msg.channel |= cpu_to_le32(BIT(31)); - skb = mt76x2_mcu_msg_alloc(&msg, sizeof(msg)); - return mt76x2_mcu_msg_send(&dev->mt76, skb, CMD_INIT_GAIN_OP, - true); + skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg)); + return mt76_mcu_send_msg(dev, skb, CMD_INIT_GAIN_OP, true); } int mt76x2_mcu_init(struct mt76x2_dev *dev) { + static const struct mt76_mcu_ops mt76x2_mcu_ops = { + .mcu_msg_alloc = mt76x2_mcu_msg_alloc, + .mcu_send_msg = mt76x2_mcu_msg_send, + }; int ret; + dev->mt76.mcu_ops = &mt76x2_mcu_ops; + ret = mt76pci_load_rom_patch(dev); if (ret) return ret; From 79394f40801065bc2c7c13cc9ec7a9467060a389 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Sun, 9 Sep 2018 23:58:01 +0200 Subject: [PATCH 208/276] mt76: unify firmware header between mt76x0 and mt76x2 Move mt76x2_fw_header definition in mt76x02_mcu.h and remove duplicated code Signed-off-by: Lorenzo Bianconi Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c | 15 +++------------ .../net/wireless/mediatek/mt76/mt76x02_mcu.h | 17 +++++++++++++++++ drivers/net/wireless/mediatek/mt76/mt76x2_mcu.c | 8 ++++---- drivers/net/wireless/mediatek/mt76/mt76x2_mcu.h | 17 ----------------- .../net/wireless/mediatek/mt76/mt76x2u_mcu.c | 8 ++++---- 5 files changed, 28 insertions(+), 37 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c index d757cde33f74..f5f619a3a196 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c @@ -73,17 +73,8 @@ mt76x0_mcu_calibrate(struct mt76x0_dev *dev, enum mcu_calibrate cal, u32 val) return mt76_mcu_send_msg(dev, skb, CMD_CALIBRATION_OP, true); } -struct mt76_fw_header { - __le32 ilm_len; - __le32 dlm_len; - __le16 build_ver; - __le16 fw_ver; - u8 pad[4]; - char build_time[16]; -}; - struct mt76_fw { - struct mt76_fw_header hdr; + struct mt76x02_fw_header hdr; u8 ivb[MT_MCU_IVB_SIZE]; u8 ilm[]; }; @@ -140,7 +131,7 @@ mt76x0_upload_firmware(struct mt76x0_dev *dev, const struct mt76_fw *fw) static int mt76x0_load_firmware(struct mt76x0_dev *dev) { const struct firmware *fw; - const struct mt76_fw_header *hdr; + const struct mt76x02_fw_header *hdr; int len, ret; u32 val; @@ -157,7 +148,7 @@ static int mt76x0_load_firmware(struct mt76x0_dev *dev) if (!fw || !fw->data || fw->size < sizeof(*hdr)) goto err_inv_fw; - hdr = (const struct mt76_fw_header *) fw->data; + hdr = (const struct mt76x02_fw_header *)fw->data; if (le32_to_cpu(hdr->ilm_len) <= MT_MCU_IVB_SIZE) goto err_inv_fw; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mcu.h b/drivers/net/wireless/mediatek/mt76/mt76x02_mcu.h index 21181fddee98..88b33b12ed4e 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_mcu.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mcu.h @@ -68,4 +68,21 @@ enum mcu_function { GET_FW_VERSION = 5, }; +struct mt76x02_fw_header { + __le32 ilm_len; + __le32 dlm_len; + __le16 build_ver; + __le16 fw_ver; + u8 pad[4]; + char build_time[16]; +}; + +struct mt76x02_patch_header { + char build_time[16]; + char platform[4]; + char hw_version[4]; + char patch_version[4]; + u8 pad[2]; +}; + #endif /* __MT76x02_MCU_H */ diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.c index d067ad48c397..3fbaebe8b408 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.c @@ -104,7 +104,7 @@ static int mt76pci_load_rom_patch(struct mt76x2_dev *dev) { const struct firmware *fw = NULL; - struct mt76x2_patch_header *hdr; + struct mt76x02_patch_header *hdr; bool rom_protect = !is_mt7612(dev); int len, ret = 0; __le32 *cur; @@ -139,7 +139,7 @@ mt76pci_load_rom_patch(struct mt76x2_dev *dev) goto out; } - hdr = (struct mt76x2_patch_header *) fw->data; + hdr = (struct mt76x02_patch_header *)fw->data; dev_info(dev->mt76.dev, "ROM patch build: %.15s\n", hdr->build_time); mt76_wr(dev, MT_MCU_PCIE_REMAP_BASE4, MT_MCU_ROM_PATCH_OFFSET); @@ -170,7 +170,7 @@ static int mt76pci_load_firmware(struct mt76x2_dev *dev) { const struct firmware *fw; - const struct mt76x2_fw_header *hdr; + const struct mt76x02_fw_header *hdr; int len, ret; __le32 *cur; u32 offset, val; @@ -182,7 +182,7 @@ mt76pci_load_firmware(struct mt76x2_dev *dev) if (!fw || !fw->data || fw->size < sizeof(*hdr)) goto error; - hdr = (const struct mt76x2_fw_header *) fw->data; + hdr = (const struct mt76x02_fw_header *)fw->data; len = sizeof(*hdr); len += le32_to_cpu(hdr->ilm_len); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.h b/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.h index 564bcac27401..c5da3293dafd 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.h @@ -101,23 +101,6 @@ struct mt76x2_tssi_comp { u8 offset1; } __packed __aligned(4); -struct mt76x2_fw_header { - __le32 ilm_len; - __le32 dlm_len; - __le16 build_ver; - __le16 fw_ver; - u8 pad[4]; - char build_time[16]; -}; - -struct mt76x2_patch_header { - char build_time[16]; - char platform[4]; - char hw_version[4]; - char patch_version[4]; - u8 pad[2]; -}; - int mt76x2_mcu_calibrate(struct mt76x2_dev *dev, enum mcu_calibration type, u32 param); int mt76x2_mcu_tssi_comp(struct mt76x2_dev *dev, struct mt76x2_tssi_comp *tssi_data); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2u_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x2u_mcu.c index e93123e4a395..412e8f466061 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2u_mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2u_mcu.c @@ -236,7 +236,7 @@ static void mt76x2u_mcu_reset_wmt(struct mt76x2_dev *dev) static int mt76x2u_mcu_load_rom_patch(struct mt76x2_dev *dev) { bool rom_protect = !is_mt7612(dev); - struct mt76x2_patch_header *hdr; + struct mt76x02_patch_header *hdr; u32 val, patch_mask, patch_reg; const struct firmware *fw; int err; @@ -271,7 +271,7 @@ static int mt76x2u_mcu_load_rom_patch(struct mt76x2_dev *dev) goto out; } - hdr = (struct mt76x2_patch_header *)fw->data; + hdr = (struct mt76x02_patch_header *)fw->data; dev_info(dev->mt76.dev, "ROM patch build: %.15s\n", hdr->build_time); /* enable USB_DMA_CFG */ @@ -323,7 +323,7 @@ static int mt76x2u_mcu_load_rom_patch(struct mt76x2_dev *dev) static int mt76x2u_mcu_load_firmware(struct mt76x2_dev *dev) { u32 val, dlm_offset = MT76U_MCU_DLM_OFFSET; - const struct mt76x2_fw_header *hdr; + const struct mt76x02_fw_header *hdr; int err, len, ilm_len, dlm_len; const struct firmware *fw; @@ -336,7 +336,7 @@ static int mt76x2u_mcu_load_firmware(struct mt76x2_dev *dev) goto out; } - hdr = (const struct mt76x2_fw_header *)fw->data; + hdr = (const struct mt76x02_fw_header *)fw->data; ilm_len = le32_to_cpu(hdr->ilm_len); dlm_len = le32_to_cpu(hdr->dlm_len); len = sizeof(*hdr) + ilm_len + dlm_len; From 36fd09dd0fa4cb60f7fb0971b7e26c1fad8499ce Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Sun, 9 Sep 2018 23:58:02 +0200 Subject: [PATCH 209/276] mt76: move mt76{0,2} mcu shared code in mt76x02_mcu.c Move shared mt76x2/mt76x0 mcu shared code in a common file and remove duplicated code Signed-off-by: Lorenzo Bianconi Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/Makefile | 2 +- .../net/wireless/mediatek/mt76/mt76x0/mcu.c | 18 +- .../net/wireless/mediatek/mt76/mt76x0/mcu.h | 3 - .../net/wireless/mediatek/mt76/mt76x0/phy.c | 2 +- .../net/wireless/mediatek/mt76/mt76x02_mcu.c | 183 ++++++++++++++++++ .../net/wireless/mediatek/mt76/mt76x02_mcu.h | 10 + drivers/net/wireless/mediatek/mt76/mt76x2.h | 4 - .../net/wireless/mediatek/mt76/mt76x2_dma.c | 30 --- .../net/wireless/mediatek/mt76/mt76x2_init.c | 4 +- .../net/wireless/mediatek/mt76/mt76x2_mcu.c | 128 +----------- .../net/wireless/mediatek/mt76/mt76x2_phy.c | 2 +- drivers/net/wireless/mediatek/mt76/mt76x2u.h | 1 - .../net/wireless/mediatek/mt76/mt76x2u_init.c | 2 +- .../net/wireless/mediatek/mt76/mt76x2u_mcu.c | 39 +--- 14 files changed, 206 insertions(+), 222 deletions(-) create mode 100644 drivers/net/wireless/mediatek/mt76/mt76x02_mcu.c diff --git a/drivers/net/wireless/mediatek/mt76/Makefile b/drivers/net/wireless/mediatek/mt76/Makefile index e8bd26923d73..6a5c224e9bea 100644 --- a/drivers/net/wireless/mediatek/mt76/Makefile +++ b/drivers/net/wireless/mediatek/mt76/Makefile @@ -15,7 +15,7 @@ mt76-usb-y := usb.o usb_trace.o usb_mcu.o CFLAGS_trace.o := -I$(src) CFLAGS_usb_trace.o := -I$(src) -mt76x02-lib-y := mt76x02_util.o mt76x02_mac.o +mt76x02-lib-y := mt76x02_util.o mt76x02_mac.o mt76x02_mcu.o mt76x02-usb-y := mt76x02_usb_mcu.o mt76x02_usb_core.o diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c index f5f619a3a196..551dad6ca058 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c @@ -41,22 +41,6 @@ static inline void skb_put_le32(struct sk_buff *skb, u32 val) put_unaligned_le32(val, skb_put(skb, 4)); } -int mt76x0_mcu_function_select(struct mt76x0_dev *dev, - enum mcu_function func, u32 val) -{ - struct sk_buff *skb; - struct { - __le32 id; - __le32 value; - } __packed __aligned(4) msg = { - .id = cpu_to_le32(func), - .value = cpu_to_le32(val), - }; - - skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg)); - return mt76_mcu_send_msg(dev, skb, CMD_FUN_SET_OP, func == 5); -} - int mt76x0_mcu_calibrate(struct mt76x0_dev *dev, enum mcu_calibrate cal, u32 val) { @@ -227,5 +211,5 @@ int mt76x0_mcu_init(struct mt76x0_dev *dev) int mt76x0_mcu_cmd_init(struct mt76x0_dev *dev) { - return mt76x0_mcu_function_select(dev, Q_SELECT, 1); + return mt76x02_mcu_function_select(&dev->mt76, Q_SELECT, 1, false); } diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.h b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.h index a551ad5e3af4..6ba38022d26a 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.h @@ -47,7 +47,4 @@ int mt76x0_mcu_cmd_init(struct mt76x0_dev *dev); int mt76x0_mcu_calibrate(struct mt76x0_dev *dev, enum mcu_calibrate cal, u32 val); -int -mt76x0_mcu_function_select(struct mt76x0_dev *dev, enum mcu_function func, u32 val); - #endif diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c index 0e9cf354cbec..512e637635f5 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c @@ -641,7 +641,7 @@ mt76x0_bbp_set_bw(struct mt76x0_dev *dev, enum nl80211_chan_width width) return ; } - mt76x0_mcu_function_select(dev, BW_SETTING, bw); + mt76x02_mcu_function_select(&dev->mt76, BW_SETTING, bw, false); } static void diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x02_mcu.c new file mode 100644 index 000000000000..3dc36ace91da --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mcu.c @@ -0,0 +1,183 @@ +/* + * Copyright (C) 2016 Felix Fietkau + * Copyright (C) 2018 Lorenzo Bianconi + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include + +#include "mt76.h" +#include "mt76x02_mcu.h" +#include "mt76x02_dma.h" + +struct sk_buff *mt76x02_mcu_msg_alloc(const void *data, int len) +{ + struct sk_buff *skb; + + skb = alloc_skb(len, GFP_KERNEL); + if (!skb) + return NULL; + memcpy(skb_put(skb, len), data, len); + + return skb; +} +EXPORT_SYMBOL_GPL(mt76x02_mcu_msg_alloc); + +static struct sk_buff * +mt76x02_mcu_get_response(struct mt76_dev *dev, unsigned long expires) +{ + unsigned long timeout; + + if (!time_is_after_jiffies(expires)) + return NULL; + + timeout = expires - jiffies; + wait_event_timeout(dev->mmio.mcu.wait, + !skb_queue_empty(&dev->mmio.mcu.res_q), + timeout); + return skb_dequeue(&dev->mmio.mcu.res_q); +} + +static int +mt76x02_tx_queue_mcu(struct mt76_dev *dev, enum mt76_txq_id qid, + struct sk_buff *skb, int cmd, int seq) +{ + struct mt76_queue *q = &dev->q_tx[qid]; + struct mt76_queue_buf buf; + dma_addr_t addr; + u32 tx_info; + + tx_info = MT_MCU_MSG_TYPE_CMD | + FIELD_PREP(MT_MCU_MSG_CMD_TYPE, cmd) | + FIELD_PREP(MT_MCU_MSG_CMD_SEQ, seq) | + FIELD_PREP(MT_MCU_MSG_PORT, CPU_TX_PORT) | + FIELD_PREP(MT_MCU_MSG_LEN, skb->len); + + addr = dma_map_single(dev->dev, skb->data, skb->len, + DMA_TO_DEVICE); + if (dma_mapping_error(dev->dev, addr)) + return -ENOMEM; + + buf.addr = addr; + buf.len = skb->len; + spin_lock_bh(&q->lock); + dev->queue_ops->add_buf(dev, q, &buf, 1, tx_info, skb, NULL); + dev->queue_ops->kick(dev, q); + spin_unlock_bh(&q->lock); + + return 0; +} + +int mt76x02_mcu_msg_send(struct mt76_dev *dev, struct sk_buff *skb, + int cmd, bool wait_resp) +{ + unsigned long expires = jiffies + HZ; + int ret; + u8 seq; + + if (!skb) + return -EINVAL; + + mutex_lock(&dev->mmio.mcu.mutex); + + seq = ++dev->mmio.mcu.msg_seq & 0xf; + if (!seq) + seq = ++dev->mmio.mcu.msg_seq & 0xf; + + ret = mt76x02_tx_queue_mcu(dev, MT_TXQ_MCU, skb, cmd, seq); + if (ret) + goto out; + + while (wait_resp) { + u32 *rxfce; + bool check_seq = false; + + skb = mt76x02_mcu_get_response(dev, expires); + if (!skb) { + dev_err(dev->dev, + "MCU message %d (seq %d) timed out\n", cmd, + seq); + ret = -ETIMEDOUT; + break; + } + + rxfce = (u32 *) skb->cb; + + if (seq == FIELD_GET(MT_RX_FCE_INFO_CMD_SEQ, *rxfce)) + check_seq = true; + + dev_kfree_skb(skb); + if (check_seq) + break; + } + +out: + mutex_unlock(&dev->mmio.mcu.mutex); + + return ret; +} +EXPORT_SYMBOL_GPL(mt76x02_mcu_msg_send); + +int mt76x02_mcu_function_select(struct mt76_dev *dev, + enum mcu_function func, + u32 val, bool wait_resp) +{ + struct sk_buff *skb; + struct { + __le32 id; + __le32 value; + } __packed __aligned(4) msg = { + .id = cpu_to_le32(func), + .value = cpu_to_le32(val), + }; + + skb = dev->mcu_ops->mcu_msg_alloc(&msg, sizeof(msg)); + return dev->mcu_ops->mcu_send_msg(dev, skb, CMD_FUN_SET_OP, + wait_resp); +} +EXPORT_SYMBOL_GPL(mt76x02_mcu_function_select); + +int mt76x02_mcu_set_radio_state(struct mt76_dev *dev, bool on, + bool wait_resp) +{ + struct sk_buff *skb; + struct { + __le32 mode; + __le32 level; + } __packed __aligned(4) msg = { + .mode = cpu_to_le32(on ? RADIO_ON : RADIO_OFF), + .level = cpu_to_le32(0), + }; + + skb = dev->mcu_ops->mcu_msg_alloc(&msg, sizeof(msg)); + return dev->mcu_ops->mcu_send_msg(dev, skb, CMD_POWER_SAVING_OP, + wait_resp); +} +EXPORT_SYMBOL_GPL(mt76x02_mcu_set_radio_state); + +int mt76x02_mcu_cleanup(struct mt76_dev *dev) +{ + struct sk_buff *skb; + + dev->bus->wr(dev, MT_MCU_INT_LEVEL, 1); + usleep_range(20000, 30000); + + while ((skb = skb_dequeue(&dev->mmio.mcu.res_q)) != NULL) + dev_kfree_skb(skb); + + return 0; +} +EXPORT_SYMBOL_GPL(mt76x02_mcu_cleanup); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mcu.h b/drivers/net/wireless/mediatek/mt76/mt76x02_mcu.h index 88b33b12ed4e..cbdf6fc09971 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_mcu.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mcu.h @@ -85,4 +85,14 @@ struct mt76x02_patch_header { u8 pad[2]; }; +int mt76x02_mcu_cleanup(struct mt76_dev *dev); +struct sk_buff *mt76x02_mcu_msg_alloc(const void *data, int len); +int mt76x02_mcu_msg_send(struct mt76_dev *dev, struct sk_buff *skb, + int cmd, bool wait_resp); +int mt76x02_mcu_function_select(struct mt76_dev *dev, + enum mcu_function func, + u32 val, bool wait_resp); +int mt76x02_mcu_set_radio_state(struct mt76_dev *dev, bool on, + bool wait_resp); + #endif /* __MT76x02_MCU_H */ diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2.h b/drivers/net/wireless/mediatek/mt76/mt76x2.h index 07400d9aba3f..3150e43a3e31 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x2.h @@ -188,18 +188,14 @@ void mt76x2_phy_set_txpower(struct mt76x2_dev *dev); int mt76x2_mcu_init(struct mt76x2_dev *dev); int mt76x2_mcu_set_channel(struct mt76x2_dev *dev, u8 channel, u8 bw, u8 bw_index, bool scan); -int mt76x2_mcu_set_radio_state(struct mt76x2_dev *dev, bool on); int mt76x2_mcu_load_cr(struct mt76x2_dev *dev, u8 type, u8 temp_level, u8 channel); -int mt76x2_mcu_cleanup(struct mt76x2_dev *dev); int mt76x2_dma_init(struct mt76x2_dev *dev); void mt76x2_dma_cleanup(struct mt76x2_dev *dev); void mt76x2_cleanup(struct mt76x2_dev *dev); -int mt76x2_tx_queue_mcu(struct mt76_dev *dev, enum mt76_txq_id qid, - struct sk_buff *skb, int cmd, int seq); void mt76x2_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, struct sk_buff *skb); int mt76x2_tx_prepare_skb(struct mt76_dev *mdev, void *txwi, diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_dma.c b/drivers/net/wireless/mediatek/mt76/mt76x2_dma.c index b1d6937c1e5f..879ed9138841 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_dma.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_dma.c @@ -17,36 +17,6 @@ #include "mt76x2.h" #include "mt76x02_dma.h" -int -mt76x2_tx_queue_mcu(struct mt76_dev *dev, enum mt76_txq_id qid, - struct sk_buff *skb, int cmd, int seq) -{ - struct mt76_queue *q = &dev->q_tx[qid]; - struct mt76_queue_buf buf; - dma_addr_t addr; - u32 tx_info; - - tx_info = MT_MCU_MSG_TYPE_CMD | - FIELD_PREP(MT_MCU_MSG_CMD_TYPE, cmd) | - FIELD_PREP(MT_MCU_MSG_CMD_SEQ, seq) | - FIELD_PREP(MT_MCU_MSG_PORT, CPU_TX_PORT) | - FIELD_PREP(MT_MCU_MSG_LEN, skb->len); - - addr = dma_map_single(dev->dev, skb->data, skb->len, - DMA_TO_DEVICE); - if (dma_mapping_error(dev->dev, addr)) - return -ENOMEM; - - buf.addr = addr; - buf.len = skb->len; - spin_lock_bh(&q->lock); - dev->queue_ops->add_buf(dev, q, &buf, 1, tx_info, skb, NULL); - dev->queue_ops->kick(dev, q); - spin_unlock_bh(&q->lock); - - return 0; -} - static int mt76x2_init_tx_queue(struct mt76x2_dev *dev, struct mt76_queue *q, int idx, int n_desc) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_init.c b/drivers/net/wireless/mediatek/mt76/mt76x2_init.c index 56a4b86bb665..33f7fabf45c0 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_init.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_init.c @@ -402,7 +402,7 @@ void mt76x2_stop_hardware(struct mt76x2_dev *dev) { cancel_delayed_work_sync(&dev->cal_work); cancel_delayed_work_sync(&dev->mac_work); - mt76x2_mcu_set_radio_state(dev, false); + mt76x02_mcu_set_radio_state(&dev->mt76, false, true); mt76x2_mac_stop(dev, false); } @@ -412,7 +412,7 @@ void mt76x2_cleanup(struct mt76x2_dev *dev) tasklet_disable(&dev->pre_tbtt_tasklet); mt76x2_stop_hardware(dev); mt76x2_dma_cleanup(dev); - mt76x2_mcu_cleanup(dev); + mt76x02_mcu_cleanup(&dev->mt76); } struct mt76x2_dev *mt76x2_alloc_device(struct device *pdev) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.c index 3fbaebe8b408..edcee8d5c764 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.c @@ -23,83 +23,6 @@ #include "mt76x2_eeprom.h" #include "mt76x02_dma.h" -static struct sk_buff *mt76x2_mcu_msg_alloc(const void *data, int len) -{ - struct sk_buff *skb; - - skb = alloc_skb(len, GFP_KERNEL); - if (!skb) - return NULL; - memcpy(skb_put(skb, len), data, len); - - return skb; -} - -static struct sk_buff * -mt76x2_mcu_get_response(struct mt76_dev *dev, unsigned long expires) -{ - unsigned long timeout; - - if (!time_is_after_jiffies(expires)) - return NULL; - - timeout = expires - jiffies; - wait_event_timeout(dev->mmio.mcu.wait, - !skb_queue_empty(&dev->mmio.mcu.res_q), - timeout); - return skb_dequeue(&dev->mmio.mcu.res_q); -} - -static int -mt76x2_mcu_msg_send(struct mt76_dev *dev, struct sk_buff *skb, - int cmd, bool wait_resp) -{ - unsigned long expires = jiffies + HZ; - int ret; - u8 seq; - - if (!skb) - return -EINVAL; - - mutex_lock(&dev->mmio.mcu.mutex); - - seq = ++dev->mmio.mcu.msg_seq & 0xf; - if (!seq) - seq = ++dev->mmio.mcu.msg_seq & 0xf; - - ret = mt76x2_tx_queue_mcu(dev, MT_TXQ_MCU, skb, cmd, seq); - if (ret) - goto out; - - while (wait_resp) { - u32 *rxfce; - bool check_seq = false; - - skb = mt76x2_mcu_get_response(dev, expires); - if (!skb) { - dev_err(dev->dev, - "MCU message %d (seq %d) timed out\n", cmd, - seq); - ret = -ETIMEDOUT; - break; - } - - rxfce = (u32 *) skb->cb; - - if (seq == FIELD_GET(MT_RX_FCE_INFO_CMD_SEQ, *rxfce)) - check_seq = true; - - dev_kfree_skb(skb); - if (check_seq) - break; - } - -out: - mutex_unlock(&dev->mmio.mcu.mutex); - - return ret; -} - static int mt76pci_load_rom_patch(struct mt76x2_dev *dev) { @@ -242,23 +165,6 @@ mt76pci_load_firmware(struct mt76x2_dev *dev) return -ENOENT; } -static int -mt76x2_mcu_function_select(struct mt76x2_dev *dev, enum mcu_function func, - u32 val) -{ - struct sk_buff *skb; - struct { - __le32 id; - __le32 value; - } __packed __aligned(4) msg = { - .id = cpu_to_le32(func), - .value = cpu_to_le32(val), - }; - - skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg)); - return mt76_mcu_send_msg(dev, skb, CMD_FUN_SET_OP, true); -} - int mt76x2_mcu_load_cr(struct mt76x2_dev *dev, u8 type, u8 temp_level, u8 channel) { @@ -319,21 +225,6 @@ int mt76x2_mcu_set_channel(struct mt76x2_dev *dev, u8 channel, u8 bw, return mt76_mcu_send_msg(dev, skb, CMD_SWITCH_CHANNEL_OP, true); } -int mt76x2_mcu_set_radio_state(struct mt76x2_dev *dev, bool on) -{ - struct sk_buff *skb; - struct { - __le32 mode; - __le32 level; - } __packed __aligned(4) msg = { - .mode = cpu_to_le32(on ? RADIO_ON : RADIO_OFF), - .level = cpu_to_le32(0), - }; - - skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg)); - return mt76_mcu_send_msg(dev, skb, CMD_POWER_SAVING_OP, true); -} - int mt76x2_mcu_calibrate(struct mt76x2_dev *dev, enum mcu_calibration type, u32 param) { @@ -399,8 +290,8 @@ int mt76x2_mcu_init_gain(struct mt76x2_dev *dev, u8 channel, u32 gain, int mt76x2_mcu_init(struct mt76x2_dev *dev) { static const struct mt76_mcu_ops mt76x2_mcu_ops = { - .mcu_msg_alloc = mt76x2_mcu_msg_alloc, - .mcu_send_msg = mt76x2_mcu_msg_send, + .mcu_msg_alloc = mt76x02_mcu_msg_alloc, + .mcu_send_msg = mt76x02_mcu_msg_send, }; int ret; @@ -414,19 +305,6 @@ int mt76x2_mcu_init(struct mt76x2_dev *dev) if (ret) return ret; - mt76x2_mcu_function_select(dev, Q_SELECT, 1); - return 0; -} - -int mt76x2_mcu_cleanup(struct mt76x2_dev *dev) -{ - struct sk_buff *skb; - - mt76_wr(dev, MT_MCU_INT_LEVEL, 1); - usleep_range(20000, 30000); - - while ((skb = skb_dequeue(&dev->mt76.mmio.mcu.res_q)) != NULL) - dev_kfree_skb(skb); - + mt76x02_mcu_function_select(&dev->mt76, Q_SELECT, 1, true); return 0; } diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_phy.c b/drivers/net/wireless/mediatek/mt76/mt76x2_phy.c index 84c96c0415b6..f7c902ad4c96 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_phy.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_phy.c @@ -489,7 +489,7 @@ int mt76x2_phy_start(struct mt76x2_dev *dev) { int ret; - ret = mt76x2_mcu_set_radio_state(dev, true); + ret = mt76x02_mcu_set_radio_state(&dev->mt76, true, true); if (ret) return ret; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2u.h b/drivers/net/wireless/mediatek/mt76/mt76x2u.h index 83abbafc0c1a..2e7789e6a849 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2u.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x2u.h @@ -60,7 +60,6 @@ int mt76x2u_mcu_init_gain(struct mt76x2_dev *dev, u8 channel, u32 gain, bool force); int mt76x2u_mcu_set_dynamic_vga(struct mt76x2_dev *dev, u8 channel, bool ap, bool ext, int rssi, u32 false_cca); -int mt76x2u_mcu_set_radio_state(struct mt76x2_dev *dev, bool val); int mt76x2u_mcu_load_cr(struct mt76x2_dev *dev, u8 type, u8 temp_level, u8 channel); int mt76x2u_mcu_init(struct mt76x2_dev *dev); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2u_init.c b/drivers/net/wireless/mediatek/mt76/mt76x2u_init.c index 2f828658f566..6661b9228e45 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2u_init.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2u_init.c @@ -310,7 +310,7 @@ void mt76x2u_stop_hw(struct mt76x2_dev *dev) void mt76x2u_cleanup(struct mt76x2_dev *dev) { - mt76x2u_mcu_set_radio_state(dev, false); + mt76x02_mcu_set_radio_state(&dev->mt76, false, false); mt76x2u_stop_hw(dev); mt76u_queues_deinit(&dev->mt76); mt76u_mcu_deinit(&dev->mt76); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2u_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x2u_mcu.c index 412e8f466061..abb9308d2179 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2u_mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2u_mcu.c @@ -29,40 +29,6 @@ #define MT76U_MCU_DLM_OFFSET 0x110000 #define MT76U_MCU_ROM_PATCH_OFFSET 0x90000 -static int -mt76x2u_mcu_function_select(struct mt76x2_dev *dev, enum mcu_function func, - u32 val) -{ - struct { - __le32 id; - __le32 value; - } __packed __aligned(4) msg = { - .id = cpu_to_le32(func), - .value = cpu_to_le32(val), - }; - struct sk_buff *skb; - - skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg)); - return mt76_mcu_send_msg(dev, skb, CMD_FUN_SET_OP, - func != Q_SELECT); -} - -int mt76x2u_mcu_set_radio_state(struct mt76x2_dev *dev, bool val) -{ - struct { - __le32 mode; - __le32 level; - } __packed __aligned(4) msg = { - .mode = cpu_to_le32(val ? RADIO_ON : RADIO_OFF), - .level = cpu_to_le32(0), - }; - struct sk_buff *skb; - - skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg)); - return mt76_mcu_send_msg(dev, skb, CMD_POWER_SAVING_OP, - false); -} - int mt76x2u_mcu_load_cr(struct mt76x2_dev *dev, u8 type, u8 temp_level, u8 channel) { @@ -426,9 +392,10 @@ int mt76x2u_mcu_init(struct mt76x2_dev *dev) { int err; - err = mt76x2u_mcu_function_select(dev, Q_SELECT, 1); + err = mt76x02_mcu_function_select(&dev->mt76, Q_SELECT, + 1, false); if (err < 0) return err; - return mt76x2u_mcu_set_radio_state(dev, true); + return mt76x02_mcu_set_radio_state(&dev->mt76, true, false); } From bc3669017282cee1cde0e770956723fcb532cc55 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Sun, 9 Sep 2018 23:58:03 +0200 Subject: [PATCH 210/276] mt76x2: move mt76x2 mcu shared code in mt76x2_mcu_common.c Move shared mt76x2 {pcie/usb} mcu shared code in a common file and remove duplicated code Signed-off-by: Lorenzo Bianconi Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/Makefile | 2 +- .../net/wireless/mediatek/mt76/mt76x2_mcu.c | 95 -------------- .../mediatek/mt76/mt76x2_mcu_common.c | 124 ++++++++++++++++++ drivers/net/wireless/mediatek/mt76/mt76x2u.h | 8 -- .../net/wireless/mediatek/mt76/mt76x2u_init.c | 2 +- .../net/wireless/mediatek/mt76/mt76x2u_mcu.c | 94 ------------- .../net/wireless/mediatek/mt76/mt76x2u_phy.c | 8 +- 7 files changed, 130 insertions(+), 203 deletions(-) create mode 100644 drivers/net/wireless/mediatek/mt76/mt76x2_mcu_common.c diff --git a/drivers/net/wireless/mediatek/mt76/Makefile b/drivers/net/wireless/mediatek/mt76/Makefile index 6a5c224e9bea..4d25b5c3b70b 100644 --- a/drivers/net/wireless/mediatek/mt76/Makefile +++ b/drivers/net/wireless/mediatek/mt76/Makefile @@ -22,7 +22,7 @@ mt76x02-usb-y := mt76x02_usb_mcu.o mt76x02_usb_core.o mt76x2-common-y := \ mt76x2_eeprom.o mt76x2_tx_common.o mt76x2_mac_common.o \ mt76x2_init_common.o mt76x2_common.o mt76x2_phy_common.o \ - mt76x2_debugfs.o + mt76x2_debugfs.o mt76x2_mcu_common.o mt76x2e-y := \ mt76x2_pci.o mt76x2_dma.o \ diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.c index edcee8d5c764..d808892a8995 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.c @@ -165,66 +165,6 @@ mt76pci_load_firmware(struct mt76x2_dev *dev) return -ENOENT; } -int mt76x2_mcu_load_cr(struct mt76x2_dev *dev, u8 type, u8 temp_level, - u8 channel) -{ - struct sk_buff *skb; - struct { - u8 cr_mode; - u8 temp; - u8 ch; - u8 _pad0; - - __le32 cfg; - } __packed __aligned(4) msg = { - .cr_mode = type, - .temp = temp_level, - .ch = channel, - }; - u32 val; - - val = BIT(31); - val |= (mt76x2_eeprom_get(dev, MT_EE_NIC_CONF_0) >> 8) & 0x00ff; - val |= (mt76x2_eeprom_get(dev, MT_EE_NIC_CONF_1) << 8) & 0xff00; - msg.cfg = cpu_to_le32(val); - - /* first set the channel without the extension channel info */ - skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg)); - return mt76_mcu_send_msg(dev, skb, CMD_LOAD_CR, true); -} - -int mt76x2_mcu_set_channel(struct mt76x2_dev *dev, u8 channel, u8 bw, - u8 bw_index, bool scan) -{ - struct sk_buff *skb; - struct { - u8 idx; - u8 scan; - u8 bw; - u8 _pad0; - - __le16 chainmask; - u8 ext_chan; - u8 _pad1; - - } __packed __aligned(4) msg = { - .idx = channel, - .scan = scan, - .bw = bw, - .chainmask = cpu_to_le16(dev->chainmask), - }; - - /* first set the channel without the extension channel info */ - skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg)); - mt76_mcu_send_msg(dev, skb, CMD_SWITCH_CHANNEL_OP, true); - - usleep_range(5000, 10000); - - msg.ext_chan = 0xe0 + bw_index; - skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg)); - return mt76_mcu_send_msg(dev, skb, CMD_SWITCH_CHANNEL_OP, true); -} - int mt76x2_mcu_calibrate(struct mt76x2_dev *dev, enum mcu_calibration type, u32 param) { @@ -252,41 +192,6 @@ int mt76x2_mcu_calibrate(struct mt76x2_dev *dev, enum mcu_calibration type, return 0; } -int mt76x2_mcu_tssi_comp(struct mt76x2_dev *dev, - struct mt76x2_tssi_comp *tssi_data) -{ - struct sk_buff *skb; - struct { - __le32 id; - struct mt76x2_tssi_comp data; - } __packed __aligned(4) msg = { - .id = cpu_to_le32(MCU_CAL_TSSI_COMP), - .data = *tssi_data, - }; - - skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg)); - return mt76_mcu_send_msg(dev, skb, CMD_CALIBRATION_OP, true); -} - -int mt76x2_mcu_init_gain(struct mt76x2_dev *dev, u8 channel, u32 gain, - bool force) -{ - struct sk_buff *skb; - struct { - __le32 channel; - __le32 gain_val; - } __packed __aligned(4) msg = { - .channel = cpu_to_le32(channel), - .gain_val = cpu_to_le32(gain), - }; - - if (force) - msg.channel |= cpu_to_le32(BIT(31)); - - skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg)); - return mt76_mcu_send_msg(dev, skb, CMD_INIT_GAIN_OP, true); -} - int mt76x2_mcu_init(struct mt76x2_dev *dev) { static const struct mt76_mcu_ops mt76x2_mcu_ops = { diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mcu_common.c b/drivers/net/wireless/mediatek/mt76/mt76x2_mcu_common.c new file mode 100644 index 000000000000..72f6bfb7a258 --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mcu_common.c @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2016 Felix Fietkau + * Copyright (C) 2018 Lorenzo Bianconi + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include + +#include "mt76x2.h" +#include "mt76x2_mcu.h" +#include "mt76x2_eeprom.h" +#include "mt76x02_dma.h" + +int mt76x2_mcu_set_channel(struct mt76x2_dev *dev, u8 channel, u8 bw, + u8 bw_index, bool scan) +{ + struct sk_buff *skb; + struct { + u8 idx; + u8 scan; + u8 bw; + u8 _pad0; + + __le16 chainmask; + u8 ext_chan; + u8 _pad1; + + } __packed __aligned(4) msg = { + .idx = channel, + .scan = scan, + .bw = bw, + .chainmask = cpu_to_le16(dev->chainmask), + }; + + /* first set the channel without the extension channel info */ + skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg)); + mt76_mcu_send_msg(dev, skb, CMD_SWITCH_CHANNEL_OP, true); + + usleep_range(5000, 10000); + + msg.ext_chan = 0xe0 + bw_index; + skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg)); + return mt76_mcu_send_msg(dev, skb, CMD_SWITCH_CHANNEL_OP, true); +} +EXPORT_SYMBOL_GPL(mt76x2_mcu_set_channel); + +int mt76x2_mcu_load_cr(struct mt76x2_dev *dev, u8 type, u8 temp_level, + u8 channel) +{ + struct sk_buff *skb; + struct { + u8 cr_mode; + u8 temp; + u8 ch; + u8 _pad0; + + __le32 cfg; + } __packed __aligned(4) msg = { + .cr_mode = type, + .temp = temp_level, + .ch = channel, + }; + u32 val; + + val = BIT(31); + val |= (mt76x2_eeprom_get(dev, MT_EE_NIC_CONF_0) >> 8) & 0x00ff; + val |= (mt76x2_eeprom_get(dev, MT_EE_NIC_CONF_1) << 8) & 0xff00; + msg.cfg = cpu_to_le32(val); + + /* first set the channel without the extension channel info */ + skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg)); + return mt76_mcu_send_msg(dev, skb, CMD_LOAD_CR, true); +} +EXPORT_SYMBOL_GPL(mt76x2_mcu_load_cr); + +int mt76x2_mcu_init_gain(struct mt76x2_dev *dev, u8 channel, u32 gain, + bool force) +{ + struct sk_buff *skb; + struct { + __le32 channel; + __le32 gain_val; + } __packed __aligned(4) msg = { + .channel = cpu_to_le32(channel), + .gain_val = cpu_to_le32(gain), + }; + + if (force) + msg.channel |= cpu_to_le32(BIT(31)); + + skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg)); + return mt76_mcu_send_msg(dev, skb, CMD_INIT_GAIN_OP, true); +} +EXPORT_SYMBOL_GPL(mt76x2_mcu_init_gain); + +int mt76x2_mcu_tssi_comp(struct mt76x2_dev *dev, + struct mt76x2_tssi_comp *tssi_data) +{ + struct sk_buff *skb; + struct { + __le32 id; + struct mt76x2_tssi_comp data; + } __packed __aligned(4) msg = { + .id = cpu_to_le32(MCU_CAL_TSSI_COMP), + .data = *tssi_data, + }; + + skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg)); + return mt76_mcu_send_msg(dev, skb, CMD_CALIBRATION_OP, true); +} +EXPORT_SYMBOL_GPL(mt76x2_mcu_tssi_comp); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2u.h b/drivers/net/wireless/mediatek/mt76/mt76x2u.h index 2e7789e6a849..d3bc7904dbb7 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2u.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x2u.h @@ -50,18 +50,10 @@ void mt76x2u_phy_set_txdac(struct mt76x2_dev *dev); void mt76x2u_phy_set_rxpath(struct mt76x2_dev *dev); void mt76x2u_mcu_complete_urb(struct urb *urb); -int mt76x2u_mcu_set_channel(struct mt76x2_dev *dev, u8 channel, u8 bw, - u8 bw_index, bool scan); int mt76x2u_mcu_calibrate(struct mt76x2_dev *dev, enum mcu_calibration type, u32 val); -int mt76x2u_mcu_tssi_comp(struct mt76x2_dev *dev, - struct mt76x2_tssi_comp *tssi_data); -int mt76x2u_mcu_init_gain(struct mt76x2_dev *dev, u8 channel, u32 gain, - bool force); int mt76x2u_mcu_set_dynamic_vga(struct mt76x2_dev *dev, u8 channel, bool ap, bool ext, int rssi, u32 false_cca); -int mt76x2u_mcu_load_cr(struct mt76x2_dev *dev, u8 type, - u8 temp_level, u8 channel); int mt76x2u_mcu_init(struct mt76x2_dev *dev); int mt76x2u_mcu_fw_init(struct mt76x2_dev *dev); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2u_init.c b/drivers/net/wireless/mediatek/mt76/mt76x2u_init.c index 6661b9228e45..e41880c43fa7 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2u_init.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2u_init.c @@ -240,7 +240,7 @@ int mt76x2u_init_hardware(struct mt76x2_dev *dev) mt76_rmw(dev, MT_US_CYC_CFG, MT_US_CYC_CNT, 0x1e); mt76_wr(dev, MT_TXOP_CTRL_CFG, 0x583f); - err = mt76x2u_mcu_load_cr(dev, MT_RF_BBP_CR, 0, 0); + err = mt76x2_mcu_load_cr(dev, MT_RF_BBP_CR, 0, 0); if (err < 0) return err; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2u_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x2u_mcu.c index abb9308d2179..808e5d4579c6 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2u_mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2u_mcu.c @@ -29,65 +29,6 @@ #define MT76U_MCU_DLM_OFFSET 0x110000 #define MT76U_MCU_ROM_PATCH_OFFSET 0x90000 -int mt76x2u_mcu_load_cr(struct mt76x2_dev *dev, u8 type, u8 temp_level, - u8 channel) -{ - struct { - u8 cr_mode; - u8 temp; - u8 ch; - u8 _pad0; - __le32 cfg; - } __packed __aligned(4) msg = { - .cr_mode = type, - .temp = temp_level, - .ch = channel, - }; - struct sk_buff *skb; - u32 val; - - val = BIT(31); - val |= (mt76x2_eeprom_get(dev, MT_EE_NIC_CONF_0) >> 8) & 0x00ff; - val |= (mt76x2_eeprom_get(dev, MT_EE_NIC_CONF_1) << 8) & 0xff00; - msg.cfg = cpu_to_le32(val); - - /* first set the channel without the extension channel info */ - skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg)); - return mt76_mcu_send_msg(dev, skb, CMD_LOAD_CR, true); -} - -int mt76x2u_mcu_set_channel(struct mt76x2_dev *dev, u8 channel, u8 bw, - u8 bw_index, bool scan) -{ - struct { - u8 idx; - u8 scan; - u8 bw; - u8 _pad0; - - __le16 chainmask; - u8 ext_chan; - u8 _pad1; - - } __packed __aligned(4) msg = { - .idx = channel, - .scan = scan, - .bw = bw, - .chainmask = cpu_to_le16(dev->chainmask), - }; - struct sk_buff *skb; - - /* first set the channel without the extension channel info */ - skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg)); - mt76_mcu_send_msg(dev, skb, CMD_SWITCH_CHANNEL_OP, true); - - usleep_range(5000, 10000); - - msg.ext_chan = 0xe0 + bw_index; - skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg)); - return mt76_mcu_send_msg(dev, skb, CMD_SWITCH_CHANNEL_OP, true); -} - int mt76x2u_mcu_calibrate(struct mt76x2_dev *dev, enum mcu_calibration type, u32 val) { @@ -104,25 +45,6 @@ int mt76x2u_mcu_calibrate(struct mt76x2_dev *dev, enum mcu_calibration type, return mt76_mcu_send_msg(dev, skb, CMD_CALIBRATION_OP, true); } -int mt76x2u_mcu_init_gain(struct mt76x2_dev *dev, u8 channel, u32 gain, - bool force) -{ - struct { - __le32 channel; - __le32 gain_val; - } __packed __aligned(4) msg = { - .channel = cpu_to_le32(channel), - .gain_val = cpu_to_le32(gain), - }; - struct sk_buff *skb; - - if (force) - msg.channel |= cpu_to_le32(BIT(31)); - - skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg)); - return mt76_mcu_send_msg(dev, skb, CMD_INIT_GAIN_OP, true); -} - int mt76x2u_mcu_set_dynamic_vga(struct mt76x2_dev *dev, u8 channel, bool ap, bool ext, int rssi, u32 false_cca) { @@ -147,22 +69,6 @@ int mt76x2u_mcu_set_dynamic_vga(struct mt76x2_dev *dev, u8 channel, bool ap, return mt76_mcu_send_msg(dev, skb, CMD_DYNC_VGA_OP, true); } -int mt76x2u_mcu_tssi_comp(struct mt76x2_dev *dev, - struct mt76x2_tssi_comp *tssi_data) -{ - struct { - __le32 id; - struct mt76x2_tssi_comp data; - } __packed __aligned(4) msg = { - .id = cpu_to_le32(MCU_CAL_TSSI_COMP), - .data = *tssi_data, - }; - struct sk_buff *skb; - - skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg)); - return mt76_mcu_send_msg(dev, skb, CMD_CALIBRATION_OP, true); -} - static void mt76x2u_mcu_load_ivb(struct mt76x2_dev *dev) { mt76u_vendor_request(&dev->mt76, MT_VEND_DEV_MODE, diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2u_phy.c b/drivers/net/wireless/mediatek/mt76/mt76x2u_phy.c index 5158063d0c2e..89defeee4bf3 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2u_phy.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2u_phy.c @@ -84,7 +84,7 @@ mt76x2u_phy_tssi_compensate(struct mt76x2_dev *dev) if (!dev->cal.tssi_comp_pending) { /* TSSI trigger */ t.cal_mode = BIT(0); - mt76x2u_mcu_tssi_comp(dev, &t); + mt76x2_mcu_tssi_comp(dev, &t); dev->cal.tssi_comp_pending = true; } else { if (mt76_rr(dev, MT_BBP(CORE, 34)) & BIT(4)) @@ -101,7 +101,7 @@ mt76x2u_phy_tssi_compensate(struct mt76x2_dev *dev) t.offset0 = txp.chain[0].tssi_offset; t.slope1 = txp.chain[1].tssi_slope; t.offset1 = txp.chain[1].tssi_offset; - mt76x2u_mcu_tssi_comp(dev, &t); + mt76x2_mcu_tssi_comp(dev, &t); if (t.pa_mode || dev->cal.dpd_cal_done) return; @@ -239,11 +239,11 @@ int mt76x2u_phy_set_channel(struct mt76x2_dev *dev, MT_EXT_CCA_CFG_CCA_MASK), ext_cca_chan[ch_group_index]); - ret = mt76x2u_mcu_set_channel(dev, channel, bw, bw_index, scan); + ret = mt76x2_mcu_set_channel(dev, channel, bw, bw_index, scan); if (ret) return ret; - mt76x2u_mcu_init_gain(dev, channel, dev->cal.rx.mcu_gain, true); + mt76x2_mcu_init_gain(dev, channel, dev->cal.rx.mcu_gain, true); /* Enable LDPC Rx */ if (mt76xx_rev(dev) >= MT76XX_REV_E3) From edaa580bc830e5197272c80cf12c98cf16e48bb7 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Sun, 9 Sep 2018 23:58:04 +0200 Subject: [PATCH 211/276] mt76: move shared mcu_calibrate routine in mt76x02-lib module Move mcu_calibrate routine in mt76x02-lib module since it is shared between USB and PCI code. Moreover remove duplicated code Signed-off-by: Lorenzo Bianconi Signed-off-by: Felix Fietkau --- .../net/wireless/mediatek/mt76/mt76x0/mcu.c | 16 ---------- .../net/wireless/mediatek/mt76/mt76x0/mcu.h | 3 -- .../net/wireless/mediatek/mt76/mt76x0/phy.c | 22 +++++++------- .../net/wireless/mediatek/mt76/mt76x02_mcu.c | 30 +++++++++++++++++++ .../net/wireless/mediatek/mt76/mt76x02_mcu.h | 2 ++ .../net/wireless/mediatek/mt76/mt76x2_mcu.c | 27 ----------------- .../net/wireless/mediatek/mt76/mt76x2_mcu.h | 2 -- .../net/wireless/mediatek/mt76/mt76x2_phy.c | 22 +++++++------- drivers/net/wireless/mediatek/mt76/mt76x2u.h | 2 -- .../net/wireless/mediatek/mt76/mt76x2u_mcu.c | 16 ---------- .../net/wireless/mediatek/mt76/mt76x2u_phy.c | 23 +++++++------- 11 files changed, 68 insertions(+), 97 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c index 551dad6ca058..dc28b9b31ace 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c @@ -41,22 +41,6 @@ static inline void skb_put_le32(struct sk_buff *skb, u32 val) put_unaligned_le32(val, skb_put(skb, 4)); } -int -mt76x0_mcu_calibrate(struct mt76x0_dev *dev, enum mcu_calibrate cal, u32 val) -{ - struct sk_buff *skb; - struct { - __le32 id; - __le32 value; - } __packed __aligned(4) msg = { - .id = cpu_to_le32(cal), - .value = cpu_to_le32(val), - }; - - skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg)); - return mt76_mcu_send_msg(dev, skb, CMD_CALIBRATION_OP, true); -} - struct mt76_fw { struct mt76x02_fw_header hdr; u8 ivb[MT_MCU_IVB_SIZE]; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.h b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.h index 6ba38022d26a..4945c6890ce7 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.h @@ -44,7 +44,4 @@ enum mcu_calibrate { int mt76x0_mcu_init(struct mt76x0_dev *dev); int mt76x0_mcu_cmd_init(struct mt76x0_dev *dev); -int -mt76x0_mcu_calibrate(struct mt76x0_dev *dev, enum mcu_calibrate cal, u32 val); - #endif diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c index 512e637635f5..2b6d928aab89 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c @@ -760,7 +760,7 @@ __mt76x0_phy_set_channel(struct mt76x0_dev *dev, mt76x0_vco_cal(dev, channel); if (scan) - mt76x0_mcu_calibrate(dev, MCU_CAL_RXDCOC, 1); + mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_RXDCOC, 1, false); mt76x0_phy_set_chan_pwr(dev, channel); @@ -786,7 +786,7 @@ void mt76x0_phy_recalibrate_after_assoc(struct mt76x0_dev *dev) u8 channel = dev->mt76.chandef.chan->hw_value; int is_5ghz = (dev->mt76.chandef.chan->band == NL80211_BAND_5GHZ) ? 1 : 0; - mt76x0_mcu_calibrate(dev, MCU_CAL_R, 0); + mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_R, 0, false); mt76x0_vco_cal(dev, channel); @@ -798,20 +798,22 @@ void mt76x0_phy_recalibrate_after_assoc(struct mt76x0_dev *dev) reg_val &= 0xffffff7e; mt76_wr(dev, 0x2124, reg_val); - mt76x0_mcu_calibrate(dev, MCU_CAL_RXDCOC, 0); + mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_RXDCOC, 0, false); - mt76x0_mcu_calibrate(dev, MCU_CAL_LC, is_5ghz); - mt76x0_mcu_calibrate(dev, MCU_CAL_LOFT, is_5ghz); - mt76x0_mcu_calibrate(dev, MCU_CAL_TXIQ, is_5ghz); - mt76x0_mcu_calibrate(dev, MCU_CAL_TX_GROUP_DELAY, is_5ghz); - mt76x0_mcu_calibrate(dev, MCU_CAL_RXIQ, is_5ghz); - mt76x0_mcu_calibrate(dev, MCU_CAL_RX_GROUP_DELAY, is_5ghz); + mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_LC, is_5ghz, false); + mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_LOFT, is_5ghz, false); + mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_TXIQ, is_5ghz, false); + mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_TX_GROUP_DELAY, + is_5ghz, false); + mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_RXIQ, is_5ghz, false); + mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_RX_GROUP_DELAY, + is_5ghz, false); mt76_wr(dev, 0x2124, reg_val); mt76_wr(dev, MT_TX_ALC_CFG_0, tx_alc); msleep(100); - mt76x0_mcu_calibrate(dev, MCU_CAL_RXDCOC, 1); + mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_RXDCOC, 1, false); } void mt76x0_agc_save(struct mt76x0_dev *dev) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x02_mcu.c index 3dc36ace91da..5a2fba3462fd 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mcu.c @@ -168,6 +168,36 @@ int mt76x02_mcu_set_radio_state(struct mt76_dev *dev, bool on, } EXPORT_SYMBOL_GPL(mt76x02_mcu_set_radio_state); +int mt76x02_mcu_calibrate(struct mt76_dev *dev, int type, + u32 param, bool wait) +{ + struct sk_buff *skb; + struct { + __le32 id; + __le32 value; + } __packed __aligned(4) msg = { + .id = cpu_to_le32(type), + .value = cpu_to_le32(param), + }; + int ret; + + if (wait) + dev->bus->rmw(dev, MT_MCU_COM_REG0, BIT(31), 0); + + skb = dev->mcu_ops->mcu_msg_alloc(&msg, sizeof(msg)); + ret = dev->mcu_ops->mcu_send_msg(dev, skb, CMD_CALIBRATION_OP, true); + if (ret) + return ret; + + if (wait && + WARN_ON(!__mt76_poll_msec(dev, MT_MCU_COM_REG0, + BIT(31), BIT(31), 100))) + return -ETIMEDOUT; + + return 0; +} +EXPORT_SYMBOL_GPL(mt76x02_mcu_calibrate); + int mt76x02_mcu_cleanup(struct mt76_dev *dev) { struct sk_buff *skb; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mcu.h b/drivers/net/wireless/mediatek/mt76/mt76x02_mcu.h index cbdf6fc09971..2f5af3dad2bb 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_mcu.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mcu.h @@ -86,6 +86,8 @@ struct mt76x02_patch_header { }; int mt76x02_mcu_cleanup(struct mt76_dev *dev); +int mt76x02_mcu_calibrate(struct mt76_dev *dev, int type, + u32 param, bool wait); struct sk_buff *mt76x02_mcu_msg_alloc(const void *data, int len); int mt76x02_mcu_msg_send(struct mt76_dev *dev, struct sk_buff *skb, int cmd, bool wait_resp); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.c index d808892a8995..f92bebfa21fd 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.c @@ -165,33 +165,6 @@ mt76pci_load_firmware(struct mt76x2_dev *dev) return -ENOENT; } -int mt76x2_mcu_calibrate(struct mt76x2_dev *dev, enum mcu_calibration type, - u32 param) -{ - struct sk_buff *skb; - struct { - __le32 id; - __le32 value; - } __packed __aligned(4) msg = { - .id = cpu_to_le32(type), - .value = cpu_to_le32(param), - }; - int ret; - - mt76_clear(dev, MT_MCU_COM_REG0, BIT(31)); - - skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg)); - ret = mt76_mcu_send_msg(dev, skb, CMD_CALIBRATION_OP, true); - if (ret) - return ret; - - if (WARN_ON(!mt76_poll_msec(dev, MT_MCU_COM_REG0, - BIT(31), BIT(31), 100))) - return -ETIMEDOUT; - - return 0; -} - int mt76x2_mcu_init(struct mt76x2_dev *dev) { static const struct mt76_mcu_ops mt76x2_mcu_ops = { diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.h b/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.h index c5da3293dafd..3de062d0b644 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.h @@ -101,8 +101,6 @@ struct mt76x2_tssi_comp { u8 offset1; } __packed __aligned(4); -int mt76x2_mcu_calibrate(struct mt76x2_dev *dev, enum mcu_calibration type, - u32 param); int mt76x2_mcu_tssi_comp(struct mt76x2_dev *dev, struct mt76x2_tssi_comp *tssi_data); int mt76x2_mcu_init_gain(struct mt76x2_dev *dev, u8 channel, u32 gain, bool force); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_phy.c b/drivers/net/wireless/mediatek/mt76/mt76x2_phy.c index f7c902ad4c96..f3a4484a3efe 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_phy.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_phy.c @@ -37,7 +37,7 @@ mt76x2_phy_tssi_init_cal(struct mt76x2_dev *dev) if (mt76x2_ext_pa_enabled(dev, chan->band)) flag |= BIT(8); - mt76x2_mcu_calibrate(dev, MCU_CAL_TSSI, flag); + mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_TSSI, flag, true); dev->cal.tssi_cal_done = true; return true; } @@ -61,13 +61,13 @@ mt76x2_phy_channel_calibrate(struct mt76x2_dev *dev, bool mac_stopped) mt76x2_mac_stop(dev, false); if (is_5ghz) - mt76x2_mcu_calibrate(dev, MCU_CAL_LC, 0); + mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_LC, 0, true); - mt76x2_mcu_calibrate(dev, MCU_CAL_TX_LOFT, is_5ghz); - mt76x2_mcu_calibrate(dev, MCU_CAL_TXIQ, is_5ghz); - mt76x2_mcu_calibrate(dev, MCU_CAL_RXIQC_FI, is_5ghz); - mt76x2_mcu_calibrate(dev, MCU_CAL_TEMP_SENSOR, 0); - mt76x2_mcu_calibrate(dev, MCU_CAL_TX_SHAPING, 0); + mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_TX_LOFT, is_5ghz, true); + mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_TXIQ, is_5ghz, true); + mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_RXIQC_FI, is_5ghz, true); + mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_TEMP_SENSOR, 0, true); + mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_TX_SHAPING, 0, true); if (!mac_stopped) mt76x2_mac_resume(dev); @@ -363,14 +363,14 @@ int mt76x2_phy_set_channel(struct mt76x2_dev *dev, u8 val = mt76x2_eeprom_get(dev, MT_EE_BT_RCAL_RESULT); if (val != 0xff) - mt76x2_mcu_calibrate(dev, MCU_CAL_R, 0); + mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_R, 0, true); } - mt76x2_mcu_calibrate(dev, MCU_CAL_RXDCOC, channel); + mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_RXDCOC, channel, true); /* Rx LPF calibration */ if (!dev->cal.init_cal_done) - mt76x2_mcu_calibrate(dev, MCU_CAL_RC, 0); + mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_RC, 0, true); dev->cal.init_cal_done = true; @@ -439,7 +439,7 @@ mt76x2_phy_tssi_compensate(struct mt76x2_dev *dev) return; usleep_range(10000, 20000); - mt76x2_mcu_calibrate(dev, MCU_CAL_DPD, chan->hw_value); + mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_DPD, chan->hw_value, true); dev->cal.dpd_cal_done = true; } } diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2u.h b/drivers/net/wireless/mediatek/mt76/mt76x2u.h index d3bc7904dbb7..a0ff6472de1f 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2u.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x2u.h @@ -50,8 +50,6 @@ void mt76x2u_phy_set_txdac(struct mt76x2_dev *dev); void mt76x2u_phy_set_rxpath(struct mt76x2_dev *dev); void mt76x2u_mcu_complete_urb(struct urb *urb); -int mt76x2u_mcu_calibrate(struct mt76x2_dev *dev, enum mcu_calibration type, - u32 val); int mt76x2u_mcu_set_dynamic_vga(struct mt76x2_dev *dev, u8 channel, bool ap, bool ext, int rssi, u32 false_cca); int mt76x2u_mcu_init(struct mt76x2_dev *dev); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2u_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x2u_mcu.c index 808e5d4579c6..fe86b9c696d9 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2u_mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2u_mcu.c @@ -29,22 +29,6 @@ #define MT76U_MCU_DLM_OFFSET 0x110000 #define MT76U_MCU_ROM_PATCH_OFFSET 0x90000 -int mt76x2u_mcu_calibrate(struct mt76x2_dev *dev, enum mcu_calibration type, - u32 val) -{ - struct { - __le32 id; - __le32 value; - } __packed __aligned(4) msg = { - .id = cpu_to_le32(type), - .value = cpu_to_le32(val), - }; - struct sk_buff *skb; - - skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg)); - return mt76_mcu_send_msg(dev, skb, CMD_CALIBRATION_OP, true); -} - int mt76x2u_mcu_set_dynamic_vga(struct mt76x2_dev *dev, u8 channel, bool ap, bool ext, int rssi, u32 false_cca) { diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2u_phy.c b/drivers/net/wireless/mediatek/mt76/mt76x2u_phy.c index 89defeee4bf3..c18e75478a6a 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2u_phy.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2u_phy.c @@ -61,12 +61,12 @@ void mt76x2u_phy_channel_calibrate(struct mt76x2_dev *dev) mt76x2u_mac_stop(dev); if (is_5ghz) - mt76x2u_mcu_calibrate(dev, MCU_CAL_LC, 0); + mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_LC, 0, false); - mt76x2u_mcu_calibrate(dev, MCU_CAL_TX_LOFT, is_5ghz); - mt76x2u_mcu_calibrate(dev, MCU_CAL_TXIQ, is_5ghz); - mt76x2u_mcu_calibrate(dev, MCU_CAL_RXIQC_FI, is_5ghz); - mt76x2u_mcu_calibrate(dev, MCU_CAL_TEMP_SENSOR, 0); + mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_TX_LOFT, is_5ghz, false); + mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_TXIQ, is_5ghz, false); + mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_RXIQC_FI, is_5ghz, false); + mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_TEMP_SENSOR, 0, false); mt76x2u_mac_resume(dev); } @@ -107,7 +107,8 @@ mt76x2u_phy_tssi_compensate(struct mt76x2_dev *dev) return; usleep_range(10000, 20000); - mt76x2u_mcu_calibrate(dev, MCU_CAL_DPD, chan->hw_value); + mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_DPD, + chan->hw_value, false); dev->cal.dpd_cal_done = true; } } @@ -253,14 +254,15 @@ int mt76x2u_phy_set_channel(struct mt76x2_dev *dev, u8 val = mt76x2_eeprom_get(dev, MT_EE_BT_RCAL_RESULT); if (val != 0xff) - mt76x2u_mcu_calibrate(dev, MCU_CAL_R, 0); + mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_R, + 0, false); } - mt76x2u_mcu_calibrate(dev, MCU_CAL_RXDCOC, channel); + mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_RXDCOC, channel, false); /* Rx LPF calibration */ if (!dev->cal.init_cal_done) - mt76x2u_mcu_calibrate(dev, MCU_CAL_RC, 0); + mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_RC, 0, false); dev->cal.init_cal_done = true; mt76_wr(dev, MT_BBP(AGC, 61), 0xff64a4e2); @@ -292,7 +294,8 @@ int mt76x2u_phy_set_channel(struct mt76x2_dev *dev, flag |= BIT(0); if (mt76x2_ext_pa_enabled(dev, chan->band)) flag |= BIT(8); - mt76x2u_mcu_calibrate(dev, MCU_CAL_TSSI, flag); + mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_TSSI, + flag, false); dev->cal.tssi_cal_done = true; } } From 8842d485cbadaef6724dd4138367e7ddf3ef9dcf Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Sun, 9 Sep 2018 23:58:05 +0200 Subject: [PATCH 212/276] mt76x2: move mt76x2_phy_tssi_compensate in mt76x2-common module Move mt76x2_phy_tssi_compensate routine in mt76x2-common module since it is shared between mt76x2 and mt76x2u drivers Signed-off-by: Lorenzo Bianconi Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt76x2.h | 1 + .../net/wireless/mediatek/mt76/mt76x2_phy.c | 43 +----------------- .../mediatek/mt76/mt76x2_phy_common.c | 43 ++++++++++++++++++ .../net/wireless/mediatek/mt76/mt76x2u_phy.c | 44 +------------------ 4 files changed, 46 insertions(+), 85 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2.h b/drivers/net/wireless/mediatek/mt76/mt76x2.h index 3150e43a3e31..784962913d9a 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x2.h @@ -237,6 +237,7 @@ int mt76x2_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u16 queue, const struct ieee80211_tx_queue_params *params); void mt76x2_txq_init(struct mt76x2_dev *dev, struct ieee80211_txq *txq); +void mt76x2_phy_tssi_compensate(struct mt76x2_dev *dev, bool wait); void mt76x2_phy_set_txpower_regs(struct mt76x2_dev *dev, enum nl80211_band band); void mt76x2_configure_tx_delay(struct mt76x2_dev *dev, diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_phy.c b/drivers/net/wireless/mediatek/mt76/mt76x2_phy.c index f3a4484a3efe..920bb7c89af9 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_phy.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_phy.c @@ -403,47 +403,6 @@ int mt76x2_phy_set_channel(struct mt76x2_dev *dev, return 0; } -static void -mt76x2_phy_tssi_compensate(struct mt76x2_dev *dev) -{ - struct ieee80211_channel *chan = dev->mt76.chandef.chan; - struct mt76x2_tx_power_info txp; - struct mt76x2_tssi_comp t = {}; - - if (!dev->cal.tssi_cal_done) - return; - - if (!dev->cal.tssi_comp_pending) { - /* TSSI trigger */ - t.cal_mode = BIT(0); - mt76x2_mcu_tssi_comp(dev, &t); - dev->cal.tssi_comp_pending = true; - } else { - if (mt76_rr(dev, MT_BBP(CORE, 34)) & BIT(4)) - return; - - dev->cal.tssi_comp_pending = false; - mt76x2_get_power_info(dev, &txp, chan); - - if (mt76x2_ext_pa_enabled(dev, chan->band)) - t.pa_mode = 1; - - t.cal_mode = BIT(1); - t.slope0 = txp.chain[0].tssi_slope; - t.offset0 = txp.chain[0].tssi_offset; - t.slope1 = txp.chain[1].tssi_slope; - t.offset1 = txp.chain[1].tssi_offset; - mt76x2_mcu_tssi_comp(dev, &t); - - if (t.pa_mode || dev->cal.dpd_cal_done) - return; - - usleep_range(10000, 20000); - mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_DPD, chan->hw_value, true); - dev->cal.dpd_cal_done = true; - } -} - static void mt76x2_phy_temp_compensate(struct mt76x2_dev *dev) { @@ -478,7 +437,7 @@ void mt76x2_phy_calibrate(struct work_struct *work) dev = container_of(work, struct mt76x2_dev, cal_work.work); mt76x2_phy_channel_calibrate(dev, false); - mt76x2_phy_tssi_compensate(dev); + mt76x2_phy_tssi_compensate(dev, true); mt76x2_phy_temp_compensate(dev); mt76x2_phy_update_channel_gain(dev); ieee80211_queue_delayed_work(mt76_hw(dev), &dev->cal_work, diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_phy_common.c b/drivers/net/wireless/mediatek/mt76/mt76x2_phy_common.c index c38855342731..3b704a70fad1 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_phy_common.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_phy_common.c @@ -17,6 +17,7 @@ #include "mt76x2.h" #include "mt76x2_eeprom.h" +#include "mt76x2_mcu.h" static void mt76x2_adjust_high_lna_gain(struct mt76x2_dev *dev, int reg, s8 offset) @@ -347,3 +348,45 @@ int mt76x2_phy_get_min_avg_rssi(struct mt76x2_dev *dev) return min_rssi; } EXPORT_SYMBOL_GPL(mt76x2_phy_get_min_avg_rssi); + +void mt76x2_phy_tssi_compensate(struct mt76x2_dev *dev, bool wait) +{ + struct ieee80211_channel *chan = dev->mt76.chandef.chan; + struct mt76x2_tx_power_info txp; + struct mt76x2_tssi_comp t = {}; + + if (!dev->cal.tssi_cal_done) + return; + + if (!dev->cal.tssi_comp_pending) { + /* TSSI trigger */ + t.cal_mode = BIT(0); + mt76x2_mcu_tssi_comp(dev, &t); + dev->cal.tssi_comp_pending = true; + } else { + if (mt76_rr(dev, MT_BBP(CORE, 34)) & BIT(4)) + return; + + dev->cal.tssi_comp_pending = false; + mt76x2_get_power_info(dev, &txp, chan); + + if (mt76x2_ext_pa_enabled(dev, chan->band)) + t.pa_mode = 1; + + t.cal_mode = BIT(1); + t.slope0 = txp.chain[0].tssi_slope; + t.offset0 = txp.chain[0].tssi_offset; + t.slope1 = txp.chain[1].tssi_slope; + t.offset1 = txp.chain[1].tssi_offset; + mt76x2_mcu_tssi_comp(dev, &t); + + if (t.pa_mode || dev->cal.dpd_cal_done) + return; + + usleep_range(10000, 20000); + mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_DPD, + chan->hw_value, wait); + dev->cal.dpd_cal_done = true; + } +} +EXPORT_SYMBOL_GPL(mt76x2_phy_tssi_compensate); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2u_phy.c b/drivers/net/wireless/mediatek/mt76/mt76x2u_phy.c index c18e75478a6a..97f40fef5559 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2u_phy.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2u_phy.c @@ -71,48 +71,6 @@ void mt76x2u_phy_channel_calibrate(struct mt76x2_dev *dev) mt76x2u_mac_resume(dev); } -static void -mt76x2u_phy_tssi_compensate(struct mt76x2_dev *dev) -{ - struct ieee80211_channel *chan = dev->mt76.chandef.chan; - struct mt76x2_tx_power_info txp; - struct mt76x2_tssi_comp t = {}; - - if (!dev->cal.tssi_cal_done) - return; - - if (!dev->cal.tssi_comp_pending) { - /* TSSI trigger */ - t.cal_mode = BIT(0); - mt76x2_mcu_tssi_comp(dev, &t); - dev->cal.tssi_comp_pending = true; - } else { - if (mt76_rr(dev, MT_BBP(CORE, 34)) & BIT(4)) - return; - - dev->cal.tssi_comp_pending = false; - mt76x2_get_power_info(dev, &txp, chan); - - if (mt76x2_ext_pa_enabled(dev, chan->band)) - t.pa_mode = 1; - - t.cal_mode = BIT(1); - t.slope0 = txp.chain[0].tssi_slope; - t.offset0 = txp.chain[0].tssi_offset; - t.slope1 = txp.chain[1].tssi_slope; - t.offset1 = txp.chain[1].tssi_offset; - mt76x2_mcu_tssi_comp(dev, &t); - - if (t.pa_mode || dev->cal.dpd_cal_done) - return; - - usleep_range(10000, 20000); - mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_DPD, - chan->hw_value, false); - dev->cal.dpd_cal_done = true; - } -} - static void mt76x2u_phy_update_channel_gain(struct mt76x2_dev *dev) { @@ -156,7 +114,7 @@ void mt76x2u_phy_calibrate(struct work_struct *work) struct mt76x2_dev *dev; dev = container_of(work, struct mt76x2_dev, cal_work.work); - mt76x2u_phy_tssi_compensate(dev); + mt76x2_phy_tssi_compensate(dev, false); mt76x2u_phy_update_channel_gain(dev); ieee80211_queue_delayed_work(mt76_hw(dev), &dev->cal_work, From c12128ce44b04a987c4eb0f733cc99c4dd50d45a Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 13 Jul 2018 16:26:15 +0200 Subject: [PATCH 213/276] mt76: use a per rx queue page fragment cache Using the NAPI or netdev frag cache along with other drivers can lead to 32 KiB pages being held for a long time, despite only being used for very few page fragments. This can happen if the driver grabs one or two fragments for rx ring refill, while other drivers use (and free up) the remaining fragments. The 32 KiB higher-order page can only be freed once all users have freed their fragments. Depending on the traffic patterns, this can waste a lot of memory and look a lot like a memory leak. Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/dma.c | 16 +++++++++------- drivers/net/wireless/mediatek/mt76/mt76.h | 1 + drivers/net/wireless/mediatek/mt76/usb.c | 11 ++++++++++- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/dma.c b/drivers/net/wireless/mediatek/mt76/dma.c index c51da2205b93..f7fbd7016403 100644 --- a/drivers/net/wireless/mediatek/mt76/dma.c +++ b/drivers/net/wireless/mediatek/mt76/dma.c @@ -322,19 +322,13 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q, bool napi) int len = SKB_WITH_OVERHEAD(q->buf_size); int offset = q->buf_offset; int idx; - void *(*alloc)(unsigned int fragsz); - - if (napi) - alloc = napi_alloc_frag; - else - alloc = netdev_alloc_frag; spin_lock_bh(&q->lock); while (q->queued < q->ndesc - 1) { struct mt76_queue_buf qbuf; - buf = alloc(q->buf_size); + buf = page_frag_alloc(&q->rx_page, q->buf_size, GFP_ATOMIC); if (!buf) break; @@ -361,6 +355,7 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q, bool napi) static void mt76_dma_rx_cleanup(struct mt76_dev *dev, struct mt76_queue *q) { + struct page *page; void *buf; bool more; @@ -373,6 +368,13 @@ mt76_dma_rx_cleanup(struct mt76_dev *dev, struct mt76_queue *q) skb_free_frag(buf); } while (1); spin_unlock_bh(&q->lock); + + if (!q->rx_page.va) + return; + + page = virt_to_page(q->rx_page.va); + __page_frag_cache_drain(page, q->rx_page.pagecnt_bias); + memset(&q->rx_page, 0, sizeof(q->rx_page)); } static void diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h index 56983213093f..dbda49243a10 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76.h +++ b/drivers/net/wireless/mediatek/mt76/mt76.h @@ -121,6 +121,7 @@ struct mt76_queue { dma_addr_t desc_dma; struct sk_buff *rx_head; + struct page_frag_cache rx_page; }; struct mt76_mcu_ops { diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c index 16a9682d5452..be43e2941dc4 100644 --- a/drivers/net/wireless/mediatek/mt76/usb.c +++ b/drivers/net/wireless/mediatek/mt76/usb.c @@ -275,6 +275,7 @@ static int mt76u_fill_rx_sg(struct mt76_dev *dev, struct mt76u_buf *buf, int nsgs, int len, int sglen) { + struct mt76_queue *q = &dev->q_rx[MT_RXQ_MAIN]; struct urb *urb = buf->urb; int i; @@ -283,7 +284,7 @@ mt76u_fill_rx_sg(struct mt76_dev *dev, struct mt76u_buf *buf, void *data; int offset; - data = netdev_alloc_frag(len); + data = page_frag_alloc(&q->rx_page, q->buf_size, GFP_ATOMIC); if (!data) break; @@ -550,10 +551,18 @@ static int mt76u_alloc_rx(struct mt76_dev *dev) static void mt76u_free_rx(struct mt76_dev *dev) { struct mt76_queue *q = &dev->q_rx[MT_RXQ_MAIN]; + struct page *page; int i; for (i = 0; i < q->ndesc; i++) mt76u_buf_free(&q->entry[i].ubuf); + + if (!q->rx_page.va) + return; + + page = virt_to_page(q->rx_page.va); + __page_frag_cache_drain(page, q->rx_page.pagecnt_bias); + memset(&q->rx_page, 0, sizeof(q->rx_page)); } static void mt76u_stop_rx(struct mt76_dev *dev) From 576ecf653836e19f18b332b0326e32977e258ac6 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Tue, 11 Sep 2018 23:09:28 +0200 Subject: [PATCH 214/276] mt76x0: usb: move firmware loading to usb.c Firmware loading is usb specific, move it to usb.c file. Signed-off-by: Stanislaw Gruszka Signed-off-by: Lorenzo Bianconi Signed-off-by: Felix Fietkau --- .../net/wireless/mediatek/mt76/mt76x0/init.c | 9 - .../net/wireless/mediatek/mt76/mt76x0/mcu.c | 167 ----------------- .../net/wireless/mediatek/mt76/mt76x0/mcu.h | 1 - .../net/wireless/mediatek/mt76/mt76x0/usb.c | 171 ++++++++++++++++++ 4 files changed, 171 insertions(+), 177 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c index 7e415b361ad1..43c4ad25c84e 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c @@ -396,15 +396,6 @@ int mt76x0_init_hardware(struct mt76x0_dev *dev) dev->beacon_offsets = beacon_offsets; - mt76x0_chip_onoff(dev, true, true); - - if (!mt76x02_wait_for_mac(&dev->mt76)) - return -ETIMEDOUT; - - ret = mt76x0_mcu_init(dev); - if (ret) - return ret; - if (!mt76_poll_msec(dev, MT_WPDMA_GLO_CFG, MT_WPDMA_GLO_CFG_TX_DMA_BUSY | MT_WPDMA_GLO_CFG_RX_DMA_BUSY, 0, 100)) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c index dc28b9b31ace..72a61fdc19aa 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c @@ -15,7 +15,6 @@ */ #include -#include #include #include #include @@ -27,172 +26,6 @@ #include "trace.h" #include "../mt76x02_usb.h" -#define MCU_FW_URB_MAX_PAYLOAD 0x38f8 -#define MCU_FW_URB_SIZE (MCU_FW_URB_MAX_PAYLOAD + 12) -#define MCU_RESP_URB_SIZE 1024 - -static inline int firmware_running(struct mt76x0_dev *dev) -{ - return mt76_rr(dev, MT_MCU_COM_REG0) == 1; -} - -static inline void skb_put_le32(struct sk_buff *skb, u32 val) -{ - put_unaligned_le32(val, skb_put(skb, 4)); -} - -struct mt76_fw { - struct mt76x02_fw_header hdr; - u8 ivb[MT_MCU_IVB_SIZE]; - u8 ilm[]; -}; - -static int -mt76x0_upload_firmware(struct mt76x0_dev *dev, const struct mt76_fw *fw) -{ - void *ivb; - u32 ilm_len, dlm_len; - int i, ret; - - ivb = kmemdup(fw->ivb, sizeof(fw->ivb), GFP_KERNEL); - if (!ivb) - return -ENOMEM; - - ilm_len = le32_to_cpu(fw->hdr.ilm_len) - sizeof(fw->ivb); - dev_dbg(dev->mt76.dev, "loading FW - ILM %u + IVB %zu\n", - ilm_len, sizeof(fw->ivb)); - ret = mt76x02u_mcu_fw_send_data(&dev->mt76, fw->ilm, ilm_len, - MCU_FW_URB_MAX_PAYLOAD, - sizeof(fw->ivb)); - if (ret) - goto error; - - dlm_len = le32_to_cpu(fw->hdr.dlm_len); - dev_dbg(dev->mt76.dev, "loading FW - DLM %u\n", dlm_len); - ret = mt76x02u_mcu_fw_send_data(&dev->mt76, fw->ilm + ilm_len, - dlm_len, MCU_FW_URB_MAX_PAYLOAD, - MT_MCU_DLM_OFFSET); - if (ret) - goto error; - - ret = mt76u_vendor_request(&dev->mt76, MT_VEND_DEV_MODE, - USB_DIR_OUT | USB_TYPE_VENDOR, - 0x12, 0, ivb, sizeof(fw->ivb)); - if (ret < 0) - goto error; - ret = 0; - - for (i = 100; i && !firmware_running(dev); i--) - msleep(10); - if (!i) { - ret = -ETIMEDOUT; - goto error; - } - - dev_dbg(dev->mt76.dev, "Firmware running!\n"); -error: - kfree(ivb); - - return ret; -} - -static int mt76x0_load_firmware(struct mt76x0_dev *dev) -{ - const struct firmware *fw; - const struct mt76x02_fw_header *hdr; - int len, ret; - u32 val; - - mt76_wr(dev, MT_USB_DMA_CFG, (MT_USB_DMA_CFG_RX_BULK_EN | - MT_USB_DMA_CFG_TX_BULK_EN)); - - if (firmware_running(dev)) - return 0; - - ret = request_firmware(&fw, MT7610_FIRMWARE, dev->mt76.dev); - if (ret) - return ret; - - if (!fw || !fw->data || fw->size < sizeof(*hdr)) - goto err_inv_fw; - - hdr = (const struct mt76x02_fw_header *)fw->data; - - if (le32_to_cpu(hdr->ilm_len) <= MT_MCU_IVB_SIZE) - goto err_inv_fw; - - len = sizeof(*hdr); - len += le32_to_cpu(hdr->ilm_len); - len += le32_to_cpu(hdr->dlm_len); - - if (fw->size != len) - goto err_inv_fw; - - val = le16_to_cpu(hdr->fw_ver); - dev_dbg(dev->mt76.dev, - "Firmware Version: %d.%d.%02d Build: %x Build time: %.16s\n", - (val >> 12) & 0xf, (val >> 8) & 0xf, val & 0xf, - le16_to_cpu(hdr->build_ver), hdr->build_time); - - len = le32_to_cpu(hdr->ilm_len); - - mt76_wr(dev, 0x1004, 0x2c); - - mt76_set(dev, MT_USB_DMA_CFG, (MT_USB_DMA_CFG_RX_BULK_EN | - MT_USB_DMA_CFG_TX_BULK_EN) | - FIELD_PREP(MT_USB_DMA_CFG_RX_BULK_AGG_TOUT, 0x20)); - mt76x02u_mcu_fw_reset(&dev->mt76); - msleep(5); -/* - mt76x0_rmw(dev, MT_PBF_CFG, 0, (MT_PBF_CFG_TX0Q_EN | - MT_PBF_CFG_TX1Q_EN | - MT_PBF_CFG_TX2Q_EN | - MT_PBF_CFG_TX3Q_EN)); -*/ - - mt76_wr(dev, MT_FCE_PSE_CTRL, 1); - - /* FCE tx_fs_base_ptr */ - mt76_wr(dev, MT_TX_CPU_FROM_FCE_BASE_PTR, 0x400230); - /* FCE tx_fs_max_cnt */ - mt76_wr(dev, MT_TX_CPU_FROM_FCE_MAX_COUNT, 1); - /* FCE pdma enable */ - mt76_wr(dev, MT_FCE_PDMA_GLOBAL_CONF, 0x44); - /* FCE skip_fs_en */ - mt76_wr(dev, MT_FCE_SKIP_FS, 3); - - val = mt76_rr(dev, MT_USB_DMA_CFG); - val |= MT_USB_DMA_CFG_UDMA_TX_WL_DROP; - mt76_wr(dev, MT_USB_DMA_CFG, val); - val &= ~MT_USB_DMA_CFG_UDMA_TX_WL_DROP; - mt76_wr(dev, MT_USB_DMA_CFG, val); - - ret = mt76x0_upload_firmware(dev, (const struct mt76_fw *)fw->data); - release_firmware(fw); - - mt76_wr(dev, MT_FCE_PSE_CTRL, 1); - - return ret; - -err_inv_fw: - dev_err(dev->mt76.dev, "Invalid firmware image\n"); - release_firmware(fw); - return -ENOENT; -} - -int mt76x0_mcu_init(struct mt76x0_dev *dev) -{ - int ret; - - ret = mt76x0_load_firmware(dev); - if (ret) - return ret; - - set_bit(MT76_STATE_MCU_RUNNING, &dev->mt76.state); - - return 0; -} - int mt76x0_mcu_cmd_init(struct mt76x0_dev *dev) { return mt76x02_mcu_function_select(&dev->mt76, Q_SELECT, 1, false); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.h b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.h index 4945c6890ce7..1a1c15eca42d 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.h @@ -41,7 +41,6 @@ enum mcu_calibrate { MCU_CAL_TX_GROUP_DELAY, }; -int mt76x0_mcu_init(struct mt76x0_dev *dev); int mt76x0_mcu_cmd_init(struct mt76x0_dev *dev); #endif diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c index 2f05f7383117..3be3402620fc 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c @@ -13,10 +13,12 @@ #include #include +#include #include #include "mt76x0.h" #include "usb.h" +#include "mcu.h" #include "trace.h" #include "../mt76x02_util.h" #include "../mt76x02_usb.h" @@ -48,6 +50,166 @@ static struct usb_device_id mt76x0_device_table[] = { { 0, } }; +struct mt76_fw { + struct mt76x02_fw_header hdr; + u8 ivb[MT_MCU_IVB_SIZE]; + u8 ilm[]; +}; + +#define MCU_FW_URB_MAX_PAYLOAD 0x38f8 +#define MCU_FW_URB_SIZE (MCU_FW_URB_MAX_PAYLOAD + 12) + +static inline int mt76x0_firmware_running(struct mt76x0_dev *dev) +{ + return mt76_rr(dev, MT_MCU_COM_REG0) == 1; +} + +static int +mt76x0u_upload_firmware(struct mt76x0_dev *dev, const struct mt76_fw *fw) +{ + void *ivb; + u32 ilm_len, dlm_len; + int i, ret; + + ivb = kmemdup(fw->ivb, sizeof(fw->ivb), GFP_KERNEL); + if (!ivb) + return -ENOMEM; + + ilm_len = le32_to_cpu(fw->hdr.ilm_len) - sizeof(fw->ivb); + dev_dbg(dev->mt76.dev, "loading FW - ILM %u + IVB %zu\n", + ilm_len, sizeof(fw->ivb)); + ret = mt76x02u_mcu_fw_send_data(&dev->mt76, fw->ilm, ilm_len, + MCU_FW_URB_MAX_PAYLOAD, + sizeof(fw->ivb)); + if (ret) + goto error; + + dlm_len = le32_to_cpu(fw->hdr.dlm_len); + dev_dbg(dev->mt76.dev, "loading FW - DLM %u\n", dlm_len); + ret = mt76x02u_mcu_fw_send_data(&dev->mt76, fw->ilm + ilm_len, + dlm_len, MCU_FW_URB_MAX_PAYLOAD, + MT_MCU_DLM_OFFSET); + if (ret) + goto error; + + ret = mt76u_vendor_request(&dev->mt76, MT_VEND_DEV_MODE, + USB_DIR_OUT | USB_TYPE_VENDOR, + 0x12, 0, ivb, sizeof(fw->ivb)); + if (ret < 0) + goto error; + ret = 0; + + for (i = 100; i && !mt76x0_firmware_running(dev); i--) + msleep(10); + if (!i) { + ret = -ETIMEDOUT; + goto error; + } + + dev_dbg(dev->mt76.dev, "Firmware running!\n"); +error: + kfree(ivb); + + return ret; +} + +static int mt76x0u_load_firmware(struct mt76x0_dev *dev) +{ + const struct firmware *fw; + const struct mt76x02_fw_header *hdr; + int len, ret; + u32 val; + + mt76_wr(dev, MT_USB_DMA_CFG, (MT_USB_DMA_CFG_RX_BULK_EN | + MT_USB_DMA_CFG_TX_BULK_EN)); + + if (mt76x0_firmware_running(dev)) + return 0; + + ret = request_firmware(&fw, MT7610_FIRMWARE, dev->mt76.dev); + if (ret) + return ret; + + if (!fw || !fw->data || fw->size < sizeof(*hdr)) + goto err_inv_fw; + + hdr = (const struct mt76x02_fw_header *)fw->data; + + if (le32_to_cpu(hdr->ilm_len) <= MT_MCU_IVB_SIZE) + goto err_inv_fw; + + len = sizeof(*hdr); + len += le32_to_cpu(hdr->ilm_len); + len += le32_to_cpu(hdr->dlm_len); + + if (fw->size != len) + goto err_inv_fw; + + val = le16_to_cpu(hdr->fw_ver); + dev_dbg(dev->mt76.dev, + "Firmware Version: %d.%d.%02d Build: %x Build time: %.16s\n", + (val >> 12) & 0xf, (val >> 8) & 0xf, val & 0xf, + le16_to_cpu(hdr->build_ver), hdr->build_time); + + len = le32_to_cpu(hdr->ilm_len); + + mt76_wr(dev, 0x1004, 0x2c); + + mt76_set(dev, MT_USB_DMA_CFG, (MT_USB_DMA_CFG_RX_BULK_EN | + MT_USB_DMA_CFG_TX_BULK_EN) | + FIELD_PREP(MT_USB_DMA_CFG_RX_BULK_AGG_TOUT, 0x20)); + mt76x02u_mcu_fw_reset(&dev->mt76); + msleep(5); +/* + mt76x0_rmw(dev, MT_PBF_CFG, 0, (MT_PBF_CFG_TX0Q_EN | + MT_PBF_CFG_TX1Q_EN | + MT_PBF_CFG_TX2Q_EN | + MT_PBF_CFG_TX3Q_EN)); +*/ + + mt76_wr(dev, MT_FCE_PSE_CTRL, 1); + + /* FCE tx_fs_base_ptr */ + mt76_wr(dev, MT_TX_CPU_FROM_FCE_BASE_PTR, 0x400230); + /* FCE tx_fs_max_cnt */ + mt76_wr(dev, MT_TX_CPU_FROM_FCE_MAX_COUNT, 1); + /* FCE pdma enable */ + mt76_wr(dev, MT_FCE_PDMA_GLOBAL_CONF, 0x44); + /* FCE skip_fs_en */ + mt76_wr(dev, MT_FCE_SKIP_FS, 3); + + val = mt76_rr(dev, MT_USB_DMA_CFG); + val |= MT_USB_DMA_CFG_UDMA_TX_WL_DROP; + mt76_wr(dev, MT_USB_DMA_CFG, val); + val &= ~MT_USB_DMA_CFG_UDMA_TX_WL_DROP; + mt76_wr(dev, MT_USB_DMA_CFG, val); + + ret = mt76x0u_upload_firmware(dev, (const struct mt76_fw *)fw->data); + release_firmware(fw); + + mt76_wr(dev, MT_FCE_PSE_CTRL, 1); + + return ret; + +err_inv_fw: + dev_err(dev->mt76.dev, "Invalid firmware image\n"); + release_firmware(fw); + return -ENOENT; +} + +static int mt76x0u_mcu_init(struct mt76x0_dev *dev) +{ + int ret; + + ret = mt76x0u_load_firmware(dev); + if (ret) + return ret; + + set_bit(MT76_STATE_MCU_RUNNING, &dev->mt76.state); + + return 0; +} + static int mt76x0u_probe(struct usb_interface *usb_intf, const struct usb_device_id *id) { @@ -101,6 +263,15 @@ static int mt76x0u_probe(struct usb_interface *usb_intf, if (ret < 0) goto err; + mt76x0_chip_onoff(dev, true, true); + + if (!mt76x02_wait_for_mac(&dev->mt76)) + return -ETIMEDOUT; + + ret = mt76x0u_mcu_init(dev); + if (ret) + goto err_hw; + ret = mt76x0_register_device(dev); if (ret) goto err_hw; From 280415714ca1eca47582c356e981a05e4d81ce48 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Tue, 11 Sep 2018 23:09:29 +0200 Subject: [PATCH 215/276] mt76x0: remove mcu source file Remove mcu.c source file since it contains just 'one-line' function that is shared between PCI and USB code Signed-off-by: Lorenzo Bianconi Signed-off-by: Felix Fietkau --- .../wireless/mediatek/mt76/mt76x0/Makefile | 2 +- .../net/wireless/mediatek/mt76/mt76x0/init.c | 2 +- .../net/wireless/mediatek/mt76/mt76x0/mcu.c | 32 ------------------- .../net/wireless/mediatek/mt76/mt76x0/mcu.h | 2 -- 4 files changed, 2 insertions(+), 36 deletions(-) delete mode 100644 drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/Makefile b/drivers/net/wireless/mediatek/mt76/mt76x0/Makefile index 644c867c107a..48f7979e36ef 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/Makefile +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/Makefile @@ -3,7 +3,7 @@ obj-$(CONFIG_MT76x0E) += mt76x0e.o obj-$(CONFIG_MT76x0_COMMON) += mt76x0-common.o mt76x0-common-y := \ - init.o main.o mcu.o trace.o eeprom.o phy.o \ + init.o main.o trace.o eeprom.o phy.o \ mac.o debugfs.o tx.o mt76x0u-y := usb.o mt76x0e-y := pci.o diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c index 43c4ad25c84e..b31ec78b064e 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c @@ -411,7 +411,7 @@ int mt76x0_init_hardware(struct mt76x0_dev *dev) mt76_wr(dev, MT_HEADER_TRANS_CTRL_REG, 0x0); mt76_wr(dev, MT_TSO_CTRL, 0x0); - ret = mt76x0_mcu_cmd_init(dev); + ret = mt76x02_mcu_function_select(&dev->mt76, Q_SELECT, 1, false); if (ret) return ret; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c deleted file mode 100644 index 72a61fdc19aa..000000000000 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.c +++ /dev/null @@ -1,32 +0,0 @@ -/* - * (c) Copyright 2002-2010, Ralink Technology, Inc. - * Copyright (C) 2014 Felix Fietkau - * Copyright (C) 2015 Jakub Kicinski - * Copyright (C) 2018 Stanislaw Gruszka - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include - -#include "mt76x0.h" -#include "dma.h" -#include "mcu.h" -#include "usb.h" -#include "trace.h" -#include "../mt76x02_usb.h" - -int mt76x0_mcu_cmd_init(struct mt76x0_dev *dev) -{ - return mt76x02_mcu_function_select(&dev->mt76, Q_SELECT, 1, false); -} diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.h b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.h index 1a1c15eca42d..f2a87d283e09 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.h @@ -41,6 +41,4 @@ enum mcu_calibrate { MCU_CAL_TX_GROUP_DELAY, }; -int mt76x0_mcu_cmd_init(struct mt76x0_dev *dev); - #endif From 196e978ca1da89b70ccaf0ae52b59a95ce94a815 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Tue, 11 Sep 2018 23:09:30 +0200 Subject: [PATCH 216/276] mt76x0: remove unused usb header file Remove unused usb header file and move mt76x0 firmware definition in usb.c Signed-off-by: Lorenzo Bianconi Signed-off-by: Felix Fietkau --- .../net/wireless/mediatek/mt76/mt76x0/init.c | 1 - .../net/wireless/mediatek/mt76/mt76x0/usb.c | 7 +-- .../net/wireless/mediatek/mt76/mt76x0/usb.h | 46 ------------------- 3 files changed, 4 insertions(+), 50 deletions(-) delete mode 100644 drivers/net/wireless/mediatek/mt76/mt76x0/usb.h diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c index b31ec78b064e..3a88be267daf 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c @@ -18,7 +18,6 @@ #include "eeprom.h" #include "trace.h" #include "mcu.h" -#include "usb.h" #include "../mt76x02_util.h" #include "initvals.h" diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c index 3be3402620fc..e7071260beda 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c @@ -17,12 +17,13 @@ #include #include "mt76x0.h" -#include "usb.h" #include "mcu.h" #include "trace.h" #include "../mt76x02_util.h" #include "../mt76x02_usb.h" +#define MT7610U_FIRMWARE "mediatek/mt7610u.bin" + static struct usb_device_id mt76x0_device_table[] = { { USB_DEVICE(0x148F, 0x7610) }, /* MT7610U */ { USB_DEVICE(0x13B1, 0x003E) }, /* Linksys AE6000 */ @@ -126,7 +127,7 @@ static int mt76x0u_load_firmware(struct mt76x0_dev *dev) if (mt76x0_firmware_running(dev)) return 0; - ret = request_firmware(&fw, MT7610_FIRMWARE, dev->mt76.dev); + ret = request_firmware(&fw, MT7610U_FIRMWARE, dev->mt76.dev); if (ret) return ret; @@ -352,7 +353,7 @@ static int __maybe_unused mt76x0_resume(struct usb_interface *usb_intf) } MODULE_DEVICE_TABLE(usb, mt76x0_device_table); -MODULE_FIRMWARE(MT7610_FIRMWARE); +MODULE_FIRMWARE(MT7610U_FIRMWARE); MODULE_LICENSE("GPL"); static struct usb_driver mt76x0_driver = { diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.h b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.h deleted file mode 100644 index 7bd075319f5b..000000000000 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2015 Jakub Kicinski - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef __MT76X0U_USB_H -#define __MT76X0U_USB_H - -#include "mt76x0.h" - -#define MT7610_FIRMWARE "mediatek/mt7610u.bin" - -#define MT_VEND_REQ_MAX_RETRY 10 -#define MT_VEND_REQ_TOUT_MS 300 - -#define MT_VEND_DEV_MODE_RESET 1 - -#define MT_VEND_BUF sizeof(__le32) - -static inline struct usb_device *mt76x0_to_usb_dev(struct mt76x0_dev *mt76x0) -{ - return interface_to_usbdev(to_usb_interface(mt76x0->mt76.dev)); -} - -static inline struct usb_device *mt76_to_usb_dev(struct mt76_dev *mt76) -{ - return interface_to_usbdev(to_usb_interface(mt76->dev)); -} - -static inline bool mt76x0_urb_has_error(struct urb *urb) -{ - return urb->status && - urb->status != -ENOENT && - urb->status != -ECONNRESET && - urb->status != -ESHUTDOWN; -} - -#endif From bf3741ada33bb4fabec99538b8014c054854912b Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Wed, 12 Sep 2018 17:19:36 +0200 Subject: [PATCH 217/276] mt76x0: usb: remove mt76_fw definition Remove mt76_fw dependency from mt76x0u_upload_firmware routine since it does not define firmware layout properly. Moreover use mt76_poll_msec utility routine to check if the fw is properly running Signed-off-by: Lorenzo Bianconi Signed-off-by: Felix Fietkau --- .../net/wireless/mediatek/mt76/mt76x0/usb.c | 69 +++++++++---------- 1 file changed, 33 insertions(+), 36 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c index e7071260beda..bb8c0cd3d48a 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c @@ -51,12 +51,6 @@ static struct usb_device_id mt76x0_device_table[] = { { 0, } }; -struct mt76_fw { - struct mt76x02_fw_header hdr; - u8 ivb[MT_MCU_IVB_SIZE]; - u8 ilm[]; -}; - #define MCU_FW_URB_MAX_PAYLOAD 0x38f8 #define MCU_FW_URB_SIZE (MCU_FW_URB_MAX_PAYLOAD + 12) @@ -66,52 +60,55 @@ static inline int mt76x0_firmware_running(struct mt76x0_dev *dev) } static int -mt76x0u_upload_firmware(struct mt76x0_dev *dev, const struct mt76_fw *fw) +mt76x0u_upload_firmware(struct mt76x0_dev *dev, + const struct mt76x02_fw_header *hdr) { - void *ivb; + u8 *fw_payload = (u8 *)(hdr + 1); u32 ilm_len, dlm_len; - int i, ret; + void *ivb; + int err; - ivb = kmemdup(fw->ivb, sizeof(fw->ivb), GFP_KERNEL); + ivb = kmemdup(fw_payload, MT_MCU_IVB_SIZE, GFP_KERNEL); if (!ivb) return -ENOMEM; - ilm_len = le32_to_cpu(fw->hdr.ilm_len) - sizeof(fw->ivb); - dev_dbg(dev->mt76.dev, "loading FW - ILM %u + IVB %zu\n", - ilm_len, sizeof(fw->ivb)); - ret = mt76x02u_mcu_fw_send_data(&dev->mt76, fw->ilm, ilm_len, - MCU_FW_URB_MAX_PAYLOAD, - sizeof(fw->ivb)); - if (ret) - goto error; + ilm_len = le32_to_cpu(hdr->ilm_len) - MT_MCU_IVB_SIZE; + dev_dbg(dev->mt76.dev, "loading FW - ILM %u + IVB %u\n", + ilm_len, MT_MCU_IVB_SIZE); + err = mt76x02u_mcu_fw_send_data(&dev->mt76, + fw_payload + MT_MCU_IVB_SIZE, + ilm_len, MCU_FW_URB_MAX_PAYLOAD, + MT_MCU_IVB_SIZE); + if (err) + goto out; - dlm_len = le32_to_cpu(fw->hdr.dlm_len); + dlm_len = le32_to_cpu(hdr->dlm_len); dev_dbg(dev->mt76.dev, "loading FW - DLM %u\n", dlm_len); - ret = mt76x02u_mcu_fw_send_data(&dev->mt76, fw->ilm + ilm_len, + err = mt76x02u_mcu_fw_send_data(&dev->mt76, + fw_payload + le32_to_cpu(hdr->ilm_len), dlm_len, MCU_FW_URB_MAX_PAYLOAD, MT_MCU_DLM_OFFSET); - if (ret) - goto error; + if (err) + goto out; - ret = mt76u_vendor_request(&dev->mt76, MT_VEND_DEV_MODE, + err = mt76u_vendor_request(&dev->mt76, MT_VEND_DEV_MODE, USB_DIR_OUT | USB_TYPE_VENDOR, - 0x12, 0, ivb, sizeof(fw->ivb)); - if (ret < 0) - goto error; - ret = 0; + 0x12, 0, ivb, MT_MCU_IVB_SIZE); + if (err < 0) + goto out; - for (i = 100; i && !mt76x0_firmware_running(dev); i--) - msleep(10); - if (!i) { - ret = -ETIMEDOUT; - goto error; + if (!mt76_poll_msec(dev, MT_MCU_COM_REG0, 1, 1, 1000)) { + dev_err(dev->mt76.dev, "Firmware failed to start\n"); + err = -ETIMEDOUT; + goto out; } dev_dbg(dev->mt76.dev, "Firmware running!\n"); -error: + +out: kfree(ivb); - return ret; + return err; } static int mt76x0u_load_firmware(struct mt76x0_dev *dev) @@ -185,7 +182,7 @@ static int mt76x0u_load_firmware(struct mt76x0_dev *dev) val &= ~MT_USB_DMA_CFG_UDMA_TX_WL_DROP; mt76_wr(dev, MT_USB_DMA_CFG, val); - ret = mt76x0u_upload_firmware(dev, (const struct mt76_fw *)fw->data); + ret = mt76x0u_upload_firmware(dev, hdr); release_firmware(fw); mt76_wr(dev, MT_FCE_PSE_CTRL, 1); @@ -203,7 +200,7 @@ static int mt76x0u_mcu_init(struct mt76x0_dev *dev) int ret; ret = mt76x0u_load_firmware(dev); - if (ret) + if (ret < 0) return ret; set_bit(MT76_STATE_MCU_RUNNING, &dev->mt76.state); From 330994e8e8ec5d0b269a5265e6032b37e29aa336 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Wed, 5 Sep 2018 09:48:58 +0200 Subject: [PATCH 218/276] brcmfmac: fix for proper support of 160MHz bandwidth Decoding of firmware channel information was not complete for 160MHz support. This resulted in the following warning: WARNING: CPU: 2 PID: 2222 at .../broadcom/brcm80211/brcmutil/d11.c:196 brcmu_d11ac_decchspec+0x2e/0x100 [brcmutil] Modules linked in: brcmfmac(O) brcmutil(O) sha256_generic cfg80211 ... CPU: 2 PID: 2222 Comm: kworker/2:0 Tainted: G O 4.17.0-wt-testing-x64-00002-gf1bed50 #1 Hardware name: Dell Inc. Latitude E6410/07XJP9, BIOS A07 02/15/2011 Workqueue: events request_firmware_work_func RIP: 0010:brcmu_d11ac_decchspec+0x2e/0x100 [brcmutil] RSP: 0018:ffffc90000047bd0 EFLAGS: 00010206 RAX: 000000000000e832 RBX: ffff8801146fe910 RCX: ffff8801146fd3c0 RDX: 0000000000002800 RSI: 0000000000000070 RDI: ffffc90000047c30 RBP: ffffc90000047bd0 R08: 0000000000000000 R09: ffffffffa0798c80 R10: ffff88012bca55e0 R11: ffff880110a4ea00 R12: ffff8801146f8000 R13: ffffc90000047c30 R14: ffff8801146fe930 R15: ffff8801138e02e0 FS: 0000000000000000(0000) GS:ffff88012bc80000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f18ce8b8070 CR3: 000000000200a003 CR4: 00000000000206e0 Call Trace: brcmf_setup_wiphybands+0x212/0x780 [brcmfmac] brcmf_cfg80211_attach+0xae2/0x11a0 [brcmfmac] brcmf_attach+0x1fc/0x4b0 [brcmfmac] ? __kmalloc+0x13c/0x1c0 brcmf_pcie_setup+0x99b/0xe00 [brcmfmac] brcmf_fw_request_done+0x16a/0x1f0 [brcmfmac] request_firmware_work_func+0x36/0x60 process_one_work+0x146/0x350 worker_thread+0x4a/0x3b0 kthread+0x102/0x140 ? process_one_work+0x350/0x350 ? kthread_bind+0x20/0x20 ret_from_fork+0x35/0x40 Code: 66 90 0f b7 07 55 48 89 e5 89 c2 88 47 02 88 47 03 66 81 e2 00 38 66 81 fa 00 18 74 6e 66 81 fa 00 20 74 39 66 81 fa 00 10 74 14 <0f> 0b 66 25 00 c0 74 20 66 3d 00 c0 75 20 c6 47 04 01 5d c3 66 ---[ end trace 550c46682415b26d ]--- brcmfmac: brcmf_construct_chaninfo: Ignoring unexpected firmware channel 50 This patch adds the missing stuff to properly handle this. Reviewed-by: Hante Meuleman Reviewed-by: Pieter-Paul Giesberts Reviewed-by: Franky Lin Signed-off-by: Arend van Spriel Signed-off-by: Kalle Valo --- .../broadcom/brcm80211/brcmutil/d11.c | 34 ++++++++++++++++++- .../broadcom/brcm80211/include/brcmu_wifi.h | 2 ++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmutil/d11.c b/drivers/net/wireless/broadcom/brcm80211/brcmutil/d11.c index d8b79cb72b58..e7584b842dce 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmutil/d11.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmutil/d11.c @@ -77,6 +77,8 @@ static u16 d11ac_bw(enum brcmu_chan_bw bw) return BRCMU_CHSPEC_D11AC_BW_40; case BRCMU_CHAN_BW_80: return BRCMU_CHSPEC_D11AC_BW_80; + case BRCMU_CHAN_BW_160: + return BRCMU_CHSPEC_D11AC_BW_160; default: WARN_ON(1); } @@ -190,8 +192,38 @@ static void brcmu_d11ac_decchspec(struct brcmu_chan *ch) break; } break; - case BRCMU_CHSPEC_D11AC_BW_8080: case BRCMU_CHSPEC_D11AC_BW_160: + switch (ch->sb) { + case BRCMU_CHAN_SB_LLL: + ch->control_ch_num -= CH_70MHZ_APART; + break; + case BRCMU_CHAN_SB_LLU: + ch->control_ch_num -= CH_50MHZ_APART; + break; + case BRCMU_CHAN_SB_LUL: + ch->control_ch_num -= CH_30MHZ_APART; + break; + case BRCMU_CHAN_SB_LUU: + ch->control_ch_num -= CH_10MHZ_APART; + break; + case BRCMU_CHAN_SB_ULL: + ch->control_ch_num += CH_10MHZ_APART; + break; + case BRCMU_CHAN_SB_ULU: + ch->control_ch_num += CH_30MHZ_APART; + break; + case BRCMU_CHAN_SB_UUL: + ch->control_ch_num += CH_50MHZ_APART; + break; + case BRCMU_CHAN_SB_UUU: + ch->control_ch_num += CH_70MHZ_APART; + break; + default: + WARN_ON_ONCE(1); + break; + } + break; + case BRCMU_CHSPEC_D11AC_BW_8080: default: WARN_ON_ONCE(1); break; diff --git a/drivers/net/wireless/broadcom/brcm80211/include/brcmu_wifi.h b/drivers/net/wireless/broadcom/brcm80211/include/brcmu_wifi.h index 91fca79e6158..dddebaa60352 100644 --- a/drivers/net/wireless/broadcom/brcm80211/include/brcmu_wifi.h +++ b/drivers/net/wireless/broadcom/brcm80211/include/brcmu_wifi.h @@ -29,6 +29,8 @@ #define CH_UPPER_SB 0x01 #define CH_LOWER_SB 0x02 #define CH_EWA_VALID 0x04 +#define CH_70MHZ_APART 14 +#define CH_50MHZ_APART 10 #define CH_30MHZ_APART 6 #define CH_20MHZ_APART 4 #define CH_10MHZ_APART 2 From 59c2a30d36c8ae430d26a902c4c9665ea33ccee5 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Wed, 5 Sep 2018 09:48:59 +0200 Subject: [PATCH 219/276] brcmfmac: increase buffer for obtaining firmware capabilities When obtaining the firmware capability a buffer is provided of 512 bytes. However, if all features in firmware are supported the buffer needs to be 565 bytes as otherwise truncated information is retrieved from firmware. Increasing the buffer to 768 bytes on stack. Reviewed-by: Hante Meuleman Reviewed-by: Pieter-Paul Giesberts Reviewed-by: Franky Lin Signed-off-by: Arend van Spriel Signed-off-by: Kalle Valo --- drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c index 8347da632a5b..4c5a3995dc35 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c @@ -178,7 +178,7 @@ static void brcmf_feat_iovar_data_set(struct brcmf_if *ifp, ifp->fwil_fwerr = false; } -#define MAX_CAPS_BUFFER_SIZE 512 +#define MAX_CAPS_BUFFER_SIZE 768 static void brcmf_feat_firmware_capabilities(struct brcmf_if *ifp) { char caps[MAX_CAPS_BUFFER_SIZE]; From 761cb7cdef1a27d7b90cd061d19b116a74ab4aff Mon Sep 17 00:00:00 2001 From: zhong jiang Date: Sat, 8 Sep 2018 21:40:43 +0800 Subject: [PATCH 220/276] brcm80211: remove redundant condition check before debugfs_remove_recursive debugfs_remove_recursive has taken IS_ERR_OR_NULL into account. So just remove the condition check before debugfs_remove_recursive. Signed-off-by: zhong jiang Signed-off-by: Kalle Valo --- drivers/net/wireless/broadcom/brcm80211/brcmsmac/debug.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/debug.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/debug.c index 2fe1f6863278..3bd54f125776 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/debug.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/debug.c @@ -62,8 +62,7 @@ int brcms_debugfs_attach(struct brcms_pub *drvr) void brcms_debugfs_detach(struct brcms_pub *drvr) { - if (!IS_ERR_OR_NULL(drvr->dbgfs_dir)) - debugfs_remove_recursive(drvr->dbgfs_dir); + debugfs_remove_recursive(drvr->dbgfs_dir); } struct dentry *brcms_debugfs_get_devdir(struct brcms_pub *drvr) From a8254fa4ba60b85829b6e5ede6564f81cd70d59f Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Tue, 11 Sep 2018 11:24:04 +0800 Subject: [PATCH 221/276] brcmfmac: remove set but not used variables 'sfdoff' and 'pad_size' Fixes gcc '-Wunused-but-set-variable' warning: drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c: In function 'brcmf_sdio_rxglom': drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c:1466:11: warning: variable 'sfdoff' set but not used [-Wunused-but-set-variable] drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c: In function 'brcmf_sdio_bus_preinit': drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c:3408:7: warning: variable 'pad_size' set but not used [-Wunused-but-set-variable] Signed-off-by: YueHaibing Signed-off-by: Kalle Valo --- drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c index a907d7b065fa..bed8531b2f94 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c @@ -1463,7 +1463,7 @@ static u8 brcmf_sdio_rxglom(struct brcmf_sdio *bus, u8 rxseq) struct sk_buff *pfirst, *pnext; int errcode; - u8 doff, sfdoff; + u8 doff; struct brcmf_sdio_hdrinfo rd_new; @@ -1597,7 +1597,6 @@ static u8 brcmf_sdio_rxglom(struct brcmf_sdio *bus, u8 rxseq) /* Remove superframe header, remember offset */ skb_pull(pfirst, rd_new.dat_offset); - sfdoff = rd_new.dat_offset; num = 0; /* Validate all the subframe headers */ @@ -3405,7 +3404,6 @@ static int brcmf_sdio_bus_preinit(struct device *dev) struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; struct brcmf_sdio *bus = sdiodev->bus; struct brcmf_core *core = bus->sdio_core; - uint pad_size; u32 value; int err; @@ -3448,7 +3446,6 @@ static int brcmf_sdio_bus_preinit(struct device *dev) if (sdiodev->sg_support) { bus->txglom = false; value = 1; - pad_size = bus->sdiodev->func2->cur_blksize << 1; err = brcmf_iovar_data_set(bus->sdiodev->dev, "bus:rxglom", &value, sizeof(u32)); if (err < 0) { From 6c3efbe77bc78bf49db851aec7f385be475afca6 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 13 Sep 2018 08:15:17 +0200 Subject: [PATCH 222/276] brcmsmac: Use kvmalloc() for ucode allocations The ucode chunk might be relatively large and the allocation with kmalloc() may fail occasionally. Since the data isn't DMA-transferred but by manual loops, we can use vmalloc instead of kmalloc. For a better performance, though, kvmalloc() would be the best choice in such a case, so let's replace with it. Bugzilla: https://bugzilla.suse.com/show_bug.cgi?id=1103431 Signed-off-by: Takashi Iwai Signed-off-by: Kalle Valo --- .../net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c index ecc89e718b9c..6255fb6d97a7 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c @@ -1578,10 +1578,10 @@ int brcms_ucode_init_buf(struct brcms_info *wl, void **pbuf, u32 idx) if (le32_to_cpu(hdr->idx) == idx) { pdata = wl->fw.fw_bin[i]->data + le32_to_cpu(hdr->offset); - *pbuf = kmemdup(pdata, len, GFP_KERNEL); + *pbuf = kvmalloc(len, GFP_KERNEL); if (*pbuf == NULL) goto fail; - + memcpy(*pbuf, pdata, len); return 0; } } @@ -1629,7 +1629,7 @@ int brcms_ucode_init_uint(struct brcms_info *wl, size_t *n_bytes, u32 idx) */ void brcms_ucode_free_buf(void *p) { - kfree(p); + kvfree(p); } /* From 93ed990e3a6e722b7b1e1d59b3ceb8d91e36e682 Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Tue, 11 Sep 2018 12:28:24 +0000 Subject: [PATCH 223/276] qtnfmac: remove set but not used variable 'vif' Fixes gcc '-Wunused-but-set-variable' warning: drivers/net/wireless/quantenna/qtnfmac/cfg80211.c: In function 'qtnf_dump_survey': drivers/net/wireless/quantenna/qtnfmac/cfg80211.c:694:19: warning: variable 'vif' set but not used [-Wunused-but-set-variable] Signed-off-by: YueHaibing Reviewed-by: Sergey Matyukevich Signed-off-by: Kalle Valo --- drivers/net/wireless/quantenna/qtnfmac/cfg80211.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c b/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c index 4aa332f4646b..452d4b7c832d 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c +++ b/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c @@ -691,11 +691,8 @@ qtnf_dump_survey(struct wiphy *wiphy, struct net_device *dev, const struct cfg80211_chan_def *chandef = &wdev->chandef; struct ieee80211_channel *chan; struct qtnf_chan_stats stats; - struct qtnf_vif *vif; int ret; - vif = qtnf_netdev_get_priv(dev); - sband = wiphy->bands[NL80211_BAND_2GHZ]; if (sband && idx >= sband->n_channels) { idx -= sband->n_channels; From 7eff5136744866f55bb779545950d712730b22b5 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Thu, 17 May 2018 13:55:38 +0300 Subject: [PATCH 224/276] iwlwifi: mvm: fix a comment about the SP length The SP length in the ADD_STA command is an actual number of frames, and not the SP len as it appears in the WME IE. Fix that comment. The actual code is fine. Signed-off-by: Emmanuel Grumbach Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/api/sta.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/sta.h b/drivers/net/wireless/intel/iwlwifi/fw/api/sta.h index dc40cbd52f92..450227f81706 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/sta.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/sta.h @@ -8,6 +8,7 @@ * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH * Copyright(c) 2016 - 2017 Intel Deutschland GmbH + * Copyright(c) 2018 Intel Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -30,6 +31,7 @@ * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH * Copyright(c) 2016 - 2017 Intel Deutschland GmbH + * Copyright(c) 2018 Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -391,7 +393,7 @@ enum iwl_sta_type { * @tfd_queue_msk: tfd queues used by this station. * Obselete for new TX API (9 and above). * @rx_ba_window: aggregation window size - * @sp_length: the size of the SP as it appears in the WME IE + * @sp_length: the size of the SP in actual number of frames * @uapsd_acs: 4 LS bits are trigger enabled ACs, 4 MS bits are the deliver * enabled ACs. * From d25eec305c9743e929b821933590c27c2a499975 Mon Sep 17 00:00:00 2001 From: Sara Sharon Date: Thu, 17 May 2018 14:04:19 +0300 Subject: [PATCH 225/276] iwlwifi: fw: add a restart FW debug function Move the restart FW debug code to a function. This avoids code duplication and lays the infra to support the new start and stop host commands in some future devices. Signed-off-by: Sara Sharon Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 35 ++++------------ drivers/net/wireless/intel/iwlwifi/fw/dbg.h | 42 +++++++++++++++++-- drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 2 +- .../wireless/intel/iwlwifi/pcie/trans-gen2.c | 2 +- .../net/wireless/intel/iwlwifi/pcie/trans.c | 2 +- 5 files changed, 49 insertions(+), 34 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index 9963d6c84908..b0da16f3f474 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -1149,6 +1149,7 @@ void iwl_fw_error_dump_wk(struct work_struct *work) { struct iwl_fw_runtime *fwrt = container_of(work, struct iwl_fw_runtime, dump.wk.work); + struct iwl_fw_dbg_params params = {0}; if (fwrt->ops && fwrt->ops->dump_start && fwrt->ops->dump_start(fwrt->ops_ctx)) @@ -1162,38 +1163,16 @@ void iwl_fw_error_dump_wk(struct work_struct *work) goto out; } - if (fwrt->trans->cfg->device_family == IWL_DEVICE_FAMILY_7000) { - /* stop recording */ - iwl_fw_dbg_stop_recording(fwrt->trans); + iwl_fw_dbg_stop_recording(fwrt->trans, ¶ms); - iwl_fw_error_dump(fwrt); + iwl_fw_error_dump(fwrt); - /* start recording again if the firmware is not crashed */ - if (!test_bit(STATUS_FW_ERROR, &fwrt->trans->status) && - fwrt->fw->dbg_dest_tlv) { - iwl_clear_bits_prph(fwrt->trans, - MON_BUFF_SAMPLE_CTL, 0x100); - iwl_clear_bits_prph(fwrt->trans, - MON_BUFF_SAMPLE_CTL, 0x1); - iwl_set_bits_prph(fwrt->trans, - MON_BUFF_SAMPLE_CTL, 0x1); - } - } else { - u32 in_sample = iwl_read_prph(fwrt->trans, DBGC_IN_SAMPLE); - u32 out_ctrl = iwl_read_prph(fwrt->trans, DBGC_OUT_CTRL); - - iwl_fw_dbg_stop_recording(fwrt->trans); + /* start recording again if the firmware is not crashed */ + if (!test_bit(STATUS_FW_ERROR, &fwrt->trans->status) && + fwrt->fw->dbg_dest_tlv) { /* wait before we collect the data till the DBGC stop */ udelay(500); - - iwl_fw_error_dump(fwrt); - - /* start recording again if the firmware is not crashed */ - if (!test_bit(STATUS_FW_ERROR, &fwrt->trans->status) && - fwrt->fw->dbg_dest_tlv) { - iwl_write_prph(fwrt->trans, DBGC_IN_SAMPLE, in_sample); - iwl_write_prph(fwrt->trans, DBGC_OUT_CTRL, out_ctrl); - } + iwl_fw_dbg_restart_recording(fwrt->trans, ¶ms); } out: if (fwrt->ops && fwrt->ops->dump_end) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h index d04e68104ded..878758b6c7ae 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h @@ -83,6 +83,16 @@ struct iwl_fw_dump_desc { struct iwl_fw_error_dump_trigger_desc trig_desc; }; +/** + * struct iwl_fw_dbg_params - register values to restore + * @in_sample: DBGC_IN_SAMPLE value + * @out_ctrl: DBGC_OUT_CTRL value + */ +struct iwl_fw_dbg_params { + u32 in_sample; + u32 out_ctrl; +}; + extern const struct iwl_fw_dump_desc iwl_dump_desc_assert; static inline void iwl_fw_free_dump_desc(struct iwl_fw_runtime *fwrt) @@ -196,14 +206,40 @@ _iwl_fw_dbg_trigger_simple_stop(struct iwl_fw_runtime *fwrt, iwl_fw_dbg_get_trigger((fwrt)->fw,\ (trig))) -static inline void iwl_fw_dbg_stop_recording(struct iwl_trans *trans) +static inline void +iwl_fw_dbg_stop_recording(struct iwl_trans *trans, + struct iwl_fw_dbg_params *params) { if (trans->cfg->device_family == IWL_DEVICE_FAMILY_7000) { iwl_set_bits_prph(trans, MON_BUFF_SAMPLE_CTL, 0x100); + return; + } + + if (params) { + params->in_sample = iwl_read_prph(trans, DBGC_IN_SAMPLE); + params->out_ctrl = iwl_read_prph(trans, DBGC_OUT_CTRL); + } + + iwl_write_prph(trans, DBGC_IN_SAMPLE, 0); + udelay(100); + iwl_write_prph(trans, DBGC_OUT_CTRL, 0); +} + +static inline void +iwl_fw_dbg_restart_recording(struct iwl_trans *trans, + struct iwl_fw_dbg_params *params) +{ + if (WARN_ON(!params)) + return; + + if (trans->cfg->device_family == IWL_DEVICE_FAMILY_7000) { + iwl_clear_bits_prph(trans, MON_BUFF_SAMPLE_CTL, 0x100); + iwl_clear_bits_prph(trans, MON_BUFF_SAMPLE_CTL, 0x1); + iwl_set_bits_prph(trans, MON_BUFF_SAMPLE_CTL, 0x1); } else { - iwl_write_prph(trans, DBGC_IN_SAMPLE, 0); + iwl_write_prph(trans, DBGC_IN_SAMPLE, params->in_sample); udelay(100); - iwl_write_prph(trans, DBGC_OUT_CTRL, 0); + iwl_write_prph(trans, DBGC_OUT_CTRL, params->out_ctrl); } } diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c index 99050c8dd432..5305342439b2 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c @@ -1042,7 +1042,7 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw, * the recording automatically before entering D3. This can * be removed once the FW starts doing that. */ - iwl_fw_dbg_stop_recording(mvm->fwrt.trans); + iwl_fw_dbg_stop_recording(mvm->fwrt.trans, NULL); /* must be last -- this switches firmware state */ ret = iwl_mvm_send_cmd(mvm, &d3_cfg_cmd); diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c index 5f61b02e651e..b5902c74e5d0 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c @@ -165,7 +165,7 @@ void _iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans, bool low_power) trans_pcie->is_down = true; /* Stop dbgc before stopping device */ - iwl_fw_dbg_stop_recording(trans); + iwl_fw_dbg_stop_recording(trans, NULL); /* tell the device to stop sending interrupts */ iwl_disable_interrupts(trans); diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index cc8c53dc0ab6..5ecd5c8d0f02 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -1243,7 +1243,7 @@ static void _iwl_trans_pcie_stop_device(struct iwl_trans *trans, bool low_power) trans_pcie->is_down = true; /* Stop dbgc before stopping device */ - iwl_fw_dbg_stop_recording(trans); + iwl_fw_dbg_stop_recording(trans, NULL); /* tell the device to stop sending interrupts */ iwl_disable_interrupts(trans); From 5cfe79c8d92ae1c4fcac35723fba43ff0b2e4e48 Mon Sep 17 00:00:00 2001 From: Sara Sharon Date: Thu, 17 May 2018 14:41:10 +0300 Subject: [PATCH 226/276] iwlwifi: fw: stop and start debugging using host command In new devices, access to periphery is forbidden. Send instead host command to start and stop debugging. Memory allocation is written in context info, but in case we need to update it there is a dedicated command. Add definitions, currently unused, of the new command. Signed-off-by: Sara Sharon Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/fw/api/debug.h | 32 +++++++++++++ drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 4 +- drivers/net/wireless/intel/iwlwifi/fw/dbg.h | 46 +++++++++++++++++-- drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 2 +- .../wireless/intel/iwlwifi/pcie/trans-gen2.c | 2 +- .../net/wireless/intel/iwlwifi/pcie/trans.c | 2 +- 6 files changed, 79 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/debug.h b/drivers/net/wireless/intel/iwlwifi/fw/api/debug.h index 106782341544..dc1fa377087a 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/debug.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/debug.h @@ -8,6 +8,7 @@ * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * Copyright(c) 2016 - 2017 Intel Deutschland GmbH + * Copyright (C) 2018 Intel Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -30,6 +31,7 @@ * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * Copyright(c) 2016 - 2017 Intel Deutschland GmbH + * Copyright (C) 2018 Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -336,6 +338,9 @@ struct iwl_dbg_mem_access_rsp { #define CONT_REC_COMMAND_SIZE 80 #define ENABLE_CONT_RECORDING 0x15 #define DISABLE_CONT_RECORDING 0x16 +#define BUFFER_ALLOCATION 0x27 +#define START_DEBUG_RECORDING 0x29 +#define STOP_DEBUG_RECORDING 0x2A /* * struct iwl_continuous_record_mode - recording mode @@ -353,4 +358,31 @@ struct iwl_continuous_record_cmd { sizeof(struct iwl_continuous_record_mode)]; } __packed; +/* maximum fragments to be allocated per target of allocationId */ +#define IWL_BUFFER_LOCATION_MAX_FRAGS 2 + +/** + * struct iwl_fragment_data single fragment structure + * @address: 64bit start address + * @size: size in bytes + */ +struct iwl_fragment_data { + __le64 address; + __le32 size; +} __packed; /* FRAGMENT_STRUCTURE_API_S_VER_1 */ + +/** + * struct iwl_buffer_allocation_cmd - buffer allocation command structure + * @allocation_id: id of the allocation + * @buffer_location: location of the buffer + * @num_frags: number of fragments + * @fragments: memory fragments + */ +struct iwl_buffer_allocation_cmd { + __le32 allocation_id; + __le32 buffer_location; + __le32 num_frags; + struct iwl_fragment_data fragments[IWL_BUFFER_LOCATION_MAX_FRAGS]; +} __packed; /* BUFFER_ALLOCATION_CMD_API_S_VER_1 */ + #endif /* __iwl_fw_api_debug_h__ */ diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index b0da16f3f474..cebc9e99961e 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -1163,7 +1163,7 @@ void iwl_fw_error_dump_wk(struct work_struct *work) goto out; } - iwl_fw_dbg_stop_recording(fwrt->trans, ¶ms); + iwl_fw_dbg_stop_recording(fwrt, ¶ms); iwl_fw_error_dump(fwrt); @@ -1172,7 +1172,7 @@ void iwl_fw_error_dump_wk(struct work_struct *work) fwrt->fw->dbg_dest_tlv) { /* wait before we collect the data till the DBGC stop */ udelay(500); - iwl_fw_dbg_restart_recording(fwrt->trans, ¶ms); + iwl_fw_dbg_restart_recording(fwrt, ¶ms); } out: if (fwrt->ops && fwrt->ops->dump_end) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h index 878758b6c7ae..3c89230fae6a 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h @@ -71,6 +71,7 @@ #include "iwl-io.h" #include "file.h" #include "error-dump.h" +#include "api/commands.h" /** * struct iwl_fw_dump_desc - describes the dump @@ -206,9 +207,26 @@ _iwl_fw_dbg_trigger_simple_stop(struct iwl_fw_runtime *fwrt, iwl_fw_dbg_get_trigger((fwrt)->fw,\ (trig))) +static int iwl_fw_dbg_start_stop_hcmd(struct iwl_fw_runtime *fwrt, bool start) +{ + struct iwl_continuous_record_cmd cont_rec = {}; + struct iwl_host_cmd hcmd = { + .id = LDBG_CONFIG_CMD, + .flags = CMD_ASYNC, + .data[0] = &cont_rec, + .len[0] = sizeof(cont_rec), + }; + + cont_rec.record_mode.enable_recording = start ? + cpu_to_le16(START_DEBUG_RECORDING) : + cpu_to_le16(STOP_DEBUG_RECORDING); + + return iwl_trans_send_cmd(fwrt->trans, &hcmd); +} + static inline void -iwl_fw_dbg_stop_recording(struct iwl_trans *trans, - struct iwl_fw_dbg_params *params) +_iwl_fw_dbg_stop_recording(struct iwl_trans *trans, + struct iwl_fw_dbg_params *params) { if (trans->cfg->device_family == IWL_DEVICE_FAMILY_7000) { iwl_set_bits_prph(trans, MON_BUFF_SAMPLE_CTL, 0x100); @@ -226,8 +244,18 @@ iwl_fw_dbg_stop_recording(struct iwl_trans *trans, } static inline void -iwl_fw_dbg_restart_recording(struct iwl_trans *trans, - struct iwl_fw_dbg_params *params) +iwl_fw_dbg_stop_recording(struct iwl_fw_runtime *fwrt, + struct iwl_fw_dbg_params *params) +{ + if (fwrt->trans->cfg->device_family < IWL_DEVICE_FAMILY_22560) + _iwl_fw_dbg_stop_recording(fwrt->trans, params); + else + iwl_fw_dbg_start_stop_hcmd(fwrt, false); +} + +static inline void +_iwl_fw_dbg_restart_recording(struct iwl_trans *trans, + struct iwl_fw_dbg_params *params) { if (WARN_ON(!params)) return; @@ -243,6 +271,16 @@ iwl_fw_dbg_restart_recording(struct iwl_trans *trans, } } +static inline void +iwl_fw_dbg_restart_recording(struct iwl_fw_runtime *fwrt, + struct iwl_fw_dbg_params *params) +{ + if (fwrt->trans->cfg->device_family < IWL_DEVICE_FAMILY_22560) + _iwl_fw_dbg_restart_recording(fwrt->trans, params); + else + iwl_fw_dbg_start_stop_hcmd(fwrt, true); +} + static inline void iwl_fw_dump_conf_clear(struct iwl_fw_runtime *fwrt) { fwrt->dump.conf = FW_DBG_INVALID; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c index 5305342439b2..b09446697c46 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c @@ -1042,7 +1042,7 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw, * the recording automatically before entering D3. This can * be removed once the FW starts doing that. */ - iwl_fw_dbg_stop_recording(mvm->fwrt.trans, NULL); + _iwl_fw_dbg_stop_recording(mvm->fwrt.trans, NULL); /* must be last -- this switches firmware state */ ret = iwl_mvm_send_cmd(mvm, &d3_cfg_cmd); diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c index b5902c74e5d0..77f3610e5ca9 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c @@ -165,7 +165,7 @@ void _iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans, bool low_power) trans_pcie->is_down = true; /* Stop dbgc before stopping device */ - iwl_fw_dbg_stop_recording(trans, NULL); + _iwl_fw_dbg_stop_recording(trans, NULL); /* tell the device to stop sending interrupts */ iwl_disable_interrupts(trans); diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index 5ecd5c8d0f02..1012d71bad6f 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -1243,7 +1243,7 @@ static void _iwl_trans_pcie_stop_device(struct iwl_trans *trans, bool low_power) trans_pcie->is_down = true; /* Stop dbgc before stopping device */ - iwl_fw_dbg_stop_recording(trans, NULL); + _iwl_fw_dbg_stop_recording(trans, NULL); /* tell the device to stop sending interrupts */ iwl_disable_interrupts(trans); From 838f4c73a353be28222593babeeac9edca1b1be0 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 22 May 2018 14:25:59 +0200 Subject: [PATCH 227/276] iwlwifi: RX API: remove unnecessary anonymous struct There's no value in having an anonymous struct for holding a few fields, remove it. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/fw/api/rx.h | 26 +++++++++---------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h b/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h index 2078ef425f8c..415b8842b426 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h @@ -601,23 +601,21 @@ struct iwl_rx_mpdu_desc { */ u8 mac_phy_idx; /* DW4 - carries csum data only when rpa_en == 1 */ - struct { + /** + * @raw_csum: raw checksum (alledgedly unreliable) + */ + __le16 raw_csum; + + union { /** - * @raw_csum: raw checksum (alledgedly unreliable) + * @l3l4_flags: &enum iwl_rx_l3l4_flags */ - __le16 raw_csum; + __le16 l3l4_flags; - union { - /** - * @l3l4_flags: &enum iwl_rx_l3l4_flags - */ - __le16 l3l4_flags; - - /** - * @sigb_common2: for HE sniffer, HE-SIG-B common part 2 - */ - __le16 sigb_common2; - }; + /** + * @sigb_common2: for HE sniffer, HE-SIG-B common part 2 + */ + __le16 sigb_common2; }; /* DW5 */ /** From da7527173b18bb8fc77407071ca427341b555d6f Mon Sep 17 00:00:00 2001 From: Shahar S Matityahu Date: Tue, 10 Apr 2018 12:29:49 +0300 Subject: [PATCH 228/276] iwlwifi: debug flow cleanup Cleanup of the debug flow by moving several flows to separate functions to increase readability. Three functions were created: 1. iwl_fw_get_prph_len - returns the size needed for periphery dump. 2. iwl_fw_dump_mem for - executes the memory dumping flow. 3. iwl_trans_get_fw_monitor_len - returns the size needed for monitor dump. Signed-off-by: Shahar S Matityahu Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 212 ++++++++++-------- .../net/wireless/intel/iwlwifi/pcie/trans.c | 67 +++--- 2 files changed, 151 insertions(+), 128 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index cebc9e99961e..5029fd91f0bb 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -538,12 +538,108 @@ static struct scatterlist *alloc_sgtable(int size) return table; } +static int iwl_fw_get_prph_len(struct iwl_fw_runtime *fwrt) +{ + u32 prph_len = 0; + int i; + + for (i = 0; i < ARRAY_SIZE(iwl_prph_dump_addr_comm); + i++) { + /* The range includes both boundaries */ + int num_bytes_in_chunk = + iwl_prph_dump_addr_comm[i].end - + iwl_prph_dump_addr_comm[i].start + 4; + + prph_len += sizeof(struct iwl_fw_error_dump_data) + + sizeof(struct iwl_fw_error_dump_prph) + + num_bytes_in_chunk; + } + + if (fwrt->trans->cfg->mq_rx_supported) { + for (i = 0; i < + ARRAY_SIZE(iwl_prph_dump_addr_9000); i++) { + /* The range includes both boundaries */ + int num_bytes_in_chunk = + iwl_prph_dump_addr_9000[i].end - + iwl_prph_dump_addr_9000[i].start + 4; + + prph_len += sizeof(struct iwl_fw_error_dump_data) + + sizeof(struct iwl_fw_error_dump_prph) + + num_bytes_in_chunk; + } + } + return prph_len; +} + +static void iwl_fw_dump_mem(struct iwl_fw_runtime *fwrt, + struct iwl_fw_error_dump_data **dump_data, + u32 sram_len, u32 sram_ofs, u32 smem_len, + u32 sram2_len) +{ + const struct iwl_fw_dbg_mem_seg_tlv *fw_dbg_mem = fwrt->fw->dbg_mem_tlv; + struct iwl_fw_error_dump_mem *dump_mem; + int i; + + if (!fwrt->fw->n_dbg_mem_tlv) { + (*dump_data)->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM); + (*dump_data)->len = cpu_to_le32(sram_len + sizeof(*dump_mem)); + dump_mem = (void *)(*dump_data)->data; + dump_mem->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM_SRAM); + dump_mem->offset = cpu_to_le32(sram_ofs); + iwl_trans_read_mem_bytes(fwrt->trans, sram_ofs, dump_mem->data, + sram_len); + *dump_data = iwl_fw_error_next_data(*dump_data); + } + + for (i = 0; i < fwrt->fw->n_dbg_mem_tlv; i++) { + u32 len = le32_to_cpu(fw_dbg_mem[i].len); + u32 ofs = le32_to_cpu(fw_dbg_mem[i].ofs); + + (*dump_data)->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM); + (*dump_data)->len = cpu_to_le32(len + sizeof(*dump_mem)); + dump_mem = (void *)(*dump_data)->data; + dump_mem->type = fw_dbg_mem[i].data_type; + dump_mem->offset = cpu_to_le32(ofs); + + IWL_DEBUG_INFO(fwrt, "WRT memory dump. Type=%u\n", + dump_mem->type); + + iwl_trans_read_mem_bytes(fwrt->trans, ofs, dump_mem->data, len); + *dump_data = iwl_fw_error_next_data(*dump_data); + } + + if (smem_len) { + IWL_DEBUG_INFO(fwrt, "WRT SMEM dump\n"); + (*dump_data)->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM); + (*dump_data)->len = cpu_to_le32(smem_len + sizeof(*dump_mem)); + dump_mem = (void *)(*dump_data)->data; + dump_mem->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM_SMEM); + dump_mem->offset = cpu_to_le32(fwrt->trans->cfg->smem_offset); + iwl_trans_read_mem_bytes(fwrt->trans, + fwrt->trans->cfg->smem_offset, + dump_mem->data, smem_len); + *dump_data = iwl_fw_error_next_data(*dump_data); + } + + if (sram2_len) { + IWL_DEBUG_INFO(fwrt, "WRT SRAM dump\n"); + (*dump_data)->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM); + (*dump_data)->len = cpu_to_le32(sram2_len + sizeof(*dump_mem)); + dump_mem = (void *)(*dump_data)->data; + dump_mem->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM_SRAM); + dump_mem->offset = cpu_to_le32(fwrt->trans->cfg->dccm2_offset); + iwl_trans_read_mem_bytes(fwrt->trans, + fwrt->trans->cfg->dccm2_offset, + dump_mem->data, sram2_len); + *dump_data = iwl_fw_error_next_data(*dump_data); + } +} + void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt) { struct iwl_fw_error_dump_file *dump_file; struct iwl_fw_error_dump_data *dump_data; struct iwl_fw_error_dump_info *dump_info; - struct iwl_fw_error_dump_mem *dump_mem; struct iwl_fw_error_dump_smem_cfg *dump_smem_cfg; struct iwl_fw_error_dump_trigger_desc *dump_trig; struct iwl_fw_dump_ptrs *fw_error_dump; @@ -655,35 +751,8 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt) /* Make room for PRPH registers */ if (!fwrt->trans->cfg->gen2 && - fwrt->fw->dbg_dump_mask & BIT(IWL_FW_ERROR_DUMP_PRPH)) { - for (i = 0; i < ARRAY_SIZE(iwl_prph_dump_addr_comm); - i++) { - /* The range includes both boundaries */ - int num_bytes_in_chunk = - iwl_prph_dump_addr_comm[i].end - - iwl_prph_dump_addr_comm[i].start + 4; - - prph_len += sizeof(*dump_data) + - sizeof(struct iwl_fw_error_dump_prph) + - num_bytes_in_chunk; - } - } - - if (!fwrt->trans->cfg->gen2 && - fwrt->trans->cfg->mq_rx_supported && - fwrt->fw->dbg_dump_mask & BIT(IWL_FW_ERROR_DUMP_PRPH)) { - for (i = 0; i < - ARRAY_SIZE(iwl_prph_dump_addr_9000); i++) { - /* The range includes both boundaries */ - int num_bytes_in_chunk = - iwl_prph_dump_addr_9000[i].end - - iwl_prph_dump_addr_9000[i].start + 4; - - prph_len += sizeof(*dump_data) + - sizeof(struct iwl_fw_error_dump_prph) + - num_bytes_in_chunk; - } - } + fwrt->fw->dbg_dump_mask & BIT(IWL_FW_ERROR_DUMP_PRPH)) + prph_len += iwl_fw_get_prph_len(fwrt); if (fwrt->trans->cfg->device_family == IWL_DEVICE_FAMILY_7000 && fwrt->fw->dbg_dump_mask & BIT(IWL_FW_ERROR_DUMP_RADIO_REG)) @@ -703,18 +772,19 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt) if (fwrt->fw->dbg_dump_mask & BIT(IWL_FW_ERROR_DUMP_MEM)) { /* Make room for the SMEM, if it exists */ if (smem_len) - file_len += sizeof(*dump_data) + sizeof(*dump_mem) + - smem_len; + file_len += sizeof(*dump_data) + smem_len + + sizeof(struct iwl_fw_error_dump_mem); /* Make room for the secondary SRAM, if it exists */ if (sram2_len) - file_len += sizeof(*dump_data) + sizeof(*dump_mem) + - sram2_len; + file_len += sizeof(*dump_data) + sram2_len + + sizeof(struct iwl_fw_error_dump_mem); /* Make room for MEM segments */ for (i = 0; i < fwrt->fw->n_dbg_mem_tlv; i++) { - file_len += sizeof(*dump_data) + sizeof(*dump_mem) + - le32_to_cpu(fw_dbg_mem[i].len); + file_len += sizeof(*dump_data) + + le32_to_cpu(fw_dbg_mem[i].len) + + sizeof(struct iwl_fw_error_dump_mem); } } @@ -746,7 +816,8 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt) if (fwrt->fw->dbg_dump_mask & BIT(IWL_FW_ERROR_DUMP_MEM) && !fwrt->fw->n_dbg_mem_tlv) - file_len += sizeof(*dump_data) + sram_len + sizeof(*dump_mem); + file_len += sizeof(*dump_data) + sram_len + + sizeof(struct iwl_fw_error_dump_mem); dump_file = vzalloc(file_len); if (!dump_file) { @@ -833,17 +904,10 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt) if (monitor_dump_only) goto dump_trans_data; - if (!fwrt->fw->n_dbg_mem_tlv && - fwrt->fw->dbg_dump_mask & BIT(IWL_FW_ERROR_DUMP_MEM)) { - dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM); - dump_data->len = cpu_to_le32(sram_len + sizeof(*dump_mem)); - dump_mem = (void *)dump_data->data; - dump_mem->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM_SRAM); - dump_mem->offset = cpu_to_le32(sram_ofs); - iwl_trans_read_mem_bytes(fwrt->trans, sram_ofs, dump_mem->data, - sram_len); - dump_data = iwl_fw_error_next_data(dump_data); - } + if (fwrt->fw->dbg_dump_mask & BIT(IWL_FW_ERROR_DUMP_MEM)) + iwl_fw_dump_mem(fwrt, &dump_data, sram_len, sram_ofs, smem_len, + sram2_len); + if (iwl_fw_dbg_is_d3_debug_enabled(fwrt) && fwrt->dump.d3_debug_data) { u32 addr = fwrt->trans->cfg->d3_debug_data_base_addr; @@ -852,8 +916,7 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt) dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_D3_DEBUG_DATA); dump_data->len = cpu_to_le32(data_size * 2); - memcpy(dump_data->data, fwrt->dump.d3_debug_data, - data_size); + memcpy(dump_data->data, fwrt->dump.d3_debug_data, data_size); kfree(fwrt->dump.d3_debug_data); fwrt->dump.d3_debug_data = NULL; @@ -865,55 +928,6 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt) dump_data = iwl_fw_error_next_data(dump_data); } - for (i = 0; i < fwrt->fw->n_dbg_mem_tlv; i++) { - u32 len = le32_to_cpu(fw_dbg_mem[i].len); - u32 ofs = le32_to_cpu(fw_dbg_mem[i].ofs); - - if (!(fwrt->fw->dbg_dump_mask & BIT(IWL_FW_ERROR_DUMP_MEM))) - break; - - dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM); - dump_data->len = cpu_to_le32(len + sizeof(*dump_mem)); - dump_mem = (void *)dump_data->data; - dump_mem->type = fw_dbg_mem[i].data_type; - dump_mem->offset = cpu_to_le32(ofs); - - IWL_DEBUG_INFO(fwrt, "WRT memory dump. Type=%u\n", - dump_mem->type); - - iwl_trans_read_mem_bytes(fwrt->trans, ofs, - dump_mem->data, - len); - - dump_data = iwl_fw_error_next_data(dump_data); - } - - if (smem_len && fwrt->fw->dbg_dump_mask & BIT(IWL_FW_ERROR_DUMP_MEM)) { - IWL_DEBUG_INFO(fwrt, "WRT SMEM dump\n"); - dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM); - dump_data->len = cpu_to_le32(smem_len + sizeof(*dump_mem)); - dump_mem = (void *)dump_data->data; - dump_mem->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM_SMEM); - dump_mem->offset = cpu_to_le32(fwrt->trans->cfg->smem_offset); - iwl_trans_read_mem_bytes(fwrt->trans, - fwrt->trans->cfg->smem_offset, - dump_mem->data, smem_len); - dump_data = iwl_fw_error_next_data(dump_data); - } - - if (sram2_len && fwrt->fw->dbg_dump_mask & BIT(IWL_FW_ERROR_DUMP_MEM)) { - IWL_DEBUG_INFO(fwrt, "WRT SRAM dump\n"); - dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM); - dump_data->len = cpu_to_le32(sram2_len + sizeof(*dump_mem)); - dump_mem = (void *)dump_data->data; - dump_mem->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM_SRAM); - dump_mem->offset = cpu_to_le32(fwrt->trans->cfg->dccm2_offset); - iwl_trans_read_mem_bytes(fwrt->trans, - fwrt->trans->cfg->dccm2_offset, - dump_mem->data, sram2_len); - dump_data = iwl_fw_error_next_data(dump_data); - } - /* Dump fw's virtual image */ if (fwrt->fw->dbg_dump_mask & BIT(IWL_FW_ERROR_DUMP_PAGING) && !fwrt->trans->cfg->gen2 && diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index 1012d71bad6f..93c336ebfa40 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -2912,36 +2912,17 @@ iwl_trans_pcie_dump_monitor(struct iwl_trans *trans, return len; } -static struct iwl_trans_dump_data -*iwl_trans_pcie_dump_data(struct iwl_trans *trans, - const struct iwl_fw_dbg_trigger_tlv *trigger) +static int iwl_trans_get_fw_monitor_len(struct iwl_trans *trans, int *len) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - struct iwl_fw_error_dump_data *data; - struct iwl_txq *cmdq = trans_pcie->txq[trans_pcie->cmd_queue]; - struct iwl_fw_error_dump_txcmd *txcmd; - struct iwl_trans_dump_data *dump_data; - u32 len, num_rbs = 0; - u32 monitor_len; - int i, ptr; - bool dump_rbs = test_bit(STATUS_FW_ERROR, &trans->status) && - !trans->cfg->mq_rx_supported && - trans->dbg_dump_mask & BIT(IWL_FW_ERROR_DUMP_RB); - /* transport dump header */ - len = sizeof(*dump_data); - - /* host commands */ - len += sizeof(*data) + - cmdq->n_window * (sizeof(*txcmd) + TFD_MAX_PAYLOAD_SIZE); - - /* FW monitor */ if (trans_pcie->fw_mon_cpu_addr) { - len += sizeof(*data) + sizeof(struct iwl_fw_error_dump_fw_mon) + - trans_pcie->fw_mon_size; - monitor_len = trans_pcie->fw_mon_size; + *len += sizeof(struct iwl_fw_error_dump_data) + + sizeof(struct iwl_fw_error_dump_fw_mon) + + trans_pcie->fw_mon_size; + return trans_pcie->fw_mon_size; } else if (trans->dbg_dest_tlv) { - u32 base, end, cfg_reg; + u32 base, end, cfg_reg, monitor_len; if (trans->dbg_dest_tlv->version == 1) { cfg_reg = le32_to_cpu(trans->dbg_dest_tlv->base_reg); @@ -2971,11 +2952,39 @@ static struct iwl_trans_dump_data end += (1 << trans->dbg_dest_tlv->end_shift); monitor_len = end - base; } - len += sizeof(*data) + sizeof(struct iwl_fw_error_dump_fw_mon) + - monitor_len; - } else { - monitor_len = 0; + *len += sizeof(struct iwl_fw_error_dump_data) + + sizeof(struct iwl_fw_error_dump_fw_mon) + + monitor_len; + return monitor_len; } + return 0; +} + +static struct iwl_trans_dump_data +*iwl_trans_pcie_dump_data(struct iwl_trans *trans, + const struct iwl_fw_dbg_trigger_tlv *trigger) +{ + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + struct iwl_fw_error_dump_data *data; + struct iwl_txq *cmdq = trans_pcie->txq[trans_pcie->cmd_queue]; + struct iwl_fw_error_dump_txcmd *txcmd; + struct iwl_trans_dump_data *dump_data; + u32 len, num_rbs = 0; + u32 monitor_len; + int i, ptr; + bool dump_rbs = test_bit(STATUS_FW_ERROR, &trans->status) && + !trans->cfg->mq_rx_supported && + trans->dbg_dump_mask & BIT(IWL_FW_ERROR_DUMP_RB); + + /* transport dump header */ + len = sizeof(*dump_data); + + /* host commands */ + len += sizeof(*data) + + cmdq->n_window * (sizeof(*txcmd) + TFD_MAX_PAYLOAD_SIZE); + + /* FW monitor */ + monitor_len = iwl_trans_get_fw_monitor_len(trans, &len); if (trigger && (trigger->mode & IWL_FW_DBG_TRIGGER_MONITOR_ONLY)) { if (!(trans->dbg_dump_mask & From caf3216f6554b4699f0e84852ba4b1f47769a2de Mon Sep 17 00:00:00 2001 From: Shaul Triebitz Date: Tue, 22 May 2018 17:37:31 +0300 Subject: [PATCH 229/276] iwlwifi: iwlmvm: fix typo when checking for TX Beamforming Check the actual bit (mask) in Rx notification rate_n_flags. Signed-off-by: Shaul Triebitz Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c index f415c72394ee..4400e69a39b6 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c @@ -1150,7 +1150,7 @@ static void iwl_mvm_rx_he(struct iwl_mvm *mvm, struct sk_buff *skb, he->data1 |= cpu_to_le16(he_type >> RATE_MCS_HE_TYPE_POS); - if (rate_n_flags & RATE_MCS_BF_POS) + if (rate_n_flags & RATE_MCS_BF_MSK) he->data5 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA5_TXBF); switch ((rate_n_flags & RATE_MCS_HE_GI_LTF_MSK) >> From a76938f35e4cfb9bc40a405220ec040f6b45d09c Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 23 May 2018 10:56:55 +0200 Subject: [PATCH 230/276] iwlwifi: mvm: report RU offset is known We already report the RU offset, so we'd better also report that we know the value. Fixes: e5721e3f770f ("iwlwifi: mvm: add radiotap data for HE") Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c index 4400e69a39b6..89b4b882ef80 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c @@ -1102,7 +1102,8 @@ static void iwl_mvm_rx_he(struct iwl_mvm *mvm, struct sk_buff *skb, le16_encode_bits(offs, IEEE80211_RADIOTAP_HE_DATA2_RU_OFFSET); he->data2 |= - cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_PRISEC_80_KNOWN); + cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_PRISEC_80_KNOWN | + IEEE80211_RADIOTAP_HE_DATA2_RU_OFFSET_KNOWN); if (he_phy_data & IWL_RX_HE_PHY_RU_ALLOC_SEC80) he->data2 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_PRISEC_80_SEC); From b08e876daf2afc78351f0a10b7821a512e6003da Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 23 May 2018 13:39:26 +0200 Subject: [PATCH 231/276] iwlwifi: remove ucode error tracepoint Alexei's patch, assumed that all versions of "struct iwl_error_event_table" are the same, but there are really different versions in different files. Rather than trying to fix this, or splitting the tracepoint, or anything of the sort, just remove it entirely - turns out that nobody really uses it. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/dvm/main.c | 2 +- .../intel/iwlwifi/iwl-devtrace-iwlwifi.h | 55 ------------------- .../net/wireless/intel/iwlwifi/iwl-devtrace.c | 3 +- .../net/wireless/intel/iwlwifi/mvm/utils.c | 1 - 4 files changed, 2 insertions(+), 59 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/main.c b/drivers/net/wireless/intel/iwlwifi/dvm/main.c index 1ef072071b0b..1088ff036e13 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/main.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/main.c @@ -2,6 +2,7 @@ * * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2015 Intel Deutschland GmbH + * Copyright (C) 2018 Intel Corporation * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. @@ -1647,7 +1648,6 @@ static void iwl_dump_nic_error_log(struct iwl_priv *priv) priv->status, table.valid); } - trace_iwlwifi_dev_ucode_error(trans->dev, &table, 0, table.brd_ver); IWL_ERR(priv, "0x%08X | %-28s\n", table.error_id, desc_lookup(table.error_id)); IWL_ERR(priv, "0x%08X | uPc\n", table.pc); diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-iwlwifi.h b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-iwlwifi.h index 82cfbfa0795d..8e87186682e7 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-iwlwifi.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-iwlwifi.h @@ -128,61 +128,6 @@ TRACE_EVENT(iwlwifi_dev_tx, __entry->framelen, __entry->skbaddr) ); -struct iwl_error_event_table; -TRACE_EVENT(iwlwifi_dev_ucode_error, - TP_PROTO(const struct device *dev, const struct iwl_error_event_table *table, - u32 hw_ver, u32 brd_ver), - TP_ARGS(dev, table, hw_ver, brd_ver), - TP_STRUCT__entry( - DEV_ENTRY - __field(u32, desc) - __field(u32, tsf_low) - __field(u32, data1) - __field(u32, data2) - __field(u32, line) - __field(u32, blink2) - __field(u32, ilink1) - __field(u32, ilink2) - __field(u32, bcon_time) - __field(u32, gp1) - __field(u32, gp2) - __field(u32, rev_type) - __field(u32, major) - __field(u32, minor) - __field(u32, hw_ver) - __field(u32, brd_ver) - ), - TP_fast_assign( - DEV_ASSIGN; - __entry->desc = table->error_id; - __entry->tsf_low = table->tsf_low; - __entry->data1 = table->data1; - __entry->data2 = table->data2; - __entry->line = table->line; - __entry->blink2 = table->blink2; - __entry->ilink1 = table->ilink1; - __entry->ilink2 = table->ilink2; - __entry->bcon_time = table->bcon_time; - __entry->gp1 = table->gp1; - __entry->gp2 = table->gp2; - __entry->rev_type = table->gp3; - __entry->major = table->ucode_ver; - __entry->minor = table->hw_ver; - __entry->hw_ver = hw_ver; - __entry->brd_ver = brd_ver; - ), - TP_printk("[%s] #%02d %010u data 0x%08X 0x%08X line %u, " - "blink2 0x%05X ilink 0x%05X 0x%05X " - "bcon_tm %010u gp 0x%08X 0x%08X rev_type 0x%08X major 0x%08X " - "minor 0x%08X hw 0x%08X brd 0x%08X", - __get_str(dev), __entry->desc, __entry->tsf_low, - __entry->data1, __entry->data2, __entry->line, - __entry->blink2, __entry->ilink1, __entry->ilink2, - __entry->bcon_time, __entry->gp1, __entry->gp2, - __entry->rev_type, __entry->major, __entry->minor, - __entry->hw_ver, __entry->brd_ver) -); - TRACE_EVENT(iwlwifi_dev_ucode_event, TP_PROTO(const struct device *dev, u32 time, u32 data, u32 ev), TP_ARGS(dev, time, data, ev), diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.c b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.c index 27b4dd409a0e..9805432f124f 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.c @@ -1,6 +1,7 @@ /****************************************************************************** * * Copyright(c) 2009 - 2014 Intel Corporation. All rights reserved. + * Copyright (C) 2018 Intel Corporation * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -26,12 +27,10 @@ #ifndef __CHECKER__ #include "iwl-trans.h" -#include "dvm/commands.h" #define CREATE_TRACE_POINTS #include "iwl-devtrace.h" EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_event); -EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_error); EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_cont_event); EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_wrap_event); #endif diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c index 99a872769e90..dcacc4d11abc 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c @@ -546,7 +546,6 @@ static void iwl_mvm_dump_lmac_error_log(struct iwl_mvm *mvm, u32 base) IWL_ERR(mvm, "Loaded firmware version: %s\n", mvm->fw->fw_version); - trace_iwlwifi_dev_ucode_error(trans->dev, &table, table.hw_ver, table.brd_ver); IWL_ERR(mvm, "0x%08X | %-28s\n", table.error_id, desc_lookup(table.error_id)); IWL_ERR(mvm, "0x%08X | trm_hw_status0\n", table.trm_hw_status0); From 79f25b10c9da3dbc953e47033d0494e51580ac3b Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 29 May 2018 10:04:16 +0300 Subject: [PATCH 232/276] iwlwifi: dbg: don't crash if the firmware crashes in the middle of a debug dump We can dump data from the firmware either when it crashes, or when the firmware is alive. Not all the data is available if the firmware is running (like the Tx / Rx FIFOs which are available only when the firmware is halted), so we first check that the firmware is alive to compute the required size for the dump and then fill the buffer with the data. When we allocate the buffer, we test the STATUS_FW_ERROR bit to check if the firmware is alive or not. This bit can be changed during the course of the dump since it is modified in the interrupt handler. We hit a case where we allocate the buffer while the firmware is sill working, and while we start to fill the buffer, the firmware crashes. Then we test STATUS_FW_ERROR again and decide to fill the buffer with data like the FIFOs even if no room was allocated for this data in the buffer. This means that we overflow the buffer that was allocated leading to memory corruption. To fix this, test the STATUS_FW_ERROR bit only once and rely on local variables to check if we should dump fifos or other firmware components. Fixes: 04fd2c28226f ("iwlwifi: mvm: add rxf and txf to dump data") Signed-off-by: Emmanuel Grumbach Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index 5029fd91f0bb..0dcf1a673478 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -882,7 +882,7 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt) } /* We only dump the FIFOs if the FW is in error state */ - if (test_bit(STATUS_FW_ERROR, &fwrt->trans->status)) { + if (fifo_data_len) { iwl_fw_dump_fifos(fwrt, &dump_data); if (radio_len) iwl_read_radio_regs(fwrt, &dump_data); From a40287727d9b737e183959fd31a4e0c55f312853 Mon Sep 17 00:00:00 2001 From: Erel Geron Date: Mon, 28 May 2018 17:15:56 +0300 Subject: [PATCH 233/276] iwlwifi: fix non_shared_ant for 22000 devices The non-shared antenna was wrong for 22000 device series. Fix it to ANT_B for correct antenna preference by coex in MVM driver. Fixes: e34d975e40ff ("iwlwifi: Add a000 HW family support") Signed-off-by: Erel Geron Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/cfg/22000.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c index 204a51fd6375..a8acc755a02c 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c @@ -143,7 +143,7 @@ static const struct iwl_ht_params iwl_22000_ht_params = { .ucode_api_min = IWL_22000_UCODE_API_MIN, \ .led_mode = IWL_LED_RF_STATE, \ .nvm_hw_section_num = NVM_HW_SECTION_NUM_FAMILY_22000, \ - .non_shared_ant = ANT_A, \ + .non_shared_ant = ANT_B, \ .dccm_offset = IWL_22000_DCCM_OFFSET, \ .dccm_len = IWL_22000_DCCM_LEN, \ .dccm2_offset = IWL_22000_DCCM2_OFFSET, \ From 10a970dff16816201d82b526f3a80d615f2e578c Mon Sep 17 00:00:00 2001 From: "Dreyfuss, Haim" Date: Mon, 21 May 2018 10:36:46 +0300 Subject: [PATCH 234/276] iwlwifi: mvm: cleanup dead code on resume flow for non unified image. CDB support has nothing to do with non unified image. Signed-off-by: Haim Dreyfuss Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c index b09446697c46..210be26aadaa 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c @@ -434,23 +434,13 @@ static int iwl_mvm_d3_reprogram(struct iwl_mvm *mvm, struct ieee80211_vif *vif, u8 chains_static, chains_dynamic; struct cfg80211_chan_def chandef; int ret, i; - struct iwl_binding_cmd binding_cmd = {}; + struct iwl_binding_cmd_v1 binding_cmd = {}; struct iwl_time_quota_cmd quota_cmd = {}; struct iwl_time_quota_data *quota; u32 status; - int size; - if (fw_has_capa(&mvm->fw->ucode_capa, - IWL_UCODE_TLV_CAPA_BINDING_CDB_SUPPORT)) { - size = sizeof(binding_cmd); - if (mvmvif->phy_ctxt->channel->band == NL80211_BAND_2GHZ || - !iwl_mvm_is_cdb_supported(mvm)) - binding_cmd.lmac_id = cpu_to_le32(IWL_LMAC_24G_INDEX); - else - binding_cmd.lmac_id = cpu_to_le32(IWL_LMAC_5G_INDEX); - } else { - size = IWL_BINDING_CMD_SIZE_V1; - } + if (WARN_ON_ONCE(iwl_mvm_is_cdb_supported(mvm))) + return -EINVAL; /* add back the PHY */ if (WARN_ON(!mvmvif->phy_ctxt)) @@ -497,7 +487,8 @@ static int iwl_mvm_d3_reprogram(struct iwl_mvm *mvm, struct ieee80211_vif *vif, status = 0; ret = iwl_mvm_send_cmd_pdu_status(mvm, BINDING_CONTEXT_CMD, - size, &binding_cmd, &status); + IWL_BINDING_CMD_SIZE_V1, &binding_cmd, + &status); if (ret) { IWL_ERR(mvm, "Failed to add binding: %d\n", ret); return ret; From 989209610b60a3f0f39001f37da61698bbec8b5c Mon Sep 17 00:00:00 2001 From: Shaul Triebitz Date: Sun, 25 Feb 2018 18:37:30 +0200 Subject: [PATCH 235/276] iwlwifi: mvm: enable sending HE_AIR_SNIFFER command via debugfs In order to receive TB (Trigger Based) PPDU in monitor mode, the Driver must send the HE_AIR_SNIFFER_CONFIG_CMD host command. Enable that via debugfs. Signed-off-by: Liad Kaufman Signed-off-by: Ido Yariv Signed-off-by: Shaul Triebitz Signed-off-by: Luca Coelho --- .../wireless/intel/iwlwifi/fw/api/datapath.h | 5 +++ .../net/wireless/intel/iwlwifi/fw/api/mac.h | 14 ++++++++ .../net/wireless/intel/iwlwifi/mvm/debugfs.c | 32 +++++++++++++++++++ 3 files changed, 51 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/datapath.h b/drivers/net/wireless/intel/iwlwifi/fw/api/datapath.h index 59b3c6e8f37b..eff3249af48a 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/datapath.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/datapath.h @@ -99,6 +99,11 @@ enum iwl_data_path_subcmd_ids { */ TLC_MNG_CONFIG_CMD = 0xF, + /** + * @HE_AIR_SNIFFER_CONFIG_CMD: &struct iwl_he_monitor_cmd + */ + HE_AIR_SNIFFER_CONFIG_CMD = 0x13, + /** * @TLC_MNG_UPDATE_NOTIF: &struct iwl_tlc_update_notif */ diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/mac.h b/drivers/net/wireless/intel/iwlwifi/fw/api/mac.h index 55594c93b014..1dd23f846fb9 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/mac.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/mac.h @@ -578,4 +578,18 @@ struct iwl_he_sta_context_cmd { struct iwl_he_backoff_conf trig_based_txf[AC_NUM]; } __packed; /* STA_CONTEXT_DOT11AX_API_S */ +/** + * struct iwl_he_monitor_cmd - configure air sniffer for HE + * @bssid: the BSSID to sniff for + * @reserved1: reserved for dword alignment + * @aid: the AID to track on for HE MU + * @reserved2: reserved for future use + */ +struct iwl_he_monitor_cmd { + u8 bssid[6]; + __le16 reserved1; + __le16 aid; + u8 reserved2[6]; +} __packed; /* HE_AIR_SNIFFER_CONFIG_CMD_API_S_VER_1 */ + #endif /* __iwl_fw_api_mac_h__ */ diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c index 202158d03d36..de40752aa67e 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c @@ -1727,6 +1727,35 @@ iwl_dbgfs_send_echo_cmd_write(struct iwl_mvm *mvm, char *buf, return ret ?: count; } +static ssize_t +iwl_dbgfs_he_sniffer_params_write(struct iwl_mvm *mvm, char *buf, + size_t count, loff_t *ppos) +{ + struct iwl_he_monitor_cmd he_mon_cmd = {}; + u32 aid; + int ret; + + if (!iwl_mvm_firmware_running(mvm)) + return -EIO; + + ret = sscanf(buf, "%x %2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx", &aid, + &he_mon_cmd.bssid[0], &he_mon_cmd.bssid[1], + &he_mon_cmd.bssid[2], &he_mon_cmd.bssid[3], + &he_mon_cmd.bssid[4], &he_mon_cmd.bssid[5]); + if (ret != 7) + return -EINVAL; + + he_mon_cmd.aid = cpu_to_le16(aid); + + mutex_lock(&mvm->mutex); + ret = iwl_mvm_send_cmd_pdu(mvm, iwl_cmd_id(HE_AIR_SNIFFER_CONFIG_CMD, + DATA_PATH_GROUP, 0), 0, + sizeof(he_mon_cmd), &he_mon_cmd); + mutex_unlock(&mvm->mutex); + + return ret ?: count; +} + static ssize_t iwl_dbgfs_uapsd_noagg_bssids_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) @@ -1796,6 +1825,8 @@ MVM_DEBUGFS_READ_WRITE_FILE_OPS(d3_sram, 8); MVM_DEBUGFS_READ_FILE_OPS(sar_geo_profile); #endif +MVM_DEBUGFS_WRITE_FILE_OPS(he_sniffer_params, 32); + static ssize_t iwl_dbgfs_mem_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { @@ -1984,6 +2015,7 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir) #ifdef CONFIG_ACPI MVM_DEBUGFS_ADD_FILE(sar_geo_profile, dbgfs_dir, 0400); #endif + MVM_DEBUGFS_ADD_FILE(he_sniffer_params, mvm->debugfs_dir, 0200); if (!debugfs_create_bool("enable_scan_iteration_notif", 0600, From 84fb372c892e231e9a2ffdaa5c2df52d94aa536c Mon Sep 17 00:00:00 2001 From: Sara Sharon Date: Wed, 30 May 2018 15:19:56 +0300 Subject: [PATCH 236/276] iwlwifi: pcie: read correct prph address for newer devices For newer devices we have higher range of periphery addresses. Currently it is masked out, so we end up reading another address. Signed-off-by: Sara Sharon Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index 93c336ebfa40..ab0a5a663a6d 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -1805,18 +1805,30 @@ static u32 iwl_trans_pcie_read32(struct iwl_trans *trans, u32 ofs) return readl(IWL_TRANS_GET_PCIE_TRANS(trans)->hw_base + ofs); } +static u32 iwl_trans_pcie_prph_msk(struct iwl_trans *trans) +{ + if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) + return 0x00FFFFFF; + else + return 0x000FFFFF; +} + static u32 iwl_trans_pcie_read_prph(struct iwl_trans *trans, u32 reg) { + u32 mask = iwl_trans_pcie_prph_msk(trans); + iwl_trans_pcie_write32(trans, HBUS_TARG_PRPH_RADDR, - ((reg & 0x000FFFFF) | (3 << 24))); + ((reg & mask) | (3 << 24))); return iwl_trans_pcie_read32(trans, HBUS_TARG_PRPH_RDAT); } static void iwl_trans_pcie_write_prph(struct iwl_trans *trans, u32 addr, u32 val) { + u32 mask = iwl_trans_pcie_prph_msk(trans); + iwl_trans_pcie_write32(trans, HBUS_TARG_PRPH_WADDR, - ((addr & 0x000FFFFF) | (3 << 24))); + ((addr & mask) | (3 << 24))); iwl_trans_pcie_write32(trans, HBUS_TARG_PRPH_WDAT, val); } From 7f768ad5eb46a8a12c9bb8e37e73fe5b4a66533b Mon Sep 17 00:00:00 2001 From: David Spinadel Date: Tue, 7 Nov 2017 11:59:57 +0200 Subject: [PATCH 237/276] iwlwifi: mvm: Support TKIP on gen2 data path Make the adjustments for gen2 TX and RX of TKIP packets. Strip MIC on RX. Don't add IV space and keep the MIC space zeroed on TX. Devices that support gen2 data path support TKIP only in station mode. In all other modes, fall back to SW encryption. Do this early in the set_key() callback so that the key flags would not be incorrectly set. Signed-off-by: David Spinadel Signed-off-by: Ilan Peer Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 11 +++++++++-- drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 9 ++++++++- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index 134bb9fd21a4..b55a2e4a0024 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -3151,8 +3151,15 @@ static int iwl_mvm_mac_set_key(struct ieee80211_hw *hw, switch (key->cipher) { case WLAN_CIPHER_SUITE_TKIP: - key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; - key->flags |= IEEE80211_KEY_FLAG_PUT_IV_SPACE; + if (!mvm->trans->cfg->gen2) { + key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; + key->flags |= IEEE80211_KEY_FLAG_PUT_IV_SPACE; + } else if (vif->type == NL80211_IFTYPE_STATION) { + key->flags |= IEEE80211_KEY_FLAG_PUT_MIC_SPACE; + } else { + IWL_DEBUG_MAC80211(mvm, "Use SW encryption for TKIP\n"); + return -EOPNOTSUPP; + } break; case WLAN_CIPHER_SUITE_CCMP: case WLAN_CIPHER_SUITE_GCMP: diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c index 89b4b882ef80..894dd6379b9a 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c @@ -283,6 +283,10 @@ static int iwl_mvm_rx_crypto(struct iwl_mvm *mvm, struct ieee80211_hdr *hdr, !(status & IWL_RX_MPDU_RES_STATUS_TTAK_OK)) return 0; + if (mvm->trans->cfg->gen2 && + !(status & RX_MPDU_RES_STATUS_MIC_OK)) + stats->flag |= RX_FLAG_MMIC_ERROR; + *crypt_len = IEEE80211_TKIP_IV_LEN; /* fall through if TTAK OK */ case IWL_RX_MPDU_STATUS_SEC_WEP: @@ -294,8 +298,11 @@ static int iwl_mvm_rx_crypto(struct iwl_mvm *mvm, struct ieee80211_hdr *hdr, IWL_RX_MPDU_STATUS_SEC_WEP) *crypt_len = IEEE80211_WEP_IV_LEN; - if (pkt_flags & FH_RSCSR_RADA_EN) + if (pkt_flags & FH_RSCSR_RADA_EN) { stats->flag |= RX_FLAG_ICV_STRIPPED; + if (mvm->trans->cfg->gen2) + stats->flag |= RX_FLAG_MMIC_STRIPPED; + } return 0; case IWL_RX_MPDU_STATUS_SEC_EXT_ENC: From 6f68cc367ab6578a33cca21b6056804165621f00 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 30 May 2018 14:13:18 +0200 Subject: [PATCH 238/276] iwlwifi: api: annotate compressed BA notif array sizes Annotate the compressed BA notification array sizes and make both of them 0-length since the length of 1 is just confusing - it may be different than that and the offset to the second one needs to be calculated in the C code anyhow. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/api/tx.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h b/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h index 135135d80d4d..358bdf051e83 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h @@ -747,9 +747,9 @@ enum iwl_mvm_ba_resp_flags { * @tfd_cnt: number of TFD-Q elements * @ra_tid_cnt: number of RATID-Q elements * @tfd: array of TFD queue status updates. See &iwl_mvm_compressed_ba_tfd - * for details. + * for details. Length in @tfd_cnt. * @ra_tid: array of RA-TID queue status updates. For debug purposes only. See - * &iwl_mvm_compressed_ba_ratid for more details. + * &iwl_mvm_compressed_ba_ratid for more details. Length in @ra_tid_cnt. */ struct iwl_mvm_compressed_ba_notif { __le32 flags; @@ -766,7 +766,7 @@ struct iwl_mvm_compressed_ba_notif { __le32 tx_rate; __le16 tfd_cnt; __le16 ra_tid_cnt; - struct iwl_mvm_compressed_ba_tfd tfd[1]; + struct iwl_mvm_compressed_ba_tfd tfd[0]; struct iwl_mvm_compressed_ba_ratid ra_tid[0]; } __packed; /* COMPRESSED_BA_RES_API_S_VER_4 */ From 3f425b81ce41ab076e5052160a6defbfa8e7e56a Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 1 Jun 2018 09:39:37 +0200 Subject: [PATCH 239/276] iwlwifi: pcie: gen2: pull adding frags to helper routine Move the skb fragment loop into a helper routine to be able to reuse it later. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/pcie/tx-gen2.c | 51 ++++++++++++------- 1 file changed, 32 insertions(+), 19 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c index a33fb335849e..943891a9d3e7 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c @@ -416,6 +416,35 @@ iwl_tfh_tfd *iwl_pcie_gen2_build_tx_amsdu(struct iwl_trans *trans, return NULL; } +static int iwl_pcie_gen2_tx_add_frags(struct iwl_trans *trans, + struct sk_buff *skb, + struct iwl_tfh_tfd *tfd, + struct iwl_cmd_meta *out_meta) +{ + int i; + + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { + const skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; + dma_addr_t tb_phys; + int tb_idx; + + if (!skb_frag_size(frag)) + continue; + + tb_phys = skb_frag_dma_map(trans->dev, frag, 0, + skb_frag_size(frag), DMA_TO_DEVICE); + + if (unlikely(dma_mapping_error(trans->dev, tb_phys))) + return -ENOMEM; + tb_idx = iwl_pcie_gen2_set_tb(trans, tfd, tb_phys, + skb_frag_size(frag)); + + out_meta->tbs |= BIT(tb_idx); + } + + return 0; +} + static struct iwl_tfh_tfd *iwl_pcie_gen2_build_tx(struct iwl_trans *trans, struct iwl_txq *txq, @@ -428,7 +457,7 @@ iwl_tfh_tfd *iwl_pcie_gen2_build_tx(struct iwl_trans *trans, int idx = iwl_pcie_get_cmd_index(txq, txq->write_ptr); struct iwl_tfh_tfd *tfd = iwl_pcie_get_tfd(trans, txq, idx); dma_addr_t tb_phys; - int i, len, tb1_len, tb2_len; + int len, tb1_len, tb2_len; void *tb1_addr; tb_phys = iwl_pcie_get_first_tb_dma(txq, idx); @@ -467,24 +496,8 @@ iwl_tfh_tfd *iwl_pcie_gen2_build_tx(struct iwl_trans *trans, iwl_pcie_gen2_set_tb(trans, tfd, tb_phys, tb2_len); } - /* set up the remaining entries to point to the data */ - for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { - const skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; - int tb_idx; - - if (!skb_frag_size(frag)) - continue; - - tb_phys = skb_frag_dma_map(trans->dev, frag, 0, - skb_frag_size(frag), DMA_TO_DEVICE); - - if (unlikely(dma_mapping_error(trans->dev, tb_phys))) - goto out_err; - tb_idx = iwl_pcie_gen2_set_tb(trans, tfd, tb_phys, - skb_frag_size(frag)); - - out_meta->tbs |= BIT(tb_idx); - } + if (iwl_pcie_gen2_tx_add_frags(trans, skb, tfd, out_meta)) + goto out_err; trace_iwlwifi_dev_tx(trans->dev, skb, tfd, sizeof(*tfd), &dev_cmd->hdr, IWL_FIRST_TB_SIZE + tb1_len, hdr_len); From 53f474e6a8d74d5dc0c3a015d889471f9a157685 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 1 Jun 2018 09:45:55 +0200 Subject: [PATCH 240/276] iwlwifi: pcie: gen2: build A-MSDU only for GSO If the incoming frame should be an A-MSDU, it may already be one, for example in the case of NAN multicast being encapsulated in an A-MSDU. Thus, use the GSO algorithm to build A-MSDU only if the skb actually contains GSO data. Fixes: 6ffe5de35b05 ("iwlwifi: pcie: add AMSDU to gen2") Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c index 943891a9d3e7..ba9d37bed4c2 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c @@ -539,7 +539,12 @@ struct iwl_tfh_tfd *iwl_pcie_gen2_build_tfd(struct iwl_trans *trans, hdr_len = ieee80211_hdrlen(hdr->frame_control); - if (amsdu) + /* + * Only build A-MSDUs here if doing so by GSO, otherwise it may be + * an A-MSDU for other reasons, e.g. NAN or an A-MSDU having been + * built in the higher layers already. + */ + if (amsdu && skb_shinfo(skb)->gso_size) return iwl_pcie_gen2_build_tx_amsdu(trans, txq, dev_cmd, skb, out_meta, hdr_len, len); From 7d50d76e308dc8f9bf1d8006b25bf88f81ce69df Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 1 Jun 2018 10:04:44 +0200 Subject: [PATCH 241/276] iwlwifi: pcie: tx: unify TFD unmapping When anything fails, we unmap the whole TFD in three different places scattered throughout the code. Unify this to a single place. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/pcie/tx.c | 28 +++++--------------- 1 file changed, 7 insertions(+), 21 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c index 5091cd567b63..2742c41c88b3 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c @@ -1994,11 +1994,8 @@ static int iwl_fill_data_tbs(struct iwl_trans *trans, struct sk_buff *skb, dma_addr_t tb2_phys = dma_map_single(trans->dev, skb->data + hdr_len, tb2_len, DMA_TO_DEVICE); - if (unlikely(dma_mapping_error(trans->dev, tb2_phys))) { - iwl_pcie_tfd_unmap(trans, out_meta, txq, - txq->write_ptr); + if (unlikely(dma_mapping_error(trans->dev, tb2_phys))) return -EINVAL; - } iwl_pcie_txq_build_tfd(trans, txq, tb2_phys, tb2_len, false); } @@ -2014,11 +2011,8 @@ static int iwl_fill_data_tbs(struct iwl_trans *trans, struct sk_buff *skb, tb_phys = skb_frag_dma_map(trans->dev, frag, 0, skb_frag_size(frag), DMA_TO_DEVICE); - if (unlikely(dma_mapping_error(trans->dev, tb_phys))) { - iwl_pcie_tfd_unmap(trans, out_meta, txq, - txq->write_ptr); + if (unlikely(dma_mapping_error(trans->dev, tb_phys))) return -EINVAL; - } tb_idx = iwl_pcie_txq_build_tfd(trans, txq, tb_phys, skb_frag_size(frag), false); @@ -2091,7 +2085,6 @@ static int iwl_fill_data_tbs_amsdu(struct iwl_trans *trans, struct sk_buff *skb, u8 *start_hdr; struct iwl_tso_hdr_page *hdr_page; struct page **page_ptr; - int ret; struct tso_t tso; /* if the packet is protected, then it must be CCMP or GCMP */ @@ -2177,10 +2170,8 @@ static int iwl_fill_data_tbs_amsdu(struct iwl_trans *trans, struct sk_buff *skb, if (trans_pcie->sw_csum_tx) { csum_skb = alloc_skb(data_left + tcp_hdrlen(skb), GFP_ATOMIC); - if (!csum_skb) { - ret = -ENOMEM; - goto out_unmap; - } + if (!csum_skb) + return -ENOMEM; iwl_compute_pseudo_hdr_csum(iph, tcph, skb->protocol == @@ -2201,8 +2192,7 @@ static int iwl_fill_data_tbs_amsdu(struct iwl_trans *trans, struct sk_buff *skb, hdr_tb_len, DMA_TO_DEVICE); if (unlikely(dma_mapping_error(trans->dev, hdr_tb_phys))) { dev_kfree_skb(csum_skb); - ret = -EINVAL; - goto out_unmap; + return -EINVAL; } iwl_pcie_txq_build_tfd(trans, txq, hdr_tb_phys, hdr_tb_len, false); @@ -2227,8 +2217,7 @@ static int iwl_fill_data_tbs_amsdu(struct iwl_trans *trans, struct sk_buff *skb, size, DMA_TO_DEVICE); if (unlikely(dma_mapping_error(trans->dev, tb_phys))) { dev_kfree_skb(csum_skb); - ret = -EINVAL; - goto out_unmap; + return -EINVAL; } iwl_pcie_txq_build_tfd(trans, txq, tb_phys, @@ -2262,10 +2251,6 @@ static int iwl_fill_data_tbs_amsdu(struct iwl_trans *trans, struct sk_buff *skb, skb_push(skb, hdr_len + iv_len); return 0; - -out_unmap: - iwl_pcie_tfd_unmap(trans, out_meta, txq, txq->write_ptr); - return ret; } #else /* CONFIG_INET */ static int iwl_fill_data_tbs_amsdu(struct iwl_trans *trans, struct sk_buff *skb, @@ -2477,6 +2462,7 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, spin_unlock(&txq->lock); return 0; out_err: + iwl_pcie_tfd_unmap(trans, out_meta, txq, txq->write_ptr); spin_unlock(&txq->lock); return -1; } From bb03927e0eafef4d2509ff3df7550acf98efea97 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 1 Jun 2018 10:10:57 +0200 Subject: [PATCH 242/276] iwlwifi: pcie: tx: pull tracing out of iwl_fill_data_tbs() This will allow us to reuse the function later for adding fraglist SKBs to the TFD. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/pcie/tx.c | 41 ++++++++++---------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c index 2742c41c88b3..14b6e726da46 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c @@ -1977,26 +1977,24 @@ int iwl_trans_pcie_send_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) static int iwl_fill_data_tbs(struct iwl_trans *trans, struct sk_buff *skb, struct iwl_txq *txq, u8 hdr_len, - struct iwl_cmd_meta *out_meta, - struct iwl_device_cmd *dev_cmd, u16 tb1_len) + struct iwl_cmd_meta *out_meta) { - struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - u16 tb2_len; + u16 head_tb_len; int i; /* * Set up TFD's third entry to point directly to remainder * of skb's head, if any */ - tb2_len = skb_headlen(skb) - hdr_len; + head_tb_len = skb_headlen(skb) - hdr_len; - if (tb2_len > 0) { - dma_addr_t tb2_phys = dma_map_single(trans->dev, - skb->data + hdr_len, - tb2_len, DMA_TO_DEVICE); - if (unlikely(dma_mapping_error(trans->dev, tb2_phys))) + if (head_tb_len > 0) { + dma_addr_t tb_phys = dma_map_single(trans->dev, + skb->data + hdr_len, + head_tb_len, DMA_TO_DEVICE); + if (unlikely(dma_mapping_error(trans->dev, tb_phys))) return -EINVAL; - iwl_pcie_txq_build_tfd(trans, txq, tb2_phys, tb2_len, false); + iwl_pcie_txq_build_tfd(trans, txq, tb_phys, head_tb_len, false); } /* set up the remaining entries to point to the data */ @@ -2019,12 +2017,6 @@ static int iwl_fill_data_tbs(struct iwl_trans *trans, struct sk_buff *skb, out_meta->tbs |= BIT(tb_idx); } - trace_iwlwifi_dev_tx(trans->dev, skb, - iwl_pcie_get_tfd(trans, txq, txq->write_ptr), - trans_pcie->tfd_size, - &dev_cmd->hdr, IWL_FIRST_TB_SIZE + tb1_len, - hdr_len); - trace_iwlwifi_dev_tx_data(trans->dev, skb, hdr_len); return 0; } @@ -2415,9 +2407,18 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, out_meta, dev_cmd, tb1_len))) goto out_err; - } else if (unlikely(iwl_fill_data_tbs(trans, skb, txq, hdr_len, - out_meta, dev_cmd, tb1_len))) { - goto out_err; + } else { + if (unlikely(iwl_fill_data_tbs(trans, skb, txq, hdr_len, + out_meta))) + goto out_err; + + trace_iwlwifi_dev_tx(trans->dev, skb, + iwl_pcie_get_tfd(trans, txq, + txq->write_ptr), + trans_pcie->tfd_size, + &dev_cmd->hdr, IWL_FIRST_TB_SIZE + tb1_len, + hdr_len); + trace_iwlwifi_dev_tx_data(trans->dev, skb, hdr_len); } /* building the A-MSDU might have changed this data, so memcpy it now */ From 9a098a89df79e4cc5e743d7d4acf42bdbcc32ee7 Mon Sep 17 00:00:00 2001 From: Rajat Jain Date: Thu, 26 Apr 2018 17:43:50 -0700 Subject: [PATCH 243/276] iwlwifi: pcie: Fail fast if HW is inaccessible at probe If the HW is not responding at probe time, fail immediately complaining about it. Without this, we see that the kernel spends > 100ms trying to load firmware (even gives an incorrect impression that it actually loaded a firmware) and do unnecesary processing before concluding that the device is not accessible: INFO kernel: [ 34.092678] iwlwifi 0000:01:00.0: enabling device (0000 -> 0002) WARNING kernel: [ 34.093560] iwlwifi 0000:01:00.0: Direct firmware load for iwl-dbg-cfg.ini failed with error -2 INFO kernel: [ 34.111523] iwlwifi 0000:01:00.0: loaded firmware version 17.318154.0 op_mode iwlmvm INFO kernel: [ 34.173250] iwlwifi 0000:01:00.0: Detected Intel(R) Dual Band Wireless AC 7265, REV=0xFFFFFFFF ERR kernel: [ 34.198023] iwlwifi 0000:01:00.0: iwlwifi transaction failed, dumping registers ERR kernel: [ 34.198044] iwlwifi 0000:01:00.0: iwlwifi device config registers: Signed-off-by: Rajat Jain Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index ab0a5a663a6d..a5f51018029a 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -3318,6 +3318,12 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, iwl_disable_interrupts(trans); trans->hw_rev = iwl_read32(trans, CSR_HW_REV); + if (trans->hw_rev == 0xffffffff) { + dev_err(&pdev->dev, "HW_REV=0xFFFFFFFF, PCI issues?\n"); + ret = -EIO; + goto out_no_pci; + } + /* * In the 8000 HW family the format of the 4 bytes of CSR_HW_REV have * changed, and now the revision step also includes bit 0-1 (no more From 81f0c66187e1ebb7b63529d82faf7ff1e0ef428a Mon Sep 17 00:00:00 2001 From: Golan Ben Ami Date: Tue, 5 Jun 2018 11:58:13 +0300 Subject: [PATCH 244/276] iwlwifi: pcie: fit reclaim msg to MAX_MSG_LEN Today, the length of a debug message in iwl_trans_pcie_reclaim may pass the MAX_MSG_LEN, which is 110. An example for this kind of message is: 'iwl_trans_pcie_reclaim: Read index for DMA queue txq id (2), last_to_free 65535 is out of range [0-65536] 2 2.' Cut the message a bit so it will fit the allowed MAX_MSG_LEN. Signed-off-by: Golan Ben Ami Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/pcie/tx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c index 14b6e726da46..6b6b86458819 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c @@ -1097,7 +1097,7 @@ void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn, if (!iwl_queue_used(txq, last_to_free)) { IWL_ERR(trans, - "%s: Read index for DMA queue txq id (%d), last_to_free %d is out of range [0-%d] %d %d.\n", + "%s: Read index for txq id (%d), last_to_free %d is out of range [0-%d] %d %d.\n", __func__, txq_id, last_to_free, trans->cfg->base_params->max_tfd_queue_size, txq->write_ptr, txq->read_ptr); From 034925cb5d7bed359c42b3519c1d3fab0a26d27b Mon Sep 17 00:00:00 2001 From: Shaul Triebitz Date: Thu, 10 May 2018 17:34:52 +0300 Subject: [PATCH 245/276] iwlwifi: mvm: do not override amsdu size user settings Since AMSDUs are not de-aggregated by HW in monitor mode, we still need the option for setting large RBs (up to 12K). Signed-off-by: Shaul Triebitz Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index e2463e8e486b..d728b854be95 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -584,6 +584,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, }; int err, scan_size; u32 min_backoff; + enum iwl_amsdu_size rb_size_default; /* * We use IWL_MVM_STATION_COUNT to check the validity of the station @@ -694,8 +695,16 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, trans_cfg.op_mode = op_mode; trans_cfg.no_reclaim_cmds = no_reclaim_cmds; trans_cfg.n_no_reclaim_cmds = ARRAY_SIZE(no_reclaim_cmds); + + if (mvm->trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) + rb_size_default = IWL_AMSDU_2K; + else + rb_size_default = IWL_AMSDU_4K; + switch (iwlwifi_mod_params.amsdu_size) { case IWL_AMSDU_DEF: + trans_cfg.rx_buf_size = rb_size_default; + break; case IWL_AMSDU_4K: trans_cfg.rx_buf_size = IWL_AMSDU_4K; break; @@ -708,17 +717,12 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, default: pr_err("%s: Unsupported amsdu_size: %d\n", KBUILD_MODNAME, iwlwifi_mod_params.amsdu_size); - trans_cfg.rx_buf_size = IWL_AMSDU_4K; + trans_cfg.rx_buf_size = rb_size_default; } - /* the hardware splits the A-MSDU */ - if (mvm->trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) { - trans_cfg.rx_buf_size = IWL_AMSDU_2K; - /* TODO: remove when balanced power mode is fw supported */ + /* TODO: remove when balanced power mode is fw supported */ + if (mvm->trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) iwlmvm_mod_params.power_scheme = IWL_POWER_SCHEME_CAM; - } else if (mvm->cfg->mq_rx_supported) { - trans_cfg.rx_buf_size = IWL_AMSDU_4K; - } trans->wide_cmd_header = true; trans_cfg.bc_table_dword = From 753e9761284b9b09120c21b155c7220605763522 Mon Sep 17 00:00:00 2001 From: Shaul Triebitz Date: Thu, 10 May 2018 17:40:44 +0300 Subject: [PATCH 246/276] iwlwifi: pcie: set RB size according to user settings RB size can be configured by user to be greater than 4K. That's needed for monitor to capture big AMSDUs. The firmware now enables different RB sizes configuration via context info. Signed-off-by: Shaul Triebitz Signed-off-by: Luca Coelho --- .../wireless/intel/iwlwifi/iwl-context-info.h | 25 +++++++++++++++-- .../wireless/intel/iwlwifi/pcie/ctxt-info.c | 28 +++++++++++++++---- 2 files changed, 46 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-context-info.h b/drivers/net/wireless/intel/iwlwifi/iwl-context-info.h index 4b6fdf3b15fb..5ed07e37e3ee 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-context-info.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-context-info.h @@ -64,20 +64,41 @@ * the init done for driver command that configures several system modes * @IWL_CTXT_INFO_EARLY_DEBUG: enable early debug * @IWL_CTXT_INFO_ENABLE_CDMP: enable core dump - * @IWL_CTXT_INFO_RB_SIZE_4K: Use 4K RB size (the default is 2K) * @IWL_CTXT_INFO_RB_CB_SIZE_POS: position of the RBD Cyclic Buffer Size * exponent, the actual size is 2**value, valid sizes are 8-2048. * The value is four bits long. Maximum valid exponent is 12 * @IWL_CTXT_INFO_TFD_FORMAT_LONG: use long TFD Format (the * default is short format - not supported by the driver) + * @IWL_CTXT_INFO_RB_SIZE_POS: RB size position + * (values are IWL_CTXT_INFO_RB_SIZE_*K) + * @IWL_CTXT_INFO_RB_SIZE_1K: Value for 1K RB size + * @IWL_CTXT_INFO_RB_SIZE_2K: Value for 2K RB size + * @IWL_CTXT_INFO_RB_SIZE_4K: Value for 4K RB size + * @IWL_CTXT_INFO_RB_SIZE_8K: Value for 8K RB size + * @IWL_CTXT_INFO_RB_SIZE_12K: Value for 12K RB size + * @IWL_CTXT_INFO_RB_SIZE_16K: Value for 16K RB size + * @IWL_CTXT_INFO_RB_SIZE_20K: Value for 20K RB size + * @IWL_CTXT_INFO_RB_SIZE_24K: Value for 24K RB size + * @IWL_CTXT_INFO_RB_SIZE_28K: Value for 28K RB size + * @IWL_CTXT_INFO_RB_SIZE_32K: Value for 32K RB size */ enum iwl_context_info_flags { IWL_CTXT_INFO_AUTO_FUNC_INIT = BIT(0), IWL_CTXT_INFO_EARLY_DEBUG = BIT(1), IWL_CTXT_INFO_ENABLE_CDMP = BIT(2), - IWL_CTXT_INFO_RB_SIZE_4K = BIT(3), IWL_CTXT_INFO_RB_CB_SIZE_POS = 4, IWL_CTXT_INFO_TFD_FORMAT_LONG = BIT(8), + IWL_CTXT_INFO_RB_SIZE_POS = 9, + IWL_CTXT_INFO_RB_SIZE_1K = 0x1, + IWL_CTXT_INFO_RB_SIZE_2K = 0x2, + IWL_CTXT_INFO_RB_SIZE_4K = 0x4, + IWL_CTXT_INFO_RB_SIZE_8K = 0x8, + IWL_CTXT_INFO_RB_SIZE_12K = 0x9, + IWL_CTXT_INFO_RB_SIZE_16K = 0xa, + IWL_CTXT_INFO_RB_SIZE_20K = 0xb, + IWL_CTXT_INFO_RB_SIZE_24K = 0xc, + IWL_CTXT_INFO_RB_SIZE_28K = 0xd, + IWL_CTXT_INFO_RB_SIZE_32K = 0xe, }; /* diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info.c b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info.c index b2cd7ef5fc3a..6f45a0303ddd 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info.c @@ -162,7 +162,7 @@ int iwl_pcie_ctxt_info_init(struct iwl_trans *trans, struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_context_info *ctxt_info; struct iwl_context_info_rbd_cfg *rx_cfg; - u32 control_flags = 0; + u32 control_flags = 0, rb_size; int ret; ctxt_info = dma_alloc_coherent(trans->dev, sizeof(*ctxt_info), @@ -177,11 +177,29 @@ int iwl_pcie_ctxt_info_init(struct iwl_trans *trans, /* size is in DWs */ ctxt_info->version.size = cpu_to_le16(sizeof(*ctxt_info) / 4); + switch (trans_pcie->rx_buf_size) { + case IWL_AMSDU_2K: + rb_size = IWL_CTXT_INFO_RB_SIZE_2K; + break; + case IWL_AMSDU_4K: + rb_size = IWL_CTXT_INFO_RB_SIZE_4K; + break; + case IWL_AMSDU_8K: + rb_size = IWL_CTXT_INFO_RB_SIZE_8K; + break; + case IWL_AMSDU_12K: + rb_size = IWL_CTXT_INFO_RB_SIZE_12K; + break; + default: + WARN_ON(1); + rb_size = IWL_CTXT_INFO_RB_SIZE_4K; + } + BUILD_BUG_ON(RX_QUEUE_CB_SIZE(MQ_RX_TABLE_SIZE) > 0xF); - control_flags = IWL_CTXT_INFO_RB_SIZE_4K | - IWL_CTXT_INFO_TFD_FORMAT_LONG | - RX_QUEUE_CB_SIZE(MQ_RX_TABLE_SIZE) << - IWL_CTXT_INFO_RB_CB_SIZE_POS; + control_flags = IWL_CTXT_INFO_TFD_FORMAT_LONG | + (RX_QUEUE_CB_SIZE(MQ_RX_TABLE_SIZE) << + IWL_CTXT_INFO_RB_CB_SIZE_POS) | + (rb_size << IWL_CTXT_INFO_RB_SIZE_POS); ctxt_info->control.control_flags = cpu_to_le32(control_flags); /* initialize RX default queue */ From 7126b6f2bbdf8e25f85e7ca6d91d49ea4ce9f6a6 Mon Sep 17 00:00:00 2001 From: Sara Sharon Date: Sun, 3 Jun 2018 09:19:35 +0300 Subject: [PATCH 247/276] iwlwifi: mvm: use correct FIFO length Current FIFO size calculation is wrong for two reasons: - We access lmac 0 by default - We don't take 11ax into consideration. Fix both. Signed-off-by: Sara Sharon Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/mvm/mac-ctxt.c | 4 ++ drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 47 +++++++++++++------ 2 files changed, 36 insertions(+), 15 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c index 56871aff1698..781f30356720 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c @@ -82,6 +82,10 @@ const u8 iwl_mvm_ac_to_gen2_tx_fifo[] = { IWL_GEN2_EDCA_TX_FIFO_VI, IWL_GEN2_EDCA_TX_FIFO_BE, IWL_GEN2_EDCA_TX_FIFO_BK, + IWL_GEN2_TRIG_TX_FIFO_VO, + IWL_GEN2_TRIG_TX_FIFO_VI, + IWL_GEN2_TRIG_TX_FIFO_BE, + IWL_GEN2_TRIG_TX_FIFO_BK, }; struct iwl_mvm_mac_iface_iterator_data { diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c index ffc0ad1eef15..a6877b3f8037 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c @@ -840,6 +840,36 @@ iwl_mvm_tx_tso_segment(struct sk_buff *skb, unsigned int num_subframes, return 0; } +static unsigned int iwl_mvm_max_amsdu_size(struct iwl_mvm *mvm, + struct ieee80211_sta *sta, + unsigned int tid) +{ + struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); + enum nl80211_band band = mvmsta->vif->bss_conf.chandef.chan->band; + u8 ac = tid_to_mac80211_ac[tid]; + unsigned int txf; + int lmac = IWL_LMAC_24G_INDEX; + + if (iwl_mvm_is_cdb_supported(mvm) && + band == NL80211_BAND_5GHZ) + lmac = IWL_LMAC_5G_INDEX; + + /* For HE redirect to trigger based fifos */ + if (sta->he_cap.has_he && !WARN_ON(!iwl_mvm_has_new_tx_api(mvm))) + ac += 4; + + txf = iwl_mvm_mac_ac_to_tx_fifo(mvm, ac); + + /* + * Don't send an AMSDU that will be longer than the TXF. + * Add a security margin of 256 for the TX command + headers. + * We also want to have the start of the next packet inside the + * fifo to be able to send bursts. + */ + return min_t(unsigned int, mvmsta->max_amsdu_len, + mvm->fwrt.smem_cfg.lmac[lmac].txfifo_size[txf] - 256); +} + static int iwl_mvm_tx_tso(struct iwl_mvm *mvm, struct sk_buff *skb, struct ieee80211_tx_info *info, struct ieee80211_sta *sta, @@ -852,7 +882,7 @@ static int iwl_mvm_tx_tso(struct iwl_mvm *mvm, struct sk_buff *skb, u16 snap_ip_tcp, pad; unsigned int dbg_max_amsdu_len; netdev_features_t netdev_flags = NETIF_F_CSUM_MASK | NETIF_F_SG; - u8 tid, txf; + u8 tid; snap_ip_tcp = 8 + skb_transport_header(skb) - skb_network_header(skb) + tcp_hdrlen(skb); @@ -891,20 +921,7 @@ static int iwl_mvm_tx_tso(struct iwl_mvm *mvm, struct sk_buff *skb, !(mvmsta->amsdu_enabled & BIT(tid))) return iwl_mvm_tx_tso_segment(skb, 1, netdev_flags, mpdus_skb); - max_amsdu_len = mvmsta->max_amsdu_len; - - /* the Tx FIFO to which this A-MSDU will be routed */ - txf = iwl_mvm_mac_ac_to_tx_fifo(mvm, tid_to_mac80211_ac[tid]); - - /* - * Don't send an AMSDU that will be longer than the TXF. - * Add a security margin of 256 for the TX command + headers. - * We also want to have the start of the next packet inside the - * fifo to be able to send bursts. - */ - max_amsdu_len = min_t(unsigned int, max_amsdu_len, - mvm->fwrt.smem_cfg.lmac[0].txfifo_size[txf] - - 256); + max_amsdu_len = iwl_mvm_max_amsdu_size(mvm, sta, tid); if (unlikely(dbg_max_amsdu_len)) max_amsdu_len = min_t(unsigned int, max_amsdu_len, From 337bfc9881a277a973aa6a58418d281557ab6cdd Mon Sep 17 00:00:00 2001 From: Avraham Stern Date: Mon, 4 Jun 2018 15:10:18 +0300 Subject: [PATCH 248/276] iwlwifi: mvm: set wep key for all stations in soft ap mode When operating as a soft ap with wep security, the key was not configured to the fw for the stations, based on the fact that the key will be specified in the tx command. However, in the new tx api the tx command does not include the key, which resulted in all data frames going out un-encrypted. Fix it by configuring the key for all the stations as they are added. Signed-off-by: Avraham Stern Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/mvm/mac80211.c | 29 ++++++++++++++----- drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 1 + drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 21 ++++++++++++++ 3 files changed, 43 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index b55a2e4a0024..c445e93951bf 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -2476,6 +2476,9 @@ static void iwl_mvm_stop_ap_ibss(struct ieee80211_hw *hw, iwl_mvm_mac_ctxt_remove(mvm, vif); + kfree(mvmvif->ap_wep_key); + mvmvif->ap_wep_key = NULL; + mutex_unlock(&mvm->mutex); } @@ -2968,7 +2971,13 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw, iwl_mvm_rs_rate_init(mvm, sta, mvmvif->phy_ctxt->channel->band, true); - ret = 0; + /* if wep is used, need to set the key for the station now */ + if (vif->type == NL80211_IFTYPE_AP && mvmvif->ap_wep_key) + ret = iwl_mvm_set_sta_key(mvm, vif, sta, + mvmvif->ap_wep_key, + STA_KEY_IDX_INVALID); + else + ret = 0; } else if (old_state == IEEE80211_STA_AUTHORIZED && new_state == IEEE80211_STA_ASSOC) { /* disable beacon filtering */ @@ -3174,13 +3183,17 @@ static int iwl_mvm_mac_set_key(struct ieee80211_hw *hw, break; case WLAN_CIPHER_SUITE_WEP40: case WLAN_CIPHER_SUITE_WEP104: - /* For non-client mode, only use WEP keys for TX as we probably - * don't have a station yet anyway and would then have to keep - * track of the keys, linking them to each of the clients/peers - * as they appear. For now, don't do that, for performance WEP - * offload doesn't really matter much, but we need it for some - * other offload features in client mode. - */ + if (vif->type == NL80211_IFTYPE_AP) { + struct iwl_mvm_vif *mvmvif = + iwl_mvm_vif_from_mac80211(vif); + + mvmvif->ap_wep_key = kmemdup(key, + sizeof(*key) + key->keylen, + GFP_KERNEL); + if (!mvmvif->ap_wep_key) + return -ENOMEM; + } + if (vif->type != NL80211_IFTYPE_STATION) return 0; break; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index 087e8a454ac2..33f8697740a5 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -471,6 +471,7 @@ struct iwl_mvm_vif { netdev_features_t features; struct iwl_probe_resp_data __rcu *probe_resp_data; + struct ieee80211_key_conf *ap_wep_key; }; static inline struct iwl_mvm_vif * diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c index 6ebc715d90df..550e24da0f5b 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c @@ -67,6 +67,14 @@ #include "sta.h" #include "rs.h" +static int iwl_mvm_set_fw_key_idx(struct iwl_mvm *mvm); + +static int iwl_mvm_send_sta_key(struct iwl_mvm *mvm, + u32 sta_id, + struct ieee80211_key_conf *key, bool mcast, + u32 tkip_iv32, u16 *tkip_p1k, u32 cmd_flags, + u8 key_offset, bool mfp); + /* * New version of ADD_STA_sta command added new fields at the end of the * structure, so sending the size of the relevant API's structure is enough to @@ -2096,6 +2104,19 @@ int iwl_mvm_add_mcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif) iwl_mvm_enable_txq(mvm, vif->cab_queue, vif->cab_queue, 0, &cfg, timeout); + if (mvmvif->ap_wep_key) { + u8 key_offset = iwl_mvm_set_fw_key_idx(mvm); + + if (key_offset == STA_KEY_IDX_INVALID) + return -ENOSPC; + + ret = iwl_mvm_send_sta_key(mvm, mvmvif->mcast_sta.sta_id, + mvmvif->ap_wep_key, 1, 0, NULL, 0, + key_offset, 0); + if (ret) + return ret; + } + return 0; } From d5367de2d803658702dab1fc70e3428b26651189 Mon Sep 17 00:00:00 2001 From: Erel Geron Date: Mon, 28 May 2018 17:18:47 +0300 Subject: [PATCH 249/276] iwlwifi: mvm: TLC support for Coex Schema 2 The new coex schema requires setting the non-shared antenna for the single_stream_ant_msk field in the TLC command. Signed-off-by: Erel Geron Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/coex.c | 9 +++++++++ drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 1 + drivers/net/wireless/intel/iwlwifi/mvm/rs.c | 5 +++-- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/coex.c b/drivers/net/wireless/intel/iwlwifi/mvm/coex.c index ec3b60cdcf18..730e37744dc0 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/coex.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/coex.c @@ -691,6 +691,15 @@ bool iwl_mvm_bt_coex_is_tpc_allowed(struct iwl_mvm *mvm, return bt_activity >= BT_LOW_TRAFFIC; } +u8 iwl_mvm_bt_coex_get_single_ant_msk(struct iwl_mvm *mvm, u8 enabled_ants) +{ + if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_COEX_SCHEMA_2) && + (mvm->cfg->non_shared_ant & enabled_ants)) + return mvm->cfg->non_shared_ant; + + return first_antenna(enabled_ants); +} + u8 iwl_mvm_bt_coex_tx_prio(struct iwl_mvm *mvm, struct ieee80211_hdr *hdr, struct ieee80211_tx_info *info, u8 ac) { diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index 33f8697740a5..8f71eeed50d9 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -1819,6 +1819,7 @@ bool iwl_mvm_bt_coex_is_ant_avail(struct iwl_mvm *mvm, u8 ant); bool iwl_mvm_bt_coex_is_shared_ant_avail(struct iwl_mvm *mvm); bool iwl_mvm_bt_coex_is_tpc_allowed(struct iwl_mvm *mvm, enum nl80211_band band); +u8 iwl_mvm_bt_coex_get_single_ant_msk(struct iwl_mvm *mvm, u8 enabled_ants); u8 iwl_mvm_bt_coex_tx_prio(struct iwl_mvm *mvm, struct ieee80211_hdr *hdr, struct ieee80211_tx_info *info, u8 ac); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c index c3282f1d77ba..2c75f51a04e4 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c @@ -3213,7 +3213,7 @@ static void rs_drv_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, /* These values will be overridden later */ lq_sta->lq.single_stream_ant_msk = - first_antenna(iwl_mvm_get_valid_tx_ant(mvm)); + iwl_mvm_bt_coex_get_single_ant_msk(mvm, iwl_mvm_get_valid_tx_ant(mvm)); lq_sta->lq.dual_stream_ant_msk = ANT_AB; /* as default allow aggregation for all tids */ @@ -3576,7 +3576,8 @@ static void rs_fill_lq_cmd(struct iwl_mvm *mvm, mvmsta = iwl_mvm_sta_from_mac80211(sta); mvmvif = iwl_mvm_vif_from_mac80211(mvmsta->vif); - if (num_of_ant(initial_rate->ant) == 1) + if (!fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_COEX_SCHEMA_2) && + num_of_ant(initial_rate->ant) == 1) lq_cmd->single_stream_ant_msk = initial_rate->ant; lq_cmd->agg_frame_cnt_limit = mvmsta->max_agg_bufsize; From 5724d8b9e9723ba2816ab403939e64c792fd25cf Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 5 Jun 2018 14:47:02 +0300 Subject: [PATCH 250/276] iwlwifi: mvm: remove support for adjacent channel compensation We no longer want to consider the RSSI if the beacon / probe has been heard on an adjacent channel. This was based on a firmware capability that is now unavailable. Signed-off-by: Emmanuel Grumbach Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index c445e93951bf..4a54756bd1d8 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -554,8 +554,6 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) hw->wiphy->max_remain_on_channel_duration = 10000; hw->max_listen_interval = IWL_CONN_MAX_LISTEN_INTERVAL; - /* we can compensate an offset of up to 3 channels = 15 MHz */ - hw->wiphy->max_adj_channel_rssi_comp = 3 * 5; /* Extract MAC address */ memcpy(mvm->addresses[0].addr, mvm->nvm_data->hw_addr, ETH_ALEN); From 0044f1716c4d943674684fd738c8f7aa9d05d248 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 1 Jun 2018 10:32:55 +0200 Subject: [PATCH 251/276] iwlwifi: pcie: support transmitting SKBs with fraglist We want to be able to build A-MSDUs in higher layers, e.g. by xmit_more, so support transmitting SKBs with fraglist to use it for such. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/pcie/tx.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c index 6b6b86458819..67820bfaba64 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c @@ -2408,10 +2408,18 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, tb1_len))) goto out_err; } else { + struct sk_buff *frag; + if (unlikely(iwl_fill_data_tbs(trans, skb, txq, hdr_len, out_meta))) goto out_err; + skb_walk_frags(skb, frag) { + if (unlikely(iwl_fill_data_tbs(trans, frag, txq, 0, + out_meta))) + goto out_err; + } + trace_iwlwifi_dev_tx(trans->dev, skb, iwl_pcie_get_tfd(trans, txq, txq->write_ptr), From 88964b2ea09905c0268a5c74de902b8a5668b3e4 Mon Sep 17 00:00:00 2001 From: Sara Sharon Date: Wed, 23 May 2018 15:10:24 +0300 Subject: [PATCH 252/276] iwlwifi: pcie: add infrastructure for multiple debug buffers In future devices we will have more than one debug buffer. Prepare the infrastructure for allocation and release of multiple debug buffers by grouping the variables in an array of structures and moving it to trans section, where they will be visible to opmode and FW. Signed-off-by: Sara Sharon Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/iwl-trans.h | 17 +++ .../intel/iwlwifi/pcie/ctxt-info-gen3.c | 4 +- .../wireless/intel/iwlwifi/pcie/internal.h | 19 --- .../net/wireless/intel/iwlwifi/pcie/trans.c | 116 +++++++++--------- 4 files changed, 79 insertions(+), 77 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h index 388793b89856..6c636b2a6b43 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h @@ -679,6 +679,19 @@ enum iwl_plat_pm_mode { * enter/exit (in msecs). */ #define IWL_TRANS_IDLE_TIMEOUT 2000 +#define IWL_MAX_DEBUG_ALLOCATIONS 1 + +/** + * struct iwl_dram_data + * @physical: page phy pointer + * @block: pointer to the allocated block/page + * @size: size of the block/page + */ +struct iwl_dram_data { + dma_addr_t physical; + void *block; + int size; +}; /** * struct iwl_trans - transport common data @@ -713,6 +726,8 @@ enum iwl_plat_pm_mode { * @dbg_conf_tlv: array of pointers to configuration TLVs for debug * @dbg_trigger_tlv: array of pointers to triggers TLVs for debug * @dbg_dest_reg_num: num of reg_ops in %dbg_dest_tlv + * @num_blocks: number of blocks in fw_mon + * @fw_mon: address of the buffers for firmware monitor * @system_pm_mode: the system-wide power management mode in use. * This mode is set dynamically, depending on the WoWLAN values * configured from the userspace at runtime. @@ -764,6 +779,8 @@ struct iwl_trans { struct iwl_fw_dbg_trigger_tlv * const *dbg_trigger_tlv; u32 dbg_dump_mask; u8 dbg_dest_reg_num; + int num_blocks; + struct iwl_dram_data fw_mon[IWL_MAX_DEBUG_ALLOCATIONS]; enum iwl_plat_pm_mode system_pm_mode; enum iwl_plat_pm_mode runtime_pm_mode; diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c index 2146fda8da2f..05ed4fb88e0c 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c @@ -96,9 +96,9 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans, /* Configure debug, for integration */ iwl_pcie_alloc_fw_monitor(trans, 0); prph_sc_ctrl->hwm_cfg.hwm_base_addr = - cpu_to_le64(trans_pcie->fw_mon_phys); + cpu_to_le64(trans->fw_mon[0].physical); prph_sc_ctrl->hwm_cfg.hwm_size = - cpu_to_le32(trans_pcie->fw_mon_size); + cpu_to_le32(trans->fw_mon[0].size); /* allocate ucode sections in dram and set addresses */ ret = iwl_pcie_init_fw_sec(trans, fw, &prph_scratch->dram); diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h index 769b7354fabe..f9c4c64dee66 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h +++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h @@ -400,18 +400,6 @@ enum iwl_image_response_code { IWL_IMAGE_RESP_FAIL = 2, }; -/** - * struct iwl_dram_data - * @physical: page phy pointer - * @block: pointer to the allocated block/page - * @size: size of the block/page - */ -struct iwl_dram_data { - dma_addr_t physical; - void *block; - int size; -}; - /** * struct iwl_self_init_dram - dram data used by self init process * @fw: lmac and umac dram data @@ -463,9 +451,6 @@ struct iwl_self_init_dram { * @reg_lock: protect hw register access * @mutex: to protect stop_device / start_fw / start_hw * @cmd_in_flight: true when we have a host command in flight - * @fw_mon_phys: physical address of the buffer for the firmware monitor - * @fw_mon_cpu_addr: address of the buffer for the firmware monitor - * @fw_mon_size: size of the buffer for the firmware monitor * @msix_entries: array of MSI-X entries * @msix_enabled: true if managed to enable MSI-X * @shared_vec_mask: the type of causes the shared vector handles @@ -553,10 +538,6 @@ struct iwl_trans_pcie { bool cmd_hold_nic_awake; bool ref_cmd_in_flight; - dma_addr_t fw_mon_phys; - void *fw_mon_cpu_addr; - u32 fw_mon_size; - struct msix_entry msix_entries[IWL_MAX_RX_HW_QUEUES]; bool msix_enabled; u8 shared_vec_mask; diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index a5f51018029a..bc6682a11fa4 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -185,44 +185,28 @@ static void iwl_trans_pcie_sw_reset(struct iwl_trans *trans) static void iwl_pcie_free_fw_monitor(struct iwl_trans *trans) { - struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + int i; - if (!trans_pcie->fw_mon_cpu_addr) - return; - - dma_free_coherent(trans->dev, trans_pcie->fw_mon_size, - trans_pcie->fw_mon_cpu_addr, - trans_pcie->fw_mon_phys); - trans_pcie->fw_mon_cpu_addr = NULL; - trans_pcie->fw_mon_phys = 0; - trans_pcie->fw_mon_size = 0; + for (i = 0; i < trans->num_blocks; i++) { + dma_free_coherent(trans->dev, trans->fw_mon[i].size, + trans->fw_mon[i].block, + trans->fw_mon[i].physical); + trans->fw_mon[i].block = NULL; + trans->fw_mon[i].physical = 0; + trans->fw_mon[i].size = 0; + trans->num_blocks--; + } } -void iwl_pcie_alloc_fw_monitor(struct iwl_trans *trans, u8 max_power) +static void iwl_pcie_alloc_fw_monitor_block(struct iwl_trans *trans, + u8 max_power, u8 min_power) { - struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); void *cpu_addr = NULL; - dma_addr_t phys; + dma_addr_t phys = 0; u32 size = 0; u8 power; - if (!max_power) { - /* default max_power is maximum */ - max_power = 26; - } else { - max_power += 11; - } - - if (WARN(max_power > 26, - "External buffer size for monitor is too big %d, check the FW TLV\n", - max_power)) - return; - - if (trans_pcie->fw_mon_cpu_addr) - return; - - phys = 0; - for (power = max_power; power >= 11; power--) { + for (power = max_power; power >= min_power; power--) { size = BIT(power); cpu_addr = dma_alloc_coherent(trans->dev, size, &phys, GFP_KERNEL | __GFP_NOWARN | @@ -245,9 +229,34 @@ void iwl_pcie_alloc_fw_monitor(struct iwl_trans *trans, u8 max_power) (unsigned long)BIT(power - 10), (unsigned long)BIT(max_power - 10)); - trans_pcie->fw_mon_cpu_addr = cpu_addr; - trans_pcie->fw_mon_phys = phys; - trans_pcie->fw_mon_size = size; + trans->fw_mon[trans->num_blocks].block = cpu_addr; + trans->fw_mon[trans->num_blocks].physical = phys; + trans->fw_mon[trans->num_blocks].size = size; + trans->num_blocks++; +} + +void iwl_pcie_alloc_fw_monitor(struct iwl_trans *trans, u8 max_power) +{ + if (!max_power) { + /* default max_power is maximum */ + max_power = 26; + } else { + max_power += 11; + } + + if (WARN(max_power > 26, + "External buffer size for monitor is too big %d, check the FW TLV\n", + max_power)) + return; + + /* + * This function allocats the default fw monitor. + * The optional additional ones will be allocated in runtime + */ + if (trans->num_blocks) + return; + + iwl_pcie_alloc_fw_monitor_block(trans, max_power, 11); } static u32 iwl_trans_pcie_read_shr(struct iwl_trans *trans, u32 reg) @@ -911,7 +920,6 @@ static int iwl_pcie_load_cpu_sections(struct iwl_trans *trans, void iwl_pcie_apply_destination(struct iwl_trans *trans) { - struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); const struct iwl_fw_dbg_dest_tlv_v1 *dest = trans->dbg_dest_tlv; int i; @@ -962,18 +970,18 @@ void iwl_pcie_apply_destination(struct iwl_trans *trans) } monitor: - if (dest->monitor_mode == EXTERNAL_MODE && trans_pcie->fw_mon_size) { + if (dest->monitor_mode == EXTERNAL_MODE && trans->fw_mon[0].size) { iwl_write_prph(trans, le32_to_cpu(dest->base_reg), - trans_pcie->fw_mon_phys >> dest->base_shift); + trans->fw_mon[0].physical >> dest->base_shift); if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_8000) iwl_write_prph(trans, le32_to_cpu(dest->end_reg), - (trans_pcie->fw_mon_phys + - trans_pcie->fw_mon_size - 256) >> + (trans->fw_mon[0].physical + + trans->fw_mon[0].size - 256) >> dest->end_shift); else iwl_write_prph(trans, le32_to_cpu(dest->end_reg), - (trans_pcie->fw_mon_phys + - trans_pcie->fw_mon_size) >> + (trans->fw_mon[0].physical + + trans->fw_mon[0].size) >> dest->end_shift); } } @@ -981,7 +989,6 @@ void iwl_pcie_apply_destination(struct iwl_trans *trans) static int iwl_pcie_load_given_ucode(struct iwl_trans *trans, const struct fw_img *image) { - struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); int ret = 0; int first_ucode_section; @@ -1011,12 +1018,12 @@ static int iwl_pcie_load_given_ucode(struct iwl_trans *trans, trans->cfg->device_family == IWL_DEVICE_FAMILY_7000) { iwl_pcie_alloc_fw_monitor(trans, 0); - if (trans_pcie->fw_mon_size) { + if (trans->fw_mon[0].size) { iwl_write_prph(trans, MON_BUFF_BASE_ADDR, - trans_pcie->fw_mon_phys >> 4); + trans->fw_mon[0].physical >> 4); iwl_write_prph(trans, MON_BUFF_END_ADDR, - (trans_pcie->fw_mon_phys + - trans_pcie->fw_mon_size) >> 4); + (trans->fw_mon[0].physical + + trans->fw_mon[0].size) >> 4); } } else if (trans->dbg_dest_tlv) { iwl_pcie_apply_destination(trans); @@ -2852,10 +2859,9 @@ iwl_trans_pcie_dump_monitor(struct iwl_trans *trans, struct iwl_fw_error_dump_data **data, u32 monitor_len) { - struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); u32 len = 0; - if ((trans_pcie->fw_mon_cpu_addr && + if ((trans->num_blocks && trans->cfg->device_family == IWL_DEVICE_FAMILY_7000) || trans->dbg_dest_tlv) { struct iwl_fw_error_dump_fw_mon *fw_mon_data; @@ -2883,12 +2889,12 @@ iwl_trans_pcie_dump_monitor(struct iwl_trans *trans, cpu_to_le32(iwl_read_prph(trans, base)); len += sizeof(**data) + sizeof(*fw_mon_data); - if (trans_pcie->fw_mon_cpu_addr) { + if (trans->num_blocks) { memcpy(fw_mon_data->data, - trans_pcie->fw_mon_cpu_addr, - trans_pcie->fw_mon_size); + trans->fw_mon[0].block, + trans->fw_mon[0].size); - monitor_len = trans_pcie->fw_mon_size; + monitor_len = trans->fw_mon[0].size; } else if (trans->dbg_dest_tlv->monitor_mode == SMEM_MODE) { /* * Update pointers to reflect actual values after @@ -2926,13 +2932,11 @@ iwl_trans_pcie_dump_monitor(struct iwl_trans *trans, static int iwl_trans_get_fw_monitor_len(struct iwl_trans *trans, int *len) { - struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - - if (trans_pcie->fw_mon_cpu_addr) { + if (trans->num_blocks) { *len += sizeof(struct iwl_fw_error_dump_data) + sizeof(struct iwl_fw_error_dump_fw_mon) + - trans_pcie->fw_mon_size; - return trans_pcie->fw_mon_size; + trans->fw_mon[0].size; + return trans->fw_mon[0].size; } else if (trans->dbg_dest_tlv) { u32 base, end, cfg_reg, monitor_len; From 6a529317ff31e27885e41443e5658ef3654ce0bc Mon Sep 17 00:00:00 2001 From: Golan Ben Ami Date: Sun, 10 Jun 2018 14:12:26 +0300 Subject: [PATCH 253/276] iwlwifi: configure power scheme to balanced for 22560 devices As a temporary stage in the 22560 devices bring up, we disabled power save, to avoid bugs related to that domain. Now we would like to use power save so enable the balanced mode, and allow configuring the mode via module parameter. Signed-off-by: Golan Ben Ami Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index d728b854be95..0599d323cbeb 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -720,10 +720,6 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, trans_cfg.rx_buf_size = rb_size_default; } - /* TODO: remove when balanced power mode is fw supported */ - if (mvm->trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) - iwlmvm_mod_params.power_scheme = IWL_POWER_SCHEME_CAM; - trans->wide_cmd_header = true; trans_cfg.bc_table_dword = mvm->trans->cfg->device_family < IWL_DEVICE_FAMILY_22560; From 4ef66965ce2f4d1c94b62025d35b2bd69d3f3889 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 7 Jun 2018 10:49:55 +0200 Subject: [PATCH 254/276] iwlwifi: fix LED command capability bit The capability bit was added to the driver and had been negotiated with the firmware, but then got forgotten in the firmware and later reused for a different capability. Now the firmware added it in a new bit. Fixes: 2eabc84d2f8e ("iwlwifi: mvm: only send LEDS_CMD when the FW supports it") Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/file.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/file.h b/drivers/net/wireless/intel/iwlwifi/fw/file.h index 335b8bde3dcd..63e277b07b8a 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/file.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/file.h @@ -400,8 +400,8 @@ enum iwl_ucode_tlv_capa { IWL_UCODE_TLV_CAPA_EXTEND_SHARED_MEM_CFG = (__force iwl_ucode_tlv_capa_t)80, IWL_UCODE_TLV_CAPA_LQM_SUPPORT = (__force iwl_ucode_tlv_capa_t)81, IWL_UCODE_TLV_CAPA_TX_POWER_ACK = (__force iwl_ucode_tlv_capa_t)84, - IWL_UCODE_TLV_CAPA_LED_CMD_SUPPORT = (__force iwl_ucode_tlv_capa_t)86, IWL_UCODE_TLV_CAPA_D3_DEBUG = (__force iwl_ucode_tlv_capa_t)87, + IWL_UCODE_TLV_CAPA_LED_CMD_SUPPORT = (__force iwl_ucode_tlv_capa_t)88, IWL_UCODE_TLV_CAPA_MLME_OFFLOAD = (__force iwl_ucode_tlv_capa_t)96, NUM_IWL_UCODE_TLV_CAPA From 6f3df8c1192c873a6ad9a76328920f6f85af90a8 Mon Sep 17 00:00:00 2001 From: Ilan Peer Date: Mon, 11 Jun 2018 14:05:11 +0300 Subject: [PATCH 255/276] iwlwifi: mvm: Allow TKIP for AP mode Support for setting keys for TKIP cipher suite was mistakenly removed for AP mode. Fix this. Fixes: 85aeb58cec1a ("iwlwifi: mvm: Enable security on new TX API") Signed-off-by: Ilan Peer Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c index 550e24da0f5b..8f929c774e70 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c @@ -3149,10 +3149,6 @@ static int __iwl_mvm_set_sta_key(struct iwl_mvm *mvm, switch (keyconf->cipher) { case WLAN_CIPHER_SUITE_TKIP: - if (vif->type == NL80211_IFTYPE_AP) { - ret = -EINVAL; - break; - } addr = iwl_mvm_get_mac_addr(mvm, vif, sta); /* get phase 1 key from mac80211 */ ieee80211_get_key_rx_seq(keyconf, 0, &seq); From c15ace868dd16300ec67021903cc354fe0aa0762 Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Thu, 20 Sep 2018 13:45:49 -0700 Subject: [PATCH 256/276] ipw2x00: Remove unnecessary parentheses Clang warns when multiple pairs of parentheses are used for a single conditional statement. drivers/net/wireless/intel/ipw2x00/ipw2200.c:5655:28: warning: equality comparison with extraneous parentheses [-Wparentheses-equality] if ((priv->ieee->iw_mode == IW_MODE_ADHOC)) { ~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~ drivers/net/wireless/intel/ipw2x00/ipw2200.c:5655:28: note: remove extraneous parentheses around the comparison to silence this warning if ((priv->ieee->iw_mode == IW_MODE_ADHOC)) { ~ ^ ~ drivers/net/wireless/intel/ipw2x00/ipw2200.c:5655:28: note: use '=' to turn this equality comparison into an assignment if ((priv->ieee->iw_mode == IW_MODE_ADHOC)) { ^~ = 1 warning generated. Link: https://github.com/ClangBuiltLinux/linux/issues/134 Signed-off-by: Nathan Chancellor Signed-off-by: Kalle Valo --- drivers/net/wireless/intel/ipw2x00/ipw2200.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/ipw2x00/ipw2200.c b/drivers/net/wireless/intel/ipw2x00/ipw2200.c index 9644e7b93645..bbdca13c5a9f 100644 --- a/drivers/net/wireless/intel/ipw2x00/ipw2200.c +++ b/drivers/net/wireless/intel/ipw2x00/ipw2200.c @@ -5652,7 +5652,7 @@ static void ipw_merge_adhoc_network(struct work_struct *work) } mutex_lock(&priv->mutex); - if ((priv->ieee->iw_mode == IW_MODE_ADHOC)) { + if (priv->ieee->iw_mode == IW_MODE_ADHOC) { IPW_DEBUG_MERGE("remove network %*pE\n", priv->essid_len, priv->essid); ipw_remove_current_network(priv); From f613e4803dd6d1f41a86f6406d4c994fa3d387a0 Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Fri, 21 Sep 2018 02:48:29 -0700 Subject: [PATCH 257/276] rsi: Remove unnecessary boolean condition Clang warns that the address of a pointer will always evaluated as true in a boolean context. drivers/net/wireless/rsi/rsi_91x_mac80211.c:927:50: warning: address of array 'key->key' will always evaluate to 'true' [-Wpointer-bool-conversion] if (vif->type == NL80211_IFTYPE_STATION && key->key && ~~ ~~~~~^~~ 1 warning generated. Link: https://github.com/ClangBuiltLinux/linux/issues/136 Signed-off-by: Nathan Chancellor Signed-off-by: Kalle Valo --- drivers/net/wireless/rsi/rsi_91x_mac80211.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/rsi/rsi_91x_mac80211.c b/drivers/net/wireless/rsi/rsi_91x_mac80211.c index 4e510cbe0a89..e56fc83faf0e 100644 --- a/drivers/net/wireless/rsi/rsi_91x_mac80211.c +++ b/drivers/net/wireless/rsi/rsi_91x_mac80211.c @@ -924,7 +924,7 @@ static int rsi_hal_key_config(struct ieee80211_hw *hw, if (status) return status; - if (vif->type == NL80211_IFTYPE_STATION && key->key && + if (vif->type == NL80211_IFTYPE_STATION && (key->cipher == WLAN_CIPHER_SUITE_WEP104 || key->cipher == WLAN_CIPHER_SUITE_WEP40)) { if (!rsi_send_block_unblock_frame(adapter->priv, false)) From 0891c7f4a2532de13df49d77d14cb2f5cf099183 Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Fri, 21 Sep 2018 12:32:36 -0700 Subject: [PATCH 258/276] ath5k: Remove unused BUG_ON Clang warns that the address of a pointer will always evaluated as true in a boolean context: drivers/net/wireless/ath/ath5k/debug.c:1031:14: warning: address of array 'ah->sbands' will always evaluate to 'true' [-Wpointer-bool-conversion] BUG_ON(!ah->sbands); ~~~~~^~~~~~ ./include/asm-generic/bug.h:61:45: note: expanded from macro 'BUG_ON' #define BUG_ON(condition) do { if (unlikely(condition)) BUG(); } while (0) ^~~~~~~~~ ./include/linux/compiler.h:77:42: note: expanded from macro 'unlikely' # define unlikely(x) __builtin_expect(!!(x), 0) ^ 1 warning generated. Given that this condition is always false because of the logical not, just remove it. Link: https://github.com/ClangBuiltLinux/linux/issues/130 Signed-off-by: Nathan Chancellor Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath5k/debug.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c index e01faf641288..94f70047d3fc 100644 --- a/drivers/net/wireless/ath/ath5k/debug.c +++ b/drivers/net/wireless/ath/ath5k/debug.c @@ -1028,8 +1028,6 @@ ath5k_debug_dump_bands(struct ath5k_hw *ah) if (likely(!(ah->debug.level & ATH5K_DEBUG_DUMPBANDS))) return; - BUG_ON(!ah->sbands); - for (b = 0; b < NUM_NL80211_BANDS; b++) { struct ieee80211_supported_band *band = &ah->sbands[b]; char bname[6]; From 31138a827d1b3d6e4855bddb5a1e44e7b32309c0 Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Sat, 22 Sep 2018 23:31:15 -0700 Subject: [PATCH 259/276] rtlwifi: btcoex: Use proper enumerated types for Wi-Fi only interface Clang warns when one enumerated type is implicitly converted to another. drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c:1327:34: warning: implicit conversion from enumeration type 'enum btc_chip_interface' to different enumeration type 'enum wifionly_chip_interface' [-Wenum-conversion] wifionly_cfg->chip_interface = BTC_INTF_PCI; ~ ^~~~~~~~~~~~ drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c:1330:34: warning: implicit conversion from enumeration type 'enum btc_chip_interface' to different enumeration type 'enum wifionly_chip_interface' [-Wenum-conversion] wifionly_cfg->chip_interface = BTC_INTF_USB; ~ ^~~~~~~~~~~~ drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c:1333:34: warning: implicit conversion from enumeration type 'enum btc_chip_interface' to different enumeration type 'enum wifionly_chip_interface' [-Wenum-conversion] wifionly_cfg->chip_interface = BTC_INTF_UNKNOWN; ~ ^~~~~~~~~~~~~~~~ 3 warnings generated. Use the values from the correct enumerated type, wifionly_chip_interface. BTC_INTF_UNKNOWN = WIFIONLY_INTF_UNKNOWN = 0 BTC_INTF_PCI = WIFIONLY_INTF_PCI = 1 BTC_INTF_USB = WIFIONLY_INTF_USB = 2 Link: https://github.com/ClangBuiltLinux/linux/issues/135 Signed-off-by: Nathan Chancellor Acked-by: Ping-Ke Shih Signed-off-by: Kalle Valo --- .../net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c index b026e80940a4..6fbf8845a2ab 100644 --- a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c +++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c @@ -1324,13 +1324,13 @@ bool exhalbtc_initlize_variables_wifi_only(struct rtl_priv *rtlpriv) switch (rtlpriv->rtlhal.interface) { case INTF_PCI: - wifionly_cfg->chip_interface = BTC_INTF_PCI; + wifionly_cfg->chip_interface = WIFIONLY_INTF_PCI; break; case INTF_USB: - wifionly_cfg->chip_interface = BTC_INTF_USB; + wifionly_cfg->chip_interface = WIFIONLY_INTF_USB; break; default: - wifionly_cfg->chip_interface = BTC_INTF_UNKNOWN; + wifionly_cfg->chip_interface = WIFIONLY_INTF_UNKNOWN; break; } From 5c656c71b1bf5611ce8262bab338104e04d10b8d Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 26 Sep 2018 12:24:53 +0200 Subject: [PATCH 260/276] rt2800: move usb specific txdone/txstatus routines to rt2800lib In order to reuse usb txdone/txstatus routines for mmio, move them to common rt2800lib.c file. Signed-off-by: Stanislaw Gruszka Signed-off-by: Kalle Valo --- .../net/wireless/ralink/rt2x00/rt2800lib.c | 138 +++++++++++++++++ .../net/wireless/ralink/rt2x00/rt2800lib.h | 3 + .../net/wireless/ralink/rt2x00/rt2800usb.c | 143 +----------------- 3 files changed, 145 insertions(+), 139 deletions(-) diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c index a567bc273ffc..9f2835729016 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c @@ -957,6 +957,47 @@ static void rt2800_rate_from_status(struct skb_frame_desc *skbdesc, skbdesc->tx_rate_flags = flags; } +static bool rt2800_txdone_entry_check(struct queue_entry *entry, u32 reg) +{ + __le32 *txwi; + u32 word; + int wcid, ack, pid; + int tx_wcid, tx_ack, tx_pid, is_agg; + + /* + * This frames has returned with an IO error, + * so the status report is not intended for this + * frame. + */ + if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) + return false; + + wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID); + ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED); + pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE); + is_agg = rt2x00_get_field32(reg, TX_STA_FIFO_TX_AGGRE); + + /* + * Validate if this TX status report is intended for + * this entry by comparing the WCID/ACK/PID fields. + */ + txwi = rt2800_drv_get_txwi(entry); + + word = rt2x00_desc_read(txwi, 1); + tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID); + tx_ack = rt2x00_get_field32(word, TXWI_W1_ACK); + tx_pid = rt2x00_get_field32(word, TXWI_W1_PACKETID); + + if (wcid != tx_wcid || ack != tx_ack || (!is_agg && pid != tx_pid)) { + rt2x00_dbg(entry->queue->rt2x00dev, + "TX status report missed for queue %d entry %d\n", + entry->queue->qid, entry->entry_idx); + return false; + } + + return true; +} + void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi, bool match) { @@ -1059,6 +1100,103 @@ void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi, } EXPORT_SYMBOL_GPL(rt2800_txdone_entry); +void rt2800_txdone(struct rt2x00_dev *rt2x00dev) +{ + struct data_queue *queue; + struct queue_entry *entry; + u32 reg; + u8 qid; + bool match; + + while (kfifo_get(&rt2x00dev->txstatus_fifo, ®)) { + /* + * TX_STA_FIFO_PID_QUEUE is a 2-bit field, thus qid is + * guaranteed to be one of the TX QIDs . + */ + qid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_QUEUE); + queue = rt2x00queue_get_tx_queue(rt2x00dev, qid); + + if (unlikely(rt2x00queue_empty(queue))) { + rt2x00_dbg(rt2x00dev, "Got TX status for an empty queue %u, dropping\n", + qid); + break; + } + + entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); + + if (unlikely(test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) || + !test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))) { + rt2x00_warn(rt2x00dev, "Data pending for entry %u in queue %u\n", + entry->entry_idx, qid); + break; + } + + match = rt2800_txdone_entry_check(entry, reg); + rt2800_txdone_entry(entry, reg, rt2800_drv_get_txwi(entry), match); + } +} +EXPORT_SYMBOL_GPL(rt2800_txdone); + +static inline bool rt2800_entry_txstatus_timeout(struct queue_entry *entry) +{ + bool tout; + + if (!test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) + return false; + + tout = time_after(jiffies, entry->last_action + msecs_to_jiffies(500)); + if (unlikely(tout)) + rt2x00_dbg(entry->queue->rt2x00dev, + "TX status timeout for entry %d in queue %d\n", + entry->entry_idx, entry->queue->qid); + return tout; + +} + +bool rt2800_txstatus_timeout(struct rt2x00_dev *rt2x00dev) +{ + struct data_queue *queue; + struct queue_entry *entry; + + tx_queue_for_each(rt2x00dev, queue) { + entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); + if (rt2800_entry_txstatus_timeout(entry)) + return true; + } + return false; +} +EXPORT_SYMBOL_GPL(rt2800_txstatus_timeout); + +void rt2800_txdone_nostatus(struct rt2x00_dev *rt2x00dev) +{ + struct data_queue *queue; + struct queue_entry *entry; + + /* + * Process any trailing TX status reports for IO failures, + * we loop until we find the first non-IO error entry. This + * can either be a frame which is free, is being uploaded, + * or has completed the upload but didn't have an entry + * in the TX_STAT_FIFO register yet. + */ + tx_queue_for_each(rt2x00dev, queue) { + while (!rt2x00queue_empty(queue)) { + entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); + + if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) || + !test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) + break; + + if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags) || + rt2800_entry_txstatus_timeout(entry)) + rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE); + else + break; + } + } +} +EXPORT_SYMBOL_GPL(rt2800_txdone_nostatus); + static unsigned int rt2800_hw_beacon_base(struct rt2x00_dev *rt2x00dev, unsigned int index) { diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h index 51d9c2a932cc..0dff2c7b3010 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h @@ -195,6 +195,9 @@ void rt2800_process_rxwi(struct queue_entry *entry, struct rxdone_entry_desc *tx void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi, bool match); +void rt2800_txdone(struct rt2x00_dev *rt2x00dev); +void rt2800_txdone_nostatus(struct rt2x00_dev *rt2x00dev); +bool rt2800_txstatus_timeout(struct rt2x00_dev *rt2x00dev); void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc); void rt2800_clear_beacon(struct queue_entry *entry); diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800usb.c b/drivers/net/wireless/ralink/rt2x00/rt2800usb.c index 98a7313fea4a..19eabf16147b 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800usb.c @@ -116,35 +116,6 @@ static bool rt2800usb_txstatus_pending(struct rt2x00_dev *rt2x00dev) return false; } -static inline bool rt2800usb_entry_txstatus_timeout(struct queue_entry *entry) -{ - bool tout; - - if (!test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) - return false; - - tout = time_after(jiffies, entry->last_action + msecs_to_jiffies(500)); - if (unlikely(tout)) - rt2x00_dbg(entry->queue->rt2x00dev, - "TX status timeout for entry %d in queue %d\n", - entry->entry_idx, entry->queue->qid); - return tout; - -} - -static bool rt2800usb_txstatus_timeout(struct rt2x00_dev *rt2x00dev) -{ - struct data_queue *queue; - struct queue_entry *entry; - - tx_queue_for_each(rt2x00dev, queue) { - entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); - if (rt2800usb_entry_txstatus_timeout(entry)) - return true; - } - return false; -} - #define TXSTATUS_READ_INTERVAL 1000000 static bool rt2800usb_tx_sta_fifo_read_completed(struct rt2x00_dev *rt2x00dev, @@ -171,7 +142,7 @@ static bool rt2800usb_tx_sta_fifo_read_completed(struct rt2x00_dev *rt2x00dev, } /* Check if there is any entry that timedout waiting on TX status */ - if (rt2800usb_txstatus_timeout(rt2x00dev)) + if (rt2800_txstatus_timeout(rt2x00dev)) queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work); if (rt2800usb_txstatus_pending(rt2x00dev)) { @@ -501,123 +472,17 @@ static int rt2800usb_get_tx_data_len(struct queue_entry *entry) /* * TX control handlers */ -static bool rt2800usb_txdone_entry_check(struct queue_entry *entry, u32 reg) -{ - __le32 *txwi; - u32 word; - int wcid, ack, pid; - int tx_wcid, tx_ack, tx_pid, is_agg; - - /* - * This frames has returned with an IO error, - * so the status report is not intended for this - * frame. - */ - if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) - return false; - - wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID); - ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED); - pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE); - is_agg = rt2x00_get_field32(reg, TX_STA_FIFO_TX_AGGRE); - - /* - * Validate if this TX status report is intended for - * this entry by comparing the WCID/ACK/PID fields. - */ - txwi = rt2800usb_get_txwi(entry); - - word = rt2x00_desc_read(txwi, 1); - tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID); - tx_ack = rt2x00_get_field32(word, TXWI_W1_ACK); - tx_pid = rt2x00_get_field32(word, TXWI_W1_PACKETID); - - if (wcid != tx_wcid || ack != tx_ack || (!is_agg && pid != tx_pid)) { - rt2x00_dbg(entry->queue->rt2x00dev, - "TX status report missed for queue %d entry %d\n", - entry->queue->qid, entry->entry_idx); - return false; - } - - return true; -} - -static void rt2800usb_txdone(struct rt2x00_dev *rt2x00dev) -{ - struct data_queue *queue; - struct queue_entry *entry; - u32 reg; - u8 qid; - bool match; - - while (kfifo_get(&rt2x00dev->txstatus_fifo, ®)) { - /* - * TX_STA_FIFO_PID_QUEUE is a 2-bit field, thus qid is - * guaranteed to be one of the TX QIDs . - */ - qid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_QUEUE); - queue = rt2x00queue_get_tx_queue(rt2x00dev, qid); - - if (unlikely(rt2x00queue_empty(queue))) { - rt2x00_dbg(rt2x00dev, "Got TX status for an empty queue %u, dropping\n", - qid); - break; - } - - entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); - - if (unlikely(test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) || - !test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))) { - rt2x00_warn(rt2x00dev, "Data pending for entry %u in queue %u\n", - entry->entry_idx, qid); - break; - } - - match = rt2800usb_txdone_entry_check(entry, reg); - rt2800_txdone_entry(entry, reg, rt2800usb_get_txwi(entry), match); - } -} - -static void rt2800usb_txdone_nostatus(struct rt2x00_dev *rt2x00dev) -{ - struct data_queue *queue; - struct queue_entry *entry; - - /* - * Process any trailing TX status reports for IO failures, - * we loop until we find the first non-IO error entry. This - * can either be a frame which is free, is being uploaded, - * or has completed the upload but didn't have an entry - * in the TX_STAT_FIFO register yet. - */ - tx_queue_for_each(rt2x00dev, queue) { - while (!rt2x00queue_empty(queue)) { - entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); - - if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) || - !test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) - break; - - if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags) || - rt2800usb_entry_txstatus_timeout(entry)) - rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE); - else - break; - } - } -} - static void rt2800usb_work_txdone(struct work_struct *work) { struct rt2x00_dev *rt2x00dev = container_of(work, struct rt2x00_dev, txdone_work); while (!kfifo_is_empty(&rt2x00dev->txstatus_fifo) || - rt2800usb_txstatus_timeout(rt2x00dev)) { + rt2800_txstatus_timeout(rt2x00dev)) { - rt2800usb_txdone(rt2x00dev); + rt2800_txdone(rt2x00dev); - rt2800usb_txdone_nostatus(rt2x00dev); + rt2800_txdone_nostatus(rt2x00dev); /* * The hw may delay sending the packet after DMA complete From 0b0d556e0ebb6c966bc993e21a22a156812d8fdf Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 26 Sep 2018 12:24:54 +0200 Subject: [PATCH 261/276] rt2800mmio: use txdone/txstatus routines from lib Use usb txdone/txstatus routines (now in rt2800libc) for mmio devices. Note this also change how we handle INT_SOURCE_CSR_TX_FIFO_STATUS interrupt. Now it is disabled since IRQ routine till end of the txstatus tasklet (the same behaviour like others interrupts). Reason to do not disable this interrupt was not to miss any tx status from 16 entries FIFO register. Now, since we check for tx status timeout, we can allow to miss some tx statuses. However this will be improved in further patch where I also implement read status FIFO register in the tasklet. Signed-off-by: Stanislaw Gruszka Signed-off-by: Kalle Valo --- .../net/wireless/ralink/rt2x00/rt2800mmio.c | 180 +----------------- .../net/wireless/ralink/rt2x00/rt2x00queue.c | 1 + 2 files changed, 9 insertions(+), 172 deletions(-) diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c b/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c index e1a7ed7e4892..aa8449a5e8fe 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c @@ -175,161 +175,6 @@ static void rt2800mmio_wakeup(struct rt2x00_dev *rt2x00dev) rt2800_config(rt2x00dev, &libconf, IEEE80211_CONF_CHANGE_PS); } -static bool rt2800mmio_txdone_entry_check(struct queue_entry *entry, u32 status) -{ - __le32 *txwi; - u32 word; - int wcid, tx_wcid; - - wcid = rt2x00_get_field32(status, TX_STA_FIFO_WCID); - - txwi = rt2800_drv_get_txwi(entry); - word = rt2x00_desc_read(txwi, 1); - tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID); - - return (tx_wcid == wcid); -} - -static bool rt2800mmio_txdone_find_entry(struct queue_entry *entry, void *data) -{ - u32 status = *(u32 *)data; - - /* - * rt2800pci hardware might reorder frames when exchanging traffic - * with multiple BA enabled STAs. - * - * For example, a tx queue - * [ STA1 | STA2 | STA1 | STA2 ] - * can result in tx status reports - * [ STA1 | STA1 | STA2 | STA2 ] - * when the hw decides to aggregate the frames for STA1 into one AMPDU. - * - * To mitigate this effect, associate the tx status to the first frame - * in the tx queue with a matching wcid. - */ - if (rt2800mmio_txdone_entry_check(entry, status) && - !test_bit(ENTRY_DATA_STATUS_SET, &entry->flags)) { - /* - * Got a matching frame, associate the tx status with - * the frame - */ - entry->status = status; - set_bit(ENTRY_DATA_STATUS_SET, &entry->flags); - return true; - } - - /* Check the next frame */ - return false; -} - -static bool rt2800mmio_txdone_match_first(struct queue_entry *entry, void *data) -{ - u32 status = *(u32 *)data; - - /* - * Find the first frame without tx status and assign this status to it - * regardless if it matches or not. - */ - if (!test_bit(ENTRY_DATA_STATUS_SET, &entry->flags)) { - /* - * Got a matching frame, associate the tx status with - * the frame - */ - entry->status = status; - set_bit(ENTRY_DATA_STATUS_SET, &entry->flags); - return true; - } - - /* Check the next frame */ - return false; -} -static bool rt2800mmio_txdone_release_entries(struct queue_entry *entry, - void *data) -{ - if (test_bit(ENTRY_DATA_STATUS_SET, &entry->flags)) { - rt2800_txdone_entry(entry, entry->status, - rt2800mmio_get_txwi(entry), true); - return false; - } - - /* No more frames to release */ - return true; -} - -static bool rt2800mmio_txdone(struct rt2x00_dev *rt2x00dev) -{ - struct data_queue *queue; - u32 status; - u8 qid; - int max_tx_done = 16; - - while (kfifo_get(&rt2x00dev->txstatus_fifo, &status)) { - qid = rt2x00_get_field32(status, TX_STA_FIFO_PID_QUEUE); - if (unlikely(qid >= QID_RX)) { - /* - * Unknown queue, this shouldn't happen. Just drop - * this tx status. - */ - rt2x00_warn(rt2x00dev, "Got TX status report with unexpected pid %u, dropping\n", - qid); - break; - } - - queue = rt2x00queue_get_tx_queue(rt2x00dev, qid); - if (unlikely(queue == NULL)) { - /* - * The queue is NULL, this shouldn't happen. Stop - * processing here and drop the tx status - */ - rt2x00_warn(rt2x00dev, "Got TX status for an unavailable queue %u, dropping\n", - qid); - break; - } - - if (unlikely(rt2x00queue_empty(queue))) { - /* - * The queue is empty. Stop processing here - * and drop the tx status. - */ - rt2x00_warn(rt2x00dev, "Got TX status for an empty queue %u, dropping\n", - qid); - break; - } - - /* - * Let's associate this tx status with the first - * matching frame. - */ - if (!rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, - Q_INDEX, &status, - rt2800mmio_txdone_find_entry)) { - /* - * We cannot match the tx status to any frame, so just - * use the first one. - */ - if (!rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, - Q_INDEX, &status, - rt2800mmio_txdone_match_first)) { - rt2x00_warn(rt2x00dev, "No frame found for TX status on queue %u, dropping\n", - qid); - break; - } - } - - /* - * Release all frames with a valid tx status. - */ - rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, - Q_INDEX, NULL, - rt2800mmio_txdone_release_entries); - - if (--max_tx_done == 0) - break; - } - - return !max_tx_done; -} - static inline void rt2800mmio_enable_interrupt(struct rt2x00_dev *rt2x00dev, struct rt2x00_field32 irq_field) { @@ -349,14 +194,14 @@ static inline void rt2800mmio_enable_interrupt(struct rt2x00_dev *rt2x00dev, void rt2800mmio_txstatus_tasklet(unsigned long data) { struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; - if (rt2800mmio_txdone(rt2x00dev)) - tasklet_schedule(&rt2x00dev->txstatus_tasklet); - /* - * No need to enable the tx status interrupt here as we always - * leave it enabled to minimize the possibility of a tx status - * register overflow. See comment in interrupt handler. - */ + rt2800_txdone(rt2x00dev); + + rt2800_txdone_nostatus(rt2x00dev); + + if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) + rt2800mmio_enable_interrupt(rt2x00dev, + INT_SOURCE_CSR_TX_FIFO_STATUS); } EXPORT_SYMBOL_GPL(rt2800mmio_txstatus_tasklet); @@ -440,10 +285,6 @@ static void rt2800mmio_txstatus_interrupt(struct rt2x00_dev *rt2x00dev) * because we can schedule the tasklet multiple times (when the * interrupt fires again during tx status processing). * - * Furthermore we don't disable the TX_FIFO_STATUS - * interrupt here but leave it enabled so that the TX_STA_FIFO - * can also be read while the tx status tasklet gets executed. - * * Since we have only one producer and one consumer we don't * need to lock the kfifo. */ @@ -485,13 +326,8 @@ irqreturn_t rt2800mmio_interrupt(int irq, void *dev_instance) */ mask = ~reg; - if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TX_FIFO_STATUS)) { + if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TX_FIFO_STATUS)) rt2800mmio_txstatus_interrupt(rt2x00dev); - /* - * Never disable the TX_FIFO_STATUS interrupt. - */ - rt2x00_set_field32(&mask, INT_MASK_CSR_TX_FIFO_STATUS, 1); - } if (rt2x00_get_field32(reg, INT_SOURCE_CSR_PRE_TBTT)) tasklet_hi_schedule(&rt2x00dev->pretbtt_tasklet); diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c b/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c index 710e9641552e..6e8beb7ea350 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c @@ -113,6 +113,7 @@ int rt2x00queue_map_txskb(struct queue_entry *entry) return -ENOMEM; skbdesc->flags |= SKBDESC_DMA_MAPPED_TX; + rt2x00lib_dmadone(entry); return 0; } EXPORT_SYMBOL_GPL(rt2x00queue_map_txskb); From 5022efb50f625d11fdf18b1fee0f64ebb1863664 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 26 Sep 2018 12:24:55 +0200 Subject: [PATCH 262/276] rt2x00: do not check for txstatus timeout every time on tasklet Do not check for tx status timeout everytime we perform txstatus tasklet. Perform check once per half a second. Signed-off-by: Stanislaw Gruszka Signed-off-by: Kalle Valo --- drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 7 +++++++ drivers/net/wireless/ralink/rt2x00/rt2800mmio.c | 3 ++- drivers/net/wireless/ralink/rt2x00/rt2x00.h | 2 ++ drivers/net/wireless/ralink/rt2x00/rt2x00queue.c | 1 + 4 files changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c index 9f2835729016..0c56c7dca55f 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c @@ -1158,11 +1158,18 @@ bool rt2800_txstatus_timeout(struct rt2x00_dev *rt2x00dev) struct data_queue *queue; struct queue_entry *entry; + if (time_before(jiffies, + rt2x00dev->last_nostatus_check + msecs_to_jiffies(500))) + return false; + + rt2x00dev->last_nostatus_check = jiffies; + tx_queue_for_each(rt2x00dev, queue) { entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); if (rt2800_entry_txstatus_timeout(entry)) return true; } + return false; } EXPORT_SYMBOL_GPL(rt2800_txstatus_timeout); diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c b/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c index aa8449a5e8fe..d0426314c2df 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c @@ -197,7 +197,8 @@ void rt2800mmio_txstatus_tasklet(unsigned long data) rt2800_txdone(rt2x00dev); - rt2800_txdone_nostatus(rt2x00dev); + if (rt2800_txstatus_timeout(rt2x00dev)) + rt2800_txdone_nostatus(rt2x00dev); if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) rt2800mmio_enable_interrupt(rt2x00dev, diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00.h b/drivers/net/wireless/ralink/rt2x00/rt2x00.h index a279a4363bc1..af062cda4a23 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h @@ -980,6 +980,8 @@ struct rt2x00_dev { */ DECLARE_KFIFO_PTR(txstatus_fifo, u32); + unsigned long last_nostatus_check; + /* * Timer to ensure tx status reports are read (rt2800usb). */ diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c b/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c index 6e8beb7ea350..92ddc19e7bf7 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c @@ -1039,6 +1039,7 @@ void rt2x00queue_start_queues(struct rt2x00_dev *rt2x00dev) */ tx_queue_for_each(rt2x00dev, queue) rt2x00queue_start_queue(queue); + rt2x00dev->last_nostatus_check = jiffies; rt2x00queue_start_queue(rt2x00dev->rx); } From adf26a356f132e35093585521ea3e36cd185af83 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 26 Sep 2018 12:24:56 +0200 Subject: [PATCH 263/276] rt2x00: use different txstatus timeouts when flushing Use different tx status timeouts for normal operation and when flushing. This increase timeout to 2s for normal operation as when there are bad radio conditions and frames are reposted many times device can not provide the status for quite long. With new timeout we can still get valid status on such bad conditions. Signed-off-by: Stanislaw Gruszka Signed-off-by: Kalle Valo --- .../net/wireless/ralink/rt2x00/rt2800lib.c | 31 +++++++++++++------ drivers/net/wireless/ralink/rt2x00/rt2x00.h | 1 + .../net/wireless/ralink/rt2x00/rt2x00mac.c | 4 +++ 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c index 0c56c7dca55f..595cb9c90b81 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c @@ -1137,36 +1137,47 @@ void rt2800_txdone(struct rt2x00_dev *rt2x00dev) } EXPORT_SYMBOL_GPL(rt2800_txdone); -static inline bool rt2800_entry_txstatus_timeout(struct queue_entry *entry) +static inline bool rt2800_entry_txstatus_timeout(struct rt2x00_dev *rt2x00dev, + struct queue_entry *entry) { - bool tout; + bool ret; + unsigned long tout; if (!test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) return false; - tout = time_after(jiffies, entry->last_action + msecs_to_jiffies(500)); - if (unlikely(tout)) + if (test_bit(DEVICE_STATE_FLUSHING, &rt2x00dev->flags)) + tout = msecs_to_jiffies(100); + else + tout = msecs_to_jiffies(2000); + + ret = time_after(jiffies, entry->last_action + tout); + if (unlikely(ret)) rt2x00_dbg(entry->queue->rt2x00dev, "TX status timeout for entry %d in queue %d\n", entry->entry_idx, entry->queue->qid); - return tout; - + return ret; } bool rt2800_txstatus_timeout(struct rt2x00_dev *rt2x00dev) { struct data_queue *queue; struct queue_entry *entry; + unsigned long tout; - if (time_before(jiffies, - rt2x00dev->last_nostatus_check + msecs_to_jiffies(500))) + if (test_bit(DEVICE_STATE_FLUSHING, &rt2x00dev->flags)) + tout = msecs_to_jiffies(50); + else + tout = msecs_to_jiffies(1000); + + if (time_before(jiffies, rt2x00dev->last_nostatus_check + tout)) return false; rt2x00dev->last_nostatus_check = jiffies; tx_queue_for_each(rt2x00dev, queue) { entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); - if (rt2800_entry_txstatus_timeout(entry)) + if (rt2800_entry_txstatus_timeout(rt2x00dev, entry)) return true; } @@ -1195,7 +1206,7 @@ void rt2800_txdone_nostatus(struct rt2x00_dev *rt2x00dev) break; if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags) || - rt2800_entry_txstatus_timeout(entry)) + rt2800_entry_txstatus_timeout(rt2x00dev, entry)) rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE); else break; diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00.h b/drivers/net/wireless/ralink/rt2x00/rt2x00.h index af062cda4a23..4b1744e9fb78 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h @@ -665,6 +665,7 @@ enum rt2x00_state_flags { DEVICE_STATE_STARTED, DEVICE_STATE_ENABLED_RADIO, DEVICE_STATE_SCANNING, + DEVICE_STATE_FLUSHING, /* * Driver configuration diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00mac.c b/drivers/net/wireless/ralink/rt2x00/rt2x00mac.c index fa2fd64084ac..2825560e2424 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00mac.c @@ -720,8 +720,12 @@ void rt2x00mac_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) return; + set_bit(DEVICE_STATE_FLUSHING, &rt2x00dev->flags); + tx_queue_for_each(rt2x00dev, queue) rt2x00queue_flush_queue(queue, drop); + + clear_bit(DEVICE_STATE_FLUSHING, &rt2x00dev->flags); } EXPORT_SYMBOL_GPL(rt2x00mac_flush); From 0240564430c0697d8fde3743d70346a922466b36 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 26 Sep 2018 12:24:57 +0200 Subject: [PATCH 264/276] rt2800: flush and txstatus rework for rt2800mmio Implement custom rt2800mmio flush routine and change txstatus routine to read TX_STA_FIFO also in the tasklet. Signed-off-by: Stanislaw Gruszka Signed-off-by: Kalle Valo --- .../net/wireless/ralink/rt2x00/rt2800lib.c | 14 +-- .../net/wireless/ralink/rt2x00/rt2800mmio.c | 118 +++++++++++++----- .../net/wireless/ralink/rt2x00/rt2800mmio.h | 1 + .../net/wireless/ralink/rt2x00/rt2800pci.c | 2 +- 4 files changed, 97 insertions(+), 38 deletions(-) diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c index 595cb9c90b81..9e7b8933d30c 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c @@ -1147,7 +1147,7 @@ static inline bool rt2800_entry_txstatus_timeout(struct rt2x00_dev *rt2x00dev, return false; if (test_bit(DEVICE_STATE_FLUSHING, &rt2x00dev->flags)) - tout = msecs_to_jiffies(100); + tout = msecs_to_jiffies(50); else tout = msecs_to_jiffies(2000); @@ -1163,15 +1163,13 @@ bool rt2800_txstatus_timeout(struct rt2x00_dev *rt2x00dev) { struct data_queue *queue; struct queue_entry *entry; - unsigned long tout; - if (test_bit(DEVICE_STATE_FLUSHING, &rt2x00dev->flags)) - tout = msecs_to_jiffies(50); - else - tout = msecs_to_jiffies(1000); + if (!test_bit(DEVICE_STATE_FLUSHING, &rt2x00dev->flags)) { + unsigned long tout = msecs_to_jiffies(1000); - if (time_before(jiffies, rt2x00dev->last_nostatus_check + tout)) - return false; + if (time_before(jiffies, rt2x00dev->last_nostatus_check + tout)) + return false; + } rt2x00dev->last_nostatus_check = jiffies; diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c b/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c index d0426314c2df..ddb88cfeace2 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c @@ -191,21 +191,6 @@ static inline void rt2800mmio_enable_interrupt(struct rt2x00_dev *rt2x00dev, spin_unlock_irq(&rt2x00dev->irqmask_lock); } -void rt2800mmio_txstatus_tasklet(unsigned long data) -{ - struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; - - rt2800_txdone(rt2x00dev); - - if (rt2800_txstatus_timeout(rt2x00dev)) - rt2800_txdone_nostatus(rt2x00dev); - - if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) - rt2800mmio_enable_interrupt(rt2x00dev, - INT_SOURCE_CSR_TX_FIFO_STATUS); -} -EXPORT_SYMBOL_GPL(rt2800mmio_txstatus_tasklet); - void rt2800mmio_pretbtt_tasklet(unsigned long data) { struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; @@ -270,12 +255,26 @@ void rt2800mmio_autowake_tasklet(unsigned long data) } EXPORT_SYMBOL_GPL(rt2800mmio_autowake_tasklet); -static void rt2800mmio_txstatus_interrupt(struct rt2x00_dev *rt2x00dev) +static void rt2800mmio_txdone(struct rt2x00_dev *rt2x00dev) +{ + bool timeout = false; + + while (!kfifo_is_empty(&rt2x00dev->txstatus_fifo) || + (timeout = rt2800_txstatus_timeout(rt2x00dev))) { + + rt2800_txdone(rt2x00dev); + + if (timeout) + rt2800_txdone_nostatus(rt2x00dev); + } +} + +static bool rt2800mmio_fetch_txstatus(struct rt2x00_dev *rt2x00dev) { u32 status; - int i; + bool more = false; - /* + /* FIXEME: rewrite this comment * The TX_FIFO_STATUS interrupt needs special care. We should * read TX_STA_FIFO but we should do it immediately as otherwise * the register can overflow and we would lose status reports. @@ -286,25 +285,37 @@ static void rt2800mmio_txstatus_interrupt(struct rt2x00_dev *rt2x00dev) * because we can schedule the tasklet multiple times (when the * interrupt fires again during tx status processing). * - * Since we have only one producer and one consumer we don't + * txstatus tasklet is called with INT_SOURCE_CSR_TX_FIFO_STATUS + * disabled so have only one producer and one consumer - we don't * need to lock the kfifo. */ - for (i = 0; i < rt2x00dev->tx->limit; i++) { + while (!kfifo_is_full(&rt2x00dev->txstatus_fifo)) { status = rt2x00mmio_register_read(rt2x00dev, TX_STA_FIFO); - if (!rt2x00_get_field32(status, TX_STA_FIFO_VALID)) break; - if (!kfifo_put(&rt2x00dev->txstatus_fifo, status)) { - rt2x00_warn(rt2x00dev, "TX status FIFO overrun, drop tx status report\n"); - break; - } + kfifo_put(&rt2x00dev->txstatus_fifo, status); + more = true; } - /* Schedule the tasklet for processing the tx status. */ - tasklet_schedule(&rt2x00dev->txstatus_tasklet); + return more; } +void rt2800mmio_txstatus_tasklet(unsigned long data) +{ + struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; + + do { + rt2800mmio_txdone(rt2x00dev); + + } while (rt2800mmio_fetch_txstatus(rt2x00dev)); + + if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) + rt2800mmio_enable_interrupt(rt2x00dev, + INT_SOURCE_CSR_TX_FIFO_STATUS); +} +EXPORT_SYMBOL_GPL(rt2800mmio_txstatus_tasklet); + irqreturn_t rt2800mmio_interrupt(int irq, void *dev_instance) { struct rt2x00_dev *rt2x00dev = dev_instance; @@ -327,8 +338,10 @@ irqreturn_t rt2800mmio_interrupt(int irq, void *dev_instance) */ mask = ~reg; - if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TX_FIFO_STATUS)) - rt2800mmio_txstatus_interrupt(rt2x00dev); + if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TX_FIFO_STATUS)) { + rt2800mmio_fetch_txstatus(rt2x00dev); + tasklet_schedule(&rt2x00dev->txstatus_tasklet); + } if (rt2x00_get_field32(reg, INT_SOURCE_CSR_PRE_TBTT)) tasklet_hi_schedule(&rt2x00dev->pretbtt_tasklet); @@ -453,6 +466,53 @@ void rt2800mmio_kick_queue(struct data_queue *queue) } EXPORT_SYMBOL_GPL(rt2800mmio_kick_queue); +void rt2800mmio_flush_queue(struct data_queue *queue, bool drop) +{ + struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; + bool tx_queue = false; + unsigned int i; + + switch (queue->qid) { + case QID_AC_VO: + case QID_AC_VI: + case QID_AC_BE: + case QID_AC_BK: + tx_queue = true; + break; + case QID_RX: + break; + default: + return; + } + + for (i = 0; i < 5; i++) { + /* + * Check if the driver is already done, otherwise we + * have to sleep a little while to give the driver/hw + * the oppurtunity to complete interrupt process itself. + */ + if (rt2x00queue_empty(queue)) + break; + + /* + * For TX queues schedule completion tasklet to catch + * tx status timeouts, othewise just wait. + */ + if (tx_queue) { + tasklet_disable(&rt2x00dev->txstatus_tasklet); + rt2800mmio_txdone(rt2x00dev); + tasklet_enable(&rt2x00dev->txstatus_tasklet); + } + + /* + * Wait for a little while to give the driver + * the oppurtunity to recover itself. + */ + msleep(50); + } +} +EXPORT_SYMBOL_GPL(rt2800mmio_flush_queue); + void rt2800mmio_stop_queue(struct data_queue *queue) { struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800mmio.h b/drivers/net/wireless/ralink/rt2x00/rt2800mmio.h index b63312ce3f27..3a513273f414 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt2800mmio.h +++ b/drivers/net/wireless/ralink/rt2x00/rt2800mmio.h @@ -148,6 +148,7 @@ void rt2800mmio_toggle_irq(struct rt2x00_dev *rt2x00dev, /* Queue handlers */ void rt2800mmio_start_queue(struct data_queue *queue); void rt2800mmio_kick_queue(struct data_queue *queue); +void rt2800mmio_flush_queue(struct data_queue *queue, bool drop); void rt2800mmio_stop_queue(struct data_queue *queue); void rt2800mmio_queue_init(struct data_queue *queue); diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800pci.c b/drivers/net/wireless/ralink/rt2x00/rt2800pci.c index 71b1affc3885..0291441ac548 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800pci.c @@ -364,7 +364,7 @@ static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = { .start_queue = rt2800mmio_start_queue, .kick_queue = rt2800mmio_kick_queue, .stop_queue = rt2800mmio_stop_queue, - .flush_queue = rt2x00mmio_flush_queue, + .flush_queue = rt2800mmio_flush_queue, .write_tx_desc = rt2800mmio_write_tx_desc, .write_tx_data = rt2800_write_tx_data, .write_beacon = rt2800_write_beacon, From 4059afc6bd17dc11b15ee219d25e9901890732f7 Mon Sep 17 00:00:00 2001 From: Igor Mitsyanko Date: Mon, 24 Sep 2018 15:15:04 -0700 Subject: [PATCH 265/276] qtnfmac_pcie: do not store FW name in driver state structure Firmware name is only needed at probe stage, no point in keeping it in driver state structure. Signed-off-by: Igor Mitsyanko Signed-off-by: Kalle Valo --- drivers/net/wireless/quantenna/qtnfmac/bus.h | 1 - drivers/net/wireless/quantenna/qtnfmac/pearl/pcie.c | 8 ++++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/quantenna/qtnfmac/bus.h b/drivers/net/wireless/quantenna/qtnfmac/bus.h index 323e47cea1e2..2beca5b9de84 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/bus.h +++ b/drivers/net/wireless/quantenna/qtnfmac/bus.h @@ -57,7 +57,6 @@ struct qtnf_bus { struct qtnf_wmac *mac[QTNF_MAX_MAC]; struct qtnf_qlink_transport trans; struct qtnf_hw_info hw_info; - char fwname[32]; struct napi_struct mux_napi; struct net_device mux_dev; struct completion firmware_init_complete; diff --git a/drivers/net/wireless/quantenna/qtnfmac/pearl/pcie.c b/drivers/net/wireless/quantenna/qtnfmac/pearl/pcie.c index 3120d49df565..97cc7f2b6dd3 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/pearl/pcie.c +++ b/drivers/net/wireless/quantenna/qtnfmac/pearl/pcie.c @@ -1177,13 +1177,14 @@ static void qtnf_fw_work_handler(struct work_struct *work) const struct firmware *fw; int ret; u32 state = QTN_RC_FW_LOADRDY | QTN_RC_FW_QLINK; + const char *fwname = QTN_PCI_PEARL_FW_NAME; if (flashboot) { state |= QTN_RC_FW_FLASHBOOT; } else { - ret = request_firmware(&fw, bus->fwname, &pdev->dev); + ret = request_firmware(&fw, fwname, &pdev->dev); if (ret < 0) { - pr_err("failed to get firmware %s\n", bus->fwname); + pr_err("failed to get firmware %s\n", fwname); goto fw_load_fail; } } @@ -1205,7 +1206,7 @@ static void qtnf_fw_work_handler(struct work_struct *work) if (flashboot) { pr_info("booting firmware from flash\n"); } else { - pr_info("starting firmware upload: %s\n", bus->fwname); + pr_info("starting firmware upload: %s\n", fwname); ret = qtnf_ep_fw_load(priv, fw->data, fw->size); release_firmware(fw); @@ -1290,7 +1291,6 @@ static int qtnf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) bus->fw_state = QTNF_FW_STATE_RESET; pcie_priv->pdev = pdev; - strcpy(bus->fwname, QTN_PCI_PEARL_FW_NAME); init_completion(&bus->firmware_init_complete); mutex_init(&bus->bus_lock); spin_lock_init(&pcie_priv->tx0_lock); From 2ef0ecd7170071f142503c9e39f9f929e79947f0 Mon Sep 17 00:00:00 2001 From: Igor Mitsyanko Date: Mon, 24 Sep 2018 15:15:05 -0700 Subject: [PATCH 266/276] qtnfmac_pcie: move Pearl pcie sources to pcie-specific directory In preparation to extract common qtnfmac PCIe driver sources into a separate file, move existing Pearl-specific pcie driver sources to pcie/ directory. Signed-off-by: Igor Mitsyanko Signed-off-by: Kalle Valo --- drivers/net/wireless/quantenna/qtnfmac/Makefile | 2 +- .../quantenna/qtnfmac/{pearl/pcie.c => pcie/pearl_pcie.c} | 2 +- .../{pearl/pcie_bus_priv.h => pcie/pearl_pcie_bus_priv.h} | 4 ++-- .../qtnfmac/{pearl/pcie_ipc.h => pcie/pearl_pcie_ipc.h} | 0 .../{pearl/pcie_regs_pearl.h => pcie/pearl_pcie_regs.h} | 0 5 files changed, 4 insertions(+), 4 deletions(-) rename drivers/net/wireless/quantenna/qtnfmac/{pearl/pcie.c => pcie/pearl_pcie.c} (99%) rename drivers/net/wireless/quantenna/qtnfmac/{pearl/pcie_bus_priv.h => pcie/pearl_pcie_bus_priv.h} (97%) rename drivers/net/wireless/quantenna/qtnfmac/{pearl/pcie_ipc.h => pcie/pearl_pcie_ipc.h} (100%) rename drivers/net/wireless/quantenna/qtnfmac/{pearl/pcie_regs_pearl.h => pcie/pearl_pcie_regs.h} (100%) diff --git a/drivers/net/wireless/quantenna/qtnfmac/Makefile b/drivers/net/wireless/quantenna/qtnfmac/Makefile index 97f760a3d599..9eeddea6b106 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/Makefile +++ b/drivers/net/wireless/quantenna/qtnfmac/Makefile @@ -23,6 +23,6 @@ obj-$(CONFIG_QTNFMAC_PEARL_PCIE) += qtnfmac_pearl_pcie.o qtnfmac_pearl_pcie-objs += \ shm_ipc.o \ - pearl/pcie.o + pcie/pearl_pcie.o qtnfmac_pearl_pcie-$(CONFIG_DEBUG_FS) += debug.o diff --git a/drivers/net/wireless/quantenna/qtnfmac/pearl/pcie.c b/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie.c similarity index 99% rename from drivers/net/wireless/quantenna/qtnfmac/pearl/pcie.c rename to drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie.c index 97cc7f2b6dd3..269a6e4589e9 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/pearl/pcie.c +++ b/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie.c @@ -29,7 +29,7 @@ #include #include "qtn_hw_ids.h" -#include "pcie_bus_priv.h" +#include "pearl_pcie_bus_priv.h" #include "core.h" #include "bus.h" #include "debug.h" diff --git a/drivers/net/wireless/quantenna/qtnfmac/pearl/pcie_bus_priv.h b/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie_bus_priv.h similarity index 97% rename from drivers/net/wireless/quantenna/qtnfmac/pearl/pcie_bus_priv.h rename to drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie_bus_priv.h index 397875a50fc2..986b95736321 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/pearl/pcie_bus_priv.h +++ b/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie_bus_priv.h @@ -20,8 +20,8 @@ #include #include -#include "pcie_regs_pearl.h" -#include "pcie_ipc.h" +#include "pearl_pcie_regs.h" +#include "pearl_pcie_ipc.h" #include "shm_ipc.h" struct bus; diff --git a/drivers/net/wireless/quantenna/qtnfmac/pearl/pcie_ipc.h b/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie_ipc.h similarity index 100% rename from drivers/net/wireless/quantenna/qtnfmac/pearl/pcie_ipc.h rename to drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie_ipc.h diff --git a/drivers/net/wireless/quantenna/qtnfmac/pearl/pcie_regs_pearl.h b/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie_regs.h similarity index 100% rename from drivers/net/wireless/quantenna/qtnfmac/pearl/pcie_regs_pearl.h rename to drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie_regs.h From 91dcecece019903cdddb719b909e648803222545 Mon Sep 17 00:00:00 2001 From: Igor Mitsyanko Date: Mon, 24 Sep 2018 15:15:06 -0700 Subject: [PATCH 267/276] qtnfmac_pcie: rename private Pearl PCIe state structure In preparation to extract common pcie driver state into a separate structure, rename Pearl-specific state to qtnf_pcie_pearl_state and move it directly to pearl-specific PCIe source file. Signed-off-by: Igor Mitsyanko Signed-off-by: Kalle Valo --- .../quantenna/qtnfmac/pcie/pearl_pcie.c | 158 ++++++++++++------ .../qtnfmac/pcie/pearl_pcie_bus_priv.h | 91 ---------- 2 files changed, 111 insertions(+), 138 deletions(-) delete mode 100644 drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie_bus_priv.h diff --git a/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie.c b/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie.c index 269a6e4589e9..ab06eca63202 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie.c +++ b/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie.c @@ -28,10 +28,12 @@ #include #include +#include "pearl_pcie_regs.h" +#include "pearl_pcie_ipc.h" #include "qtn_hw_ids.h" -#include "pearl_pcie_bus_priv.h" #include "core.h" #include "bus.h" +#include "shm_ipc.h" #include "debug.h" static bool use_msi = true; @@ -52,6 +54,68 @@ MODULE_PARM_DESC(flashboot, "set to 0 to use FW binary file on FS"); #define DRV_NAME "qtnfmac_pearl_pcie" +struct qtnf_pcie_pearl_state { + struct pci_dev *pdev; + + /* lock for irq configuration changes */ + spinlock_t irq_lock; + + /* lock for tx reclaim operations */ + spinlock_t tx_reclaim_lock; + /* lock for tx0 operations */ + spinlock_t tx0_lock; + u8 msi_enabled; + u8 tx_stopped; + int mps; + + struct workqueue_struct *workqueue; + struct tasklet_struct reclaim_tq; + + void __iomem *sysctl_bar; + void __iomem *epmem_bar; + void __iomem *dmareg_bar; + + struct qtnf_shm_ipc shm_ipc_ep_in; + struct qtnf_shm_ipc shm_ipc_ep_out; + + struct qtnf_pcie_bda __iomem *bda; + void __iomem *pcie_reg_base; + + u16 tx_bd_num; + u16 rx_bd_num; + + struct sk_buff **tx_skb; + struct sk_buff **rx_skb; + + struct qtnf_tx_bd *tx_bd_vbase; + dma_addr_t tx_bd_pbase; + + struct qtnf_rx_bd *rx_bd_vbase; + dma_addr_t rx_bd_pbase; + + dma_addr_t bd_table_paddr; + void *bd_table_vaddr; + u32 bd_table_len; + + u32 rx_bd_w_index; + u32 rx_bd_r_index; + + u32 tx_bd_w_index; + u32 tx_bd_r_index; + + u32 pcie_irq_mask; + + /* diagnostics stats */ + u32 pcie_irq_count; + u32 pcie_irq_rx_count; + u32 pcie_irq_tx_count; + u32 pcie_irq_uf_count; + u32 tx_full_count; + u32 tx_done_count; + u32 tx_reclaim_done; + u32 tx_reclaim_req; +}; + static inline void qtnf_non_posted_write(u32 val, void __iomem *basereg) { writel(val, basereg); @@ -60,7 +124,7 @@ static inline void qtnf_non_posted_write(u32 val, void __iomem *basereg) readl(basereg); } -static inline void qtnf_init_hdp_irqs(struct qtnf_pcie_bus_priv *priv) +static inline void qtnf_init_hdp_irqs(struct qtnf_pcie_pearl_state *priv) { unsigned long flags; @@ -69,7 +133,7 @@ static inline void qtnf_init_hdp_irqs(struct qtnf_pcie_bus_priv *priv) spin_unlock_irqrestore(&priv->irq_lock, flags); } -static inline void qtnf_enable_hdp_irqs(struct qtnf_pcie_bus_priv *priv) +static inline void qtnf_enable_hdp_irqs(struct qtnf_pcie_pearl_state *priv) { unsigned long flags; @@ -78,7 +142,7 @@ static inline void qtnf_enable_hdp_irqs(struct qtnf_pcie_bus_priv *priv) spin_unlock_irqrestore(&priv->irq_lock, flags); } -static inline void qtnf_disable_hdp_irqs(struct qtnf_pcie_bus_priv *priv) +static inline void qtnf_disable_hdp_irqs(struct qtnf_pcie_pearl_state *priv) { unsigned long flags; @@ -87,7 +151,7 @@ static inline void qtnf_disable_hdp_irqs(struct qtnf_pcie_bus_priv *priv) spin_unlock_irqrestore(&priv->irq_lock, flags); } -static inline void qtnf_en_rxdone_irq(struct qtnf_pcie_bus_priv *priv) +static inline void qtnf_en_rxdone_irq(struct qtnf_pcie_pearl_state *priv) { unsigned long flags; @@ -97,7 +161,7 @@ static inline void qtnf_en_rxdone_irq(struct qtnf_pcie_bus_priv *priv) spin_unlock_irqrestore(&priv->irq_lock, flags); } -static inline void qtnf_dis_rxdone_irq(struct qtnf_pcie_bus_priv *priv) +static inline void qtnf_dis_rxdone_irq(struct qtnf_pcie_pearl_state *priv) { unsigned long flags; @@ -107,7 +171,7 @@ static inline void qtnf_dis_rxdone_irq(struct qtnf_pcie_bus_priv *priv) spin_unlock_irqrestore(&priv->irq_lock, flags); } -static inline void qtnf_en_txdone_irq(struct qtnf_pcie_bus_priv *priv) +static inline void qtnf_en_txdone_irq(struct qtnf_pcie_pearl_state *priv) { unsigned long flags; @@ -117,7 +181,7 @@ static inline void qtnf_en_txdone_irq(struct qtnf_pcie_bus_priv *priv) spin_unlock_irqrestore(&priv->irq_lock, flags); } -static inline void qtnf_dis_txdone_irq(struct qtnf_pcie_bus_priv *priv) +static inline void qtnf_dis_txdone_irq(struct qtnf_pcie_pearl_state *priv) { unsigned long flags; @@ -127,7 +191,7 @@ static inline void qtnf_dis_txdone_irq(struct qtnf_pcie_bus_priv *priv) spin_unlock_irqrestore(&priv->irq_lock, flags); } -static void qtnf_pcie_init_irq(struct qtnf_pcie_bus_priv *priv) +static void qtnf_pcie_init_irq(struct qtnf_pcie_pearl_state *priv) { struct pci_dev *pdev = priv->pdev; @@ -150,7 +214,7 @@ static void qtnf_pcie_init_irq(struct qtnf_pcie_bus_priv *priv) } } -static void qtnf_deassert_intx(struct qtnf_pcie_bus_priv *priv) +static void qtnf_deassert_intx(struct qtnf_pcie_pearl_state *priv) { void __iomem *reg = priv->sysctl_bar + PEARL_PCIE_CFG0_OFFSET; u32 cfg; @@ -160,7 +224,7 @@ static void qtnf_deassert_intx(struct qtnf_pcie_bus_priv *priv) qtnf_non_posted_write(cfg, reg); } -static void qtnf_reset_card(struct qtnf_pcie_bus_priv *priv) +static void qtnf_reset_card(struct qtnf_pcie_pearl_state *priv) { const u32 data = QTN_PEARL_IPC_IRQ_WORD(QTN_PEARL_LHOST_EP_RESET); void __iomem *reg = priv->sysctl_bar + @@ -173,7 +237,7 @@ static void qtnf_reset_card(struct qtnf_pcie_bus_priv *priv) static void qtnf_ipc_gen_ep_int(void *arg) { - const struct qtnf_pcie_bus_priv *priv = arg; + const struct qtnf_pcie_pearl_state *priv = arg; const u32 data = QTN_PEARL_IPC_IRQ_WORD(QTN_PEARL_LHOST_IPC_IRQ); void __iomem *reg = priv->sysctl_bar + QTN_PEARL_SYSCTL_LHOST_IRQ_OFFSET; @@ -181,7 +245,7 @@ static void qtnf_ipc_gen_ep_int(void *arg) qtnf_non_posted_write(data, reg); } -static void __iomem *qtnf_map_bar(struct qtnf_pcie_bus_priv *priv, u8 index) +static void __iomem *qtnf_map_bar(struct qtnf_pcie_pearl_state *priv, u8 index) { void __iomem *vaddr; dma_addr_t busaddr; @@ -206,7 +270,7 @@ static void __iomem *qtnf_map_bar(struct qtnf_pcie_bus_priv *priv, u8 index) static void qtnf_pcie_control_rx_callback(void *arg, const u8 *buf, size_t len) { - struct qtnf_pcie_bus_priv *priv = arg; + struct qtnf_pcie_pearl_state *priv = arg; struct qtnf_bus *bus = pci_get_drvdata(priv->pdev); struct sk_buff *skb; @@ -227,7 +291,7 @@ static void qtnf_pcie_control_rx_callback(void *arg, const u8 *buf, size_t len) qtnf_trans_handle_rx_ctl_packet(bus, skb); } -static int qtnf_pcie_init_shm_ipc(struct qtnf_pcie_bus_priv *priv) +static int qtnf_pcie_init_shm_ipc(struct qtnf_pcie_pearl_state *priv) { struct qtnf_shm_ipc_region __iomem *ipc_tx_reg; struct qtnf_shm_ipc_region __iomem *ipc_rx_reg; @@ -248,13 +312,13 @@ static int qtnf_pcie_init_shm_ipc(struct qtnf_pcie_bus_priv *priv) return 0; } -static void qtnf_pcie_free_shm_ipc(struct qtnf_pcie_bus_priv *priv) +static void qtnf_pcie_free_shm_ipc(struct qtnf_pcie_pearl_state *priv) { qtnf_shm_ipc_free(&priv->shm_ipc_ep_in); qtnf_shm_ipc_free(&priv->shm_ipc_ep_out); } -static int qtnf_pcie_init_memory(struct qtnf_pcie_bus_priv *priv) +static int qtnf_pcie_init_memory(struct qtnf_pcie_pearl_state *priv) { int ret = -ENOMEM; @@ -283,7 +347,7 @@ static int qtnf_pcie_init_memory(struct qtnf_pcie_bus_priv *priv) return 0; } -static void qtnf_tune_pcie_mps(struct qtnf_pcie_bus_priv *priv) +static void qtnf_tune_pcie_mps(struct qtnf_pcie_pearl_state *priv) { struct pci_dev *pdev = priv->pdev; struct pci_dev *parent; @@ -355,7 +419,7 @@ static int qtnf_poll_state(__le32 __iomem *reg, u32 state, u32 delay_in_ms) return 0; } -static int alloc_skb_array(struct qtnf_pcie_bus_priv *priv) +static int alloc_skb_array(struct qtnf_pcie_pearl_state *priv) { struct sk_buff **vaddr; int len; @@ -375,7 +439,7 @@ static int alloc_skb_array(struct qtnf_pcie_bus_priv *priv) return 0; } -static int alloc_bd_table(struct qtnf_pcie_bus_priv *priv) +static int alloc_bd_table(struct qtnf_pcie_pearl_state *priv) { dma_addr_t paddr; void *vaddr; @@ -426,7 +490,7 @@ static int alloc_bd_table(struct qtnf_pcie_bus_priv *priv) return 0; } -static int skb2rbd_attach(struct qtnf_pcie_bus_priv *priv, u16 index) +static int skb2rbd_attach(struct qtnf_pcie_pearl_state *priv, u16 index) { struct qtnf_rx_bd *rxbd; struct sk_buff *skb; @@ -469,7 +533,7 @@ static int skb2rbd_attach(struct qtnf_pcie_bus_priv *priv, u16 index) return 0; } -static int alloc_rx_buffers(struct qtnf_pcie_bus_priv *priv) +static int alloc_rx_buffers(struct qtnf_pcie_pearl_state *priv) { u16 i; int ret = 0; @@ -487,7 +551,7 @@ static int alloc_rx_buffers(struct qtnf_pcie_bus_priv *priv) } /* all rx/tx activity should have ceased before calling this function */ -static void qtnf_free_xfer_buffers(struct qtnf_pcie_bus_priv *priv) +static void qtnf_free_xfer_buffers(struct qtnf_pcie_pearl_state *priv) { struct qtnf_tx_bd *txbd; struct qtnf_rx_bd *rxbd; @@ -524,7 +588,7 @@ static void qtnf_free_xfer_buffers(struct qtnf_pcie_bus_priv *priv) } } -static int qtnf_hhbm_init(struct qtnf_pcie_bus_priv *priv) +static int qtnf_hhbm_init(struct qtnf_pcie_pearl_state *priv) { u32 val; @@ -542,7 +606,7 @@ static int qtnf_hhbm_init(struct qtnf_pcie_bus_priv *priv) return 0; } -static int qtnf_pcie_init_xfer(struct qtnf_pcie_bus_priv *priv) +static int qtnf_pcie_init_xfer(struct qtnf_pcie_pearl_state *priv) { int ret; u32 val; @@ -605,7 +669,7 @@ static int qtnf_pcie_init_xfer(struct qtnf_pcie_bus_priv *priv) return ret; } -static void qtnf_pcie_data_tx_reclaim(struct qtnf_pcie_bus_priv *priv) +static void qtnf_pcie_data_tx_reclaim(struct qtnf_pcie_pearl_state *priv) { struct qtnf_tx_bd *txbd; struct sk_buff *skb; @@ -656,7 +720,7 @@ static void qtnf_pcie_data_tx_reclaim(struct qtnf_pcie_bus_priv *priv) spin_unlock_irqrestore(&priv->tx_reclaim_lock, flags); } -static int qtnf_tx_queue_ready(struct qtnf_pcie_bus_priv *priv) +static int qtnf_tx_queue_ready(struct qtnf_pcie_pearl_state *priv) { if (!CIRC_SPACE(priv->tx_bd_w_index, priv->tx_bd_r_index, priv->tx_bd_num)) { @@ -675,7 +739,7 @@ static int qtnf_tx_queue_ready(struct qtnf_pcie_bus_priv *priv) static int qtnf_pcie_data_tx(struct qtnf_bus *bus, struct sk_buff *skb) { - struct qtnf_pcie_bus_priv *priv = (void *)get_bus_priv(bus); + struct qtnf_pcie_pearl_state *priv = (void *)get_bus_priv(bus); dma_addr_t txbd_paddr, skb_paddr; struct qtnf_tx_bd *txbd; unsigned long flags; @@ -750,7 +814,7 @@ static int qtnf_pcie_data_tx(struct qtnf_bus *bus, struct sk_buff *skb) static int qtnf_pcie_control_tx(struct qtnf_bus *bus, struct sk_buff *skb) { - struct qtnf_pcie_bus_priv *priv = (void *)get_bus_priv(bus); + struct qtnf_pcie_pearl_state *priv = (void *)get_bus_priv(bus); int ret; ret = qtnf_shm_ipc_send(&priv->shm_ipc_ep_in, skb->data, skb->len); @@ -766,7 +830,7 @@ static int qtnf_pcie_control_tx(struct qtnf_bus *bus, struct sk_buff *skb) static irqreturn_t qtnf_interrupt(int irq, void *data) { struct qtnf_bus *bus = (struct qtnf_bus *)data; - struct qtnf_pcie_bus_priv *priv = (void *)get_bus_priv(bus); + struct qtnf_pcie_pearl_state *priv = (void *)get_bus_priv(bus); u32 status; priv->pcie_irq_count++; @@ -807,7 +871,7 @@ static irqreturn_t qtnf_interrupt(int irq, void *data) return IRQ_HANDLED; } -static int qtnf_rx_data_ready(struct qtnf_pcie_bus_priv *priv) +static int qtnf_rx_data_ready(struct qtnf_pcie_pearl_state *priv) { u16 index = priv->rx_bd_r_index; struct qtnf_rx_bd *rxbd; @@ -825,7 +889,7 @@ static int qtnf_rx_data_ready(struct qtnf_pcie_bus_priv *priv) static int qtnf_rx_poll(struct napi_struct *napi, int budget) { struct qtnf_bus *bus = container_of(napi, struct qtnf_bus, mux_napi); - struct qtnf_pcie_bus_priv *priv = (void *)get_bus_priv(bus); + struct qtnf_pcie_pearl_state *priv = (void *)get_bus_priv(bus); struct net_device *ndev = NULL; struct sk_buff *skb = NULL; int processed = 0; @@ -930,14 +994,14 @@ static int qtnf_rx_poll(struct napi_struct *napi, int budget) static void qtnf_pcie_data_tx_timeout(struct qtnf_bus *bus, struct net_device *ndev) { - struct qtnf_pcie_bus_priv *priv = (void *)get_bus_priv(bus); + struct qtnf_pcie_pearl_state *priv = (void *)get_bus_priv(bus); tasklet_hi_schedule(&priv->reclaim_tq); } static void qtnf_pcie_data_rx_start(struct qtnf_bus *bus) { - struct qtnf_pcie_bus_priv *priv = (void *)get_bus_priv(bus); + struct qtnf_pcie_pearl_state *priv = (void *)get_bus_priv(bus); qtnf_enable_hdp_irqs(priv); napi_enable(&bus->mux_napi); @@ -945,7 +1009,7 @@ static void qtnf_pcie_data_rx_start(struct qtnf_bus *bus) static void qtnf_pcie_data_rx_stop(struct qtnf_bus *bus) { - struct qtnf_pcie_bus_priv *priv = (void *)get_bus_priv(bus); + struct qtnf_pcie_pearl_state *priv = (void *)get_bus_priv(bus); napi_disable(&bus->mux_napi); qtnf_disable_hdp_irqs(priv); @@ -965,7 +1029,7 @@ static const struct qtnf_bus_ops qtnf_pcie_bus_ops = { static int qtnf_dbg_mps_show(struct seq_file *s, void *data) { struct qtnf_bus *bus = dev_get_drvdata(s->private); - struct qtnf_pcie_bus_priv *priv = get_bus_priv(bus); + struct qtnf_pcie_pearl_state *priv = get_bus_priv(bus); seq_printf(s, "%d\n", priv->mps); @@ -975,7 +1039,7 @@ static int qtnf_dbg_mps_show(struct seq_file *s, void *data) static int qtnf_dbg_msi_show(struct seq_file *s, void *data) { struct qtnf_bus *bus = dev_get_drvdata(s->private); - struct qtnf_pcie_bus_priv *priv = get_bus_priv(bus); + struct qtnf_pcie_pearl_state *priv = get_bus_priv(bus); seq_printf(s, "%u\n", priv->msi_enabled); @@ -985,7 +1049,7 @@ static int qtnf_dbg_msi_show(struct seq_file *s, void *data) static int qtnf_dbg_irq_stats(struct seq_file *s, void *data) { struct qtnf_bus *bus = dev_get_drvdata(s->private); - struct qtnf_pcie_bus_priv *priv = get_bus_priv(bus); + struct qtnf_pcie_pearl_state *priv = get_bus_priv(bus); u32 reg = readl(PCIE_HDP_INT_EN(priv->pcie_reg_base)); u32 status; @@ -1009,7 +1073,7 @@ static int qtnf_dbg_irq_stats(struct seq_file *s, void *data) static int qtnf_dbg_hdp_stats(struct seq_file *s, void *data) { struct qtnf_bus *bus = dev_get_drvdata(s->private); - struct qtnf_pcie_bus_priv *priv = get_bus_priv(bus); + struct qtnf_pcie_pearl_state *priv = get_bus_priv(bus); seq_printf(s, "tx_full_count(%u)\n", priv->tx_full_count); seq_printf(s, "tx_done_count(%u)\n", priv->tx_done_count); @@ -1040,7 +1104,7 @@ static int qtnf_dbg_hdp_stats(struct seq_file *s, void *data) static int qtnf_dbg_shm_stats(struct seq_file *s, void *data) { struct qtnf_bus *bus = dev_get_drvdata(s->private); - struct qtnf_pcie_bus_priv *priv = get_bus_priv(bus); + struct qtnf_pcie_pearl_state *priv = get_bus_priv(bus); seq_printf(s, "shm_ipc_ep_in.tx_packet_count(%zu)\n", priv->shm_ipc_ep_in.tx_packet_count); @@ -1054,7 +1118,7 @@ static int qtnf_dbg_shm_stats(struct seq_file *s, void *data) return 0; } -static int qtnf_ep_fw_send(struct qtnf_pcie_bus_priv *priv, uint32_t size, +static int qtnf_ep_fw_send(struct qtnf_pcie_pearl_state *priv, uint32_t size, int blk, const u8 *pblk, const u8 *fw) { struct pci_dev *pdev = priv->pdev; @@ -1103,7 +1167,7 @@ static int qtnf_ep_fw_send(struct qtnf_pcie_bus_priv *priv, uint32_t size, } static int -qtnf_ep_fw_load(struct qtnf_pcie_bus_priv *priv, const u8 *fw, u32 fw_size) +qtnf_ep_fw_load(struct qtnf_pcie_pearl_state *priv, const u8 *fw, u32 fw_size) { int blk_size = QTN_PCIE_FW_BUFSZ - sizeof(struct qtnf_pcie_fw_hdr); int blk_count = fw_size / blk_size + ((fw_size % blk_size) ? 1 : 0); @@ -1172,7 +1236,7 @@ qtnf_ep_fw_load(struct qtnf_pcie_bus_priv *priv, const u8 *fw, u32 fw_size) static void qtnf_fw_work_handler(struct work_struct *work) { struct qtnf_bus *bus = container_of(work, struct qtnf_bus, fw_work); - struct qtnf_pcie_bus_priv *priv = (void *)get_bus_priv(bus); + struct qtnf_pcie_pearl_state *priv = (void *)get_bus_priv(bus); struct pci_dev *pdev = priv->pdev; const struct firmware *fw; int ret; @@ -1256,7 +1320,7 @@ static void qtnf_fw_work_handler(struct work_struct *work) static void qtnf_bringup_fw_async(struct qtnf_bus *bus) { - struct qtnf_pcie_bus_priv *priv = (void *)get_bus_priv(bus); + struct qtnf_pcie_pearl_state *priv = (void *)get_bus_priv(bus); struct pci_dev *pdev = priv->pdev; get_device(&pdev->dev); @@ -1266,7 +1330,7 @@ static void qtnf_bringup_fw_async(struct qtnf_bus *bus) static void qtnf_reclaim_tasklet_fn(unsigned long data) { - struct qtnf_pcie_bus_priv *priv = (void *)data; + struct qtnf_pcie_pearl_state *priv = (void *)data; qtnf_pcie_data_tx_reclaim(priv); qtnf_en_txdone_irq(priv); @@ -1274,7 +1338,7 @@ static void qtnf_reclaim_tasklet_fn(unsigned long data) static int qtnf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) { - struct qtnf_pcie_bus_priv *pcie_priv; + struct qtnf_pcie_pearl_state *pcie_priv; struct qtnf_bus *bus; int ret; @@ -1407,7 +1471,7 @@ static int qtnf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) static void qtnf_pcie_remove(struct pci_dev *pdev) { - struct qtnf_pcie_bus_priv *priv; + struct qtnf_pcie_pearl_state *priv; struct qtnf_bus *bus; bus = pci_get_drvdata(pdev); diff --git a/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie_bus_priv.h b/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie_bus_priv.h deleted file mode 100644 index 986b95736321..000000000000 --- a/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie_bus_priv.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2015-2016 Quantenna Communications, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef _QTN_FMAC_PCIE_H_ -#define _QTN_FMAC_PCIE_H_ - -#include -#include - -#include "pearl_pcie_regs.h" -#include "pearl_pcie_ipc.h" -#include "shm_ipc.h" - -struct bus; - -struct qtnf_pcie_bus_priv { - struct pci_dev *pdev; - - /* lock for irq configuration changes */ - spinlock_t irq_lock; - - /* lock for tx reclaim operations */ - spinlock_t tx_reclaim_lock; - /* lock for tx0 operations */ - spinlock_t tx0_lock; - u8 msi_enabled; - u8 tx_stopped; - int mps; - - struct workqueue_struct *workqueue; - struct tasklet_struct reclaim_tq; - - void __iomem *sysctl_bar; - void __iomem *epmem_bar; - void __iomem *dmareg_bar; - - struct qtnf_shm_ipc shm_ipc_ep_in; - struct qtnf_shm_ipc shm_ipc_ep_out; - - struct qtnf_pcie_bda __iomem *bda; - void __iomem *pcie_reg_base; - - u16 tx_bd_num; - u16 rx_bd_num; - - struct sk_buff **tx_skb; - struct sk_buff **rx_skb; - - struct qtnf_tx_bd *tx_bd_vbase; - dma_addr_t tx_bd_pbase; - - struct qtnf_rx_bd *rx_bd_vbase; - dma_addr_t rx_bd_pbase; - - dma_addr_t bd_table_paddr; - void *bd_table_vaddr; - u32 bd_table_len; - - u32 rx_bd_w_index; - u32 rx_bd_r_index; - - u32 tx_bd_w_index; - u32 tx_bd_r_index; - - u32 pcie_irq_mask; - - /* diagnostics stats */ - u32 pcie_irq_count; - u32 pcie_irq_rx_count; - u32 pcie_irq_tx_count; - u32 pcie_irq_uf_count; - u32 tx_full_count; - u32 tx_done_count; - u32 tx_reclaim_done; - u32 tx_reclaim_req; -}; - -#endif /* _QTN_FMAC_PCIE_H_ */ From d0b95bfa11786e14011c1159d93b82db931f9c7c Mon Sep 17 00:00:00 2001 From: Igor Mitsyanko Date: Mon, 24 Sep 2018 15:15:07 -0700 Subject: [PATCH 268/276] qtnfmac_pcie: indicate pearl-specific structures by their names In preparation to extract common PCIe driver state, indicate PEARL-specific structures by their name and move them to pearl-specific source file. Signed-off-by: Igor Mitsyanko Signed-off-by: Kalle Valo --- .../quantenna/qtnfmac/pcie/pearl_pcie.c | 89 ++++++++++++++----- .../quantenna/qtnfmac/pcie/pearl_pcie_ipc.h | 47 ---------- 2 files changed, 68 insertions(+), 68 deletions(-) diff --git a/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie.c b/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie.c index ab06eca63202..4e9eb46ea8cb 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie.c +++ b/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie.c @@ -54,6 +54,53 @@ MODULE_PARM_DESC(flashboot, "set to 0 to use FW binary file on FS"); #define DRV_NAME "qtnfmac_pearl_pcie" +struct qtnf_pearl_bda { + __le16 bda_len; + __le16 bda_version; + __le32 bda_pci_endian; + __le32 bda_ep_state; + __le32 bda_rc_state; + __le32 bda_dma_mask; + __le32 bda_msi_addr; + __le32 bda_flashsz; + u8 bda_boardname[PCIE_BDA_NAMELEN]; + __le32 bda_rc_msi_enabled; + u8 bda_hhbm_list[PCIE_HHBM_MAX_SIZE]; + __le32 bda_dsbw_start_index; + __le32 bda_dsbw_end_index; + __le32 bda_dsbw_total_bytes; + __le32 bda_rc_tx_bd_base; + __le32 bda_rc_tx_bd_num; + u8 bda_pcie_mac[QTN_ENET_ADDR_LENGTH]; + struct qtnf_shm_ipc_region bda_shm_reg1 __aligned(4096); /* host TX */ + struct qtnf_shm_ipc_region bda_shm_reg2 __aligned(4096); /* host RX */ +} __packed; + +struct qtnf_pearl_tx_bd { + __le32 addr; + __le32 addr_h; + __le32 info; + __le32 info_h; +} __packed; + +struct qtnf_pearl_rx_bd { + __le32 addr; + __le32 addr_h; + __le32 info; + __le32 info_h; + __le32 next_ptr; + __le32 next_ptr_h; +} __packed; + +struct qtnf_pearl_fw_hdr { + u8 boardflg[8]; + __le32 fwsize; + __le32 seqnum; + __le32 type; + __le32 pktlen; + __le32 crc; +} __packed; + struct qtnf_pcie_pearl_state { struct pci_dev *pdev; @@ -78,7 +125,7 @@ struct qtnf_pcie_pearl_state { struct qtnf_shm_ipc shm_ipc_ep_in; struct qtnf_shm_ipc shm_ipc_ep_out; - struct qtnf_pcie_bda __iomem *bda; + struct qtnf_pearl_bda __iomem *bda; void __iomem *pcie_reg_base; u16 tx_bd_num; @@ -87,10 +134,10 @@ struct qtnf_pcie_pearl_state { struct sk_buff **tx_skb; struct sk_buff **rx_skb; - struct qtnf_tx_bd *tx_bd_vbase; + struct qtnf_pearl_tx_bd *tx_bd_vbase; dma_addr_t tx_bd_pbase; - struct qtnf_rx_bd *rx_bd_vbase; + struct qtnf_pearl_rx_bd *rx_bd_vbase; dma_addr_t rx_bd_pbase; dma_addr_t bd_table_paddr; @@ -445,8 +492,8 @@ static int alloc_bd_table(struct qtnf_pcie_pearl_state *priv) void *vaddr; int len; - len = priv->tx_bd_num * sizeof(struct qtnf_tx_bd) + - priv->rx_bd_num * sizeof(struct qtnf_rx_bd); + len = priv->tx_bd_num * sizeof(struct qtnf_pearl_tx_bd) + + priv->rx_bd_num * sizeof(struct qtnf_pearl_rx_bd); vaddr = dmam_alloc_coherent(&priv->pdev->dev, len, &paddr, GFP_KERNEL); if (!vaddr) @@ -470,8 +517,8 @@ static int alloc_bd_table(struct qtnf_pcie_pearl_state *priv) /* rx bd */ - vaddr = ((struct qtnf_tx_bd *)vaddr) + priv->tx_bd_num; - paddr += priv->tx_bd_num * sizeof(struct qtnf_tx_bd); + vaddr = ((struct qtnf_pearl_tx_bd *)vaddr) + priv->tx_bd_num; + paddr += priv->tx_bd_num * sizeof(struct qtnf_pearl_tx_bd); priv->rx_bd_vbase = vaddr; priv->rx_bd_pbase = paddr; @@ -482,7 +529,7 @@ static int alloc_bd_table(struct qtnf_pcie_pearl_state *priv) #endif writel(QTN_HOST_LO32(paddr), PCIE_HDP_TX_HOST_Q_BASE_L(priv->pcie_reg_base)); - writel(priv->rx_bd_num | (sizeof(struct qtnf_rx_bd)) << 16, + writel(priv->rx_bd_num | (sizeof(struct qtnf_pearl_rx_bd)) << 16, PCIE_HDP_TX_HOST_Q_SZ_CTRL(priv->pcie_reg_base)); pr_debug("RX descriptor table: vaddr=0x%p paddr=%pad\n", vaddr, &paddr); @@ -492,7 +539,7 @@ static int alloc_bd_table(struct qtnf_pcie_pearl_state *priv) static int skb2rbd_attach(struct qtnf_pcie_pearl_state *priv, u16 index) { - struct qtnf_rx_bd *rxbd; + struct qtnf_pearl_rx_bd *rxbd; struct sk_buff *skb; dma_addr_t paddr; @@ -539,7 +586,7 @@ static int alloc_rx_buffers(struct qtnf_pcie_pearl_state *priv) int ret = 0; memset(priv->rx_bd_vbase, 0x0, - priv->rx_bd_num * sizeof(struct qtnf_rx_bd)); + priv->rx_bd_num * sizeof(struct qtnf_pearl_rx_bd)); for (i = 0; i < priv->rx_bd_num; i++) { ret = skb2rbd_attach(priv, i); @@ -553,8 +600,8 @@ static int alloc_rx_buffers(struct qtnf_pcie_pearl_state *priv) /* all rx/tx activity should have ceased before calling this function */ static void qtnf_free_xfer_buffers(struct qtnf_pcie_pearl_state *priv) { - struct qtnf_tx_bd *txbd; - struct qtnf_rx_bd *rxbd; + struct qtnf_pearl_tx_bd *txbd; + struct qtnf_pearl_rx_bd *rxbd; struct sk_buff *skb; dma_addr_t paddr; int i; @@ -622,7 +669,7 @@ static int qtnf_pcie_init_xfer(struct qtnf_pcie_pearl_state *priv) return -EINVAL; } - val = priv->tx_bd_num * sizeof(struct qtnf_tx_bd); + val = priv->tx_bd_num * sizeof(struct qtnf_pearl_tx_bd); if (val > PCIE_HHBM_MAX_SIZE) { pr_err("tx_bd_size_param %u is too large\n", priv->tx_bd_num); @@ -671,7 +718,7 @@ static int qtnf_pcie_init_xfer(struct qtnf_pcie_pearl_state *priv) static void qtnf_pcie_data_tx_reclaim(struct qtnf_pcie_pearl_state *priv) { - struct qtnf_tx_bd *txbd; + struct qtnf_pearl_tx_bd *txbd; struct sk_buff *skb; unsigned long flags; dma_addr_t paddr; @@ -741,7 +788,7 @@ static int qtnf_pcie_data_tx(struct qtnf_bus *bus, struct sk_buff *skb) { struct qtnf_pcie_pearl_state *priv = (void *)get_bus_priv(bus); dma_addr_t txbd_paddr, skb_paddr; - struct qtnf_tx_bd *txbd; + struct qtnf_pearl_tx_bd *txbd; unsigned long flags; int len, i; u32 info; @@ -782,7 +829,7 @@ static int qtnf_pcie_data_tx(struct qtnf_bus *bus, struct sk_buff *skb) dma_wmb(); /* write new TX descriptor to PCIE_RX_FIFO on EP */ - txbd_paddr = priv->tx_bd_pbase + i * sizeof(struct qtnf_tx_bd); + txbd_paddr = priv->tx_bd_pbase + i * sizeof(struct qtnf_pearl_tx_bd); #ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT writel(QTN_HOST_HI32(txbd_paddr), @@ -874,7 +921,7 @@ static irqreturn_t qtnf_interrupt(int irq, void *data) static int qtnf_rx_data_ready(struct qtnf_pcie_pearl_state *priv) { u16 index = priv->rx_bd_r_index; - struct qtnf_rx_bd *rxbd; + struct qtnf_pearl_rx_bd *rxbd; u32 descw; rxbd = &priv->rx_bd_vbase[index]; @@ -893,7 +940,7 @@ static int qtnf_rx_poll(struct napi_struct *napi, int budget) struct net_device *ndev = NULL; struct sk_buff *skb = NULL; int processed = 0; - struct qtnf_rx_bd *rxbd; + struct qtnf_pearl_rx_bd *rxbd; dma_addr_t skb_paddr; int consume; u32 descw; @@ -1124,7 +1171,7 @@ static int qtnf_ep_fw_send(struct qtnf_pcie_pearl_state *priv, uint32_t size, struct pci_dev *pdev = priv->pdev; struct qtnf_bus *bus = pci_get_drvdata(pdev); - struct qtnf_pcie_fw_hdr *hdr; + struct qtnf_pearl_fw_hdr *hdr; u8 *pdata; int hds = sizeof(*hdr); @@ -1139,7 +1186,7 @@ static int qtnf_ep_fw_send(struct qtnf_pcie_pearl_state *priv, uint32_t size, skb->len = QTN_PCIE_FW_BUFSZ; skb->dev = NULL; - hdr = (struct qtnf_pcie_fw_hdr *)skb->data; + hdr = (struct qtnf_pearl_fw_hdr *)skb->data; memcpy(hdr->boardflg, QTN_PCIE_BOARDFLG, strlen(QTN_PCIE_BOARDFLG)); hdr->fwsize = cpu_to_le32(size); hdr->seqnum = cpu_to_le32(blk); @@ -1169,7 +1216,7 @@ static int qtnf_ep_fw_send(struct qtnf_pcie_pearl_state *priv, uint32_t size, static int qtnf_ep_fw_load(struct qtnf_pcie_pearl_state *priv, const u8 *fw, u32 fw_size) { - int blk_size = QTN_PCIE_FW_BUFSZ - sizeof(struct qtnf_pcie_fw_hdr); + int blk_size = QTN_PCIE_FW_BUFSZ - sizeof(struct qtnf_pearl_fw_hdr); int blk_count = fw_size / blk_size + ((fw_size % blk_size) ? 1 : 0); const u8 *pblk = fw; int threshold = 0; diff --git a/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie_ipc.h b/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie_ipc.h index 00bb21a1c47a..af528b81e87d 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie_ipc.h +++ b/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie_ipc.h @@ -101,44 +101,6 @@ enum qtnf_pcie_bda_ipc_flags { QTN_PCIE_IPC_FLAG_SHM_PIO = BIT(1), }; -struct qtnf_pcie_bda { - __le16 bda_len; - __le16 bda_version; - __le32 bda_pci_endian; - __le32 bda_ep_state; - __le32 bda_rc_state; - __le32 bda_dma_mask; - __le32 bda_msi_addr; - __le32 bda_flashsz; - u8 bda_boardname[PCIE_BDA_NAMELEN]; - __le32 bda_rc_msi_enabled; - u8 bda_hhbm_list[PCIE_HHBM_MAX_SIZE]; - __le32 bda_dsbw_start_index; - __le32 bda_dsbw_end_index; - __le32 bda_dsbw_total_bytes; - __le32 bda_rc_tx_bd_base; - __le32 bda_rc_tx_bd_num; - u8 bda_pcie_mac[QTN_ENET_ADDR_LENGTH]; - struct qtnf_shm_ipc_region bda_shm_reg1 __aligned(4096); /* host TX */ - struct qtnf_shm_ipc_region bda_shm_reg2 __aligned(4096); /* host RX */ -} __packed; - -struct qtnf_tx_bd { - __le32 addr; - __le32 addr_h; - __le32 info; - __le32 info_h; -} __packed; - -struct qtnf_rx_bd { - __le32 addr; - __le32 addr_h; - __le32 info; - __le32 info_h; - __le32 next_ptr; - __le32 next_ptr_h; -} __packed; - enum qtnf_fw_loadtype { QTN_FW_DBEGIN, QTN_FW_DSUB, @@ -146,13 +108,4 @@ enum qtnf_fw_loadtype { QTN_FW_CTRL }; -struct qtnf_pcie_fw_hdr { - u8 boardflg[8]; - __le32 fwsize; - __le32 seqnum; - __le32 type; - __le32 pktlen; - __le32 crc; -} __packed; - #endif /* _QTN_FMAC_PCIE_IPC_H_ */ From 21077d09b4a67e3bcf88d1e6be634c7950db84fa Mon Sep 17 00:00:00 2001 From: Igor Mitsyanko Date: Mon, 24 Sep 2018 15:15:08 -0700 Subject: [PATCH 269/276] qtnfmac_pcie: pearl: rename spinlock tx0_lock to tx_lock tx_lock name will later be reused when common pcie code is extracted to separate files. Signed-off-by: Igor Mitsyanko Signed-off-by: Kalle Valo --- .../net/wireless/quantenna/qtnfmac/pcie/pearl_pcie.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie.c b/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie.c index 4e9eb46ea8cb..791a1e354915 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie.c +++ b/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie.c @@ -110,7 +110,7 @@ struct qtnf_pcie_pearl_state { /* lock for tx reclaim operations */ spinlock_t tx_reclaim_lock; /* lock for tx0 operations */ - spinlock_t tx0_lock; + spinlock_t tx_lock; u8 msi_enabled; u8 tx_stopped; int mps; @@ -794,7 +794,7 @@ static int qtnf_pcie_data_tx(struct qtnf_bus *bus, struct sk_buff *skb) u32 info; int ret = 0; - spin_lock_irqsave(&priv->tx0_lock, flags); + spin_lock_irqsave(&priv->tx_lock, flags); if (!qtnf_tx_queue_ready(priv)) { if (skb->dev) { @@ -802,7 +802,7 @@ static int qtnf_pcie_data_tx(struct qtnf_bus *bus, struct sk_buff *skb) priv->tx_stopped = 1; } - spin_unlock_irqrestore(&priv->tx0_lock, flags); + spin_unlock_irqrestore(&priv->tx_lock, flags); return NETDEV_TX_BUSY; } @@ -852,7 +852,7 @@ static int qtnf_pcie_data_tx(struct qtnf_bus *bus, struct sk_buff *skb) } priv->tx_done_count++; - spin_unlock_irqrestore(&priv->tx0_lock, flags); + spin_unlock_irqrestore(&priv->tx_lock, flags); qtnf_pcie_data_tx_reclaim(priv); @@ -1404,7 +1404,7 @@ static int qtnf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) init_completion(&bus->firmware_init_complete); mutex_init(&bus->bus_lock); - spin_lock_init(&pcie_priv->tx0_lock); + spin_lock_init(&pcie_priv->tx_lock); spin_lock_init(&pcie_priv->irq_lock); spin_lock_init(&pcie_priv->tx_reclaim_lock); From c9ff6c9157c2e6d68aafd50078520519bf99ea94 Mon Sep 17 00:00:00 2001 From: Igor Mitsyanko Date: Mon, 24 Sep 2018 15:15:09 -0700 Subject: [PATCH 270/276] qtnfmac_pcie: separate platform-independent PCIe structure Move platform-independent PCIe data structure to a separate header file so it can be reused by different devices. Signed-off-by: Igor Mitsyanko Signed-off-by: Kalle Valo --- .../quantenna/qtnfmac/pcie/pcie_priv.h | 70 +++ .../quantenna/qtnfmac/pcie/pearl_pcie.c | 469 ++++++++---------- .../quantenna/qtnfmac/pcie/pearl_pcie_ipc.h | 7 - 3 files changed, 286 insertions(+), 260 deletions(-) create mode 100644 drivers/net/wireless/quantenna/qtnfmac/pcie/pcie_priv.h diff --git a/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie_priv.h b/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie_priv.h new file mode 100644 index 000000000000..8da9612eeed3 --- /dev/null +++ b/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie_priv.h @@ -0,0 +1,70 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* Copyright (c) 2018 Quantenna Communications, Inc. All rights reserved. */ + +#ifndef _QTN_FMAC_PCIE_H_ +#define _QTN_FMAC_PCIE_H_ + +#include +#include +#include +#include +#include +#include + +#include "shm_ipc.h" + +#define SKB_BUF_SIZE 2048 + +#define QTN_FW_DL_TIMEOUT_MS 3000 +#define QTN_FW_QLINK_TIMEOUT_MS 30000 +#define QTN_EP_RESET_WAIT_MS 1000 + +struct qtnf_pcie_bus_priv { + struct pci_dev *pdev; + + spinlock_t tx_reclaim_lock; + spinlock_t tx_lock; + int mps; + + struct workqueue_struct *workqueue; + struct tasklet_struct reclaim_tq; + + void __iomem *sysctl_bar; + void __iomem *epmem_bar; + void __iomem *dmareg_bar; + + struct qtnf_shm_ipc shm_ipc_ep_in; + struct qtnf_shm_ipc shm_ipc_ep_out; + + u16 tx_bd_num; + u16 rx_bd_num; + + struct sk_buff **tx_skb; + struct sk_buff **rx_skb; + + u32 rx_bd_w_index; + u32 rx_bd_r_index; + + u32 tx_bd_w_index; + u32 tx_bd_r_index; + + /* diagnostics stats */ + u32 pcie_irq_count; + u32 tx_full_count; + u32 tx_done_count; + u32 tx_reclaim_done; + u32 tx_reclaim_req; + + u8 msi_enabled; + u8 tx_stopped; +}; + +static inline void qtnf_non_posted_write(u32 val, void __iomem *basereg) +{ + writel(val, basereg); + + /* flush posted write */ + readl(basereg); +} + +#endif /* _QTN_FMAC_PCIE_H_ */ diff --git a/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie.c b/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie.c index 791a1e354915..97f3001846f8 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie.c +++ b/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie.c @@ -28,6 +28,7 @@ #include #include +#include "pcie_priv.h" #include "pearl_pcie_regs.h" #include "pearl_pcie_ipc.h" #include "qtn_hw_ids.h" @@ -102,38 +103,14 @@ struct qtnf_pearl_fw_hdr { } __packed; struct qtnf_pcie_pearl_state { - struct pci_dev *pdev; + struct qtnf_pcie_bus_priv base; /* lock for irq configuration changes */ spinlock_t irq_lock; - /* lock for tx reclaim operations */ - spinlock_t tx_reclaim_lock; - /* lock for tx0 operations */ - spinlock_t tx_lock; - u8 msi_enabled; - u8 tx_stopped; - int mps; - - struct workqueue_struct *workqueue; - struct tasklet_struct reclaim_tq; - - void __iomem *sysctl_bar; - void __iomem *epmem_bar; - void __iomem *dmareg_bar; - - struct qtnf_shm_ipc shm_ipc_ep_in; - struct qtnf_shm_ipc shm_ipc_ep_out; - struct qtnf_pearl_bda __iomem *bda; void __iomem *pcie_reg_base; - u16 tx_bd_num; - u16 rx_bd_num; - - struct sk_buff **tx_skb; - struct sk_buff **rx_skb; - struct qtnf_pearl_tx_bd *tx_bd_vbase; dma_addr_t tx_bd_pbase; @@ -143,102 +120,80 @@ struct qtnf_pcie_pearl_state { dma_addr_t bd_table_paddr; void *bd_table_vaddr; u32 bd_table_len; - - u32 rx_bd_w_index; - u32 rx_bd_r_index; - - u32 tx_bd_w_index; - u32 tx_bd_r_index; - u32 pcie_irq_mask; - - /* diagnostics stats */ - u32 pcie_irq_count; u32 pcie_irq_rx_count; u32 pcie_irq_tx_count; u32 pcie_irq_uf_count; - u32 tx_full_count; - u32 tx_done_count; - u32 tx_reclaim_done; - u32 tx_reclaim_req; }; -static inline void qtnf_non_posted_write(u32 val, void __iomem *basereg) -{ - writel(val, basereg); - - /* flush posted write */ - readl(basereg); -} - -static inline void qtnf_init_hdp_irqs(struct qtnf_pcie_pearl_state *priv) +static inline void qtnf_init_hdp_irqs(struct qtnf_pcie_pearl_state *ps) { unsigned long flags; - spin_lock_irqsave(&priv->irq_lock, flags); - priv->pcie_irq_mask = (PCIE_HDP_INT_RX_BITS | PCIE_HDP_INT_TX_BITS); - spin_unlock_irqrestore(&priv->irq_lock, flags); + spin_lock_irqsave(&ps->irq_lock, flags); + ps->pcie_irq_mask = (PCIE_HDP_INT_RX_BITS | PCIE_HDP_INT_TX_BITS); + spin_unlock_irqrestore(&ps->irq_lock, flags); } -static inline void qtnf_enable_hdp_irqs(struct qtnf_pcie_pearl_state *priv) +static inline void qtnf_enable_hdp_irqs(struct qtnf_pcie_pearl_state *ps) { unsigned long flags; - spin_lock_irqsave(&priv->irq_lock, flags); - writel(priv->pcie_irq_mask, PCIE_HDP_INT_EN(priv->pcie_reg_base)); - spin_unlock_irqrestore(&priv->irq_lock, flags); + spin_lock_irqsave(&ps->irq_lock, flags); + writel(ps->pcie_irq_mask, PCIE_HDP_INT_EN(ps->pcie_reg_base)); + spin_unlock_irqrestore(&ps->irq_lock, flags); } -static inline void qtnf_disable_hdp_irqs(struct qtnf_pcie_pearl_state *priv) +static inline void qtnf_disable_hdp_irqs(struct qtnf_pcie_pearl_state *ps) { unsigned long flags; - spin_lock_irqsave(&priv->irq_lock, flags); - writel(0x0, PCIE_HDP_INT_EN(priv->pcie_reg_base)); - spin_unlock_irqrestore(&priv->irq_lock, flags); + spin_lock_irqsave(&ps->irq_lock, flags); + writel(0x0, PCIE_HDP_INT_EN(ps->pcie_reg_base)); + spin_unlock_irqrestore(&ps->irq_lock, flags); } -static inline void qtnf_en_rxdone_irq(struct qtnf_pcie_pearl_state *priv) +static inline void qtnf_en_rxdone_irq(struct qtnf_pcie_pearl_state *ps) { unsigned long flags; - spin_lock_irqsave(&priv->irq_lock, flags); - priv->pcie_irq_mask |= PCIE_HDP_INT_RX_BITS; - writel(priv->pcie_irq_mask, PCIE_HDP_INT_EN(priv->pcie_reg_base)); - spin_unlock_irqrestore(&priv->irq_lock, flags); + spin_lock_irqsave(&ps->irq_lock, flags); + ps->pcie_irq_mask |= PCIE_HDP_INT_RX_BITS; + writel(ps->pcie_irq_mask, PCIE_HDP_INT_EN(ps->pcie_reg_base)); + spin_unlock_irqrestore(&ps->irq_lock, flags); } -static inline void qtnf_dis_rxdone_irq(struct qtnf_pcie_pearl_state *priv) +static inline void qtnf_dis_rxdone_irq(struct qtnf_pcie_pearl_state *ps) { unsigned long flags; - spin_lock_irqsave(&priv->irq_lock, flags); - priv->pcie_irq_mask &= ~PCIE_HDP_INT_RX_BITS; - writel(priv->pcie_irq_mask, PCIE_HDP_INT_EN(priv->pcie_reg_base)); - spin_unlock_irqrestore(&priv->irq_lock, flags); + spin_lock_irqsave(&ps->irq_lock, flags); + ps->pcie_irq_mask &= ~PCIE_HDP_INT_RX_BITS; + writel(ps->pcie_irq_mask, PCIE_HDP_INT_EN(ps->pcie_reg_base)); + spin_unlock_irqrestore(&ps->irq_lock, flags); } -static inline void qtnf_en_txdone_irq(struct qtnf_pcie_pearl_state *priv) +static inline void qtnf_en_txdone_irq(struct qtnf_pcie_pearl_state *ps) { unsigned long flags; - spin_lock_irqsave(&priv->irq_lock, flags); - priv->pcie_irq_mask |= PCIE_HDP_INT_TX_BITS; - writel(priv->pcie_irq_mask, PCIE_HDP_INT_EN(priv->pcie_reg_base)); - spin_unlock_irqrestore(&priv->irq_lock, flags); + spin_lock_irqsave(&ps->irq_lock, flags); + ps->pcie_irq_mask |= PCIE_HDP_INT_TX_BITS; + writel(ps->pcie_irq_mask, PCIE_HDP_INT_EN(ps->pcie_reg_base)); + spin_unlock_irqrestore(&ps->irq_lock, flags); } -static inline void qtnf_dis_txdone_irq(struct qtnf_pcie_pearl_state *priv) +static inline void qtnf_dis_txdone_irq(struct qtnf_pcie_pearl_state *ps) { unsigned long flags; - spin_lock_irqsave(&priv->irq_lock, flags); - priv->pcie_irq_mask &= ~PCIE_HDP_INT_TX_BITS; - writel(priv->pcie_irq_mask, PCIE_HDP_INT_EN(priv->pcie_reg_base)); - spin_unlock_irqrestore(&priv->irq_lock, flags); + spin_lock_irqsave(&ps->irq_lock, flags); + ps->pcie_irq_mask &= ~PCIE_HDP_INT_TX_BITS; + writel(ps->pcie_irq_mask, PCIE_HDP_INT_EN(ps->pcie_reg_base)); + spin_unlock_irqrestore(&ps->irq_lock, flags); } -static void qtnf_pcie_init_irq(struct qtnf_pcie_pearl_state *priv) +static void qtnf_pcie_init_irq(struct qtnf_pcie_bus_priv *priv) { struct pci_dev *pdev = priv->pdev; @@ -261,9 +216,9 @@ static void qtnf_pcie_init_irq(struct qtnf_pcie_pearl_state *priv) } } -static void qtnf_deassert_intx(struct qtnf_pcie_pearl_state *priv) +static void qtnf_deassert_intx(struct qtnf_pcie_pearl_state *ps) { - void __iomem *reg = priv->sysctl_bar + PEARL_PCIE_CFG0_OFFSET; + void __iomem *reg = ps->base.sysctl_bar + PEARL_PCIE_CFG0_OFFSET; u32 cfg; cfg = readl(reg); @@ -271,28 +226,28 @@ static void qtnf_deassert_intx(struct qtnf_pcie_pearl_state *priv) qtnf_non_posted_write(cfg, reg); } -static void qtnf_reset_card(struct qtnf_pcie_pearl_state *priv) +static void qtnf_reset_card(struct qtnf_pcie_pearl_state *ps) { const u32 data = QTN_PEARL_IPC_IRQ_WORD(QTN_PEARL_LHOST_EP_RESET); - void __iomem *reg = priv->sysctl_bar + + void __iomem *reg = ps->base.sysctl_bar + QTN_PEARL_SYSCTL_LHOST_IRQ_OFFSET; qtnf_non_posted_write(data, reg); msleep(QTN_EP_RESET_WAIT_MS); - pci_restore_state(priv->pdev); + pci_restore_state(ps->base.pdev); } static void qtnf_ipc_gen_ep_int(void *arg) { - const struct qtnf_pcie_pearl_state *priv = arg; + const struct qtnf_pcie_pearl_state *ps = arg; const u32 data = QTN_PEARL_IPC_IRQ_WORD(QTN_PEARL_LHOST_IPC_IRQ); - void __iomem *reg = priv->sysctl_bar + + void __iomem *reg = ps->base.sysctl_bar + QTN_PEARL_SYSCTL_LHOST_IRQ_OFFSET; qtnf_non_posted_write(data, reg); } -static void __iomem *qtnf_map_bar(struct qtnf_pcie_pearl_state *priv, u8 index) +static void __iomem *qtnf_map_bar(struct qtnf_pcie_bus_priv *priv, u8 index) { void __iomem *vaddr; dma_addr_t busaddr; @@ -317,7 +272,7 @@ static void __iomem *qtnf_map_bar(struct qtnf_pcie_pearl_state *priv, u8 index) static void qtnf_pcie_control_rx_callback(void *arg, const u8 *buf, size_t len) { - struct qtnf_pcie_pearl_state *priv = arg; + struct qtnf_pcie_bus_priv *priv = arg; struct qtnf_bus *bus = pci_get_drvdata(priv->pdev); struct sk_buff *skb; @@ -338,35 +293,36 @@ static void qtnf_pcie_control_rx_callback(void *arg, const u8 *buf, size_t len) qtnf_trans_handle_rx_ctl_packet(bus, skb); } -static int qtnf_pcie_init_shm_ipc(struct qtnf_pcie_pearl_state *priv) +static int qtnf_pcie_init_shm_ipc(struct qtnf_pcie_pearl_state *ps) { struct qtnf_shm_ipc_region __iomem *ipc_tx_reg; struct qtnf_shm_ipc_region __iomem *ipc_rx_reg; - const struct qtnf_shm_ipc_int ipc_int = { qtnf_ipc_gen_ep_int, priv }; + const struct qtnf_shm_ipc_int ipc_int = { qtnf_ipc_gen_ep_int, ps }; const struct qtnf_shm_ipc_rx_callback rx_callback = { - qtnf_pcie_control_rx_callback, priv }; + qtnf_pcie_control_rx_callback, ps }; - ipc_tx_reg = &priv->bda->bda_shm_reg1; - ipc_rx_reg = &priv->bda->bda_shm_reg2; + ipc_tx_reg = &ps->bda->bda_shm_reg1; + ipc_rx_reg = &ps->bda->bda_shm_reg2; - qtnf_shm_ipc_init(&priv->shm_ipc_ep_in, QTNF_SHM_IPC_OUTBOUND, - ipc_tx_reg, priv->workqueue, + qtnf_shm_ipc_init(&ps->base.shm_ipc_ep_in, QTNF_SHM_IPC_OUTBOUND, + ipc_tx_reg, ps->base.workqueue, &ipc_int, &rx_callback); - qtnf_shm_ipc_init(&priv->shm_ipc_ep_out, QTNF_SHM_IPC_INBOUND, - ipc_rx_reg, priv->workqueue, + qtnf_shm_ipc_init(&ps->base.shm_ipc_ep_out, QTNF_SHM_IPC_INBOUND, + ipc_rx_reg, ps->base.workqueue, &ipc_int, &rx_callback); return 0; } -static void qtnf_pcie_free_shm_ipc(struct qtnf_pcie_pearl_state *priv) +static void qtnf_pcie_free_shm_ipc(struct qtnf_pcie_bus_priv *priv) { qtnf_shm_ipc_free(&priv->shm_ipc_ep_in); qtnf_shm_ipc_free(&priv->shm_ipc_ep_out); } -static int qtnf_pcie_init_memory(struct qtnf_pcie_pearl_state *priv) +static int qtnf_pcie_init_memory(struct qtnf_pcie_pearl_state *ps) { + struct qtnf_pcie_bus_priv *priv = &ps->base; int ret = -ENOMEM; priv->sysctl_bar = qtnf_map_bar(priv, QTN_SYSCTL_BAR); @@ -387,14 +343,14 @@ static int qtnf_pcie_init_memory(struct qtnf_pcie_pearl_state *priv) return ret; } - priv->pcie_reg_base = priv->dmareg_bar; - priv->bda = priv->epmem_bar; - writel(priv->msi_enabled, &priv->bda->bda_rc_msi_enabled); + ps->pcie_reg_base = priv->dmareg_bar; + ps->bda = priv->epmem_bar; + writel(priv->msi_enabled, &ps->bda->bda_rc_msi_enabled); return 0; } -static void qtnf_tune_pcie_mps(struct qtnf_pcie_pearl_state *priv) +static void qtnf_tune_pcie_mps(struct qtnf_pcie_bus_priv *priv) { struct pci_dev *pdev = priv->pdev; struct pci_dev *parent; @@ -466,7 +422,7 @@ static int qtnf_poll_state(__le32 __iomem *reg, u32 state, u32 delay_in_ms) return 0; } -static int alloc_skb_array(struct qtnf_pcie_pearl_state *priv) +static int alloc_skb_array(struct qtnf_pcie_bus_priv *priv) { struct sk_buff **vaddr; int len; @@ -486,8 +442,9 @@ static int alloc_skb_array(struct qtnf_pcie_pearl_state *priv) return 0; } -static int alloc_bd_table(struct qtnf_pcie_pearl_state *priv) +static int alloc_bd_table(struct qtnf_pcie_pearl_state *ps) { + struct qtnf_pcie_bus_priv *priv = &ps->base; dma_addr_t paddr; void *vaddr; int len; @@ -503,12 +460,12 @@ static int alloc_bd_table(struct qtnf_pcie_pearl_state *priv) memset(vaddr, 0, len); - priv->bd_table_vaddr = vaddr; - priv->bd_table_paddr = paddr; - priv->bd_table_len = len; + ps->bd_table_vaddr = vaddr; + ps->bd_table_paddr = paddr; + ps->bd_table_len = len; - priv->tx_bd_vbase = vaddr; - priv->tx_bd_pbase = paddr; + ps->tx_bd_vbase = vaddr; + ps->tx_bd_pbase = paddr; pr_debug("TX descriptor table: vaddr=0x%p paddr=%pad\n", vaddr, &paddr); @@ -520,25 +477,26 @@ static int alloc_bd_table(struct qtnf_pcie_pearl_state *priv) vaddr = ((struct qtnf_pearl_tx_bd *)vaddr) + priv->tx_bd_num; paddr += priv->tx_bd_num * sizeof(struct qtnf_pearl_tx_bd); - priv->rx_bd_vbase = vaddr; - priv->rx_bd_pbase = paddr; + ps->rx_bd_vbase = vaddr; + ps->rx_bd_pbase = paddr; #ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT writel(QTN_HOST_HI32(paddr), - PCIE_HDP_TX_HOST_Q_BASE_H(priv->pcie_reg_base)); + PCIE_HDP_TX_HOST_Q_BASE_H(ps->pcie_reg_base)); #endif writel(QTN_HOST_LO32(paddr), - PCIE_HDP_TX_HOST_Q_BASE_L(priv->pcie_reg_base)); + PCIE_HDP_TX_HOST_Q_BASE_L(ps->pcie_reg_base)); writel(priv->rx_bd_num | (sizeof(struct qtnf_pearl_rx_bd)) << 16, - PCIE_HDP_TX_HOST_Q_SZ_CTRL(priv->pcie_reg_base)); + PCIE_HDP_TX_HOST_Q_SZ_CTRL(ps->pcie_reg_base)); pr_debug("RX descriptor table: vaddr=0x%p paddr=%pad\n", vaddr, &paddr); return 0; } -static int skb2rbd_attach(struct qtnf_pcie_pearl_state *priv, u16 index) +static int skb2rbd_attach(struct qtnf_pcie_pearl_state *ps, u16 index) { + struct qtnf_pcie_bus_priv *priv = &ps->base; struct qtnf_pearl_rx_bd *rxbd; struct sk_buff *skb; dma_addr_t paddr; @@ -550,7 +508,7 @@ static int skb2rbd_attach(struct qtnf_pcie_pearl_state *priv, u16 index) } priv->rx_skb[index] = skb; - rxbd = &priv->rx_bd_vbase[index]; + rxbd = &ps->rx_bd_vbase[index]; paddr = pci_map_single(priv->pdev, skb->data, SKB_BUF_SIZE, PCI_DMA_FROMDEVICE); @@ -571,25 +529,25 @@ static int skb2rbd_attach(struct qtnf_pcie_pearl_state *priv, u16 index) #ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT writel(QTN_HOST_HI32(paddr), - PCIE_HDP_HHBM_BUF_PTR_H(priv->pcie_reg_base)); + PCIE_HDP_HHBM_BUF_PTR_H(ps->pcie_reg_base)); #endif writel(QTN_HOST_LO32(paddr), - PCIE_HDP_HHBM_BUF_PTR(priv->pcie_reg_base)); + PCIE_HDP_HHBM_BUF_PTR(ps->pcie_reg_base)); - writel(index, PCIE_HDP_TX_HOST_Q_WR_PTR(priv->pcie_reg_base)); + writel(index, PCIE_HDP_TX_HOST_Q_WR_PTR(ps->pcie_reg_base)); return 0; } -static int alloc_rx_buffers(struct qtnf_pcie_pearl_state *priv) +static int alloc_rx_buffers(struct qtnf_pcie_pearl_state *ps) { u16 i; int ret = 0; - memset(priv->rx_bd_vbase, 0x0, - priv->rx_bd_num * sizeof(struct qtnf_pearl_rx_bd)); + memset(ps->rx_bd_vbase, 0x0, + ps->base.rx_bd_num * sizeof(struct qtnf_pearl_rx_bd)); - for (i = 0; i < priv->rx_bd_num; i++) { - ret = skb2rbd_attach(priv, i); + for (i = 0; i < ps->base.rx_bd_num; i++) { + ret = skb2rbd_attach(ps, i); if (ret) break; } @@ -598,8 +556,9 @@ static int alloc_rx_buffers(struct qtnf_pcie_pearl_state *priv) } /* all rx/tx activity should have ceased before calling this function */ -static void qtnf_free_xfer_buffers(struct qtnf_pcie_pearl_state *priv) +static void qtnf_free_xfer_buffers(struct qtnf_pcie_pearl_state *ps) { + struct qtnf_pcie_bus_priv *priv = &ps->base; struct qtnf_pearl_tx_bd *txbd; struct qtnf_pearl_rx_bd *rxbd; struct sk_buff *skb; @@ -609,7 +568,7 @@ static void qtnf_free_xfer_buffers(struct qtnf_pcie_pearl_state *priv) /* free rx buffers */ for (i = 0; i < priv->rx_bd_num; i++) { if (priv->rx_skb && priv->rx_skb[i]) { - rxbd = &priv->rx_bd_vbase[i]; + rxbd = &ps->rx_bd_vbase[i]; skb = priv->rx_skb[i]; paddr = QTN_HOST_ADDR(le32_to_cpu(rxbd->addr_h), le32_to_cpu(rxbd->addr)); @@ -623,7 +582,7 @@ static void qtnf_free_xfer_buffers(struct qtnf_pcie_pearl_state *priv) /* free tx buffers */ for (i = 0; i < priv->tx_bd_num; i++) { if (priv->tx_skb && priv->tx_skb[i]) { - txbd = &priv->tx_bd_vbase[i]; + txbd = &ps->tx_bd_vbase[i]; skb = priv->tx_skb[i]; paddr = QTN_HOST_ADDR(le32_to_cpu(txbd->addr_h), le32_to_cpu(txbd->addr)); @@ -635,26 +594,27 @@ static void qtnf_free_xfer_buffers(struct qtnf_pcie_pearl_state *priv) } } -static int qtnf_hhbm_init(struct qtnf_pcie_pearl_state *priv) +static int qtnf_hhbm_init(struct qtnf_pcie_pearl_state *ps) { u32 val; - val = readl(PCIE_HHBM_CONFIG(priv->pcie_reg_base)); + val = readl(PCIE_HHBM_CONFIG(ps->pcie_reg_base)); val |= HHBM_CONFIG_SOFT_RESET; - writel(val, PCIE_HHBM_CONFIG(priv->pcie_reg_base)); + writel(val, PCIE_HHBM_CONFIG(ps->pcie_reg_base)); usleep_range(50, 100); val &= ~HHBM_CONFIG_SOFT_RESET; #ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT val |= HHBM_64BIT; #endif - writel(val, PCIE_HHBM_CONFIG(priv->pcie_reg_base)); - writel(priv->rx_bd_num, PCIE_HHBM_Q_LIMIT_REG(priv->pcie_reg_base)); + writel(val, PCIE_HHBM_CONFIG(ps->pcie_reg_base)); + writel(ps->base.rx_bd_num, PCIE_HHBM_Q_LIMIT_REG(ps->pcie_reg_base)); return 0; } -static int qtnf_pcie_init_xfer(struct qtnf_pcie_pearl_state *priv) +static int qtnf_pcie_init_xfer(struct qtnf_pcie_pearl_state *ps) { + struct qtnf_pcie_bus_priv *priv = &ps->base; int ret; u32 val; @@ -689,7 +649,7 @@ static int qtnf_pcie_init_xfer(struct qtnf_pcie_pearl_state *priv) return -EINVAL; } - ret = qtnf_hhbm_init(priv); + ret = qtnf_hhbm_init(ps); if (ret) { pr_err("failed to init h/w queues\n"); return ret; @@ -701,13 +661,13 @@ static int qtnf_pcie_init_xfer(struct qtnf_pcie_pearl_state *priv) return ret; } - ret = alloc_bd_table(priv); + ret = alloc_bd_table(ps); if (ret) { pr_err("failed to allocate bd table\n"); return ret; } - ret = alloc_rx_buffers(priv); + ret = alloc_rx_buffers(ps); if (ret) { pr_err("failed to allocate rx buffers\n"); return ret; @@ -716,8 +676,9 @@ static int qtnf_pcie_init_xfer(struct qtnf_pcie_pearl_state *priv) return ret; } -static void qtnf_pcie_data_tx_reclaim(struct qtnf_pcie_pearl_state *priv) +static void qtnf_pcie_data_tx_reclaim(struct qtnf_pcie_pearl_state *ps) { + struct qtnf_pcie_bus_priv *priv = &ps->base; struct qtnf_pearl_tx_bd *txbd; struct sk_buff *skb; unsigned long flags; @@ -728,7 +689,7 @@ static void qtnf_pcie_data_tx_reclaim(struct qtnf_pcie_pearl_state *priv) spin_lock_irqsave(&priv->tx_reclaim_lock, flags); - tx_done_index = readl(PCIE_HDP_RX0DMA_CNT(priv->pcie_reg_base)) + tx_done_index = readl(PCIE_HDP_RX0DMA_CNT(ps->pcie_reg_base)) & (priv->tx_bd_num - 1); i = priv->tx_bd_r_index; @@ -736,7 +697,7 @@ static void qtnf_pcie_data_tx_reclaim(struct qtnf_pcie_pearl_state *priv) while (CIRC_CNT(tx_done_index, i, priv->tx_bd_num)) { skb = priv->tx_skb[i]; if (likely(skb)) { - txbd = &priv->tx_bd_vbase[i]; + txbd = &ps->tx_bd_vbase[i]; paddr = QTN_HOST_ADDR(le32_to_cpu(txbd->addr_h), le32_to_cpu(txbd->addr)); pci_unmap_single(priv->pdev, paddr, skb->len, @@ -767,11 +728,13 @@ static void qtnf_pcie_data_tx_reclaim(struct qtnf_pcie_pearl_state *priv) spin_unlock_irqrestore(&priv->tx_reclaim_lock, flags); } -static int qtnf_tx_queue_ready(struct qtnf_pcie_pearl_state *priv) +static int qtnf_tx_queue_ready(struct qtnf_pcie_pearl_state *ps) { + struct qtnf_pcie_bus_priv *priv = &ps->base; + if (!CIRC_SPACE(priv->tx_bd_w_index, priv->tx_bd_r_index, priv->tx_bd_num)) { - qtnf_pcie_data_tx_reclaim(priv); + qtnf_pcie_data_tx_reclaim(ps); if (!CIRC_SPACE(priv->tx_bd_w_index, priv->tx_bd_r_index, priv->tx_bd_num)) { @@ -786,7 +749,8 @@ static int qtnf_tx_queue_ready(struct qtnf_pcie_pearl_state *priv) static int qtnf_pcie_data_tx(struct qtnf_bus *bus, struct sk_buff *skb) { - struct qtnf_pcie_pearl_state *priv = (void *)get_bus_priv(bus); + struct qtnf_pcie_pearl_state *ps = (void *)get_bus_priv(bus); + struct qtnf_pcie_bus_priv *priv = &ps->base; dma_addr_t txbd_paddr, skb_paddr; struct qtnf_pearl_tx_bd *txbd; unsigned long flags; @@ -796,7 +760,7 @@ static int qtnf_pcie_data_tx(struct qtnf_bus *bus, struct sk_buff *skb) spin_lock_irqsave(&priv->tx_lock, flags); - if (!qtnf_tx_queue_ready(priv)) { + if (!qtnf_tx_queue_ready(ps)) { if (skb->dev) { netif_tx_stop_all_queues(skb->dev); priv->tx_stopped = 1; @@ -818,7 +782,7 @@ static int qtnf_pcie_data_tx(struct qtnf_bus *bus, struct sk_buff *skb) goto tx_done; } - txbd = &priv->tx_bd_vbase[i]; + txbd = &ps->tx_bd_vbase[i]; txbd->addr = cpu_to_le32(QTN_HOST_LO32(skb_paddr)); txbd->addr_h = cpu_to_le32(QTN_HOST_HI32(skb_paddr)); @@ -829,14 +793,14 @@ static int qtnf_pcie_data_tx(struct qtnf_bus *bus, struct sk_buff *skb) dma_wmb(); /* write new TX descriptor to PCIE_RX_FIFO on EP */ - txbd_paddr = priv->tx_bd_pbase + i * sizeof(struct qtnf_pearl_tx_bd); + txbd_paddr = ps->tx_bd_pbase + i * sizeof(struct qtnf_pearl_tx_bd); #ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT writel(QTN_HOST_HI32(txbd_paddr), - PCIE_HDP_HOST_WR_DESC0_H(priv->pcie_reg_base)); + PCIE_HDP_HOST_WR_DESC0_H(ps->pcie_reg_base)); #endif writel(QTN_HOST_LO32(txbd_paddr), - PCIE_HDP_HOST_WR_DESC0(priv->pcie_reg_base)); + PCIE_HDP_HOST_WR_DESC0(ps->pcie_reg_base)); if (++i >= priv->tx_bd_num) i = 0; @@ -854,14 +818,14 @@ static int qtnf_pcie_data_tx(struct qtnf_bus *bus, struct sk_buff *skb) priv->tx_done_count++; spin_unlock_irqrestore(&priv->tx_lock, flags); - qtnf_pcie_data_tx_reclaim(priv); + qtnf_pcie_data_tx_reclaim(ps); return NETDEV_TX_OK; } static int qtnf_pcie_control_tx(struct qtnf_bus *bus, struct sk_buff *skb) { - struct qtnf_pcie_pearl_state *priv = (void *)get_bus_priv(bus); + struct qtnf_pcie_bus_priv *priv = (void *)get_bus_priv(bus); int ret; ret = qtnf_shm_ipc_send(&priv->shm_ipc_ep_in, skb->data, skb->len); @@ -877,54 +841,55 @@ static int qtnf_pcie_control_tx(struct qtnf_bus *bus, struct sk_buff *skb) static irqreturn_t qtnf_interrupt(int irq, void *data) { struct qtnf_bus *bus = (struct qtnf_bus *)data; - struct qtnf_pcie_pearl_state *priv = (void *)get_bus_priv(bus); + struct qtnf_pcie_pearl_state *ps = (void *)get_bus_priv(bus); + struct qtnf_pcie_bus_priv *priv = &ps->base; u32 status; priv->pcie_irq_count++; - status = readl(PCIE_HDP_INT_STATUS(priv->pcie_reg_base)); + status = readl(PCIE_HDP_INT_STATUS(ps->pcie_reg_base)); qtnf_shm_ipc_irq_handler(&priv->shm_ipc_ep_in); qtnf_shm_ipc_irq_handler(&priv->shm_ipc_ep_out); - if (!(status & priv->pcie_irq_mask)) + if (!(status & ps->pcie_irq_mask)) goto irq_done; if (status & PCIE_HDP_INT_RX_BITS) - priv->pcie_irq_rx_count++; + ps->pcie_irq_rx_count++; if (status & PCIE_HDP_INT_TX_BITS) - priv->pcie_irq_tx_count++; + ps->pcie_irq_tx_count++; if (status & PCIE_HDP_INT_HHBM_UF) - priv->pcie_irq_uf_count++; + ps->pcie_irq_uf_count++; if (status & PCIE_HDP_INT_RX_BITS) { - qtnf_dis_rxdone_irq(priv); + qtnf_dis_rxdone_irq(ps); napi_schedule(&bus->mux_napi); } if (status & PCIE_HDP_INT_TX_BITS) { - qtnf_dis_txdone_irq(priv); + qtnf_dis_txdone_irq(ps); tasklet_hi_schedule(&priv->reclaim_tq); } irq_done: /* H/W workaround: clean all bits, not only enabled */ - qtnf_non_posted_write(~0U, PCIE_HDP_INT_STATUS(priv->pcie_reg_base)); + qtnf_non_posted_write(~0U, PCIE_HDP_INT_STATUS(ps->pcie_reg_base)); if (!priv->msi_enabled) - qtnf_deassert_intx(priv); + qtnf_deassert_intx(ps); return IRQ_HANDLED; } -static int qtnf_rx_data_ready(struct qtnf_pcie_pearl_state *priv) +static int qtnf_rx_data_ready(struct qtnf_pcie_pearl_state *ps) { - u16 index = priv->rx_bd_r_index; + u16 index = ps->base.rx_bd_r_index; struct qtnf_pearl_rx_bd *rxbd; u32 descw; - rxbd = &priv->rx_bd_vbase[index]; + rxbd = &ps->rx_bd_vbase[index]; descw = le32_to_cpu(rxbd->info); if (descw & QTN_TXDONE_MASK) @@ -936,7 +901,8 @@ static int qtnf_rx_data_ready(struct qtnf_pcie_pearl_state *priv) static int qtnf_rx_poll(struct napi_struct *napi, int budget) { struct qtnf_bus *bus = container_of(napi, struct qtnf_bus, mux_napi); - struct qtnf_pcie_pearl_state *priv = (void *)get_bus_priv(bus); + struct qtnf_pcie_pearl_state *ps = (void *)get_bus_priv(bus); + struct qtnf_pcie_bus_priv *priv = &ps->base; struct net_device *ndev = NULL; struct sk_buff *skb = NULL; int processed = 0; @@ -950,13 +916,11 @@ static int qtnf_rx_poll(struct napi_struct *napi, int budget) int ret; while (processed < budget) { - - - if (!qtnf_rx_data_ready(priv)) + if (!qtnf_rx_data_ready(ps)) goto rx_out; r_idx = priv->rx_bd_r_index; - rxbd = &priv->rx_bd_vbase[r_idx]; + rxbd = &ps->rx_bd_vbase[r_idx]; descw = le32_to_cpu(rxbd->info); skb = priv->rx_skb[r_idx]; @@ -1018,7 +982,7 @@ static int qtnf_rx_poll(struct napi_struct *napi, int budget) if (++w_idx >= priv->rx_bd_num) w_idx = 0; - ret = skb2rbd_attach(priv, w_idx); + ret = skb2rbd_attach(ps, w_idx); if (ret) { pr_err("failed to allocate new rx_skb[%d]\n", w_idx); @@ -1032,7 +996,7 @@ static int qtnf_rx_poll(struct napi_struct *napi, int budget) rx_out: if (processed < budget) { napi_complete(napi); - qtnf_en_rxdone_irq(priv); + qtnf_en_rxdone_irq(ps); } return processed; @@ -1041,25 +1005,25 @@ static int qtnf_rx_poll(struct napi_struct *napi, int budget) static void qtnf_pcie_data_tx_timeout(struct qtnf_bus *bus, struct net_device *ndev) { - struct qtnf_pcie_pearl_state *priv = (void *)get_bus_priv(bus); + struct qtnf_pcie_pearl_state *ps = (void *)get_bus_priv(bus); - tasklet_hi_schedule(&priv->reclaim_tq); + tasklet_hi_schedule(&ps->base.reclaim_tq); } static void qtnf_pcie_data_rx_start(struct qtnf_bus *bus) { - struct qtnf_pcie_pearl_state *priv = (void *)get_bus_priv(bus); + struct qtnf_pcie_pearl_state *ps = (void *)get_bus_priv(bus); - qtnf_enable_hdp_irqs(priv); + qtnf_enable_hdp_irqs(ps); napi_enable(&bus->mux_napi); } static void qtnf_pcie_data_rx_stop(struct qtnf_bus *bus) { - struct qtnf_pcie_pearl_state *priv = (void *)get_bus_priv(bus); + struct qtnf_pcie_pearl_state *ps = (void *)get_bus_priv(bus); napi_disable(&bus->mux_napi); - qtnf_disable_hdp_irqs(priv); + qtnf_disable_hdp_irqs(ps); } static const struct qtnf_bus_ops qtnf_pcie_bus_ops = { @@ -1076,7 +1040,7 @@ static const struct qtnf_bus_ops qtnf_pcie_bus_ops = { static int qtnf_dbg_mps_show(struct seq_file *s, void *data) { struct qtnf_bus *bus = dev_get_drvdata(s->private); - struct qtnf_pcie_pearl_state *priv = get_bus_priv(bus); + struct qtnf_pcie_bus_priv *priv = get_bus_priv(bus); seq_printf(s, "%d\n", priv->mps); @@ -1086,7 +1050,7 @@ static int qtnf_dbg_mps_show(struct seq_file *s, void *data) static int qtnf_dbg_msi_show(struct seq_file *s, void *data) { struct qtnf_bus *bus = dev_get_drvdata(s->private); - struct qtnf_pcie_pearl_state *priv = get_bus_priv(bus); + struct qtnf_pcie_bus_priv *priv = get_bus_priv(bus); seq_printf(s, "%u\n", priv->msi_enabled); @@ -1096,20 +1060,20 @@ static int qtnf_dbg_msi_show(struct seq_file *s, void *data) static int qtnf_dbg_irq_stats(struct seq_file *s, void *data) { struct qtnf_bus *bus = dev_get_drvdata(s->private); - struct qtnf_pcie_pearl_state *priv = get_bus_priv(bus); - u32 reg = readl(PCIE_HDP_INT_EN(priv->pcie_reg_base)); + struct qtnf_pcie_pearl_state *ps = get_bus_priv(bus); + u32 reg = readl(PCIE_HDP_INT_EN(ps->pcie_reg_base)); u32 status; - seq_printf(s, "pcie_irq_count(%u)\n", priv->pcie_irq_count); - seq_printf(s, "pcie_irq_tx_count(%u)\n", priv->pcie_irq_tx_count); + seq_printf(s, "pcie_irq_count(%u)\n", ps->base.pcie_irq_count); + seq_printf(s, "pcie_irq_tx_count(%u)\n", ps->pcie_irq_tx_count); status = reg & PCIE_HDP_INT_TX_BITS; seq_printf(s, "pcie_irq_tx_status(%s)\n", (status == PCIE_HDP_INT_TX_BITS) ? "EN" : "DIS"); - seq_printf(s, "pcie_irq_rx_count(%u)\n", priv->pcie_irq_rx_count); + seq_printf(s, "pcie_irq_rx_count(%u)\n", ps->pcie_irq_rx_count); status = reg & PCIE_HDP_INT_RX_BITS; seq_printf(s, "pcie_irq_rx_status(%s)\n", (status == PCIE_HDP_INT_RX_BITS) ? "EN" : "DIS"); - seq_printf(s, "pcie_irq_uf_count(%u)\n", priv->pcie_irq_uf_count); + seq_printf(s, "pcie_irq_uf_count(%u)\n", ps->pcie_irq_uf_count); status = reg & PCIE_HDP_INT_HHBM_UF; seq_printf(s, "pcie_irq_hhbm_uf_status(%s)\n", (status == PCIE_HDP_INT_HHBM_UF) ? "EN" : "DIS"); @@ -1120,7 +1084,8 @@ static int qtnf_dbg_irq_stats(struct seq_file *s, void *data) static int qtnf_dbg_hdp_stats(struct seq_file *s, void *data) { struct qtnf_bus *bus = dev_get_drvdata(s->private); - struct qtnf_pcie_pearl_state *priv = get_bus_priv(bus); + struct qtnf_pcie_pearl_state *ps = get_bus_priv(bus); + struct qtnf_pcie_bus_priv *priv = &ps->base; seq_printf(s, "tx_full_count(%u)\n", priv->tx_full_count); seq_printf(s, "tx_done_count(%u)\n", priv->tx_done_count); @@ -1129,7 +1094,7 @@ static int qtnf_dbg_hdp_stats(struct seq_file *s, void *data) seq_printf(s, "tx_bd_r_index(%u)\n", priv->tx_bd_r_index); seq_printf(s, "tx_bd_p_index(%u)\n", - readl(PCIE_HDP_RX0DMA_CNT(priv->pcie_reg_base)) + readl(PCIE_HDP_RX0DMA_CNT(ps->pcie_reg_base)) & (priv->tx_bd_num - 1)); seq_printf(s, "tx_bd_w_index(%u)\n", priv->tx_bd_w_index); seq_printf(s, "tx queue len(%u)\n", @@ -1138,7 +1103,7 @@ static int qtnf_dbg_hdp_stats(struct seq_file *s, void *data) seq_printf(s, "rx_bd_r_index(%u)\n", priv->rx_bd_r_index); seq_printf(s, "rx_bd_p_index(%u)\n", - readl(PCIE_HDP_TX0DMA_CNT(priv->pcie_reg_base)) + readl(PCIE_HDP_TX0DMA_CNT(ps->pcie_reg_base)) & (priv->rx_bd_num - 1)); seq_printf(s, "rx_bd_w_index(%u)\n", priv->rx_bd_w_index); seq_printf(s, "rx alloc queue len(%u)\n", @@ -1151,7 +1116,7 @@ static int qtnf_dbg_hdp_stats(struct seq_file *s, void *data) static int qtnf_dbg_shm_stats(struct seq_file *s, void *data) { struct qtnf_bus *bus = dev_get_drvdata(s->private); - struct qtnf_pcie_pearl_state *priv = get_bus_priv(bus); + struct qtnf_pcie_bus_priv *priv = get_bus_priv(bus); seq_printf(s, "shm_ipc_ep_in.tx_packet_count(%zu)\n", priv->shm_ipc_ep_in.tx_packet_count); @@ -1165,10 +1130,10 @@ static int qtnf_dbg_shm_stats(struct seq_file *s, void *data) return 0; } -static int qtnf_ep_fw_send(struct qtnf_pcie_pearl_state *priv, uint32_t size, +static int qtnf_ep_fw_send(struct qtnf_pcie_pearl_state *ps, uint32_t size, int blk, const u8 *pblk, const u8 *fw) { - struct pci_dev *pdev = priv->pdev; + struct pci_dev *pdev = ps->base.pdev; struct qtnf_bus *bus = pci_get_drvdata(pdev); struct qtnf_pearl_fw_hdr *hdr; @@ -1214,7 +1179,7 @@ static int qtnf_ep_fw_send(struct qtnf_pcie_pearl_state *priv, uint32_t size, } static int -qtnf_ep_fw_load(struct qtnf_pcie_pearl_state *priv, const u8 *fw, u32 fw_size) +qtnf_ep_fw_load(struct qtnf_pcie_pearl_state *ps, const u8 *fw, u32 fw_size) { int blk_size = QTN_PCIE_FW_BUFSZ - sizeof(struct qtnf_pearl_fw_hdr); int blk_count = fw_size / blk_size + ((fw_size % blk_size) ? 1 : 0); @@ -1231,25 +1196,25 @@ qtnf_ep_fw_load(struct qtnf_pcie_pearl_state *priv, const u8 *fw, u32 fw_size) return -ETIMEDOUT; } - len = qtnf_ep_fw_send(priv, fw_size, blk, pblk, fw); + len = qtnf_ep_fw_send(ps, fw_size, blk, pblk, fw); if (len <= 0) continue; if (!((blk + 1) & QTN_PCIE_FW_DLMASK) || (blk == (blk_count - 1))) { - qtnf_set_state(&priv->bda->bda_rc_state, + qtnf_set_state(&ps->bda->bda_rc_state, QTN_RC_FW_SYNC); - if (qtnf_poll_state(&priv->bda->bda_ep_state, + if (qtnf_poll_state(&ps->bda->bda_ep_state, QTN_EP_FW_SYNC, QTN_FW_DL_TIMEOUT_MS)) { pr_err("FW upload failed: SYNC timed out\n"); return -ETIMEDOUT; } - qtnf_clear_state(&priv->bda->bda_ep_state, + qtnf_clear_state(&ps->bda->bda_ep_state, QTN_EP_FW_SYNC); - if (qtnf_is_state(&priv->bda->bda_ep_state, + if (qtnf_is_state(&ps->bda->bda_ep_state, QTN_EP_FW_RETRY)) { if (blk == (blk_count - 1)) { int last_round = @@ -1262,14 +1227,14 @@ qtnf_ep_fw_load(struct qtnf_pcie_pearl_state *priv, const u8 *fw, u32 fw_size) pblk -= QTN_PCIE_FW_DLMASK * blk_size; } - qtnf_clear_state(&priv->bda->bda_ep_state, + qtnf_clear_state(&ps->bda->bda_ep_state, QTN_EP_FW_RETRY); pr_warn("FW upload retry: block #%d\n", blk); continue; } - qtnf_pcie_data_tx_reclaim(priv); + qtnf_pcie_data_tx_reclaim(ps); } pblk += len; @@ -1283,8 +1248,8 @@ qtnf_ep_fw_load(struct qtnf_pcie_pearl_state *priv, const u8 *fw, u32 fw_size) static void qtnf_fw_work_handler(struct work_struct *work) { struct qtnf_bus *bus = container_of(work, struct qtnf_bus, fw_work); - struct qtnf_pcie_pearl_state *priv = (void *)get_bus_priv(bus); - struct pci_dev *pdev = priv->pdev; + struct qtnf_pcie_pearl_state *ps = (void *)get_bus_priv(bus); + struct pci_dev *pdev = ps->base.pdev; const struct firmware *fw; int ret; u32 state = QTN_RC_FW_LOADRDY | QTN_RC_FW_QLINK; @@ -1300,9 +1265,9 @@ static void qtnf_fw_work_handler(struct work_struct *work) } } - qtnf_set_state(&priv->bda->bda_rc_state, state); + qtnf_set_state(&ps->bda->bda_rc_state, state); - if (qtnf_poll_state(&priv->bda->bda_ep_state, QTN_EP_FW_LOADRDY, + if (qtnf_poll_state(&ps->bda->bda_ep_state, QTN_EP_FW_LOADRDY, QTN_FW_DL_TIMEOUT_MS)) { pr_err("card is not ready\n"); @@ -1312,14 +1277,14 @@ static void qtnf_fw_work_handler(struct work_struct *work) goto fw_load_fail; } - qtnf_clear_state(&priv->bda->bda_ep_state, QTN_EP_FW_LOADRDY); + qtnf_clear_state(&ps->bda->bda_ep_state, QTN_EP_FW_LOADRDY); if (flashboot) { pr_info("booting firmware from flash\n"); } else { pr_info("starting firmware upload: %s\n", fwname); - ret = qtnf_ep_fw_load(priv, fw->data, fw->size); + ret = qtnf_ep_fw_load(ps, fw->data, fw->size); release_firmware(fw); if (ret) { pr_err("firmware upload error\n"); @@ -1327,7 +1292,7 @@ static void qtnf_fw_work_handler(struct work_struct *work) } } - if (qtnf_poll_state(&priv->bda->bda_ep_state, QTN_EP_FW_DONE, + if (qtnf_poll_state(&ps->bda->bda_ep_state, QTN_EP_FW_DONE, QTN_FW_DL_TIMEOUT_MS)) { pr_err("firmware bringup timed out\n"); goto fw_load_fail; @@ -1336,7 +1301,7 @@ static void qtnf_fw_work_handler(struct work_struct *work) bus->fw_state = QTNF_FW_STATE_FW_DNLD_DONE; pr_info("firmware is up and running\n"); - if (qtnf_poll_state(&priv->bda->bda_ep_state, + if (qtnf_poll_state(&ps->bda->bda_ep_state, QTN_EP_FW_QLINK_DONE, QTN_FW_QLINK_TIMEOUT_MS)) { pr_err("firmware runtime failure\n"); goto fw_load_fail; @@ -1367,7 +1332,7 @@ static void qtnf_fw_work_handler(struct work_struct *work) static void qtnf_bringup_fw_async(struct qtnf_bus *bus) { - struct qtnf_pcie_pearl_state *priv = (void *)get_bus_priv(bus); + struct qtnf_pcie_bus_priv *priv = (void *)get_bus_priv(bus); struct pci_dev *pdev = priv->pdev; get_device(&pdev->dev); @@ -1377,56 +1342,56 @@ static void qtnf_bringup_fw_async(struct qtnf_bus *bus) static void qtnf_reclaim_tasklet_fn(unsigned long data) { - struct qtnf_pcie_pearl_state *priv = (void *)data; + struct qtnf_pcie_pearl_state *ps = (void *)data; - qtnf_pcie_data_tx_reclaim(priv); - qtnf_en_txdone_irq(priv); + qtnf_pcie_data_tx_reclaim(ps); + qtnf_en_txdone_irq(ps); } static int qtnf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) { - struct qtnf_pcie_pearl_state *pcie_priv; + struct qtnf_pcie_pearl_state *ps; struct qtnf_bus *bus; int ret; bus = devm_kzalloc(&pdev->dev, - sizeof(*bus) + sizeof(*pcie_priv), GFP_KERNEL); + sizeof(*bus) + sizeof(*ps), GFP_KERNEL); if (!bus) return -ENOMEM; - pcie_priv = get_bus_priv(bus); + ps = get_bus_priv(bus); pci_set_drvdata(pdev, bus); bus->bus_ops = &qtnf_pcie_bus_ops; bus->dev = &pdev->dev; bus->fw_state = QTNF_FW_STATE_RESET; - pcie_priv->pdev = pdev; + ps->base.pdev = pdev; init_completion(&bus->firmware_init_complete); mutex_init(&bus->bus_lock); - spin_lock_init(&pcie_priv->tx_lock); - spin_lock_init(&pcie_priv->irq_lock); - spin_lock_init(&pcie_priv->tx_reclaim_lock); + spin_lock_init(&ps->base.tx_lock); + spin_lock_init(&ps->irq_lock); + spin_lock_init(&ps->base.tx_reclaim_lock); /* init stats */ - pcie_priv->tx_full_count = 0; - pcie_priv->tx_done_count = 0; - pcie_priv->pcie_irq_count = 0; - pcie_priv->pcie_irq_rx_count = 0; - pcie_priv->pcie_irq_tx_count = 0; - pcie_priv->pcie_irq_uf_count = 0; - pcie_priv->tx_reclaim_done = 0; - pcie_priv->tx_reclaim_req = 0; + ps->base.tx_full_count = 0; + ps->base.tx_done_count = 0; + ps->base.pcie_irq_count = 0; + ps->pcie_irq_rx_count = 0; + ps->pcie_irq_tx_count = 0; + ps->pcie_irq_uf_count = 0; + ps->base.tx_reclaim_done = 0; + ps->base.tx_reclaim_req = 0; - tasklet_init(&pcie_priv->reclaim_tq, qtnf_reclaim_tasklet_fn, - (unsigned long)pcie_priv); + tasklet_init(&ps->base.reclaim_tq, qtnf_reclaim_tasklet_fn, + (unsigned long)ps); init_dummy_netdev(&bus->mux_dev); netif_napi_add(&bus->mux_dev, &bus->mux_napi, qtnf_rx_poll, 10); - pcie_priv->workqueue = create_singlethread_workqueue("QTNF_PEARL_PCIE"); - if (!pcie_priv->workqueue) { + ps->base.workqueue = create_singlethread_workqueue("QTNF_PEARL_PCIE"); + if (!ps->base.workqueue) { pr_err("failed to alloc bus workqueue\n"); ret = -ENODEV; goto err_init; @@ -1438,7 +1403,7 @@ static int qtnf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) goto err_base; } - qtnf_tune_pcie_mps(pcie_priv); + qtnf_tune_pcie_mps(&ps->base); ret = pcim_enable_device(pdev); if (ret) { @@ -1459,9 +1424,9 @@ static int qtnf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) } pci_set_master(pdev); - qtnf_pcie_init_irq(pcie_priv); + qtnf_pcie_init_irq(&ps->base); - ret = qtnf_pcie_init_memory(pcie_priv); + ret = qtnf_pcie_init_memory(ps); if (ret < 0) { pr_err("PCIE memory init failed\n"); goto err_base; @@ -1469,23 +1434,23 @@ static int qtnf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) pci_save_state(pdev); - ret = qtnf_pcie_init_shm_ipc(pcie_priv); + ret = qtnf_pcie_init_shm_ipc(ps); if (ret < 0) { pr_err("PCIE SHM IPC init failed\n"); goto err_base; } - ret = qtnf_pcie_init_xfer(pcie_priv); + ret = qtnf_pcie_init_xfer(ps); if (ret) { pr_err("PCIE xfer init failed\n"); goto err_ipc; } /* init default irq settings */ - qtnf_init_hdp_irqs(pcie_priv); + qtnf_init_hdp_irqs(ps); /* start with disabled irqs */ - qtnf_disable_hdp_irqs(pcie_priv); + qtnf_disable_hdp_irqs(ps); ret = devm_request_irq(&pdev->dev, pdev->irq, &qtnf_interrupt, 0, "qtnf_pcie_irq", (void *)bus); @@ -1499,18 +1464,18 @@ static int qtnf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) return 0; err_xfer: - qtnf_free_xfer_buffers(pcie_priv); + qtnf_free_xfer_buffers(ps); err_ipc: - qtnf_pcie_free_shm_ipc(pcie_priv); + qtnf_pcie_free_shm_ipc(&ps->base); err_base: - flush_workqueue(pcie_priv->workqueue); - destroy_workqueue(pcie_priv->workqueue); - netif_napi_del(&bus->mux_napi); + flush_workqueue(ps->base.workqueue); + destroy_workqueue(ps->base.workqueue); err_init: - tasklet_kill(&pcie_priv->reclaim_tq); + tasklet_kill(&ps->base.reclaim_tq); + netif_napi_del(&bus->mux_napi); pci_set_drvdata(pdev, NULL); return ret; @@ -1518,7 +1483,7 @@ static int qtnf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) static void qtnf_pcie_remove(struct pci_dev *pdev) { - struct qtnf_pcie_pearl_state *priv; + struct qtnf_pcie_pearl_state *ps; struct qtnf_bus *bus; bus = pci_get_drvdata(pdev); @@ -1531,18 +1496,16 @@ static void qtnf_pcie_remove(struct pci_dev *pdev) bus->fw_state == QTNF_FW_STATE_EP_DEAD) qtnf_core_detach(bus); - priv = get_bus_priv(bus); - + ps = get_bus_priv(bus); + qtnf_reset_card(ps); netif_napi_del(&bus->mux_napi); - flush_workqueue(priv->workqueue); - destroy_workqueue(priv->workqueue); - tasklet_kill(&priv->reclaim_tq); + flush_workqueue(ps->base.workqueue); + destroy_workqueue(ps->base.workqueue); + tasklet_kill(&ps->base.reclaim_tq); - qtnf_free_xfer_buffers(priv); + qtnf_free_xfer_buffers(ps); + qtnf_pcie_free_shm_ipc(&ps->base); qtnf_debugfs_remove(bus); - - qtnf_pcie_free_shm_ipc(priv); - qtnf_reset_card(priv); } #ifdef CONFIG_PM_SLEEP diff --git a/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie_ipc.h b/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie_ipc.h index af528b81e87d..b87505d9de29 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie_ipc.h +++ b/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie_ipc.h @@ -43,11 +43,6 @@ #define QTN_RC_FW_LOADRDY BIT(8) #define QTN_RC_FW_SYNC BIT(9) -/* state transition timeouts */ -#define QTN_FW_DL_TIMEOUT_MS 3000 -#define QTN_FW_QLINK_TIMEOUT_MS 30000 -#define QTN_EP_RESET_WAIT_MS 1000 - #define PCIE_HDP_INT_RX_BITS (0 \ | PCIE_HDP_INT_EP_TXDMA \ | PCIE_HDP_INT_EP_TXEMPTY \ @@ -77,8 +72,6 @@ #define PCIE_BDA_NAMELEN 32 #define PCIE_HHBM_MAX_SIZE 2048 -#define SKB_BUF_SIZE 2048 - #define QTN_PCIE_BOARDFLG "PCIEQTN" #define QTN_PCIE_FW_DLMASK 0xF #define QTN_PCIE_FW_BUFSZ 2048 From 789763b683eb7770dec4c6d62ccf89a80fb0e9aa Mon Sep 17 00:00:00 2001 From: Igor Mitsyanko Date: Mon, 24 Sep 2018 15:15:10 -0700 Subject: [PATCH 271/276] qtnfmac_pcie: rename platform-specific functions Rename several functions to indicate that they are platform specific. Signed-off-by: Igor Mitsyanko Signed-off-by: Kalle Valo --- .../quantenna/qtnfmac/pcie/pearl_pcie.c | 101 +++++++++--------- 1 file changed, 52 insertions(+), 49 deletions(-) diff --git a/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie.c b/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie.c index 97f3001846f8..fd11dd25ba53 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie.c +++ b/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie.c @@ -226,7 +226,7 @@ static void qtnf_deassert_intx(struct qtnf_pcie_pearl_state *ps) qtnf_non_posted_write(cfg, reg); } -static void qtnf_reset_card(struct qtnf_pcie_pearl_state *ps) +static void qtnf_pearl_reset_ep(struct qtnf_pcie_pearl_state *ps) { const u32 data = QTN_PEARL_IPC_IRQ_WORD(QTN_PEARL_LHOST_EP_RESET); void __iomem *reg = ps->base.sysctl_bar + @@ -237,7 +237,7 @@ static void qtnf_reset_card(struct qtnf_pcie_pearl_state *ps) pci_restore_state(ps->base.pdev); } -static void qtnf_ipc_gen_ep_int(void *arg) +static void qtnf_pcie_pearl_ipc_gen_ep_int(void *arg) { const struct qtnf_pcie_pearl_state *ps = arg; const u32 data = QTN_PEARL_IPC_IRQ_WORD(QTN_PEARL_LHOST_IPC_IRQ); @@ -297,7 +297,8 @@ static int qtnf_pcie_init_shm_ipc(struct qtnf_pcie_pearl_state *ps) { struct qtnf_shm_ipc_region __iomem *ipc_tx_reg; struct qtnf_shm_ipc_region __iomem *ipc_rx_reg; - const struct qtnf_shm_ipc_int ipc_int = { qtnf_ipc_gen_ep_int, ps }; + const struct qtnf_shm_ipc_int ipc_int = { + qtnf_pcie_pearl_ipc_gen_ep_int, ps }; const struct qtnf_shm_ipc_rx_callback rx_callback = { qtnf_pcie_control_rx_callback, ps }; @@ -442,7 +443,7 @@ static int alloc_skb_array(struct qtnf_pcie_bus_priv *priv) return 0; } -static int alloc_bd_table(struct qtnf_pcie_pearl_state *ps) +static int pearl_alloc_bd_table(struct qtnf_pcie_pearl_state *ps) { struct qtnf_pcie_bus_priv *priv = &ps->base; dma_addr_t paddr; @@ -494,7 +495,7 @@ static int alloc_bd_table(struct qtnf_pcie_pearl_state *ps) return 0; } -static int skb2rbd_attach(struct qtnf_pcie_pearl_state *ps, u16 index) +static int pearl_skb2rbd_attach(struct qtnf_pcie_pearl_state *ps, u16 index) { struct qtnf_pcie_bus_priv *priv = &ps->base; struct qtnf_pearl_rx_bd *rxbd; @@ -538,7 +539,7 @@ static int skb2rbd_attach(struct qtnf_pcie_pearl_state *ps, u16 index) return 0; } -static int alloc_rx_buffers(struct qtnf_pcie_pearl_state *ps) +static int pearl_alloc_rx_buffers(struct qtnf_pcie_pearl_state *ps) { u16 i; int ret = 0; @@ -547,7 +548,7 @@ static int alloc_rx_buffers(struct qtnf_pcie_pearl_state *ps) ps->base.rx_bd_num * sizeof(struct qtnf_pearl_rx_bd)); for (i = 0; i < ps->base.rx_bd_num; i++) { - ret = skb2rbd_attach(ps, i); + ret = pearl_skb2rbd_attach(ps, i); if (ret) break; } @@ -556,7 +557,7 @@ static int alloc_rx_buffers(struct qtnf_pcie_pearl_state *ps) } /* all rx/tx activity should have ceased before calling this function */ -static void qtnf_free_xfer_buffers(struct qtnf_pcie_pearl_state *ps) +static void qtnf_pearl_free_xfer_buffers(struct qtnf_pcie_pearl_state *ps) { struct qtnf_pcie_bus_priv *priv = &ps->base; struct qtnf_pearl_tx_bd *txbd; @@ -594,7 +595,7 @@ static void qtnf_free_xfer_buffers(struct qtnf_pcie_pearl_state *ps) } } -static int qtnf_hhbm_init(struct qtnf_pcie_pearl_state *ps) +static int pearl_hhbm_init(struct qtnf_pcie_pearl_state *ps) { u32 val; @@ -612,7 +613,7 @@ static int qtnf_hhbm_init(struct qtnf_pcie_pearl_state *ps) return 0; } -static int qtnf_pcie_init_xfer(struct qtnf_pcie_pearl_state *ps) +static int qtnf_pcie_pearl_init_xfer(struct qtnf_pcie_pearl_state *ps) { struct qtnf_pcie_bus_priv *priv = &ps->base; int ret; @@ -649,7 +650,7 @@ static int qtnf_pcie_init_xfer(struct qtnf_pcie_pearl_state *ps) return -EINVAL; } - ret = qtnf_hhbm_init(ps); + ret = pearl_hhbm_init(ps); if (ret) { pr_err("failed to init h/w queues\n"); return ret; @@ -661,13 +662,13 @@ static int qtnf_pcie_init_xfer(struct qtnf_pcie_pearl_state *ps) return ret; } - ret = alloc_bd_table(ps); + ret = pearl_alloc_bd_table(ps); if (ret) { pr_err("failed to allocate bd table\n"); return ret; } - ret = alloc_rx_buffers(ps); + ret = pearl_alloc_rx_buffers(ps); if (ret) { pr_err("failed to allocate rx buffers\n"); return ret; @@ -676,7 +677,7 @@ static int qtnf_pcie_init_xfer(struct qtnf_pcie_pearl_state *ps) return ret; } -static void qtnf_pcie_data_tx_reclaim(struct qtnf_pcie_pearl_state *ps) +static void qtnf_pearl_data_tx_reclaim(struct qtnf_pcie_pearl_state *ps) { struct qtnf_pcie_bus_priv *priv = &ps->base; struct qtnf_pearl_tx_bd *txbd; @@ -734,7 +735,7 @@ static int qtnf_tx_queue_ready(struct qtnf_pcie_pearl_state *ps) if (!CIRC_SPACE(priv->tx_bd_w_index, priv->tx_bd_r_index, priv->tx_bd_num)) { - qtnf_pcie_data_tx_reclaim(ps); + qtnf_pearl_data_tx_reclaim(ps); if (!CIRC_SPACE(priv->tx_bd_w_index, priv->tx_bd_r_index, priv->tx_bd_num)) { @@ -818,7 +819,7 @@ static int qtnf_pcie_data_tx(struct qtnf_bus *bus, struct sk_buff *skb) priv->tx_done_count++; spin_unlock_irqrestore(&priv->tx_lock, flags); - qtnf_pcie_data_tx_reclaim(ps); + qtnf_pearl_data_tx_reclaim(ps); return NETDEV_TX_OK; } @@ -838,7 +839,7 @@ static int qtnf_pcie_control_tx(struct qtnf_bus *bus, struct sk_buff *skb) return ret; } -static irqreturn_t qtnf_interrupt(int irq, void *data) +static irqreturn_t qtnf_pcie_pearl_interrupt(int irq, void *data) { struct qtnf_bus *bus = (struct qtnf_bus *)data; struct qtnf_pcie_pearl_state *ps = (void *)get_bus_priv(bus); @@ -898,7 +899,7 @@ static int qtnf_rx_data_ready(struct qtnf_pcie_pearl_state *ps) return 0; } -static int qtnf_rx_poll(struct napi_struct *napi, int budget) +static int qtnf_pcie_pearl_rx_poll(struct napi_struct *napi, int budget) { struct qtnf_bus *bus = container_of(napi, struct qtnf_bus, mux_napi); struct qtnf_pcie_pearl_state *ps = (void *)get_bus_priv(bus); @@ -982,7 +983,7 @@ static int qtnf_rx_poll(struct napi_struct *napi, int budget) if (++w_idx >= priv->rx_bd_num) w_idx = 0; - ret = skb2rbd_attach(ps, w_idx); + ret = pearl_skb2rbd_attach(ps, w_idx); if (ret) { pr_err("failed to allocate new rx_skb[%d]\n", w_idx); @@ -1026,7 +1027,7 @@ static void qtnf_pcie_data_rx_stop(struct qtnf_bus *bus) qtnf_disable_hdp_irqs(ps); } -static const struct qtnf_bus_ops qtnf_pcie_bus_ops = { +static const struct qtnf_bus_ops qtnf_pcie_pearl_bus_ops = { /* control path methods */ .control_tx = qtnf_pcie_control_tx, @@ -1234,7 +1235,7 @@ qtnf_ep_fw_load(struct qtnf_pcie_pearl_state *ps, const u8 *fw, u32 fw_size) continue; } - qtnf_pcie_data_tx_reclaim(ps); + qtnf_pearl_data_tx_reclaim(ps); } pblk += len; @@ -1245,7 +1246,7 @@ qtnf_ep_fw_load(struct qtnf_pcie_pearl_state *ps, const u8 *fw, u32 fw_size) return 0; } -static void qtnf_fw_work_handler(struct work_struct *work) +static void qtnf_pearl_fw_work_handler(struct work_struct *work) { struct qtnf_bus *bus = container_of(work, struct qtnf_bus, fw_work); struct qtnf_pcie_pearl_state *ps = (void *)get_bus_priv(bus); @@ -1336,19 +1337,20 @@ static void qtnf_bringup_fw_async(struct qtnf_bus *bus) struct pci_dev *pdev = priv->pdev; get_device(&pdev->dev); - INIT_WORK(&bus->fw_work, qtnf_fw_work_handler); + INIT_WORK(&bus->fw_work, qtnf_pearl_fw_work_handler); schedule_work(&bus->fw_work); } -static void qtnf_reclaim_tasklet_fn(unsigned long data) +static void qtnf_pearl_reclaim_tasklet_fn(unsigned long data) { struct qtnf_pcie_pearl_state *ps = (void *)data; - qtnf_pcie_data_tx_reclaim(ps); + qtnf_pearl_data_tx_reclaim(ps); qtnf_en_txdone_irq(ps); } -static int qtnf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) +static int qtnf_pcie_pearl_probe(struct pci_dev *pdev, + const struct pci_device_id *id) { struct qtnf_pcie_pearl_state *ps; struct qtnf_bus *bus; @@ -1362,7 +1364,7 @@ static int qtnf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) ps = get_bus_priv(bus); pci_set_drvdata(pdev, bus); - bus->bus_ops = &qtnf_pcie_bus_ops; + bus->bus_ops = &qtnf_pcie_pearl_bus_ops; bus->dev = &pdev->dev; bus->fw_state = QTNF_FW_STATE_RESET; ps->base.pdev = pdev; @@ -1383,12 +1385,12 @@ static int qtnf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) ps->base.tx_reclaim_done = 0; ps->base.tx_reclaim_req = 0; - tasklet_init(&ps->base.reclaim_tq, qtnf_reclaim_tasklet_fn, + tasklet_init(&ps->base.reclaim_tq, qtnf_pearl_reclaim_tasklet_fn, (unsigned long)ps); init_dummy_netdev(&bus->mux_dev); netif_napi_add(&bus->mux_dev, &bus->mux_napi, - qtnf_rx_poll, 10); + qtnf_pcie_pearl_rx_poll, 10); ps->base.workqueue = create_singlethread_workqueue("QTNF_PEARL_PCIE"); if (!ps->base.workqueue) { @@ -1440,7 +1442,7 @@ static int qtnf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) goto err_base; } - ret = qtnf_pcie_init_xfer(ps); + ret = qtnf_pcie_pearl_init_xfer(ps); if (ret) { pr_err("PCIE xfer init failed\n"); goto err_ipc; @@ -1452,7 +1454,8 @@ static int qtnf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) /* start with disabled irqs */ qtnf_disable_hdp_irqs(ps); - ret = devm_request_irq(&pdev->dev, pdev->irq, &qtnf_interrupt, 0, + ret = devm_request_irq(&pdev->dev, pdev->irq, + &qtnf_pcie_pearl_interrupt, 0, "qtnf_pcie_irq", (void *)bus); if (ret) { pr_err("failed to request pcie irq %d\n", pdev->irq); @@ -1464,7 +1467,7 @@ static int qtnf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) return 0; err_xfer: - qtnf_free_xfer_buffers(ps); + qtnf_pearl_free_xfer_buffers(ps); err_ipc: qtnf_pcie_free_shm_ipc(&ps->base); @@ -1481,7 +1484,7 @@ static int qtnf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) return ret; } -static void qtnf_pcie_remove(struct pci_dev *pdev) +static void qtnf_pcie_pearl_remove(struct pci_dev *pdev) { struct qtnf_pcie_pearl_state *ps; struct qtnf_bus *bus; @@ -1497,24 +1500,24 @@ static void qtnf_pcie_remove(struct pci_dev *pdev) qtnf_core_detach(bus); ps = get_bus_priv(bus); - qtnf_reset_card(ps); + qtnf_pearl_reset_ep(ps); netif_napi_del(&bus->mux_napi); flush_workqueue(ps->base.workqueue); destroy_workqueue(ps->base.workqueue); tasklet_kill(&ps->base.reclaim_tq); - qtnf_free_xfer_buffers(ps); + qtnf_pearl_free_xfer_buffers(ps); qtnf_pcie_free_shm_ipc(&ps->base); qtnf_debugfs_remove(bus); } #ifdef CONFIG_PM_SLEEP -static int qtnf_pcie_suspend(struct device *dev) +static int qtnf_pcie_pearl_suspend(struct device *dev) { return -EOPNOTSUPP; } -static int qtnf_pcie_resume(struct device *dev) +static int qtnf_pcie_pearl_resume(struct device *dev) { return 0; } @@ -1522,8 +1525,8 @@ static int qtnf_pcie_resume(struct device *dev) #ifdef CONFIG_PM_SLEEP /* Power Management Hooks */ -static SIMPLE_DEV_PM_OPS(qtnf_pcie_pm_ops, qtnf_pcie_suspend, - qtnf_pcie_resume); +static SIMPLE_DEV_PM_OPS(qtnf_pcie_pearl_pm_ops, qtnf_pcie_pearl_suspend, + qtnf_pcie_pearl_resume); #endif static const struct pci_device_id qtnf_pcie_devid_table[] = { @@ -1536,32 +1539,32 @@ static const struct pci_device_id qtnf_pcie_devid_table[] = { MODULE_DEVICE_TABLE(pci, qtnf_pcie_devid_table); -static struct pci_driver qtnf_pcie_drv_data = { +static struct pci_driver qtnf_pcie_pearl_drv_data = { .name = DRV_NAME, .id_table = qtnf_pcie_devid_table, - .probe = qtnf_pcie_probe, - .remove = qtnf_pcie_remove, + .probe = qtnf_pcie_pearl_probe, + .remove = qtnf_pcie_pearl_remove, #ifdef CONFIG_PM_SLEEP .driver = { - .pm = &qtnf_pcie_pm_ops, + .pm = &qtnf_pcie_pearl_pm_ops, }, #endif }; -static int __init qtnf_pcie_register(void) +static int __init qtnf_pcie_pearl_register(void) { pr_info("register Quantenna QSR10g FullMAC PCIE driver\n"); - return pci_register_driver(&qtnf_pcie_drv_data); + return pci_register_driver(&qtnf_pcie_pearl_drv_data); } -static void __exit qtnf_pcie_exit(void) +static void __exit qtnf_pcie_pearl_exit(void) { pr_info("unregister Quantenna QSR10g FullMAC PCIE driver\n"); - pci_unregister_driver(&qtnf_pcie_drv_data); + pci_unregister_driver(&qtnf_pcie_pearl_drv_data); } -module_init(qtnf_pcie_register); -module_exit(qtnf_pcie_exit); +module_init(qtnf_pcie_pearl_register); +module_exit(qtnf_pcie_pearl_exit); MODULE_AUTHOR("Quantenna Communications"); MODULE_DESCRIPTION("Quantenna QSR10g PCIe bus driver for 802.11 wireless LAN."); From 5163309e9a4d0972e9cac843cd2fb71443324b55 Mon Sep 17 00:00:00 2001 From: Igor Mitsyanko Date: Mon, 24 Sep 2018 15:15:11 -0700 Subject: [PATCH 272/276] qtnfmac: add missing header includes to bus.h A few include directives were missing in bus.h resulting in dependency of include order in other modules. Add missing includes. Signed-off-by: Igor Mitsyanko Signed-off-by: Kalle Valo --- drivers/net/wireless/quantenna/qtnfmac/bus.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/wireless/quantenna/qtnfmac/bus.h b/drivers/net/wireless/quantenna/qtnfmac/bus.h index 2beca5b9de84..7c4f8568d940 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/bus.h +++ b/drivers/net/wireless/quantenna/qtnfmac/bus.h @@ -20,6 +20,9 @@ #include #include +#include "trans.h" +#include "core.h" + #define QTNF_MAX_MAC 3 enum qtnf_fw_state { From addc7540708f52959c99ed3b9758a09070c102dc Mon Sep 17 00:00:00 2001 From: Igor Mitsyanko Date: Mon, 24 Sep 2018 15:15:12 -0700 Subject: [PATCH 273/276] qtnfmac_pcie: extract platform-independent PCIe code Extract platform-independent PCIe driver code into a separate file, and use it from platform-specific modules. Signed-off-by: Igor Mitsyanko Signed-off-by: Kalle Valo --- .../net/wireless/quantenna/qtnfmac/Makefile | 1 + .../wireless/quantenna/qtnfmac/pcie/pcie.c | 393 ++++++++++++++++ .../quantenna/qtnfmac/pcie/pcie_priv.h | 15 + .../quantenna/qtnfmac/pcie/pearl_pcie.c | 425 ++---------------- .../quantenna/qtnfmac/pcie/pearl_pcie_ipc.h | 4 - 5 files changed, 455 insertions(+), 383 deletions(-) create mode 100644 drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c diff --git a/drivers/net/wireless/quantenna/qtnfmac/Makefile b/drivers/net/wireless/quantenna/qtnfmac/Makefile index 9eeddea6b106..17cd7adb4109 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/Makefile +++ b/drivers/net/wireless/quantenna/qtnfmac/Makefile @@ -23,6 +23,7 @@ obj-$(CONFIG_QTNFMAC_PEARL_PCIE) += qtnfmac_pearl_pcie.o qtnfmac_pearl_pcie-objs += \ shm_ipc.o \ + pcie/pcie.o \ pcie/pearl_pcie.o qtnfmac_pearl_pcie-$(CONFIG_DEBUG_FS) += debug.o diff --git a/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c b/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c new file mode 100644 index 000000000000..f83951cd0636 --- /dev/null +++ b/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c @@ -0,0 +1,393 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* Copyright (c) 2018 Quantenna Communications, Inc. All rights reserved. */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pcie_priv.h" +#include "bus.h" +#include "shm_ipc.h" +#include "core.h" +#include "debug.h" + +#undef pr_fmt +#define pr_fmt(fmt) "qtnf_pcie: %s: " fmt, __func__ + +#define QTN_SYSCTL_BAR 0 +#define QTN_SHMEM_BAR 2 +#define QTN_DMA_BAR 3 + +int qtnf_pcie_control_tx(struct qtnf_bus *bus, struct sk_buff *skb) +{ + struct qtnf_pcie_bus_priv *priv = get_bus_priv(bus); + int ret; + + ret = qtnf_shm_ipc_send(&priv->shm_ipc_ep_in, skb->data, skb->len); + + if (ret == -ETIMEDOUT) { + pr_err("EP firmware is dead\n"); + bus->fw_state = QTNF_FW_STATE_EP_DEAD; + } + + return ret; +} + +int qtnf_pcie_alloc_skb_array(struct qtnf_pcie_bus_priv *priv) +{ + struct sk_buff **vaddr; + int len; + + len = priv->tx_bd_num * sizeof(*priv->tx_skb) + + priv->rx_bd_num * sizeof(*priv->rx_skb); + vaddr = devm_kzalloc(&priv->pdev->dev, len, GFP_KERNEL); + + if (!vaddr) + return -ENOMEM; + + priv->tx_skb = vaddr; + + vaddr += priv->tx_bd_num; + priv->rx_skb = vaddr; + + return 0; +} + +void qtnf_pcie_bringup_fw_async(struct qtnf_bus *bus) +{ + struct qtnf_pcie_bus_priv *priv = get_bus_priv(bus); + struct pci_dev *pdev = priv->pdev; + + get_device(&pdev->dev); + schedule_work(&bus->fw_work); +} + +static int qtnf_dbg_mps_show(struct seq_file *s, void *data) +{ + struct qtnf_bus *bus = dev_get_drvdata(s->private); + struct qtnf_pcie_bus_priv *priv = get_bus_priv(bus); + + seq_printf(s, "%d\n", priv->mps); + + return 0; +} + +static int qtnf_dbg_msi_show(struct seq_file *s, void *data) +{ + struct qtnf_bus *bus = dev_get_drvdata(s->private); + struct qtnf_pcie_bus_priv *priv = get_bus_priv(bus); + + seq_printf(s, "%u\n", priv->msi_enabled); + + return 0; +} + +static int qtnf_dbg_shm_stats(struct seq_file *s, void *data) +{ + struct qtnf_bus *bus = dev_get_drvdata(s->private); + struct qtnf_pcie_bus_priv *priv = get_bus_priv(bus); + + seq_printf(s, "shm_ipc_ep_in.tx_packet_count(%zu)\n", + priv->shm_ipc_ep_in.tx_packet_count); + seq_printf(s, "shm_ipc_ep_in.rx_packet_count(%zu)\n", + priv->shm_ipc_ep_in.rx_packet_count); + seq_printf(s, "shm_ipc_ep_out.tx_packet_count(%zu)\n", + priv->shm_ipc_ep_out.tx_timeout_count); + seq_printf(s, "shm_ipc_ep_out.rx_packet_count(%zu)\n", + priv->shm_ipc_ep_out.rx_packet_count); + + return 0; +} + +void qtnf_pcie_fw_boot_done(struct qtnf_bus *bus, bool boot_success, + const char *drv_name) +{ + struct qtnf_pcie_bus_priv *priv = get_bus_priv(bus); + struct pci_dev *pdev = priv->pdev; + int ret; + + if (boot_success) { + bus->fw_state = QTNF_FW_STATE_FW_DNLD_DONE; + + ret = qtnf_core_attach(bus); + if (ret) { + pr_err("failed to attach core\n"); + boot_success = false; + } + } + + if (boot_success) { + qtnf_debugfs_init(bus, drv_name); + qtnf_debugfs_add_entry(bus, "mps", qtnf_dbg_mps_show); + qtnf_debugfs_add_entry(bus, "msi_enabled", qtnf_dbg_msi_show); + qtnf_debugfs_add_entry(bus, "shm_stats", qtnf_dbg_shm_stats); + } else { + bus->fw_state = QTNF_FW_STATE_DETACHED; + } + + complete(&bus->firmware_init_complete); + put_device(&pdev->dev); +} + +static void qtnf_tune_pcie_mps(struct qtnf_pcie_bus_priv *priv) +{ + struct pci_dev *pdev = priv->pdev; + struct pci_dev *parent; + int mps_p, mps_o, mps_m, mps; + int ret; + + /* current mps */ + mps_o = pcie_get_mps(pdev); + + /* maximum supported mps */ + mps_m = 128 << pdev->pcie_mpss; + + /* suggested new mps value */ + mps = mps_m; + + if (pdev->bus && pdev->bus->self) { + /* parent (bus) mps */ + parent = pdev->bus->self; + + if (pci_is_pcie(parent)) { + mps_p = pcie_get_mps(parent); + mps = min(mps_m, mps_p); + } + } + + ret = pcie_set_mps(pdev, mps); + if (ret) { + pr_err("failed to set mps to %d, keep using current %d\n", + mps, mps_o); + priv->mps = mps_o; + return; + } + + pr_debug("set mps to %d (was %d, max %d)\n", mps, mps_o, mps_m); + priv->mps = mps; +} + +static void qtnf_pcie_init_irq(struct qtnf_pcie_bus_priv *priv, bool use_msi) +{ + struct pci_dev *pdev = priv->pdev; + + /* fall back to legacy INTx interrupts by default */ + priv->msi_enabled = 0; + + /* check if MSI capability is available */ + if (use_msi) { + if (!pci_enable_msi(pdev)) { + pr_debug("enabled MSI interrupt\n"); + priv->msi_enabled = 1; + } else { + pr_warn("failed to enable MSI interrupts"); + } + } + + if (!priv->msi_enabled) { + pr_warn("legacy PCIE interrupts enabled\n"); + pci_intx(pdev, 1); + } +} + +static void __iomem *qtnf_map_bar(struct qtnf_pcie_bus_priv *priv, u8 index) +{ + void __iomem *vaddr; + dma_addr_t busaddr; + size_t len; + int ret; + + ret = pcim_iomap_regions(priv->pdev, 1 << index, "qtnfmac_pcie"); + if (ret) + return IOMEM_ERR_PTR(ret); + + busaddr = pci_resource_start(priv->pdev, index); + len = pci_resource_len(priv->pdev, index); + vaddr = pcim_iomap_table(priv->pdev)[index]; + if (!vaddr) + return IOMEM_ERR_PTR(-ENOMEM); + + pr_debug("BAR%u vaddr=0x%p busaddr=%pad len=%u\n", + index, vaddr, &busaddr, (int)len); + + return vaddr; +} + +static int qtnf_pcie_init_memory(struct qtnf_pcie_bus_priv *priv) +{ + int ret = -ENOMEM; + + priv->sysctl_bar = qtnf_map_bar(priv, QTN_SYSCTL_BAR); + if (IS_ERR(priv->sysctl_bar)) { + pr_err("failed to map BAR%u\n", QTN_SYSCTL_BAR); + return ret; + } + + priv->dmareg_bar = qtnf_map_bar(priv, QTN_DMA_BAR); + if (IS_ERR(priv->dmareg_bar)) { + pr_err("failed to map BAR%u\n", QTN_DMA_BAR); + return ret; + } + + priv->epmem_bar = qtnf_map_bar(priv, QTN_SHMEM_BAR); + if (IS_ERR(priv->epmem_bar)) { + pr_err("failed to map BAR%u\n", QTN_SHMEM_BAR); + return ret; + } + + return 0; +} + +static void qtnf_pcie_control_rx_callback(void *arg, const u8 *buf, size_t len) +{ + struct qtnf_pcie_bus_priv *priv = arg; + struct qtnf_bus *bus = pci_get_drvdata(priv->pdev); + struct sk_buff *skb; + + if (unlikely(len == 0)) { + pr_warn("zero length packet received\n"); + return; + } + + skb = __dev_alloc_skb(len, GFP_KERNEL); + + if (unlikely(!skb)) { + pr_err("failed to allocate skb\n"); + return; + } + + skb_put_data(skb, buf, len); + + qtnf_trans_handle_rx_ctl_packet(bus, skb); +} + +void qtnf_pcie_init_shm_ipc(struct qtnf_pcie_bus_priv *priv, + struct qtnf_shm_ipc_region __iomem *ipc_tx_reg, + struct qtnf_shm_ipc_region __iomem *ipc_rx_reg, + const struct qtnf_shm_ipc_int *ipc_int) +{ + const struct qtnf_shm_ipc_rx_callback rx_callback = { + qtnf_pcie_control_rx_callback, priv }; + + qtnf_shm_ipc_init(&priv->shm_ipc_ep_in, QTNF_SHM_IPC_OUTBOUND, + ipc_tx_reg, priv->workqueue, + ipc_int, &rx_callback); + qtnf_shm_ipc_init(&priv->shm_ipc_ep_out, QTNF_SHM_IPC_INBOUND, + ipc_rx_reg, priv->workqueue, + ipc_int, &rx_callback); +} + +int qtnf_pcie_probe(struct pci_dev *pdev, size_t priv_size, + const struct qtnf_bus_ops *bus_ops, u64 dma_mask, + bool use_msi) +{ + struct qtnf_pcie_bus_priv *pcie_priv; + struct qtnf_bus *bus; + int ret; + + bus = devm_kzalloc(&pdev->dev, + sizeof(*bus) + priv_size, GFP_KERNEL); + if (!bus) + return -ENOMEM; + + pcie_priv = get_bus_priv(bus); + + pci_set_drvdata(pdev, bus); + bus->bus_ops = bus_ops; + bus->dev = &pdev->dev; + bus->fw_state = QTNF_FW_STATE_RESET; + pcie_priv->pdev = pdev; + pcie_priv->tx_stopped = 0; + + init_completion(&bus->firmware_init_complete); + mutex_init(&bus->bus_lock); + spin_lock_init(&pcie_priv->tx_lock); + spin_lock_init(&pcie_priv->tx_reclaim_lock); + + pcie_priv->tx_full_count = 0; + pcie_priv->tx_done_count = 0; + pcie_priv->pcie_irq_count = 0; + pcie_priv->tx_reclaim_done = 0; + pcie_priv->tx_reclaim_req = 0; + + pcie_priv->workqueue = create_singlethread_workqueue("QTNF_PCIE"); + if (!pcie_priv->workqueue) { + pr_err("failed to alloc bus workqueue\n"); + ret = -ENODEV; + goto err_init; + } + + init_dummy_netdev(&bus->mux_dev); + + if (!pci_is_pcie(pdev)) { + pr_err("device %s is not PCI Express\n", pci_name(pdev)); + ret = -EIO; + goto err_base; + } + + qtnf_tune_pcie_mps(pcie_priv); + + ret = pcim_enable_device(pdev); + if (ret) { + pr_err("failed to init PCI device %x\n", pdev->device); + goto err_base; + } else { + pr_debug("successful init of PCI device %x\n", pdev->device); + } + + ret = dma_set_mask_and_coherent(&pdev->dev, dma_mask); + if (ret) { + pr_err("PCIE DMA coherent mask init failed\n"); + goto err_base; + } + + pci_set_master(pdev); + qtnf_pcie_init_irq(pcie_priv, use_msi); + + ret = qtnf_pcie_init_memory(pcie_priv); + if (ret < 0) { + pr_err("PCIE memory init failed\n"); + goto err_base; + } + + pci_save_state(pdev); + + return 0; + +err_base: + flush_workqueue(pcie_priv->workqueue); + destroy_workqueue(pcie_priv->workqueue); +err_init: + pci_set_drvdata(pdev, NULL); + + return ret; +} + +static void qtnf_pcie_free_shm_ipc(struct qtnf_pcie_bus_priv *priv) +{ + qtnf_shm_ipc_free(&priv->shm_ipc_ep_in); + qtnf_shm_ipc_free(&priv->shm_ipc_ep_out); +} + +void qtnf_pcie_remove(struct qtnf_bus *bus, struct qtnf_pcie_bus_priv *priv) +{ + wait_for_completion(&bus->firmware_init_complete); + + if (bus->fw_state == QTNF_FW_STATE_ACTIVE || + bus->fw_state == QTNF_FW_STATE_EP_DEAD) + qtnf_core_detach(bus); + + netif_napi_del(&bus->mux_napi); + flush_workqueue(priv->workqueue); + destroy_workqueue(priv->workqueue); + tasklet_kill(&priv->reclaim_tq); + + qtnf_pcie_free_shm_ipc(priv); + qtnf_debugfs_remove(bus); + pci_set_drvdata(priv->pdev, NULL); +} diff --git a/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie_priv.h b/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie_priv.h index 8da9612eeed3..5c70fb4c0f92 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie_priv.h +++ b/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie_priv.h @@ -12,6 +12,7 @@ #include #include "shm_ipc.h" +#include "bus.h" #define SKB_BUF_SIZE 2048 @@ -59,6 +60,20 @@ struct qtnf_pcie_bus_priv { u8 tx_stopped; }; +int qtnf_pcie_control_tx(struct qtnf_bus *bus, struct sk_buff *skb); +int qtnf_pcie_alloc_skb_array(struct qtnf_pcie_bus_priv *priv); +void qtnf_pcie_bringup_fw_async(struct qtnf_bus *bus); +void qtnf_pcie_fw_boot_done(struct qtnf_bus *bus, bool boot_success, + const char *drv_name); +void qtnf_pcie_init_shm_ipc(struct qtnf_pcie_bus_priv *priv, + struct qtnf_shm_ipc_region __iomem *ipc_tx_reg, + struct qtnf_shm_ipc_region __iomem *ipc_rx_reg, + const struct qtnf_shm_ipc_int *ipc_int); +int qtnf_pcie_probe(struct pci_dev *pdev, size_t priv_size, + const struct qtnf_bus_ops *bus_ops, u64 dma_mask, + bool use_msi); +void qtnf_pcie_remove(struct qtnf_bus *bus, struct qtnf_pcie_bus_priv *priv); + static inline void qtnf_non_posted_write(u32 val, void __iomem *basereg) { writel(val, basereg); diff --git a/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie.c b/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie.c index fd11dd25ba53..6d72a9d0b3c3 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie.c +++ b/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie.c @@ -193,29 +193,6 @@ static inline void qtnf_dis_txdone_irq(struct qtnf_pcie_pearl_state *ps) spin_unlock_irqrestore(&ps->irq_lock, flags); } -static void qtnf_pcie_init_irq(struct qtnf_pcie_bus_priv *priv) -{ - struct pci_dev *pdev = priv->pdev; - - /* fall back to legacy INTx interrupts by default */ - priv->msi_enabled = 0; - - /* check if MSI capability is available */ - if (use_msi) { - if (!pci_enable_msi(pdev)) { - pr_debug("MSI interrupt enabled\n"); - priv->msi_enabled = 1; - } else { - pr_warn("failed to enable MSI interrupts"); - } - } - - if (!priv->msi_enabled) { - pr_warn("legacy PCIE interrupts enabled\n"); - pci_intx(pdev, 1); - } -} - static void qtnf_deassert_intx(struct qtnf_pcie_pearl_state *ps) { void __iomem *reg = ps->base.sysctl_bar + PEARL_PCIE_CFG0_OFFSET; @@ -247,148 +224,6 @@ static void qtnf_pcie_pearl_ipc_gen_ep_int(void *arg) qtnf_non_posted_write(data, reg); } -static void __iomem *qtnf_map_bar(struct qtnf_pcie_bus_priv *priv, u8 index) -{ - void __iomem *vaddr; - dma_addr_t busaddr; - size_t len; - int ret; - - ret = pcim_iomap_regions(priv->pdev, 1 << index, DRV_NAME); - if (ret) - return IOMEM_ERR_PTR(ret); - - busaddr = pci_resource_start(priv->pdev, index); - len = pci_resource_len(priv->pdev, index); - vaddr = pcim_iomap_table(priv->pdev)[index]; - if (!vaddr) - return IOMEM_ERR_PTR(-ENOMEM); - - pr_debug("BAR%u vaddr=0x%p busaddr=%pad len=%u\n", - index, vaddr, &busaddr, (int)len); - - return vaddr; -} - -static void qtnf_pcie_control_rx_callback(void *arg, const u8 *buf, size_t len) -{ - struct qtnf_pcie_bus_priv *priv = arg; - struct qtnf_bus *bus = pci_get_drvdata(priv->pdev); - struct sk_buff *skb; - - if (unlikely(len == 0)) { - pr_warn("zero length packet received\n"); - return; - } - - skb = __dev_alloc_skb(len, GFP_KERNEL); - - if (unlikely(!skb)) { - pr_err("failed to allocate skb\n"); - return; - } - - skb_put_data(skb, buf, len); - - qtnf_trans_handle_rx_ctl_packet(bus, skb); -} - -static int qtnf_pcie_init_shm_ipc(struct qtnf_pcie_pearl_state *ps) -{ - struct qtnf_shm_ipc_region __iomem *ipc_tx_reg; - struct qtnf_shm_ipc_region __iomem *ipc_rx_reg; - const struct qtnf_shm_ipc_int ipc_int = { - qtnf_pcie_pearl_ipc_gen_ep_int, ps }; - const struct qtnf_shm_ipc_rx_callback rx_callback = { - qtnf_pcie_control_rx_callback, ps }; - - ipc_tx_reg = &ps->bda->bda_shm_reg1; - ipc_rx_reg = &ps->bda->bda_shm_reg2; - - qtnf_shm_ipc_init(&ps->base.shm_ipc_ep_in, QTNF_SHM_IPC_OUTBOUND, - ipc_tx_reg, ps->base.workqueue, - &ipc_int, &rx_callback); - qtnf_shm_ipc_init(&ps->base.shm_ipc_ep_out, QTNF_SHM_IPC_INBOUND, - ipc_rx_reg, ps->base.workqueue, - &ipc_int, &rx_callback); - - return 0; -} - -static void qtnf_pcie_free_shm_ipc(struct qtnf_pcie_bus_priv *priv) -{ - qtnf_shm_ipc_free(&priv->shm_ipc_ep_in); - qtnf_shm_ipc_free(&priv->shm_ipc_ep_out); -} - -static int qtnf_pcie_init_memory(struct qtnf_pcie_pearl_state *ps) -{ - struct qtnf_pcie_bus_priv *priv = &ps->base; - int ret = -ENOMEM; - - priv->sysctl_bar = qtnf_map_bar(priv, QTN_SYSCTL_BAR); - if (IS_ERR(priv->sysctl_bar)) { - pr_err("failed to map BAR%u\n", QTN_SYSCTL_BAR); - return ret; - } - - priv->dmareg_bar = qtnf_map_bar(priv, QTN_DMA_BAR); - if (IS_ERR(priv->dmareg_bar)) { - pr_err("failed to map BAR%u\n", QTN_DMA_BAR); - return ret; - } - - priv->epmem_bar = qtnf_map_bar(priv, QTN_SHMEM_BAR); - if (IS_ERR(priv->epmem_bar)) { - pr_err("failed to map BAR%u\n", QTN_SHMEM_BAR); - return ret; - } - - ps->pcie_reg_base = priv->dmareg_bar; - ps->bda = priv->epmem_bar; - writel(priv->msi_enabled, &ps->bda->bda_rc_msi_enabled); - - return 0; -} - -static void qtnf_tune_pcie_mps(struct qtnf_pcie_bus_priv *priv) -{ - struct pci_dev *pdev = priv->pdev; - struct pci_dev *parent; - int mps_p, mps_o, mps_m, mps; - int ret; - - /* current mps */ - mps_o = pcie_get_mps(pdev); - - /* maximum supported mps */ - mps_m = 128 << pdev->pcie_mpss; - - /* suggested new mps value */ - mps = mps_m; - - if (pdev->bus && pdev->bus->self) { - /* parent (bus) mps */ - parent = pdev->bus->self; - - if (pci_is_pcie(parent)) { - mps_p = pcie_get_mps(parent); - mps = min(mps_m, mps_p); - } - } - - ret = pcie_set_mps(pdev, mps); - if (ret) { - pr_err("failed to set mps to %d, keep using current %d\n", - mps, mps_o); - priv->mps = mps_o; - return; - } - - pr_debug("set mps to %d (was %d, max %d)\n", mps, mps_o, mps_m); - priv->mps = mps; -} - static int qtnf_is_state(__le32 __iomem *reg, u32 state) { u32 s = readl(reg); @@ -423,26 +258,6 @@ static int qtnf_poll_state(__le32 __iomem *reg, u32 state, u32 delay_in_ms) return 0; } -static int alloc_skb_array(struct qtnf_pcie_bus_priv *priv) -{ - struct sk_buff **vaddr; - int len; - - len = priv->tx_bd_num * sizeof(*priv->tx_skb) + - priv->rx_bd_num * sizeof(*priv->rx_skb); - vaddr = devm_kzalloc(&priv->pdev->dev, len, GFP_KERNEL); - - if (!vaddr) - return -ENOMEM; - - priv->tx_skb = vaddr; - - vaddr += priv->tx_bd_num; - priv->rx_skb = vaddr; - - return 0; -} - static int pearl_alloc_bd_table(struct qtnf_pcie_pearl_state *ps) { struct qtnf_pcie_bus_priv *priv = &ps->base; @@ -656,7 +471,7 @@ static int qtnf_pcie_pearl_init_xfer(struct qtnf_pcie_pearl_state *ps) return ret; } - ret = alloc_skb_array(priv); + ret = qtnf_pcie_alloc_skb_array(priv); if (ret) { pr_err("failed to allocate skb array\n"); return ret; @@ -750,7 +565,7 @@ static int qtnf_tx_queue_ready(struct qtnf_pcie_pearl_state *ps) static int qtnf_pcie_data_tx(struct qtnf_bus *bus, struct sk_buff *skb) { - struct qtnf_pcie_pearl_state *ps = (void *)get_bus_priv(bus); + struct qtnf_pcie_pearl_state *ps = get_bus_priv(bus); struct qtnf_pcie_bus_priv *priv = &ps->base; dma_addr_t txbd_paddr, skb_paddr; struct qtnf_pearl_tx_bd *txbd; @@ -824,25 +639,10 @@ static int qtnf_pcie_data_tx(struct qtnf_bus *bus, struct sk_buff *skb) return NETDEV_TX_OK; } -static int qtnf_pcie_control_tx(struct qtnf_bus *bus, struct sk_buff *skb) -{ - struct qtnf_pcie_bus_priv *priv = (void *)get_bus_priv(bus); - int ret; - - ret = qtnf_shm_ipc_send(&priv->shm_ipc_ep_in, skb->data, skb->len); - - if (ret == -ETIMEDOUT) { - pr_err("EP firmware is dead\n"); - bus->fw_state = QTNF_FW_STATE_EP_DEAD; - } - - return ret; -} - static irqreturn_t qtnf_pcie_pearl_interrupt(int irq, void *data) { struct qtnf_bus *bus = (struct qtnf_bus *)data; - struct qtnf_pcie_pearl_state *ps = (void *)get_bus_priv(bus); + struct qtnf_pcie_pearl_state *ps = get_bus_priv(bus); struct qtnf_pcie_bus_priv *priv = &ps->base; u32 status; @@ -902,7 +702,7 @@ static int qtnf_rx_data_ready(struct qtnf_pcie_pearl_state *ps) static int qtnf_pcie_pearl_rx_poll(struct napi_struct *napi, int budget) { struct qtnf_bus *bus = container_of(napi, struct qtnf_bus, mux_napi); - struct qtnf_pcie_pearl_state *ps = (void *)get_bus_priv(bus); + struct qtnf_pcie_pearl_state *ps = get_bus_priv(bus); struct qtnf_pcie_bus_priv *priv = &ps->base; struct net_device *ndev = NULL; struct sk_buff *skb = NULL; @@ -1038,26 +838,6 @@ static const struct qtnf_bus_ops qtnf_pcie_pearl_bus_ops = { .data_rx_stop = qtnf_pcie_data_rx_stop, }; -static int qtnf_dbg_mps_show(struct seq_file *s, void *data) -{ - struct qtnf_bus *bus = dev_get_drvdata(s->private); - struct qtnf_pcie_bus_priv *priv = get_bus_priv(bus); - - seq_printf(s, "%d\n", priv->mps); - - return 0; -} - -static int qtnf_dbg_msi_show(struct seq_file *s, void *data) -{ - struct qtnf_bus *bus = dev_get_drvdata(s->private); - struct qtnf_pcie_bus_priv *priv = get_bus_priv(bus); - - seq_printf(s, "%u\n", priv->msi_enabled); - - return 0; -} - static int qtnf_dbg_irq_stats(struct seq_file *s, void *data) { struct qtnf_bus *bus = dev_get_drvdata(s->private); @@ -1114,27 +894,9 @@ static int qtnf_dbg_hdp_stats(struct seq_file *s, void *data) return 0; } -static int qtnf_dbg_shm_stats(struct seq_file *s, void *data) -{ - struct qtnf_bus *bus = dev_get_drvdata(s->private); - struct qtnf_pcie_bus_priv *priv = get_bus_priv(bus); - - seq_printf(s, "shm_ipc_ep_in.tx_packet_count(%zu)\n", - priv->shm_ipc_ep_in.tx_packet_count); - seq_printf(s, "shm_ipc_ep_in.rx_packet_count(%zu)\n", - priv->shm_ipc_ep_in.rx_packet_count); - seq_printf(s, "shm_ipc_ep_out.tx_packet_count(%zu)\n", - priv->shm_ipc_ep_out.tx_timeout_count); - seq_printf(s, "shm_ipc_ep_out.rx_packet_count(%zu)\n", - priv->shm_ipc_ep_out.rx_packet_count); - - return 0; -} - -static int qtnf_ep_fw_send(struct qtnf_pcie_pearl_state *ps, uint32_t size, +static int qtnf_ep_fw_send(struct pci_dev *pdev, uint32_t size, int blk, const u8 *pblk, const u8 *fw) { - struct pci_dev *pdev = ps->base.pdev; struct qtnf_bus *bus = pci_get_drvdata(pdev); struct qtnf_pearl_fw_hdr *hdr; @@ -1197,7 +959,7 @@ qtnf_ep_fw_load(struct qtnf_pcie_pearl_state *ps, const u8 *fw, u32 fw_size) return -ETIMEDOUT; } - len = qtnf_ep_fw_send(ps, fw_size, blk, pblk, fw); + len = qtnf_ep_fw_send(ps->base.pdev, fw_size, blk, pblk, fw); if (len <= 0) continue; @@ -1255,6 +1017,7 @@ static void qtnf_pearl_fw_work_handler(struct work_struct *work) int ret; u32 state = QTN_RC_FW_LOADRDY | QTN_RC_FW_QLINK; const char *fwname = QTN_PCI_PEARL_FW_NAME; + bool fw_boot_success = false; if (flashboot) { state |= QTN_RC_FW_FLASHBOOT; @@ -1262,7 +1025,7 @@ static void qtnf_pearl_fw_work_handler(struct work_struct *work) ret = request_firmware(&fw, fwname, &pdev->dev); if (ret < 0) { pr_err("failed to get firmware %s\n", fwname); - goto fw_load_fail; + goto fw_load_exit; } } @@ -1275,13 +1038,14 @@ static void qtnf_pearl_fw_work_handler(struct work_struct *work) if (!flashboot) release_firmware(fw); - goto fw_load_fail; + goto fw_load_exit; } qtnf_clear_state(&ps->bda->bda_ep_state, QTN_EP_FW_LOADRDY); if (flashboot) { pr_info("booting firmware from flash\n"); + } else { pr_info("starting firmware upload: %s\n", fwname); @@ -1289,56 +1053,33 @@ static void qtnf_pearl_fw_work_handler(struct work_struct *work) release_firmware(fw); if (ret) { pr_err("firmware upload error\n"); - goto fw_load_fail; + goto fw_load_exit; } } if (qtnf_poll_state(&ps->bda->bda_ep_state, QTN_EP_FW_DONE, QTN_FW_DL_TIMEOUT_MS)) { pr_err("firmware bringup timed out\n"); - goto fw_load_fail; + goto fw_load_exit; } - bus->fw_state = QTNF_FW_STATE_FW_DNLD_DONE; pr_info("firmware is up and running\n"); if (qtnf_poll_state(&ps->bda->bda_ep_state, QTN_EP_FW_QLINK_DONE, QTN_FW_QLINK_TIMEOUT_MS)) { pr_err("firmware runtime failure\n"); - goto fw_load_fail; + goto fw_load_exit; } - ret = qtnf_core_attach(bus); - if (ret) { - pr_err("failed to attach core\n"); - goto fw_load_fail; - } - - qtnf_debugfs_init(bus, DRV_NAME); - qtnf_debugfs_add_entry(bus, "mps", qtnf_dbg_mps_show); - qtnf_debugfs_add_entry(bus, "msi_enabled", qtnf_dbg_msi_show); - qtnf_debugfs_add_entry(bus, "hdp_stats", qtnf_dbg_hdp_stats); - qtnf_debugfs_add_entry(bus, "irq_stats", qtnf_dbg_irq_stats); - qtnf_debugfs_add_entry(bus, "shm_stats", qtnf_dbg_shm_stats); - - goto fw_load_exit; - -fw_load_fail: - bus->fw_state = QTNF_FW_STATE_DETACHED; + fw_boot_success = true; fw_load_exit: - complete(&bus->firmware_init_complete); - put_device(&pdev->dev); -} + qtnf_pcie_fw_boot_done(bus, fw_boot_success, DRV_NAME); -static void qtnf_bringup_fw_async(struct qtnf_bus *bus) -{ - struct qtnf_pcie_bus_priv *priv = (void *)get_bus_priv(bus); - struct pci_dev *pdev = priv->pdev; - - get_device(&pdev->dev); - INIT_WORK(&bus->fw_work, qtnf_pearl_fw_work_handler); - schedule_work(&bus->fw_work); + if (fw_boot_success) { + qtnf_debugfs_add_entry(bus, "hdp_stats", qtnf_dbg_hdp_stats); + qtnf_debugfs_add_entry(bus, "irq_stats", qtnf_dbg_irq_stats); + } } static void qtnf_pearl_reclaim_tasklet_fn(unsigned long data) @@ -1352,100 +1093,47 @@ static void qtnf_pearl_reclaim_tasklet_fn(unsigned long data) static int qtnf_pcie_pearl_probe(struct pci_dev *pdev, const struct pci_device_id *id) { + struct qtnf_shm_ipc_int ipc_int; struct qtnf_pcie_pearl_state *ps; struct qtnf_bus *bus; int ret; + u64 dma_mask; - bus = devm_kzalloc(&pdev->dev, - sizeof(*bus) + sizeof(*ps), GFP_KERNEL); - if (!bus) - return -ENOMEM; +#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT + dma_mask = DMA_BIT_MASK(64); +#else + dma_mask = DMA_BIT_MASK(32); +#endif + ret = qtnf_pcie_probe(pdev, sizeof(*ps), &qtnf_pcie_pearl_bus_ops, + dma_mask, use_msi); + if (ret) + return ret; + + bus = pci_get_drvdata(pdev); ps = get_bus_priv(bus); - pci_set_drvdata(pdev, bus); - bus->bus_ops = &qtnf_pcie_pearl_bus_ops; - bus->dev = &pdev->dev; - bus->fw_state = QTNF_FW_STATE_RESET; - ps->base.pdev = pdev; - - init_completion(&bus->firmware_init_complete); - mutex_init(&bus->bus_lock); - spin_lock_init(&ps->base.tx_lock); spin_lock_init(&ps->irq_lock); - spin_lock_init(&ps->base.tx_reclaim_lock); - - /* init stats */ - ps->base.tx_full_count = 0; - ps->base.tx_done_count = 0; - ps->base.pcie_irq_count = 0; - ps->pcie_irq_rx_count = 0; - ps->pcie_irq_tx_count = 0; - ps->pcie_irq_uf_count = 0; - ps->base.tx_reclaim_done = 0; - ps->base.tx_reclaim_req = 0; tasklet_init(&ps->base.reclaim_tq, qtnf_pearl_reclaim_tasklet_fn, (unsigned long)ps); - - init_dummy_netdev(&bus->mux_dev); netif_napi_add(&bus->mux_dev, &bus->mux_napi, qtnf_pcie_pearl_rx_poll, 10); + INIT_WORK(&bus->fw_work, qtnf_pearl_fw_work_handler); - ps->base.workqueue = create_singlethread_workqueue("QTNF_PEARL_PCIE"); - if (!ps->base.workqueue) { - pr_err("failed to alloc bus workqueue\n"); - ret = -ENODEV; - goto err_init; - } + ps->pcie_reg_base = ps->base.dmareg_bar; + ps->bda = ps->base.epmem_bar; + writel(ps->base.msi_enabled, &ps->bda->bda_rc_msi_enabled); - if (!pci_is_pcie(pdev)) { - pr_err("device %s is not PCI Express\n", pci_name(pdev)); - ret = -EIO; - goto err_base; - } - - qtnf_tune_pcie_mps(&ps->base); - - ret = pcim_enable_device(pdev); - if (ret) { - pr_err("failed to init PCI device %x\n", pdev->device); - goto err_base; - } else { - pr_debug("successful init of PCI device %x\n", pdev->device); - } - -#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT - ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)); -#else - ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); -#endif - if (ret) { - pr_err("PCIE DMA coherent mask init failed\n"); - goto err_base; - } - - pci_set_master(pdev); - qtnf_pcie_init_irq(&ps->base); - - ret = qtnf_pcie_init_memory(ps); - if (ret < 0) { - pr_err("PCIE memory init failed\n"); - goto err_base; - } - - pci_save_state(pdev); - - ret = qtnf_pcie_init_shm_ipc(ps); - if (ret < 0) { - pr_err("PCIE SHM IPC init failed\n"); - goto err_base; - } + ipc_int.fn = qtnf_pcie_pearl_ipc_gen_ep_int; + ipc_int.arg = ps; + qtnf_pcie_init_shm_ipc(&ps->base, &ps->bda->bda_shm_reg1, + &ps->bda->bda_shm_reg2, &ipc_int); ret = qtnf_pcie_pearl_init_xfer(ps); if (ret) { pr_err("PCIE xfer init failed\n"); - goto err_ipc; + goto error; } /* init default irq settings */ @@ -1462,24 +1150,14 @@ static int qtnf_pcie_pearl_probe(struct pci_dev *pdev, goto err_xfer; } - qtnf_bringup_fw_async(bus); + qtnf_pcie_bringup_fw_async(bus); return 0; err_xfer: qtnf_pearl_free_xfer_buffers(ps); - -err_ipc: - qtnf_pcie_free_shm_ipc(&ps->base); - -err_base: - flush_workqueue(ps->base.workqueue); - destroy_workqueue(ps->base.workqueue); - -err_init: - tasklet_kill(&ps->base.reclaim_tq); - netif_napi_del(&bus->mux_napi); - pci_set_drvdata(pdev, NULL); +error: + qtnf_pcie_remove(bus, &ps->base); return ret; } @@ -1493,22 +1171,11 @@ static void qtnf_pcie_pearl_remove(struct pci_dev *pdev) if (!bus) return; - wait_for_completion(&bus->firmware_init_complete); - - if (bus->fw_state == QTNF_FW_STATE_ACTIVE || - bus->fw_state == QTNF_FW_STATE_EP_DEAD) - qtnf_core_detach(bus); - ps = get_bus_priv(bus); - qtnf_pearl_reset_ep(ps); - netif_napi_del(&bus->mux_napi); - flush_workqueue(ps->base.workqueue); - destroy_workqueue(ps->base.workqueue); - tasklet_kill(&ps->base.reclaim_tq); + qtnf_pcie_remove(bus, &ps->base); + qtnf_pearl_reset_ep(ps); qtnf_pearl_free_xfer_buffers(ps); - qtnf_pcie_free_shm_ipc(&ps->base); - qtnf_debugfs_remove(bus); } #ifdef CONFIG_PM_SLEEP diff --git a/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie_ipc.h b/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie_ipc.h index b87505d9de29..f21e97ede090 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie_ipc.h +++ b/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie_ipc.h @@ -63,10 +63,6 @@ #define QTN_HOST_ADDR(h, l) ((u32)l) #endif -#define QTN_SYSCTL_BAR 0 -#define QTN_SHMEM_BAR 2 -#define QTN_DMA_BAR 3 - #define QTN_PCIE_BDA_VERSION 0x1002 #define PCIE_BDA_NAMELEN 32 From 86ca238cf1e99794be77d299639d6e2a1dfd67a6 Mon Sep 17 00:00:00 2001 From: Igor Mitsyanko Date: Mon, 24 Sep 2018 15:15:13 -0700 Subject: [PATCH 274/276] qtnfmac: wait for FW load work to finish at PCIe remove Waiting for "completion" to be set in FW load thread can not be used in case PCIe remove is called before FW load work was scheduled. Just wait for work completion instead to avoid problems. Signed-off-by: Igor Mitsyanko Signed-off-by: Kalle Valo --- drivers/net/wireless/quantenna/qtnfmac/bus.h | 1 - drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c | 4 +--- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/net/wireless/quantenna/qtnfmac/bus.h b/drivers/net/wireless/quantenna/qtnfmac/bus.h index 7c4f8568d940..528ca7f5e070 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/bus.h +++ b/drivers/net/wireless/quantenna/qtnfmac/bus.h @@ -62,7 +62,6 @@ struct qtnf_bus { struct qtnf_hw_info hw_info; struct napi_struct mux_napi; struct net_device mux_dev; - struct completion firmware_init_complete; struct workqueue_struct *workqueue; struct work_struct fw_work; struct work_struct event_work; diff --git a/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c b/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c index f83951cd0636..d1637f2354a6 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c +++ b/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c @@ -130,7 +130,6 @@ void qtnf_pcie_fw_boot_done(struct qtnf_bus *bus, bool boot_success, bus->fw_state = QTNF_FW_STATE_DETACHED; } - complete(&bus->firmware_init_complete); put_device(&pdev->dev); } @@ -304,7 +303,6 @@ int qtnf_pcie_probe(struct pci_dev *pdev, size_t priv_size, pcie_priv->pdev = pdev; pcie_priv->tx_stopped = 0; - init_completion(&bus->firmware_init_complete); mutex_init(&bus->bus_lock); spin_lock_init(&pcie_priv->tx_lock); spin_lock_init(&pcie_priv->tx_reclaim_lock); @@ -376,7 +374,7 @@ static void qtnf_pcie_free_shm_ipc(struct qtnf_pcie_bus_priv *priv) void qtnf_pcie_remove(struct qtnf_bus *bus, struct qtnf_pcie_bus_priv *priv) { - wait_for_completion(&bus->firmware_init_complete); + cancel_work_sync(&bus->fw_work); if (bus->fw_state == QTNF_FW_STATE_ACTIVE || bus->fw_state == QTNF_FW_STATE_EP_DEAD) From 033a759921d1ae97437bcda44e7ac5a57c81e9c8 Mon Sep 17 00:00:00 2001 From: Igor Mitsyanko Date: Mon, 24 Sep 2018 15:15:14 -0700 Subject: [PATCH 275/276] qtnfmac_pcie: check for correct CHIP ID at pcie probe Make sure that wifi device is of supported variant by checking it's CHIP ID before completing a probe sequence. Signed-off-by: Igor Mitsyanko Signed-off-by: Kalle Valo --- .../quantenna/qtnfmac/pcie/pearl_pcie.c | 24 +++++++++++++++++++ .../wireless/quantenna/qtnfmac/qtn_hw_ids.h | 14 +++++++++++ 2 files changed, 38 insertions(+) diff --git a/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie.c b/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie.c index 6d72a9d0b3c3..5aca12a51fe3 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie.c +++ b/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie.c @@ -1090,6 +1090,26 @@ static void qtnf_pearl_reclaim_tasklet_fn(unsigned long data) qtnf_en_txdone_irq(ps); } +static int qtnf_pearl_check_chip_id(struct qtnf_pcie_pearl_state *ps) +{ + unsigned int chipid; + + chipid = qtnf_chip_id_get(ps->base.sysctl_bar); + + switch (chipid) { + case QTN_CHIP_ID_PEARL: + case QTN_CHIP_ID_PEARL_B: + case QTN_CHIP_ID_PEARL_C: + pr_info("chip ID is 0x%x\n", chipid); + break; + default: + pr_err("incorrect chip ID 0x%x\n", chipid); + return -ENODEV; + } + + return 0; +} + static int qtnf_pcie_pearl_probe(struct pci_dev *pdev, const struct pci_device_id *id) { @@ -1130,6 +1150,10 @@ static int qtnf_pcie_pearl_probe(struct pci_dev *pdev, qtnf_pcie_init_shm_ipc(&ps->base, &ps->bda->bda_shm_reg1, &ps->bda->bda_shm_reg2, &ipc_int); + ret = qtnf_pearl_check_chip_id(ps); + if (ret) + goto error; + ret = qtnf_pcie_pearl_init_xfer(ps); if (ret) { pr_err("PCIE xfer init failed\n"); diff --git a/drivers/net/wireless/quantenna/qtnfmac/qtn_hw_ids.h b/drivers/net/wireless/quantenna/qtnfmac/qtn_hw_ids.h index c4ad40d59085..1fe798a9a667 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/qtn_hw_ids.h +++ b/drivers/net/wireless/quantenna/qtnfmac/qtn_hw_ids.h @@ -25,8 +25,22 @@ #define PCIE_DEVICE_ID_QTN_PEARL (0x0008) +#define QTN_REG_SYS_CTRL_CSR 0x14 +#define QTN_CHIP_ID_MASK 0xF0 +#define QTN_CHIP_ID_TOPAZ 0x40 +#define QTN_CHIP_ID_PEARL 0x50 +#define QTN_CHIP_ID_PEARL_B 0x60 +#define QTN_CHIP_ID_PEARL_C 0x70 + /* FW names */ #define QTN_PCI_PEARL_FW_NAME "qtn/fmac_qsr10g.img" +static inline unsigned int qtnf_chip_id_get(const void __iomem *regs_base) +{ + u32 board_rev = readl(regs_base + QTN_REG_SYS_CTRL_CSR); + + return board_rev & QTN_CHIP_ID_MASK; +} + #endif /* _QTN_HW_IDS_H_ */ From 297fab130cdfb3ec5bf5c53cd5f3b02a2a3d7abb Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Thu, 27 Sep 2018 17:11:19 +0100 Subject: [PATCH 276/276] b43: fix spelling mistake "hw_registred" -> "hw_registered" Trivial fix to spelling mistake struct field name, rename it. Signed-off-by: Colin Ian King Signed-off-by: Kalle Valo --- drivers/net/wireless/broadcom/b43/b43.h | 2 +- drivers/net/wireless/broadcom/b43/main.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/broadcom/b43/b43.h b/drivers/net/wireless/broadcom/b43/b43.h index b77d1a904f7e..9fc7c088a539 100644 --- a/drivers/net/wireless/broadcom/b43/b43.h +++ b/drivers/net/wireless/broadcom/b43/b43.h @@ -909,7 +909,7 @@ struct b43_wl { /* Set this if we call ieee80211_register_hw() and check if we call * ieee80211_unregister_hw(). */ - bool hw_registred; + bool hw_registered; /* We can only have one operating interface (802.11 core) * at a time. General information about this interface follows. diff --git a/drivers/net/wireless/broadcom/b43/main.c b/drivers/net/wireless/broadcom/b43/main.c index b37e7391f55d..4daa1ce8cba3 100644 --- a/drivers/net/wireless/broadcom/b43/main.c +++ b/drivers/net/wireless/broadcom/b43/main.c @@ -2611,7 +2611,7 @@ static void b43_request_firmware(struct work_struct *work) err = ieee80211_register_hw(wl->hw); if (err) goto err_one_core_detach; - wl->hw_registred = true; + wl->hw_registered = true; b43_leds_register(wl->current_dev); /* Register HW RNG driver */ @@ -5610,7 +5610,7 @@ static struct b43_wl *b43_wireless_init(struct b43_bus_dev *dev) wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST); - wl->hw_registred = false; + wl->hw_registered = false; hw->max_rates = 2; SET_IEEE80211_DEV(hw, dev->dev); if (is_valid_ether_addr(sprom->et1mac)) @@ -5693,7 +5693,7 @@ static void b43_bcma_remove(struct bcma_device *core) B43_WARN_ON(!wl); if (!wldev->fw.ucode.data) return; /* NULL if firmware never loaded */ - if (wl->current_dev == wldev && wl->hw_registred) { + if (wl->current_dev == wldev && wl->hw_registered) { b43_leds_stop(wldev); ieee80211_unregister_hw(wl->hw); } @@ -5776,7 +5776,7 @@ static void b43_ssb_remove(struct ssb_device *sdev) B43_WARN_ON(!wl); if (!wldev->fw.ucode.data) return; /* NULL if firmware never loaded */ - if (wl->current_dev == wldev && wl->hw_registred) { + if (wl->current_dev == wldev && wl->hw_registered) { b43_leds_stop(wldev); ieee80211_unregister_hw(wl->hw); }