From 32a2be499c01ee523b28018d451b39ded4297b11 Mon Sep 17 00:00:00 2001 From: Miles Hu Date: Fri, 8 May 2020 05:54:57 +0300 Subject: [PATCH 01/20] ath11k: remove stale monitor status descriptor The driver is not handling monitor status descriptor whenever the done bit of status descriptor is not set by hardware. This leave a stale entry in monitor status ring and flooding warning message. Fix that by removing the descriptor and move forward to next one in monitor status ring. Co-developed-by: Rajkumar Manoharan Signed-off-by: Rajkumar Manoharan Signed-off-by: Miles Hu Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/1588642063-6950-1-git-send-email-rmanohar@codeaurora.org --- drivers/net/wireless/ath/ath11k/dp_rx.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c index 85670608c3e2..a54610d75c40 100644 --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c @@ -2728,7 +2728,7 @@ static int ath11k_dp_rx_reap_mon_status_ring(struct ath11k_base *ab, int mac_id, ath11k_warn(ab, "rx monitor status with invalid buf_id %d\n", buf_id); spin_unlock_bh(&rx_ring->idr_lock); - continue; + goto move_next; } idr_remove(&rx_ring->bufs_idr, buf_id); @@ -2747,13 +2747,16 @@ static int ath11k_dp_rx_reap_mon_status_ring(struct ath11k_base *ab, int mac_id, tlv = (struct hal_tlv_hdr *)skb->data; if (FIELD_GET(HAL_TLV_HDR_TAG, tlv->tl) != HAL_RX_STATUS_BUFFER_DONE) { - ath11k_hal_srng_src_get_next_entry(ab, srng); - continue; + ath11k_warn(ab, "mon status DONE not set %lx\n", + FIELD_GET(HAL_TLV_HDR_TAG, + tlv->tl)); + dev_kfree_skb_any(skb); + goto move_next; } __skb_queue_tail(skb_list, skb); } - +move_next: skb = ath11k_dp_rx_alloc_mon_status_buf(ab, rx_ring, &buf_id, GFP_ATOMIC); From 7c6d67b136ceb0aebc7a3153b300e925ed915daf Mon Sep 17 00:00:00 2001 From: Rakesh Pillai Date: Fri, 8 May 2020 05:55:07 +0300 Subject: [PATCH 02/20] ath10k: Skip handling del_server during driver exit The qmi infrastructure sends the client a del_server event when the client releases its qmi handle. This is not the msg indicating the actual qmi server exiting. In such cases the del_server msg should not be processed, since the wifi firmware does not reset its qmi state. Hence skip the processing of del_server event when the driver is unloading. Tested HW: WCN3990 Tested FW: WLAN.HL.3.1-01040-QCAHLSWMTPLZ-1 Fixes: ba94c753ccb4 ("ath10k: add QMI message handshake for wcn3990 client") Signed-off-by: Rakesh Pillai Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/1588663061-12138-1-git-send-email-pillair@codeaurora.org --- drivers/net/wireless/ath/ath10k/qmi.c | 13 ++++++++++++- drivers/net/wireless/ath/ath10k/qmi.h | 6 ++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath10k/qmi.c b/drivers/net/wireless/ath/ath10k/qmi.c index 5ae829b46c3d..5468a41e928e 100644 --- a/drivers/net/wireless/ath/ath10k/qmi.c +++ b/drivers/net/wireless/ath/ath10k/qmi.c @@ -961,7 +961,16 @@ static void ath10k_qmi_del_server(struct qmi_handle *qmi_hdl, container_of(qmi_hdl, struct ath10k_qmi, qmi_hdl); qmi->fw_ready = false; - ath10k_qmi_driver_event_post(qmi, ATH10K_QMI_EVENT_SERVER_EXIT, NULL); + + /* + * The del_server event is to be processed only if coming from + * the qmi server. The qmi infrastructure sends del_server, when + * any client releases the qmi handle. In this case do not process + * this del_server event. + */ + if (qmi->state == ATH10K_QMI_STATE_INIT_DONE) + ath10k_qmi_driver_event_post(qmi, ATH10K_QMI_EVENT_SERVER_EXIT, + NULL); } static struct qmi_ops ath10k_qmi_ops = { @@ -1046,6 +1055,7 @@ int ath10k_qmi_init(struct ath10k *ar, u32 msa_size) if (ret) goto err_qmi_lookup; + qmi->state = ATH10K_QMI_STATE_INIT_DONE; return 0; err_qmi_lookup: @@ -1064,6 +1074,7 @@ int ath10k_qmi_deinit(struct ath10k *ar) struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar); struct ath10k_qmi *qmi = ar_snoc->qmi; + qmi->state = ATH10K_QMI_STATE_DEINIT; qmi_handle_release(&qmi->qmi_hdl); cancel_work_sync(&qmi->event_work); destroy_workqueue(qmi->event_wq); diff --git a/drivers/net/wireless/ath/ath10k/qmi.h b/drivers/net/wireless/ath/ath10k/qmi.h index 450be18b60ad..16190511318d 100644 --- a/drivers/net/wireless/ath/ath10k/qmi.h +++ b/drivers/net/wireless/ath/ath10k/qmi.h @@ -83,6 +83,11 @@ struct ath10k_qmi_driver_event { void *data; }; +enum ath10k_qmi_state { + ATH10K_QMI_STATE_INIT_DONE, + ATH10K_QMI_STATE_DEINIT, +}; + struct ath10k_qmi { struct ath10k *ar; struct qmi_handle qmi_hdl; @@ -102,6 +107,7 @@ struct ath10k_qmi { char fw_build_timestamp[MAX_TIMESTAMP_LEN + 1]; struct ath10k_qmi_cal_data cal_data[MAX_NUM_CAL_V01]; bool msa_fixed_perm; + enum ath10k_qmi_state state; }; int ath10k_qmi_wlan_enable(struct ath10k *ar, From c730c477176ad4af86d9aae4d360a7ad840b073a Mon Sep 17 00:00:00 2001 From: Rakesh Pillai Date: Fri, 8 May 2020 05:55:18 +0300 Subject: [PATCH 03/20] ath10k: Remove msdu from idr when management pkt send fails Currently when the sending of any management pkt via wmi command fails, the packet is being unmapped freed in the error handling. But the idr entry added, which is used to track these packet is not getting removed. Hence, during unload, in wmi cleanup, all the entries in IDR are removed and the corresponding buffer is attempted to be freed. This can cause a situation where one packet is attempted to be freed twice. Fix this error by rmeoving the msdu from the idr list when the sending of a management packet over wmi fails. Tested HW: WCN3990 Tested FW: WLAN.HL.3.1-01040-QCAHLSWMTPLZ-1 Fixes: 1807da49733e ("ath10k: wmi: add management tx by reference support over wmi") Signed-off-by: Rakesh Pillai Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/1588667015-25490-1-git-send-email-pillair@codeaurora.org --- drivers/net/wireless/ath/ath10k/mac.c | 3 +++ drivers/net/wireless/ath/ath10k/wmi-ops.h | 10 ++++++++++ drivers/net/wireless/ath/ath10k/wmi-tlv.c | 15 +++++++++++++++ 3 files changed, 28 insertions(+) diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 91f5444ecedb..919d15584d4a 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -3967,6 +3967,9 @@ void ath10k_mgmt_over_wmi_tx_work(struct work_struct *work) if (ret) { ath10k_warn(ar, "failed to transmit management frame by ref via WMI: %d\n", ret); + /* remove this msdu from idr tracking */ + ath10k_wmi_cleanup_mgmt_tx_send(ar, skb); + dma_unmap_single(ar->dev, paddr, skb->len, DMA_TO_DEVICE); ieee80211_free_txskb(ar->hw, skb); diff --git a/drivers/net/wireless/ath/ath10k/wmi-ops.h b/drivers/net/wireless/ath/ath10k/wmi-ops.h index 6b730f59fd5b..0dd484f85082 100644 --- a/drivers/net/wireless/ath/ath10k/wmi-ops.h +++ b/drivers/net/wireless/ath/ath10k/wmi-ops.h @@ -140,6 +140,7 @@ struct wmi_ops { struct sk_buff *(*gen_mgmt_tx_send)(struct ath10k *ar, struct sk_buff *skb, dma_addr_t paddr); + int (*cleanup_mgmt_tx_send)(struct ath10k *ar, struct sk_buff *msdu); struct sk_buff *(*gen_dbglog_cfg)(struct ath10k *ar, u64 module_enable, u32 log_level); struct sk_buff *(*gen_pktlog_enable)(struct ath10k *ar, u32 filter); @@ -448,6 +449,15 @@ ath10k_wmi_get_txbf_conf_scheme(struct ath10k *ar) return ar->wmi.ops->get_txbf_conf_scheme(ar); } +static inline int +ath10k_wmi_cleanup_mgmt_tx_send(struct ath10k *ar, struct sk_buff *msdu) +{ + if (!ar->wmi.ops->cleanup_mgmt_tx_send) + return -EOPNOTSUPP; + + return ar->wmi.ops->cleanup_mgmt_tx_send(ar, msdu); +} + static inline int ath10k_wmi_mgmt_tx_send(struct ath10k *ar, struct sk_buff *msdu, dma_addr_t paddr) diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.c b/drivers/net/wireless/ath/ath10k/wmi-tlv.c index 9187b62b331c..afa03cb3aaf5 100644 --- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c +++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c @@ -3015,6 +3015,18 @@ ath10k_wmi_tlv_op_gen_request_peer_stats_info(struct ath10k *ar, return skb; } +static int +ath10k_wmi_tlv_op_cleanup_mgmt_tx_send(struct ath10k *ar, + struct sk_buff *msdu) +{ + struct ath10k_skb_cb *cb = ATH10K_SKB_CB(msdu); + struct ath10k_wmi *wmi = &ar->wmi; + + idr_remove(&wmi->mgmt_pending_tx, cb->msdu_id); + + return 0; +} + static int ath10k_wmi_mgmt_tx_alloc_msdu_id(struct ath10k *ar, struct sk_buff *skb, dma_addr_t paddr) @@ -3089,6 +3101,8 @@ ath10k_wmi_tlv_op_gen_mgmt_tx_send(struct ath10k *ar, struct sk_buff *msdu, if (desc_id < 0) goto err_free_skb; + cb->msdu_id = desc_id; + ptr = (void *)skb->data; tlv = ptr; tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_MGMT_TX_CMD); @@ -4540,6 +4554,7 @@ static const struct wmi_ops wmi_tlv_ops = { .gen_force_fw_hang = ath10k_wmi_tlv_op_gen_force_fw_hang, /* .gen_mgmt_tx = not implemented; HTT is used */ .gen_mgmt_tx_send = ath10k_wmi_tlv_op_gen_mgmt_tx_send, + .cleanup_mgmt_tx_send = ath10k_wmi_tlv_op_cleanup_mgmt_tx_send, .gen_dbglog_cfg = ath10k_wmi_tlv_op_gen_dbglog_cfg, .gen_pktlog_enable = ath10k_wmi_tlv_op_gen_pktlog_enable, .gen_pktlog_disable = ath10k_wmi_tlv_op_gen_pktlog_disable, From 04a4d3416372ae19471c98ea964a4740d289beac Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 8 May 2020 05:55:30 +0300 Subject: [PATCH 04/20] wil6210: avoid gcc-10 zero-length-bounds warning gcc-10 warns about accesses inside of a zero-length array: drivers/net/wireless/ath/wil6210/cfg80211.c: In function 'wil_cfg80211_scan': drivers/net/wireless/ath/wil6210/cfg80211.c:970:23: error: array subscript 255 is outside the bounds of an interior zero-length array 'struct [0]' [-Werror=zero-length-bounds] 970 | cmd.cmd.channel_list[cmd.cmd.num_channels++].channel = ch - 1; | ~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~ In file included from drivers/net/wireless/ath/wil6210/wil6210.h:17, from drivers/net/wireless/ath/wil6210/cfg80211.c:11: drivers/net/wireless/ath/wil6210/wmi.h:477:4: note: while referencing 'channel_list' 477 | } channel_list[0]; | ^~~~~~~~~~~~ Turn this into a flexible array to avoid the warning. Signed-off-by: Arnd Bergmann Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20200505143332.1398524-1-arnd@arndb.de --- drivers/net/wireless/ath/wil6210/wmi.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/wil6210/wmi.h b/drivers/net/wireless/ath/wil6210/wmi.h index e3558136e0c4..5bba45c1de48 100644 --- a/drivers/net/wireless/ath/wil6210/wmi.h +++ b/drivers/net/wireless/ath/wil6210/wmi.h @@ -474,7 +474,7 @@ struct wmi_start_scan_cmd { struct { u8 channel; u8 reserved; - } channel_list[0]; + } channel_list[]; } __packed; #define WMI_MAX_PNO_SSID_NUM (16) From e47210f72a681b5bd5189831f286053f7a04acb5 Mon Sep 17 00:00:00 2001 From: Wen Gong Date: Fri, 8 May 2020 05:55:38 +0300 Subject: [PATCH 05/20] ath10k: fix __le32 warning in ath10k_wmi_tlv_op_gen_request_peer_stats_info() Sparse warned: drivers/net/wireless/ath/ath10k/wmi-tlv.c:3013:34: warning: incorrect type in assignment (different base types) drivers/net/wireless/ath/ath10k/wmi-tlv.c:3013:34: expected restricted __le32 [usertype] reset_after_request drivers/net/wireless/ath/ath10k/wmi-tlv.c:3013:34: got unsigned int [usertype] reset Tested with QCA6174 SDIO with firmware WLAN.RMH.4.4.1-00042. Fixes: 0f7cb26830a6 ("ath10k: add rx bitrate report for SDIO") Signed-off-by: Wen Gong Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/1588747649-18051-1-git-send-email-kvalo@codeaurora.org --- drivers/net/wireless/ath/ath10k/wmi-tlv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.c b/drivers/net/wireless/ath/ath10k/wmi-tlv.c index afa03cb3aaf5..932266d1111b 100644 --- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c +++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c @@ -3010,7 +3010,7 @@ ath10k_wmi_tlv_op_gen_request_peer_stats_info(struct ath10k *ar, if (type == WMI_REQUEST_ONE_PEER_STATS_INFO) ether_addr_copy(cmd->peer_macaddr.addr, addr); - cmd->reset_after_request = reset; + cmd->reset_after_request = __cpu_to_le32(reset); ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv request peer stats info\n"); return skb; } From 31858805f91ac79f0f0d9d982e90c68d6d3ae164 Mon Sep 17 00:00:00 2001 From: Govind Singh Date: Fri, 8 May 2020 05:55:44 +0300 Subject: [PATCH 06/20] ath11k: Add support for multibus support Current design supports only AHB interface for 11ax chipset. Refactor the code by adding hif layer for bus level abstraction to support PCI based device. Signed-off-by: Govind Singh Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20200506094400.4740-2-govinds@codeaurora.org --- drivers/net/wireless/ath/ath11k/ahb.c | 49 +++++++++++--- drivers/net/wireless/ath/ath11k/ahb.h | 22 ------ drivers/net/wireless/ath/ath11k/core.c | 41 +++-------- drivers/net/wireless/ath/ath11k/core.h | 4 +- drivers/net/wireless/ath/ath11k/dp.c | 1 + drivers/net/wireless/ath/ath11k/hal.c | 86 ++++++++++++------------ drivers/net/wireless/ath/ath11k/hal_rx.c | 21 +++--- drivers/net/wireless/ath/ath11k/hal_tx.c | 11 +-- drivers/net/wireless/ath/ath11k/hif.h | 65 ++++++++++++++++++ drivers/net/wireless/ath/ath11k/htc.c | 3 +- 10 files changed, 182 insertions(+), 121 deletions(-) create mode 100644 drivers/net/wireless/ath/ath11k/hif.h diff --git a/drivers/net/wireless/ath/ath11k/ahb.c b/drivers/net/wireless/ath/ath11k/ahb.c index 3b2b76d602f2..eaba5a189b7f 100644 --- a/drivers/net/wireless/ath/ath11k/ahb.c +++ b/drivers/net/wireless/ath/ath11k/ahb.c @@ -10,6 +10,7 @@ #include #include "ahb.h" #include "debug.h" +#include "hif.h" #include static const struct of_device_id ath11k_ahb_of_match[] = { @@ -434,6 +435,16 @@ enum ext_irq_num { tcl2host_status_ring, }; +static inline u32 ath11k_ahb_read32(struct ath11k_base *ab, u32 offset) +{ + return ioread32(ab->mem + offset); +} + +static inline void ath11k_ahb_write32(struct ath11k_base *ab, u32 offset, u32 value) +{ + iowrite32(value, ab->mem + offset); +} + static void ath11k_ahb_kill_tasklets(struct ath11k_base *ab) { int i; @@ -575,7 +586,7 @@ static void ath11k_ahb_ce_irqs_disable(struct ath11k_base *ab) } } -int ath11k_ahb_start(struct ath11k_base *ab) +static int ath11k_ahb_start(struct ath11k_base *ab) { ath11k_ahb_ce_irqs_enable(ab); ath11k_ce_rx_post_buf(ab); @@ -583,7 +594,7 @@ int ath11k_ahb_start(struct ath11k_base *ab) return 0; } -void ath11k_ahb_ext_irq_enable(struct ath11k_base *ab) +static void ath11k_ahb_ext_irq_enable(struct ath11k_base *ab) { int i; @@ -595,13 +606,13 @@ void ath11k_ahb_ext_irq_enable(struct ath11k_base *ab) } } -void ath11k_ahb_ext_irq_disable(struct ath11k_base *ab) +static void ath11k_ahb_ext_irq_disable(struct ath11k_base *ab) { __ath11k_ahb_ext_irq_disable(ab); ath11k_ahb_sync_ext_irqs(ab); } -void ath11k_ahb_stop(struct ath11k_base *ab) +static void ath11k_ahb_stop(struct ath11k_base *ab) { if (!test_bit(ATH11K_FLAG_CRASH_FLUSH, &ab->dev_flags)) ath11k_ahb_ce_irqs_disable(ab); @@ -611,7 +622,7 @@ void ath11k_ahb_stop(struct ath11k_base *ab) ath11k_ce_cleanup_pipes(ab); } -int ath11k_ahb_power_up(struct ath11k_base *ab) +static int ath11k_ahb_power_up(struct ath11k_base *ab) { int ret; @@ -622,7 +633,7 @@ int ath11k_ahb_power_up(struct ath11k_base *ab) return ret; } -void ath11k_ahb_power_down(struct ath11k_base *ab) +static void ath11k_ahb_power_down(struct ath11k_base *ab) { rproc_shutdown(ab->tgt_rproc); } @@ -834,8 +845,8 @@ static int ath11k_ahb_config_irq(struct ath11k_base *ab) return ret; } -int ath11k_ahb_map_service_to_pipe(struct ath11k_base *ab, u16 service_id, - u8 *ul_pipe, u8 *dl_pipe) +static int ath11k_ahb_map_service_to_pipe(struct ath11k_base *ab, u16 service_id, + u8 *ul_pipe, u8 *dl_pipe) { const struct service_to_pipe *entry; bool ul_set = false, dl_set = false; @@ -877,6 +888,18 @@ int ath11k_ahb_map_service_to_pipe(struct ath11k_base *ab, u16 service_id, return 0; } +static const struct ath11k_hif_ops ath11k_ahb_hif_ops = { + .start = ath11k_ahb_start, + .stop = ath11k_ahb_stop, + .read32 = ath11k_ahb_read32, + .write32 = ath11k_ahb_write32, + .irq_enable = ath11k_ahb_ext_irq_enable, + .irq_disable = ath11k_ahb_ext_irq_disable, + .map_service_to_pipe = ath11k_ahb_map_service_to_pipe, + .power_down = ath11k_ahb_power_down, + .power_up = ath11k_ahb_power_up, +}; + static int ath11k_ahb_probe(struct platform_device *pdev) { struct ath11k_base *ab; @@ -915,6 +938,7 @@ static int ath11k_ahb_probe(struct platform_device *pdev) return -ENOMEM; } + ab->hif.ops = &ath11k_ahb_hif_ops; ab->pdev = pdev; ab->hw_rev = (enum ath11k_hw_rev)of_id->data; ab->mem = mem; @@ -993,12 +1017,17 @@ static struct platform_driver ath11k_ahb_driver = { .remove = ath11k_ahb_remove, }; -int ath11k_ahb_init(void) +static int ath11k_ahb_init(void) { return platform_driver_register(&ath11k_ahb_driver); } +module_init(ath11k_ahb_init); -void ath11k_ahb_exit(void) +static void ath11k_ahb_exit(void) { platform_driver_unregister(&ath11k_ahb_driver); } +module_exit(ath11k_ahb_exit); + +MODULE_DESCRIPTION("Driver support for Qualcomm Technologies 802.11ax wireless chip"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/ath/ath11k/ahb.h b/drivers/net/wireless/ath/ath11k/ahb.h index 93f46dfe22df..6c7b26ac6545 100644 --- a/drivers/net/wireless/ath/ath11k/ahb.h +++ b/drivers/net/wireless/ath/ath11k/ahb.h @@ -10,26 +10,4 @@ #define ATH11K_AHB_RECOVERY_TIMEOUT (3 * HZ) struct ath11k_base; -static inline u32 ath11k_ahb_read32(struct ath11k_base *ab, u32 offset) -{ - return ioread32(ab->mem + offset); -} - -static inline void ath11k_ahb_write32(struct ath11k_base *ab, u32 offset, u32 value) -{ - iowrite32(value, ab->mem + offset); -} - -void ath11k_ahb_ext_irq_enable(struct ath11k_base *ab); -void ath11k_ahb_ext_irq_disable(struct ath11k_base *ab); -int ath11k_ahb_start(struct ath11k_base *ab); -void ath11k_ahb_stop(struct ath11k_base *ab); -int ath11k_ahb_power_up(struct ath11k_base *ab); -void ath11k_ahb_power_down(struct ath11k_base *ab); -int ath11k_ahb_map_service_to_pipe(struct ath11k_base *ab, u16 service_id, - u8 *ul_pipe, u8 *dl_pipe); - -int ath11k_ahb_init(void); -void ath11k_ahb_exit(void); - #endif diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c index bf5657d2ae18..985ea3bcadb9 100644 --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c @@ -12,6 +12,7 @@ #include "dp_tx.h" #include "dp_rx.h" #include "debug.h" +#include "hif.h" unsigned int ath11k_debug_mask; module_param_named(debug_mask, ath11k_debug_mask, uint, 0644); @@ -41,6 +42,7 @@ u8 ath11k_core_get_hw_mac_id(struct ath11k_base *ab, int pdev_idx) return ATH11K_INVALID_HW_MAC_ID; } } +EXPORT_SYMBOL(ath11k_core_get_hw_mac_id); static int ath11k_core_create_board_name(struct ath11k_base *ab, char *name, size_t name_len) @@ -324,7 +326,7 @@ static void ath11k_core_stop(struct ath11k_base *ab) { if (!test_bit(ATH11K_FLAG_CRASH_FLUSH, &ab->dev_flags)) ath11k_qmi_firmware_stop(ab); - ath11k_ahb_stop(ab); + ath11k_hif_stop(ab); ath11k_wmi_detach(ab); ath11k_dp_pdev_reo_cleanup(ab); @@ -347,7 +349,7 @@ static int ath11k_core_soc_create(struct ath11k_base *ab) goto err_qmi_deinit; } - ret = ath11k_ahb_power_up(ab); + ret = ath11k_hif_power_up(ab); if (ret) { ath11k_err(ab, "failed to power up :%d\n", ret); goto err_debugfs_reg; @@ -415,7 +417,7 @@ static void ath11k_core_pdev_destroy(struct ath11k_base *ab) { ath11k_thermal_unregister(ab); ath11k_mac_unregister(ab); - ath11k_ahb_ext_irq_disable(ab); + ath11k_hif_irq_disable(ab); ath11k_dp_pdev_free(ab); ath11k_debug_pdev_destroy(ab); } @@ -443,7 +445,7 @@ static int ath11k_core_start(struct ath11k_base *ab, goto err_wmi_detach; } - ret = ath11k_ahb_start(ab); + ret = ath11k_hif_start(ab); if (ret) { ath11k_err(ab, "failed to start HIF: %d\n", ret); goto err_wmi_detach; @@ -522,7 +524,7 @@ err_reo_cleanup: err_mac_destroy: ath11k_mac_destroy(ab); err_hif_stop: - ath11k_ahb_stop(ab); + ath11k_hif_stop(ab); err_wmi_detach: ath11k_wmi_detach(ab); err_firmware_stop: @@ -559,7 +561,7 @@ int ath11k_core_qmi_firmware_ready(struct ath11k_base *ab) ath11k_err(ab, "failed to create pdev core: %d\n", ret); goto err_core_stop; } - ath11k_ahb_ext_irq_enable(ab); + ath11k_hif_irq_enable(ab); mutex_unlock(&ab->core_lock); return 0; @@ -579,9 +581,9 @@ static int ath11k_core_reconfigure_on_crash(struct ath11k_base *ab) mutex_lock(&ab->core_lock); ath11k_thermal_unregister(ab); - ath11k_ahb_ext_irq_disable(ab); + ath11k_hif_irq_disable(ab); ath11k_dp_pdev_free(ab); - ath11k_ahb_stop(ab); + ath11k_hif_stop(ab); ath11k_wmi_detach(ab); ath11k_dp_pdev_reo_cleanup(ab); mutex_unlock(&ab->core_lock); @@ -744,7 +746,7 @@ void ath11k_core_deinit(struct ath11k_base *ab) mutex_unlock(&ab->core_lock); - ath11k_ahb_power_down(ab); + ath11k_hif_power_down(ab); ath11k_mac_destroy(ab); ath11k_core_soc_destroy(ab); } @@ -784,24 +786,3 @@ err_sc_free: kfree(ab); return NULL; } - -static int __init ath11k_init(void) -{ - int ret; - - ret = ath11k_ahb_init(); - if (ret) - printk(KERN_ERR "failed to register ath11k ahb driver: %d\n", - ret); - return ret; -} -module_init(ath11k_init); - -static void __exit ath11k_exit(void) -{ - ath11k_ahb_exit(); -} -module_exit(ath11k_exit); - -MODULE_DESCRIPTION("Driver support for Qualcomm Technologies 802.11ax wireless chip"); -MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h index 70ec544eee67..e86513f5b757 100644 --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h @@ -607,7 +607,9 @@ struct ath11k_base { void __iomem *mem; unsigned long mem_len; - const struct ath11k_hif_ops *hif_ops; + struct { + const struct ath11k_hif_ops *ops; + } hif; struct ath11k_ce ce; struct timer_list rx_replenish_retry; diff --git a/drivers/net/wireless/ath/ath11k/dp.c b/drivers/net/wireless/ath/ath11k/dp.c index 145015d2f49c..9ae743e528af 100644 --- a/drivers/net/wireless/ath/ath11k/dp.c +++ b/drivers/net/wireless/ath/ath11k/dp.c @@ -701,6 +701,7 @@ int ath11k_dp_service_srng(struct ath11k_base *ab, done: return tot_work_done; } +EXPORT_SYMBOL(ath11k_dp_service_srng); void ath11k_dp_pdev_free(struct ath11k_base *ab) { diff --git a/drivers/net/wireless/ath/ath11k/hal.c b/drivers/net/wireless/ath/ath11k/hal.c index 9e40c4bdd674..6d937674215e 100644 --- a/drivers/net/wireless/ath/ath11k/hal.c +++ b/drivers/net/wireless/ath/ath11k/hal.c @@ -7,6 +7,7 @@ #include "hal_tx.h" #include "debug.h" #include "hal_desc.h" +#include "hif.h" static const struct hal_srng_config hw_srng_config[] = { /* TODO: max_rings can populated by querying HW capabilities */ @@ -351,11 +352,12 @@ static void ath11k_hal_ce_dst_setup(struct ath11k_base *ab, addr = HAL_CE_DST_RING_CTRL + srng_config->reg_start[HAL_SRNG_REG_GRP_R0] + ring_num * srng_config->reg_size[HAL_SRNG_REG_GRP_R0]; - val = ath11k_ahb_read32(ab, addr); + + val = ath11k_hif_read32(ab, addr); val &= ~HAL_CE_DST_R0_DEST_CTRL_MAX_LEN; val |= FIELD_PREP(HAL_CE_DST_R0_DEST_CTRL_MAX_LEN, srng->u.dst_ring.max_buffer_length); - ath11k_ahb_write32(ab, addr, val); + ath11k_hif_write32(ab, addr, val); } static void ath11k_hal_srng_dst_hw_init(struct ath11k_base *ab, @@ -369,34 +371,34 @@ static void ath11k_hal_srng_dst_hw_init(struct ath11k_base *ab, reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R0]; if (srng->flags & HAL_SRNG_FLAGS_MSI_INTR) { - ath11k_ahb_write32(ab, reg_base + - HAL_REO1_RING_MSI1_BASE_LSB_OFFSET, + ath11k_hif_write32(ab, reg_base + + HAL_REO1_RING_MSI1_BASE_LSB_OFFSET, (u32)srng->msi_addr); val = FIELD_PREP(HAL_REO1_RING_MSI1_BASE_MSB_ADDR, ((u64)srng->msi_addr >> HAL_ADDR_MSB_REG_SHIFT)) | HAL_REO1_RING_MSI1_BASE_MSB_MSI1_ENABLE; - ath11k_ahb_write32(ab, reg_base + + ath11k_hif_write32(ab, reg_base + HAL_REO1_RING_MSI1_BASE_MSB_OFFSET, val); - ath11k_ahb_write32(ab, + ath11k_hif_write32(ab, reg_base + HAL_REO1_RING_MSI1_DATA_OFFSET, srng->msi_data); } - ath11k_ahb_write32(ab, reg_base, (u32)srng->ring_base_paddr); + ath11k_hif_write32(ab, reg_base, (u32)srng->ring_base_paddr); val = FIELD_PREP(HAL_REO1_RING_BASE_MSB_RING_BASE_ADDR_MSB, ((u64)srng->ring_base_paddr >> HAL_ADDR_MSB_REG_SHIFT)) | FIELD_PREP(HAL_REO1_RING_BASE_MSB_RING_SIZE, (srng->entry_size * srng->num_entries)); - ath11k_ahb_write32(ab, reg_base + HAL_REO1_RING_BASE_MSB_OFFSET, val); + ath11k_hif_write32(ab, reg_base + HAL_REO1_RING_BASE_MSB_OFFSET, val); val = FIELD_PREP(HAL_REO1_RING_ID_RING_ID, srng->ring_id) | FIELD_PREP(HAL_REO1_RING_ID_ENTRY_SIZE, srng->entry_size); - ath11k_ahb_write32(ab, reg_base + HAL_REO1_RING_ID_OFFSET, val); + ath11k_hif_write32(ab, reg_base + HAL_REO1_RING_ID_OFFSET, val); /* interrupt setup */ val = FIELD_PREP(HAL_REO1_RING_PRDR_INT_SETUP_INTR_TMR_THOLD, @@ -406,22 +408,22 @@ static void ath11k_hal_srng_dst_hw_init(struct ath11k_base *ab, (srng->intr_batch_cntr_thres_entries * srng->entry_size)); - ath11k_ahb_write32(ab, + ath11k_hif_write32(ab, reg_base + HAL_REO1_RING_PRODUCER_INT_SETUP_OFFSET, val); hp_addr = hal->rdp.paddr + ((unsigned long)srng->u.dst_ring.hp_addr - (unsigned long)hal->rdp.vaddr); - ath11k_ahb_write32(ab, reg_base + HAL_REO1_RING_HP_ADDR_LSB_OFFSET, + ath11k_hif_write32(ab, reg_base + HAL_REO1_RING_HP_ADDR_LSB_OFFSET, hp_addr & HAL_ADDR_LSB_REG_MASK); - ath11k_ahb_write32(ab, reg_base + HAL_REO1_RING_HP_ADDR_MSB_OFFSET, + ath11k_hif_write32(ab, reg_base + HAL_REO1_RING_HP_ADDR_MSB_OFFSET, hp_addr >> HAL_ADDR_MSB_REG_SHIFT); /* Initialize head and tail pointers to indicate ring is empty */ reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R2]; - ath11k_ahb_write32(ab, reg_base, 0); - ath11k_ahb_write32(ab, reg_base + HAL_REO1_RING_TP_OFFSET, 0); + ath11k_hif_write32(ab, reg_base, 0); + ath11k_hif_write32(ab, reg_base + HAL_REO1_RING_TP_OFFSET, 0); *srng->u.dst_ring.hp_addr = 0; reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R0]; @@ -434,7 +436,7 @@ static void ath11k_hal_srng_dst_hw_init(struct ath11k_base *ab, val |= HAL_REO1_RING_MISC_MSI_SWAP; val |= HAL_REO1_RING_MISC_SRNG_ENABLE; - ath11k_ahb_write32(ab, reg_base + HAL_REO1_RING_MISC_OFFSET, val); + ath11k_hif_write32(ab, reg_base + HAL_REO1_RING_MISC_OFFSET, val); } static void ath11k_hal_srng_src_hw_init(struct ath11k_base *ab, @@ -448,34 +450,34 @@ static void ath11k_hal_srng_src_hw_init(struct ath11k_base *ab, reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R0]; if (srng->flags & HAL_SRNG_FLAGS_MSI_INTR) { - ath11k_ahb_write32(ab, reg_base + - HAL_TCL1_RING_MSI1_BASE_LSB_OFFSET, + ath11k_hif_write32(ab, reg_base + + HAL_TCL1_RING_MSI1_BASE_LSB_OFFSET, (u32)srng->msi_addr); val = FIELD_PREP(HAL_TCL1_RING_MSI1_BASE_MSB_ADDR, ((u64)srng->msi_addr >> HAL_ADDR_MSB_REG_SHIFT)) | HAL_TCL1_RING_MSI1_BASE_MSB_MSI1_ENABLE; - ath11k_ahb_write32(ab, reg_base + + ath11k_hif_write32(ab, reg_base + HAL_TCL1_RING_MSI1_BASE_MSB_OFFSET, val); - ath11k_ahb_write32(ab, reg_base + + ath11k_hif_write32(ab, reg_base + HAL_TCL1_RING_MSI1_DATA_OFFSET, srng->msi_data); } - ath11k_ahb_write32(ab, reg_base, (u32)srng->ring_base_paddr); + ath11k_hif_write32(ab, reg_base, (u32)srng->ring_base_paddr); val = FIELD_PREP(HAL_TCL1_RING_BASE_MSB_RING_BASE_ADDR_MSB, ((u64)srng->ring_base_paddr >> HAL_ADDR_MSB_REG_SHIFT)) | FIELD_PREP(HAL_TCL1_RING_BASE_MSB_RING_SIZE, (srng->entry_size * srng->num_entries)); - ath11k_ahb_write32(ab, reg_base + HAL_TCL1_RING_BASE_MSB_OFFSET, val); + ath11k_hif_write32(ab, reg_base + HAL_TCL1_RING_BASE_MSB_OFFSET, val); val = FIELD_PREP(HAL_REO1_RING_ID_ENTRY_SIZE, srng->entry_size); - ath11k_ahb_write32(ab, reg_base + HAL_TCL1_RING_ID_OFFSET, val); + ath11k_hif_write32(ab, reg_base + HAL_TCL1_RING_ID_OFFSET, val); /* interrupt setup */ /* NOTE: IPQ8074 v2 requires the interrupt timer threshold in the @@ -488,7 +490,7 @@ static void ath11k_hal_srng_src_hw_init(struct ath11k_base *ab, (srng->intr_batch_cntr_thres_entries * srng->entry_size)); - ath11k_ahb_write32(ab, + ath11k_hif_write32(ab, reg_base + HAL_TCL1_RING_CONSR_INT_SETUP_IX0_OFFSET, val); @@ -497,7 +499,7 @@ static void ath11k_hal_srng_src_hw_init(struct ath11k_base *ab, val |= FIELD_PREP(HAL_TCL1_RING_CONSR_INT_SETUP_IX1_LOW_THOLD, srng->u.src_ring.low_threshold); } - ath11k_ahb_write32(ab, + ath11k_hif_write32(ab, reg_base + HAL_TCL1_RING_CONSR_INT_SETUP_IX1_OFFSET, val); @@ -505,18 +507,18 @@ static void ath11k_hal_srng_src_hw_init(struct ath11k_base *ab, tp_addr = hal->rdp.paddr + ((unsigned long)srng->u.src_ring.tp_addr - (unsigned long)hal->rdp.vaddr); - ath11k_ahb_write32(ab, + ath11k_hif_write32(ab, reg_base + HAL_TCL1_RING_TP_ADDR_LSB_OFFSET, tp_addr & HAL_ADDR_LSB_REG_MASK); - ath11k_ahb_write32(ab, + ath11k_hif_write32(ab, reg_base + HAL_TCL1_RING_TP_ADDR_MSB_OFFSET, tp_addr >> HAL_ADDR_MSB_REG_SHIFT); } /* Initialize head and tail pointers to indicate ring is empty */ reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R2]; - ath11k_ahb_write32(ab, reg_base, 0); - ath11k_ahb_write32(ab, reg_base + HAL_TCL1_RING_TP_OFFSET, 0); + ath11k_hif_write32(ab, reg_base, 0); + ath11k_hif_write32(ab, reg_base + HAL_TCL1_RING_TP_OFFSET, 0); *srng->u.src_ring.tp_addr = 0; reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R0]; @@ -533,7 +535,7 @@ static void ath11k_hal_srng_src_hw_init(struct ath11k_base *ab, val |= HAL_TCL1_RING_MISC_SRNG_ENABLE; - ath11k_ahb_write32(ab, reg_base + HAL_TCL1_RING_MISC_OFFSET, val); + ath11k_hif_write32(ab, reg_base + HAL_TCL1_RING_MISC_OFFSET, val); } static void ath11k_hal_srng_hw_init(struct ath11k_base *ab, @@ -889,13 +891,13 @@ void ath11k_hal_srng_access_end(struct ath11k_base *ab, struct hal_srng *srng) if (srng->ring_dir == HAL_SRNG_DIR_SRC) { srng->u.src_ring.last_tp = *(volatile u32 *)srng->u.src_ring.tp_addr; - ath11k_ahb_write32(ab, + ath11k_hif_write32(ab, (unsigned long)srng->u.src_ring.hp_addr - (unsigned long)ab->mem, srng->u.src_ring.hp); } else { srng->u.dst_ring.last_hp = *srng->u.dst_ring.hp_addr; - ath11k_ahb_write32(ab, + ath11k_hif_write32(ab, (unsigned long)srng->u.dst_ring.tp_addr - (unsigned long)ab->mem, srng->u.dst_ring.tp); @@ -929,20 +931,20 @@ void ath11k_hal_setup_link_idle_list(struct ath11k_base *ab, HAL_WBM_IDLE_SCATTER_BUF_SIZE; } - ath11k_ahb_write32(ab, + ath11k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_R0_IDLE_LIST_CONTROL_ADDR, FIELD_PREP(HAL_WBM_SCATTER_BUFFER_SIZE, reg_scatter_buf_sz) | FIELD_PREP(HAL_WBM_LINK_DESC_IDLE_LIST_MODE, 0x1)); - ath11k_ahb_write32(ab, + ath11k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_R0_IDLE_LIST_SIZE_ADDR, FIELD_PREP(HAL_WBM_SCATTER_RING_SIZE_OF_IDLE_LINK_DESC_LIST, reg_scatter_buf_sz * nsbufs)); - ath11k_ahb_write32(ab, + ath11k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_SCATTERED_RING_BASE_LSB, FIELD_PREP(BUFFER_ADDR_INFO0_ADDR, sbuf[0].paddr & HAL_ADDR_LSB_REG_MASK)); - ath11k_ahb_write32(ab, + ath11k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_SCATTERED_RING_BASE_MSB, FIELD_PREP( @@ -953,12 +955,12 @@ void ath11k_hal_setup_link_idle_list(struct ath11k_base *ab, BASE_ADDR_MATCH_TAG_VAL)); /* Setup head and tail pointers for the idle list */ - ath11k_ahb_write32(ab, + ath11k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX0, FIELD_PREP(BUFFER_ADDR_INFO0_ADDR, sbuf[nsbufs - 1].paddr)); - ath11k_ahb_write32(ab, + ath11k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX1, FIELD_PREP( @@ -967,18 +969,18 @@ void ath11k_hal_setup_link_idle_list(struct ath11k_base *ab, HAL_ADDR_MSB_REG_SHIFT)) | FIELD_PREP(HAL_WBM_SCATTERED_DESC_HEAD_P_OFFSET_IX1, (end_offset >> 2))); - ath11k_ahb_write32(ab, + ath11k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX0, FIELD_PREP(BUFFER_ADDR_INFO0_ADDR, sbuf[0].paddr)); - ath11k_ahb_write32(ab, + ath11k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_SCATTERED_DESC_PTR_TAIL_INFO_IX0, FIELD_PREP(BUFFER_ADDR_INFO0_ADDR, sbuf[0].paddr)); - ath11k_ahb_write32(ab, + ath11k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_SCATTERED_DESC_PTR_TAIL_INFO_IX1, FIELD_PREP( @@ -986,13 +988,13 @@ void ath11k_hal_setup_link_idle_list(struct ath11k_base *ab, ((u64)sbuf[0].paddr >> HAL_ADDR_MSB_REG_SHIFT)) | FIELD_PREP(HAL_WBM_SCATTERED_DESC_TAIL_P_OFFSET_IX1, 0)); - ath11k_ahb_write32(ab, + ath11k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_SCATTERED_DESC_PTR_HP_ADDR, 2 * tot_link_desc); /* Enable the SRNG */ - ath11k_ahb_write32(ab, + ath11k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_IDLE_LINK_RING_MISC_ADDR, 0x40); } diff --git a/drivers/net/wireless/ath/ath11k/hal_rx.c b/drivers/net/wireless/ath/ath11k/hal_rx.c index f277c9434a25..69b0248a7baf 100644 --- a/drivers/net/wireless/ath/ath11k/hal_rx.c +++ b/drivers/net/wireless/ath/ath11k/hal_rx.c @@ -9,6 +9,7 @@ #include "hal_tx.h" #include "hal_rx.h" #include "hal_desc.h" +#include "hif.h" static void ath11k_hal_reo_set_desc_hdr(struct hal_desc_header *hdr, u8 owner, u8 buffer_type, u32 magic) @@ -804,34 +805,34 @@ void ath11k_hal_reo_hw_setup(struct ath11k_base *ab, u32 ring_hash_map) u32 reo_base = HAL_SEQ_WCSS_UMAC_REO_REG; u32 val; - val = ath11k_ahb_read32(ab, reo_base + HAL_REO1_GEN_ENABLE); + val = ath11k_hif_read32(ab, reo_base + HAL_REO1_GEN_ENABLE); val &= ~HAL_REO1_GEN_ENABLE_FRAG_DST_RING; val |= FIELD_PREP(HAL_REO1_GEN_ENABLE_FRAG_DST_RING, HAL_SRNG_RING_ID_REO2SW1) | FIELD_PREP(HAL_REO1_GEN_ENABLE_AGING_LIST_ENABLE, 1) | FIELD_PREP(HAL_REO1_GEN_ENABLE_AGING_FLUSH_ENABLE, 1); - ath11k_ahb_write32(ab, reo_base + HAL_REO1_GEN_ENABLE, val); + ath11k_hif_write32(ab, reo_base + HAL_REO1_GEN_ENABLE, val); - ath11k_ahb_write32(ab, reo_base + HAL_REO1_AGING_THRESH_IX_0, + ath11k_hif_write32(ab, reo_base + HAL_REO1_AGING_THRESH_IX_0, HAL_DEFAULT_REO_TIMEOUT_USEC); - ath11k_ahb_write32(ab, reo_base + HAL_REO1_AGING_THRESH_IX_1, + ath11k_hif_write32(ab, reo_base + HAL_REO1_AGING_THRESH_IX_1, HAL_DEFAULT_REO_TIMEOUT_USEC); - ath11k_ahb_write32(ab, reo_base + HAL_REO1_AGING_THRESH_IX_2, + ath11k_hif_write32(ab, reo_base + HAL_REO1_AGING_THRESH_IX_2, HAL_DEFAULT_REO_TIMEOUT_USEC); - ath11k_ahb_write32(ab, reo_base + HAL_REO1_AGING_THRESH_IX_3, + ath11k_hif_write32(ab, reo_base + HAL_REO1_AGING_THRESH_IX_3, HAL_DEFAULT_REO_TIMEOUT_USEC); - ath11k_ahb_write32(ab, reo_base + HAL_REO1_DEST_RING_CTRL_IX_0, + ath11k_hif_write32(ab, reo_base + HAL_REO1_DEST_RING_CTRL_IX_0, FIELD_PREP(HAL_REO_DEST_RING_CTRL_HASH_RING_MAP, ring_hash_map)); - ath11k_ahb_write32(ab, reo_base + HAL_REO1_DEST_RING_CTRL_IX_1, + ath11k_hif_write32(ab, reo_base + HAL_REO1_DEST_RING_CTRL_IX_1, FIELD_PREP(HAL_REO_DEST_RING_CTRL_HASH_RING_MAP, ring_hash_map)); - ath11k_ahb_write32(ab, reo_base + HAL_REO1_DEST_RING_CTRL_IX_2, + ath11k_hif_write32(ab, reo_base + HAL_REO1_DEST_RING_CTRL_IX_2, FIELD_PREP(HAL_REO_DEST_RING_CTRL_HASH_RING_MAP, ring_hash_map)); - ath11k_ahb_write32(ab, reo_base + HAL_REO1_DEST_RING_CTRL_IX_3, + ath11k_hif_write32(ab, reo_base + HAL_REO1_DEST_RING_CTRL_IX_3, FIELD_PREP(HAL_REO_DEST_RING_CTRL_HASH_RING_MAP, ring_hash_map)); } diff --git a/drivers/net/wireless/ath/ath11k/hal_tx.c b/drivers/net/wireless/ath/ath11k/hal_tx.c index e4aa7e8a1284..b364c077c1f7 100644 --- a/drivers/net/wireless/ath/ath11k/hal_tx.c +++ b/drivers/net/wireless/ath/ath11k/hal_tx.c @@ -6,6 +6,7 @@ #include "ahb.h" #include "hal.h" #include "hal_tx.h" +#include "hif.h" #define DSCP_TID_MAP_TBL_ENTRY_SIZE 64 @@ -83,11 +84,11 @@ void ath11k_hal_tx_set_dscp_tid_map(struct ath11k_base *ab, int id) u32 value; int cnt = 0; - ctrl_reg_val = ath11k_ahb_read32(ab, HAL_SEQ_WCSS_UMAC_TCL_REG + + ctrl_reg_val = ath11k_hif_read32(ab, HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL1_RING_CMN_CTRL_REG); /* Enable read/write access */ ctrl_reg_val |= HAL_TCL1_RING_CMN_CTRL_DSCP_TID_MAP_PROG_EN; - ath11k_ahb_write32(ab, HAL_SEQ_WCSS_UMAC_TCL_REG + + ath11k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL1_RING_CMN_CTRL_REG, ctrl_reg_val); addr = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL1_RING_DSCP_TID_MAP + @@ -118,15 +119,15 @@ void ath11k_hal_tx_set_dscp_tid_map(struct ath11k_base *ab, int id) } for (i = 0; i < HAL_DSCP_TID_TBL_SIZE; i += 4) { - ath11k_ahb_write32(ab, addr, *(u32 *)&hw_map_val[i]); + ath11k_hif_write32(ab, addr, *(u32 *)&hw_map_val[i]); addr += 4; } /* Disable read/write access */ - ctrl_reg_val = ath11k_ahb_read32(ab, HAL_SEQ_WCSS_UMAC_TCL_REG + + ctrl_reg_val = ath11k_hif_read32(ab, HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL1_RING_CMN_CTRL_REG); ctrl_reg_val &= ~HAL_TCL1_RING_CMN_CTRL_DSCP_TID_MAP_PROG_EN; - ath11k_ahb_write32(ab, HAL_SEQ_WCSS_UMAC_TCL_REG + + ath11k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL1_RING_CMN_CTRL_REG, ctrl_reg_val); } diff --git a/drivers/net/wireless/ath/ath11k/hif.h b/drivers/net/wireless/ath/ath11k/hif.h new file mode 100644 index 000000000000..165f7e51c238 --- /dev/null +++ b/drivers/net/wireless/ath/ath11k/hif.h @@ -0,0 +1,65 @@ +/* SPDX-License-Identifier: BSD-3-Clause-Clear */ +/* + * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. + */ + +#include "core.h" + +struct ath11k_hif_ops { + u32 (*read32)(struct ath11k_base *sc, u32 address); + void (*write32)(struct ath11k_base *sc, u32 address, u32 data); + void (*irq_enable)(struct ath11k_base *sc); + void (*irq_disable)(struct ath11k_base *sc); + int (*start)(struct ath11k_base *sc); + void (*stop)(struct ath11k_base *sc); + int (*power_up)(struct ath11k_base *sc); + void (*power_down)(struct ath11k_base *sc); + int (*map_service_to_pipe)(struct ath11k_base *sc, u16 service_id, + u8 *ul_pipe, u8 *dl_pipe); +}; + +static inline int ath11k_hif_start(struct ath11k_base *sc) +{ + return sc->hif.ops->start(sc); +} + +static inline void ath11k_hif_stop(struct ath11k_base *sc) +{ + sc->hif.ops->stop(sc); +} + +static inline void ath11k_hif_irq_enable(struct ath11k_base *sc) +{ + sc->hif.ops->irq_enable(sc); +} + +static inline void ath11k_hif_irq_disable(struct ath11k_base *sc) +{ + sc->hif.ops->irq_disable(sc); +} + +static inline int ath11k_hif_power_up(struct ath11k_base *sc) +{ + return sc->hif.ops->power_up(sc); +} + +static inline void ath11k_hif_power_down(struct ath11k_base *sc) +{ + sc->hif.ops->power_down(sc); +} + +static inline u32 ath11k_hif_read32(struct ath11k_base *sc, u32 address) +{ + return sc->hif.ops->read32(sc, address); +} + +static inline void ath11k_hif_write32(struct ath11k_base *sc, u32 address, u32 data) +{ + sc->hif.ops->write32(sc, address, data); +} + +static inline int ath11k_hif_map_service_to_pipe(struct ath11k_base *sc, u16 service_id, + u8 *ul_pipe, u8 *dl_pipe) +{ + return sc->hif.ops->map_service_to_pipe(sc, service_id, ul_pipe, dl_pipe); +} diff --git a/drivers/net/wireless/ath/ath11k/htc.c b/drivers/net/wireless/ath/ath11k/htc.c index 8f54f58b83e6..1909fc3287ba 100644 --- a/drivers/net/wireless/ath/ath11k/htc.c +++ b/drivers/net/wireless/ath/ath11k/htc.c @@ -7,6 +7,7 @@ #include "ahb.h" #include "debug.h" +#include "hif.h" struct sk_buff *ath11k_htc_alloc_skb(struct ath11k_base *ab, int size) { @@ -672,7 +673,7 @@ setup: /* copy all the callbacks */ ep->ep_ops = conn_req->ep_ops; - status = ath11k_ahb_map_service_to_pipe(htc->ab, + status = ath11k_hif_map_service_to_pipe(htc->ab, ep->service_id, &ep->ul_pipe_id, &ep->dl_pipe_id); From 630ad41c195c7064d16cbe7c53a65f276efcb02c Mon Sep 17 00:00:00 2001 From: Govind Singh Date: Fri, 8 May 2020 05:55:48 +0300 Subject: [PATCH 07/20] ath11k: Add drv private for bus opaque struct Add drv private opaque structure to have bus level structure for multibus support. Signed-off-by: Govind Singh Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20200506094400.4740-3-govinds@codeaurora.org --- drivers/net/wireless/ath/ath11k/ahb.c | 2 +- drivers/net/wireless/ath/ath11k/core.c | 5 +++-- drivers/net/wireless/ath/ath11k/core.h | 6 +++++- drivers/net/wireless/ath/ath11k/hw.h | 5 +++++ 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/ahb.c b/drivers/net/wireless/ath/ath11k/ahb.c index eaba5a189b7f..ef1038aa5692 100644 --- a/drivers/net/wireless/ath/ath11k/ahb.c +++ b/drivers/net/wireless/ath/ath11k/ahb.c @@ -932,7 +932,7 @@ static int ath11k_ahb_probe(struct platform_device *pdev) return ret; } - ab = ath11k_core_alloc(&pdev->dev); + ab = ath11k_core_alloc(&pdev->dev, 0, ATH11K_BUS_AHB); if (!ab) { dev_err(&pdev->dev, "failed to allocate ath11k base\n"); return -ENOMEM; diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c index 985ea3bcadb9..a91eae6a4e57 100644 --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c @@ -756,11 +756,12 @@ void ath11k_core_free(struct ath11k_base *ab) kfree(ab); } -struct ath11k_base *ath11k_core_alloc(struct device *dev) +struct ath11k_base *ath11k_core_alloc(struct device *dev, size_t priv_size, + enum ath11k_bus bus) { struct ath11k_base *ab; - ab = kzalloc(sizeof(*ab), GFP_KERNEL); + ab = kzalloc(sizeof(*ab) + priv_size, GFP_KERNEL); if (!ab) return NULL; diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h index e86513f5b757..e04f0e711779 100644 --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h @@ -667,6 +667,9 @@ struct ath11k_base { /* Round robbin based TCL ring selector */ atomic_t tcl_ring_selector; + + /* must be last */ + u8 drv_priv[0] __aligned(sizeof(void *)); }; struct ath11k_fw_stats_pdev { @@ -803,7 +806,8 @@ struct ath11k_peer *ath11k_peer_find_by_id(struct ath11k_base *ab, int peer_id); int ath11k_core_qmi_firmware_ready(struct ath11k_base *ab); int ath11k_core_init(struct ath11k_base *ath11k); void ath11k_core_deinit(struct ath11k_base *ath11k); -struct ath11k_base *ath11k_core_alloc(struct device *dev); +struct ath11k_base *ath11k_core_alloc(struct device *dev, size_t priv_size, + enum ath11k_bus bus); void ath11k_core_free(struct ath11k_base *ath11k); int ath11k_core_fetch_bdf(struct ath11k_base *ath11k, struct ath11k_board_data *bd); diff --git a/drivers/net/wireless/ath/ath11k/hw.h b/drivers/net/wireless/ath/ath11k/hw.h index cdec95644758..dc4434aefbbe 100644 --- a/drivers/net/wireless/ath/ath11k/hw.h +++ b/drivers/net/wireless/ath/ath11k/hw.h @@ -99,6 +99,11 @@ enum ath11k_hw_rate_ofdm { ATH11K_HW_RATE_OFDM_9M, }; +enum ath11k_bus { + ATH11K_BUS_AHB, + ATH11K_BUS_PCI, +}; + struct ath11k_hw_params { const char *name; struct { From 27143fa93c3b000c968992ca2620e784249862d3 Mon Sep 17 00:00:00 2001 From: Govind Singh Date: Fri, 8 May 2020 05:55:48 +0300 Subject: [PATCH 08/20] ath11k: Remove bus layer includes from upper layer Bus level header files needs to be abstracted by upper layer. Remove bus layer includes by adding appropriate header files. Signed-off-by: Govind Singh Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20200506094400.4740-4-govinds@codeaurora.org --- drivers/net/wireless/ath/ath11k/core.c | 1 - drivers/net/wireless/ath/ath11k/hal.c | 1 - drivers/net/wireless/ath/ath11k/hal_desc.h | 2 ++ drivers/net/wireless/ath/ath11k/hal_rx.c | 1 - drivers/net/wireless/ath/ath11k/hal_tx.c | 2 +- drivers/net/wireless/ath/ath11k/hal_tx.h | 1 + drivers/net/wireless/ath/ath11k/htc.c | 1 - 7 files changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c index a91eae6a4e57..02501cc154fe 100644 --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c @@ -7,7 +7,6 @@ #include #include #include -#include "ahb.h" #include "core.h" #include "dp_tx.h" #include "dp_rx.h" diff --git a/drivers/net/wireless/ath/ath11k/hal.c b/drivers/net/wireless/ath/ath11k/hal.c index 6d937674215e..d63785178afa 100644 --- a/drivers/net/wireless/ath/ath11k/hal.c +++ b/drivers/net/wireless/ath/ath11k/hal.c @@ -3,7 +3,6 @@ * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. */ #include -#include "ahb.h" #include "hal_tx.h" #include "debug.h" #include "hal_desc.h" diff --git a/drivers/net/wireless/ath/ath11k/hal_desc.h b/drivers/net/wireless/ath/ath11k/hal_desc.h index a1f747c1c44d..8a592814efa0 100644 --- a/drivers/net/wireless/ath/ath11k/hal_desc.h +++ b/drivers/net/wireless/ath/ath11k/hal_desc.h @@ -2,6 +2,8 @@ /* * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. */ +#include "core.h" + #ifndef ATH11K_HAL_DESC_H #define ATH11K_HAL_DESC_H diff --git a/drivers/net/wireless/ath/ath11k/hal_rx.c b/drivers/net/wireless/ath/ath11k/hal_rx.c index 69b0248a7baf..129c9e1efeb9 100644 --- a/drivers/net/wireless/ath/ath11k/hal_rx.c +++ b/drivers/net/wireless/ath/ath11k/hal_rx.c @@ -3,7 +3,6 @@ * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. */ -#include "ahb.h" #include "debug.h" #include "hal.h" #include "hal_tx.h" diff --git a/drivers/net/wireless/ath/ath11k/hal_tx.c b/drivers/net/wireless/ath/ath11k/hal_tx.c index b364c077c1f7..81937c29ffca 100644 --- a/drivers/net/wireless/ath/ath11k/hal_tx.c +++ b/drivers/net/wireless/ath/ath11k/hal_tx.c @@ -3,7 +3,7 @@ * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. */ -#include "ahb.h" +#include "hal_desc.h" #include "hal.h" #include "hal_tx.h" #include "hif.h" diff --git a/drivers/net/wireless/ath/ath11k/hal_tx.h b/drivers/net/wireless/ath/ath11k/hal_tx.h index ce48a61bfb66..d4760a20fdac 100644 --- a/drivers/net/wireless/ath/ath11k/hal_tx.h +++ b/drivers/net/wireless/ath/ath11k/hal_tx.h @@ -7,6 +7,7 @@ #define ATH11K_HAL_TX_H #include "hal_desc.h" +#include "core.h" #define HAL_TX_ADDRX_EN 1 #define HAL_TX_ADDRY_EN 2 diff --git a/drivers/net/wireless/ath/ath11k/htc.c b/drivers/net/wireless/ath/ath11k/htc.c index 1909fc3287ba..ad13c648b679 100644 --- a/drivers/net/wireless/ath/ath11k/htc.c +++ b/drivers/net/wireless/ath/ath11k/htc.c @@ -5,7 +5,6 @@ #include #include -#include "ahb.h" #include "debug.h" #include "hif.h" From d3ed0cf047cf054fd54589e5d4247f0001c5d85c Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Fri, 8 May 2020 05:55:52 +0300 Subject: [PATCH 09/20] ath10k: Replace zero-length array with flexible-array The current codebase makes use of the zero-length array language extension to the C90 standard, but the preferred mechanism to declare variable-length types such as these ones is a flexible array member[1][2], introduced in C99: struct foo { int stuff; struct boo array[]; }; By making use of the mechanism above, we will get a compiler warning in case the flexible array does not occur last in the structure, which will help us prevent some kind of undefined behavior bugs from being inadvertently introduced[3] to the codebase from now on. Also, notice that, dynamic memory allocations won't be affected by this change: "Flexible array members have incomplete type, and so the sizeof operator may not be applied. As a quirk of the original implementation of zero-length arrays, sizeof evaluates to zero."[1] sizeof(flexible-array-member) triggers a warning because flexible array members have incomplete type[1]. There are some instances of code in which the sizeof operator is being incorrectly/erroneously applied to zero-length arrays and the result is zero. Such instances may be hiding some bugs. So, this work (flexible-array member conversions) will also help to get completely rid of those sorts of issues. This issue was found with the help of Coccinelle. [1] https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html [2] https://github.com/KSPP/linux/issues/21 [3] commit 76497732932f ("cxgb3/l2t: Fix undefined behaviour") Signed-off-by: Gustavo A. R. Silva Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20200507041127.GA31587@embeddedor --- drivers/net/wireless/ath/ath10k/ce.h | 2 +- drivers/net/wireless/ath/ath10k/core.h | 2 +- drivers/net/wireless/ath/ath10k/coredump.h | 4 +-- drivers/net/wireless/ath/ath10k/debug.h | 2 +- drivers/net/wireless/ath/ath10k/htt.h | 42 +++++++++++----------- drivers/net/wireless/ath/ath10k/hw.h | 2 +- drivers/net/wireless/ath/ath10k/wmi-tlv.h | 6 ++-- drivers/net/wireless/ath/ath10k/wmi.h | 42 +++++++++++----------- 8 files changed, 51 insertions(+), 51 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/ce.h b/drivers/net/wireless/ath/ath10k/ce.h index 9711f0eb9117..75df79d43120 100644 --- a/drivers/net/wireless/ath/ath10k/ce.h +++ b/drivers/net/wireless/ath/ath10k/ce.h @@ -110,7 +110,7 @@ struct ath10k_ce_ring { struct ce_desc_64 *shadow_base; /* keep last */ - void *per_transfer_context[0]; + void *per_transfer_context[]; }; struct ath10k_ce_pipe { diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index ceac76553b8f..5c18f6c20462 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h @@ -1262,7 +1262,7 @@ struct ath10k { int coex_gpio_pin; /* must be last */ - u8 drv_priv[0] __aligned(sizeof(void *)); + u8 drv_priv[] __aligned(sizeof(void *)); }; static inline bool ath10k_peer_stats_enabled(struct ath10k *ar) diff --git a/drivers/net/wireless/ath/ath10k/coredump.h b/drivers/net/wireless/ath/ath10k/coredump.h index 8bf03e8c1d3a..e760ce1a5f1e 100644 --- a/drivers/net/wireless/ath/ath10k/coredump.h +++ b/drivers/net/wireless/ath/ath10k/coredump.h @@ -88,7 +88,7 @@ struct ath10k_dump_file_data { u8 unused[128]; /* struct ath10k_tlv_dump_data + more */ - u8 data[0]; + u8 data[]; } __packed; struct ath10k_dump_ram_data_hdr { @@ -100,7 +100,7 @@ struct ath10k_dump_ram_data_hdr { /* length of payload data, not including this header */ __le32 length; - u8 data[0]; + u8 data[]; }; /* magic number to fill the holes not copied due to sections in regions */ diff --git a/drivers/net/wireless/ath/ath10k/debug.h b/drivers/net/wireless/ath/ath10k/debug.h index 4cbfd9279d6f..997c1c80aba7 100644 --- a/drivers/net/wireless/ath/ath10k/debug.h +++ b/drivers/net/wireless/ath/ath10k/debug.h @@ -65,7 +65,7 @@ struct ath10k_pktlog_hdr { __le16 log_type; /* Type of log information foll this header */ __le16 size; /* Size of variable length log information in bytes */ __le32 timestamp; - u8 payload[0]; + u8 payload[]; } __packed; /* FIXME: How to calculate the buffer size sanely? */ diff --git a/drivers/net/wireless/ath/ath10k/htt.h b/drivers/net/wireless/ath/ath10k/htt.h index 8f3710cf28f4..e504be63173a 100644 --- a/drivers/net/wireless/ath/ath10k/htt.h +++ b/drivers/net/wireless/ath/ath10k/htt.h @@ -289,12 +289,12 @@ struct htt_rx_ring_setup_hdr { struct htt_rx_ring_setup_32 { struct htt_rx_ring_setup_hdr hdr; - struct htt_rx_ring_setup_ring32 rings[0]; + struct htt_rx_ring_setup_ring32 rings[]; } __packed; struct htt_rx_ring_setup_64 { struct htt_rx_ring_setup_hdr hdr; - struct htt_rx_ring_setup_ring64 rings[0]; + struct htt_rx_ring_setup_ring64 rings[]; } __packed; /* @@ -732,7 +732,7 @@ struct htt_rx_indication { * %mpdu_ranges starts after &%prefix + roundup(%fw_rx_desc_bytes, 4) * and has %num_mpdu_ranges elements. */ - struct htt_rx_indication_mpdu_range mpdu_ranges[0]; + struct htt_rx_indication_mpdu_range mpdu_ranges[]; } __packed; /* High latency version of the RX indication */ @@ -741,7 +741,7 @@ struct htt_rx_indication_hl { struct htt_rx_indication_ppdu ppdu; struct htt_rx_indication_prefix prefix; struct fw_rx_desc_hl fw_desc; - struct htt_rx_indication_mpdu_range mpdu_ranges[0]; + struct htt_rx_indication_mpdu_range mpdu_ranges[]; } __packed; struct htt_hl_rx_desc { @@ -908,7 +908,7 @@ struct htt_append_retries { struct htt_data_tx_completion_ext { struct htt_append_retries a_retries; __le32 t_stamp; - __le16 msdus_rssi[0]; + __le16 msdus_rssi[]; } __packed; /** @@ -992,7 +992,7 @@ struct htt_data_tx_completion { } __packed; u8 num_msdus; u8 flags2; /* HTT_TX_CMPL_FLAG_DATA_RSSI */ - __le16 msdus[0]; /* variable length based on %num_msdus */ + __le16 msdus[]; /* variable length based on %num_msdus */ } __packed; #define HTT_TX_PPDU_DUR_INFO0_PEER_ID_MASK GENMASK(15, 0) @@ -1007,7 +1007,7 @@ struct htt_data_tx_ppdu_dur { struct htt_data_tx_compl_ppdu_dur { __le32 info0; /* HTT_TX_COMPL_PPDU_DUR_INFO0_ */ - struct htt_data_tx_ppdu_dur ppdu_dur[0]; + struct htt_data_tx_ppdu_dur ppdu_dur[]; } __packed; struct htt_tx_compl_ind_base { @@ -1033,7 +1033,7 @@ struct htt_rc_update { u8 addr[6]; u8 num_elems; u8 rsvd0; - struct htt_rc_tx_done_params params[0]; /* variable length %num_elems */ + struct htt_rc_tx_done_params params[]; /* variable length %num_elems */ } __packed; /* see htt_rx_indication for similar fields and descriptions */ @@ -1050,7 +1050,7 @@ struct htt_rx_fragment_indication { __le16 fw_rx_desc_bytes; __le16 rsvd0; - u8 fw_msdu_rx_desc[0]; + u8 fw_msdu_rx_desc[]; } __packed; #define ATH10K_IEEE80211_EXTIV BIT(5) @@ -1075,7 +1075,7 @@ struct htt_rx_pn_ind { u8 seqno_end; u8 pn_ie_count; u8 reserved; - u8 pn_ies[0]; + u8 pn_ies[]; } __packed; struct htt_rx_offload_msdu { @@ -1084,7 +1084,7 @@ struct htt_rx_offload_msdu { u8 vdev_id; u8 tid; u8 fw_desc; - u8 payload[0]; + u8 payload[]; } __packed; struct htt_rx_offload_ind { @@ -1167,7 +1167,7 @@ struct htt_rx_test { * a) num_ints * sizeof(__le32) * b) num_chars * sizeof(u8) aligned to 4bytes */ - u8 payload[0]; + u8 payload[]; } __packed; static inline __le32 *htt_rx_test_get_ints(struct htt_rx_test *rx_test) @@ -1201,7 +1201,7 @@ static inline u8 *htt_rx_test_get_chars(struct htt_rx_test *rx_test) */ struct htt_pktlog_msg { u8 pad[3]; - u8 payload[0]; + u8 payload[]; } __packed; struct htt_dbg_stats_rx_reorder_stats { @@ -1490,7 +1490,7 @@ struct htt_stats_conf_item { } __packed; u8 pad; __le16 length; - u8 payload[0]; /* roundup(length, 4) long */ + u8 payload[]; /* roundup(length, 4) long */ } __packed; struct htt_stats_conf { @@ -1499,7 +1499,7 @@ struct htt_stats_conf { __le32 cookie_msb; /* each item has variable length! */ - struct htt_stats_conf_item items[0]; + struct htt_stats_conf_item items[]; } __packed; static inline struct htt_stats_conf_item *htt_stats_conf_next_item( @@ -1674,7 +1674,7 @@ struct htt_tx_fetch_ind { __le16 num_resp_ids; __le16 num_records; struct htt_tx_fetch_record records[0]; - __le32 resp_ids[0]; /* ath10k_htt_get_tx_fetch_ind_resp_ids() */ + __le32 resp_ids[]; /* ath10k_htt_get_tx_fetch_ind_resp_ids() */ } __packed; static inline void * @@ -1689,13 +1689,13 @@ struct htt_tx_fetch_resp { __le16 fetch_seq_num; __le16 num_records; __le32 token; - struct htt_tx_fetch_record records[0]; + struct htt_tx_fetch_record records[]; } __packed; struct htt_tx_fetch_confirm { u8 pad0; __le16 num_resp_ids; - __le32 resp_ids[0]; + __le32 resp_ids[]; } __packed; enum htt_tx_mode_switch_mode { @@ -1727,7 +1727,7 @@ struct htt_tx_mode_switch_ind { __le16 info0; /* HTT_TX_MODE_SWITCH_IND_INFO0_ */ __le16 info1; /* HTT_TX_MODE_SWITCH_IND_INFO1_ */ u8 pad1[2]; - struct htt_tx_mode_switch_record records[0]; + struct htt_tx_mode_switch_record records[]; } __packed; struct htt_channel_change { @@ -1757,7 +1757,7 @@ struct htt_peer_tx_stats { u8 num_ppdu; u8 ppdu_len; u8 version; - u8 payload[0]; + u8 payload[]; } __packed; #define ATH10K_10_2_TX_STATS_OFFSET 136 @@ -2206,7 +2206,7 @@ struct htt_rx_desc { struct rx_ppdu_end ppdu_end; } __packed; u8 rx_hdr_status[RX_HTT_HDR_STATUS_LEN]; - u8 msdu_payload[0]; + u8 msdu_payload[]; }; #define HTT_RX_DESC_HL_INFO_SEQ_NUM_MASK 0x00000fff diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h index d9907a4648a8..f16edcb9f326 100644 --- a/drivers/net/wireless/ath/ath10k/hw.h +++ b/drivers/net/wireless/ath/ath10k/hw.h @@ -165,7 +165,7 @@ enum qca9377_chip_id_rev { struct ath10k_fw_ie { __le32 id; __le32 len; - u8 data[0]; + u8 data[]; }; enum ath10k_fw_ie_type { diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.h b/drivers/net/wireless/ath/ath10k/wmi-tlv.h index 6e0537dabd1d..e77b97ca5c7f 100644 --- a/drivers/net/wireless/ath/ath10k/wmi-tlv.h +++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.h @@ -1637,7 +1637,7 @@ wmi_tlv_svc_map_ext(const __le32 *in, unsigned long *out, size_t len) struct wmi_tlv { __le16 len; __le16 tag; - u8 value[0]; + u8 value[]; } __packed; struct ath10k_mgmt_tx_pkt_addr { @@ -2037,7 +2037,7 @@ struct wmi_tlv_bcn_tx_status_ev { struct wmi_tlv_bcn_prb_info { __le32 caps; __le32 erp; - u8 ies[0]; + u8 ies[]; } __packed; struct wmi_tlv_bcn_tmpl_cmd { @@ -2068,7 +2068,7 @@ struct wmi_tlv_diag_item { __le16 len; __le32 timestamp; __le32 code; - u8 payload[0]; + u8 payload[]; } __packed; struct wmi_tlv_diag_data_ev { diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h index 0f05405bebc0..511144b36231 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.h +++ b/drivers/net/wireless/ath/ath10k/wmi.h @@ -2292,7 +2292,7 @@ struct wmi_service_ready_event { * where FW can access this memory directly (or) by DMA. */ __le32 num_mem_reqs; - struct wlan_host_mem_req mem_reqs[0]; + struct wlan_host_mem_req mem_reqs[]; } __packed; /* This is the definition from 10.X firmware branch */ @@ -2331,7 +2331,7 @@ struct wmi_10x_service_ready_event { */ __le32 num_mem_reqs; - struct wlan_host_mem_req mem_reqs[0]; + struct wlan_host_mem_req mem_reqs[]; } __packed; #define WMI_SERVICE_READY_TIMEOUT_HZ (5 * HZ) @@ -3086,19 +3086,19 @@ struct wmi_chan_list_entry { struct wmi_chan_list { __le32 tag; /* WMI_CHAN_LIST_TAG */ __le32 num_chan; - struct wmi_chan_list_entry channel_list[0]; + struct wmi_chan_list_entry channel_list[]; } __packed; struct wmi_bssid_list { __le32 tag; /* WMI_BSSID_LIST_TAG */ __le32 num_bssid; - struct wmi_mac_addr bssid_list[0]; + struct wmi_mac_addr bssid_list[]; } __packed; struct wmi_ie_data { __le32 tag; /* WMI_IE_TAG */ __le32 ie_len; - u8 ie_data[0]; + u8 ie_data[]; } __packed; struct wmi_ssid { @@ -3109,7 +3109,7 @@ struct wmi_ssid { struct wmi_ssid_list { __le32 tag; /* WMI_SSID_LIST_TAG */ __le32 num_ssids; - struct wmi_ssid ssids[0]; + struct wmi_ssid ssids[]; } __packed; /* prefix used by scan requestor ids on the host */ @@ -3311,7 +3311,7 @@ struct wmi_stop_scan_arg { struct wmi_scan_chan_list_cmd { __le32 num_scan_chans; - struct wmi_channel chan_info[0]; + struct wmi_channel chan_info[]; } __packed; struct wmi_scan_chan_list_arg { @@ -3395,12 +3395,12 @@ struct wmi_mgmt_rx_hdr_v2 { struct wmi_mgmt_rx_event_v1 { struct wmi_mgmt_rx_hdr_v1 hdr; - u8 buf[0]; + u8 buf[]; } __packed; struct wmi_mgmt_rx_event_v2 { struct wmi_mgmt_rx_hdr_v2 hdr; - u8 buf[0]; + u8 buf[]; } __packed; struct wmi_10_4_mgmt_rx_hdr { @@ -3415,7 +3415,7 @@ struct wmi_10_4_mgmt_rx_hdr { struct wmi_10_4_mgmt_rx_event { struct wmi_10_4_mgmt_rx_hdr hdr; - u8 buf[0]; + u8 buf[]; } __packed; struct wmi_mgmt_rx_ext_info { @@ -3455,14 +3455,14 @@ struct wmi_phyerr { __le32 rssi_chains[4]; __le16 nf_chains[4]; __le32 buf_len; - u8 buf[0]; + u8 buf[]; } __packed; struct wmi_phyerr_event { __le32 num_phyerrs; __le32 tsf_l32; __le32 tsf_u32; - struct wmi_phyerr phyerrs[0]; + struct wmi_phyerr phyerrs[]; } __packed; struct wmi_10_4_phyerr_event { @@ -3479,7 +3479,7 @@ struct wmi_10_4_phyerr_event { __le32 phy_err_mask[2]; __le32 tsf_timestamp; __le32 buf_len; - u8 buf[0]; + u8 buf[]; } __packed; struct wmi_radar_found_info { @@ -3592,7 +3592,7 @@ struct wmi_mgmt_tx_hdr { struct wmi_mgmt_tx_cmd { struct wmi_mgmt_tx_hdr hdr; - u8 buf[0]; + u8 buf[]; } __packed; struct wmi_echo_event { @@ -4628,7 +4628,7 @@ struct wmi_stats_event { * By having a zero sized array, the pointer to data area * becomes available without increasing the struct size */ - u8 data[0]; + u8 data[]; } __packed; struct wmi_10_2_stats_event { @@ -4638,7 +4638,7 @@ struct wmi_10_2_stats_event { __le32 num_vdev_stats; __le32 num_peer_stats; __le32 num_bcnflt_stats; - u8 data[0]; + u8 data[]; } __packed; /* @@ -5033,7 +5033,7 @@ struct wmi_vdev_install_key_cmd { __le32 key_rxmic_len; /* contains key followed by tx mic followed by rx mic */ - u8 key_data[0]; + u8 key_data[]; } __packed; struct wmi_vdev_install_key_arg { @@ -5703,7 +5703,7 @@ struct wmi_bcn_tx_hdr { struct wmi_bcn_tx_cmd { struct wmi_bcn_tx_hdr hdr; - u8 *bcn[0]; + u8 *bcn[]; } __packed; struct wmi_bcn_tx_arg { @@ -6120,7 +6120,7 @@ struct wmi_bcn_info { struct wmi_host_swba_event { __le32 vdev_map; - struct wmi_bcn_info bcn_info[0]; + struct wmi_bcn_info bcn_info[]; } __packed; struct wmi_10_2_4_bcn_info { @@ -6130,7 +6130,7 @@ struct wmi_10_2_4_bcn_info { struct wmi_10_2_4_host_swba_event { __le32 vdev_map; - struct wmi_10_2_4_bcn_info bcn_info[0]; + struct wmi_10_2_4_bcn_info bcn_info[]; } __packed; /* 16 words = 512 client + 1 word = for guard */ @@ -6171,7 +6171,7 @@ struct wmi_10_4_bcn_info { struct wmi_10_4_host_swba_event { __le32 vdev_map; - struct wmi_10_4_bcn_info bcn_info[0]; + struct wmi_10_4_bcn_info bcn_info[]; } __packed; #define WMI_MAX_AP_VDEV 16 From a86308fc534edeceaf64670c691e17485436a4f4 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Fri, 8 May 2020 05:56:03 +0300 Subject: [PATCH 10/20] wcn36xx: Fix error handling path in 'wcn36xx_probe()' In case of error, 'qcom_wcnss_open_channel()' must be undone by a call to 'rpmsg_destroy_ept()', as already done in the remove function. Fixes: 5052de8deff5 ("soc: qcom: smd: Transition client drivers from smd to rpmsg") Signed-off-by: Christophe JAILLET Reviewed-by: Bjorn Andersson Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20200507043619.200051-1-christophe.jaillet@wanadoo.fr --- drivers/net/wireless/ath/wcn36xx/main.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c index e49c306e0eef..702b689c06df 100644 --- a/drivers/net/wireless/ath/wcn36xx/main.c +++ b/drivers/net/wireless/ath/wcn36xx/main.c @@ -1339,7 +1339,7 @@ static int wcn36xx_probe(struct platform_device *pdev) if (addr && ret != ETH_ALEN) { wcn36xx_err("invalid local-mac-address\n"); ret = -EINVAL; - goto out_wq; + goto out_destroy_ept; } else if (addr) { wcn36xx_info("mac address: %pM\n", addr); SET_IEEE80211_PERM_ADDR(wcn->hw, addr); @@ -1347,7 +1347,7 @@ static int wcn36xx_probe(struct platform_device *pdev) ret = wcn36xx_platform_get_resources(wcn, pdev); if (ret) - goto out_wq; + goto out_destroy_ept; wcn36xx_init_ieee80211(wcn); ret = ieee80211_register_hw(wcn->hw); @@ -1359,6 +1359,8 @@ static int wcn36xx_probe(struct platform_device *pdev) out_unmap: iounmap(wcn->ccu_base); iounmap(wcn->dxe_base); +out_destroy_ept: + rpmsg_destroy_ept(wcn->smd_channel); out_wq: ieee80211_free_hw(hw); out_err: From 4d0f3604c4d181b98104024c837f0e81912f55ef Mon Sep 17 00:00:00 2001 From: Govind Singh Date: Fri, 8 May 2020 05:56:10 +0300 Subject: [PATCH 11/20] ath10k: remove experimental tag from SDIO and SNOC busses in Kconfig ath10k(sdio/snoc) is no longer experimental. Remove experimental tag for SDIO/SNOC from ath10k Kconfig. Signed-off-by: Govind Singh Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20200507055324.15564-1-govinds@codeaurora.org --- drivers/net/wireless/ath/ath10k/Kconfig | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/Kconfig b/drivers/net/wireless/ath/ath10k/Kconfig index 6b3ff02a373d..b99fd0eff994 100644 --- a/drivers/net/wireless/ath/ath10k/Kconfig +++ b/drivers/net/wireless/ath/ath10k/Kconfig @@ -28,11 +28,10 @@ config ATH10K_AHB This module adds support for AHB bus config ATH10K_SDIO - tristate "Atheros ath10k SDIO support (EXPERIMENTAL)" + tristate "Atheros ath10k SDIO support" depends on ATH10K && MMC ---help--- - This module adds experimental support for SDIO/MMC bus. Currently - work in progress and will not fully work. + This module adds support for SDIO/MMC bus. config ATH10K_USB tristate "Atheros ath10k USB support (EXPERIMENTAL)" @@ -42,7 +41,7 @@ config ATH10K_USB work in progress and will not fully work. config ATH10K_SNOC - tristate "Qualcomm ath10k SNOC support (EXPERIMENTAL)" + tristate "Qualcomm ath10k SNOC support" depends on ATH10K depends on ARCH_QCOM || COMPILE_TEST select QCOM_QMI_HELPERS From 103dc3dab295159cb2c5374a0dc499cd3962d49f Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Thu, 7 May 2020 10:19:21 -0500 Subject: [PATCH 12/20] carl9170: Replace zero-length array with flexible-array The current codebase makes use of the zero-length array language extension to the C90 standard, but the preferred mechanism to declare variable-length types such as these ones is a flexible array member[1][2], introduced in C99: struct foo { int stuff; struct boo array[]; }; By making use of the mechanism above, we will get a compiler warning in case the flexible array does not occur last in the structure, which will help us prevent some kind of undefined behavior bugs from being inadvertently introduced[3] to the codebase from now on. Also, notice that, dynamic memory allocations won't be affected by this change: "Flexible array members have incomplete type, and so the sizeof operator may not be applied. As a quirk of the original implementation of zero-length arrays, sizeof evaluates to zero."[1] sizeof(flexible-array-member) triggers a warning because flexible array members have incomplete type[1]. There are some instances of code in which the sizeof operator is being incorrectly/erroneously applied to zero-length arrays and the result is zero. Such instances may be hiding some bugs. So, this work (flexible-array member conversions) will also help to get completely rid of those sorts of issues. This issue was found with the help of Coccinelle. [1] https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html [2] https://github.com/KSPP/linux/issues/21 [3] commit 76497732932f ("cxgb3/l2t: Fix undefined behaviour") Signed-off-by: Gustavo A. R. Silva Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20200507151921.GA5083@embeddedor --- drivers/net/wireless/ath/carl9170/fwcmd.h | 2 +- drivers/net/wireless/ath/carl9170/hw.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/carl9170/fwcmd.h b/drivers/net/wireless/ath/carl9170/fwcmd.h index ea1d80f9a50e..56999a3b9d3b 100644 --- a/drivers/net/wireless/ath/carl9170/fwcmd.h +++ b/drivers/net/wireless/ath/carl9170/fwcmd.h @@ -127,7 +127,7 @@ struct carl9170_write_reg { struct carl9170_write_reg_byte { __le32 addr; __le32 count; - u8 val[0]; + u8 val[]; } __packed; #define CARL9170FW_PHY_HT_ENABLE 0x4 diff --git a/drivers/net/wireless/ath/carl9170/hw.h b/drivers/net/wireless/ath/carl9170/hw.h index 08e0ae9c5836..555ad4975970 100644 --- a/drivers/net/wireless/ath/carl9170/hw.h +++ b/drivers/net/wireless/ath/carl9170/hw.h @@ -851,7 +851,7 @@ struct ar9170_stream { __le16 length; __le16 tag; - u8 payload[0]; + u8 payload[]; } __packed __aligned(4); #define AR9170_STREAM_LEN 4 From 9f12bebd512c560e9e667a6ac3cf0e04d9d7f43e Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 11 May 2020 15:53:35 +0300 Subject: [PATCH 13/20] ath10k: fix gcc-10 zero-length-bounds warnings gcc-10 started warning about out-of-bounds access for zero-length arrays: In file included from drivers/net/wireless/ath/ath10k/core.h:18, from drivers/net/wireless/ath/ath10k/htt_rx.c:8: drivers/net/wireless/ath/ath10k/htt_rx.c: In function 'ath10k_htt_rx_tx_fetch_ind': drivers/net/wireless/ath/ath10k/htt.h:1683:17: warning: array subscript 65535 is outside the bounds of an interior zero-length array 'struct htt_tx_fetch_record[0]' [-Wzero-length-bounds] 1683 | return (void *)&ind->records[le16_to_cpu(ind->num_records)]; | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ drivers/net/wireless/ath/ath10k/htt.h:1676:29: note: while referencing 'records' 1676 | struct htt_tx_fetch_record records[0]; | ^~~~~~~ Make records[] a flexible array member to allow this, moving it behind the other zero-length member that is not accessed in a way that gcc warns about. Fixes: 22e6b3bc5d96 ("ath10k: add new htt definitions") Signed-off-by: Arnd Bergmann Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20200509120707.188595-1-arnd@arndb.de --- drivers/net/wireless/ath/ath10k/htt.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/htt.h b/drivers/net/wireless/ath/ath10k/htt.h index e504be63173a..cad59494f175 100644 --- a/drivers/net/wireless/ath/ath10k/htt.h +++ b/drivers/net/wireless/ath/ath10k/htt.h @@ -1673,8 +1673,8 @@ struct htt_tx_fetch_ind { __le32 token; __le16 num_resp_ids; __le16 num_records; - struct htt_tx_fetch_record records[0]; - __le32 resp_ids[]; /* ath10k_htt_get_tx_fetch_ind_resp_ids() */ + __le32 resp_ids[0]; /* ath10k_htt_get_tx_fetch_ind_resp_ids() */ + struct htt_tx_fetch_record records[]; } __packed; static inline void * From 32221df6765b3773ff1af37c77f8531ebc48f246 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Sat, 9 May 2020 14:06:33 +0200 Subject: [PATCH 14/20] ath10k: fix ath10k_pci struct layout gcc-10 correctly points out a bug with a zero-length array in struct ath10k_pci: drivers/net/wireless/ath/ath10k/ahb.c: In function 'ath10k_ahb_remove': drivers/net/wireless/ath/ath10k/ahb.c:30:9: error: array subscript 0 is outside the bounds of an interior zero-length array 'struct ath10k_ahb[0]' [-Werror=zero-length-bounds] 30 | return &((struct ath10k_pci *)ar->drv_priv)->ahb[0]; | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In file included from drivers/net/wireless/ath/ath10k/ahb.c:13: drivers/net/wireless/ath/ath10k/pci.h:185:20: note: while referencing 'ahb' 185 | struct ath10k_ahb ahb[0]; | ^~~ The last addition to the struct ignored the comments and added new members behind the array that must remain last. Change it to a flexible-array member and move it last again to make it work correctly, prevent the same thing from happening again (all compilers warn about flexible-array members in the middle of a struct) and get it to build without warnings. Fixes: 521fc37be3d8 ("ath10k: Avoid override CE5 configuration for QCA99X0 chipsets") Signed-off-by: Arnd Bergmann Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20200509120707.188595-2-arnd@arndb.de --- drivers/net/wireless/ath/ath10k/pci.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/pci.h b/drivers/net/wireless/ath/ath10k/pci.h index e3cbd259a2dc..862d0901c5b8 100644 --- a/drivers/net/wireless/ath/ath10k/pci.h +++ b/drivers/net/wireless/ath/ath10k/pci.h @@ -178,15 +178,16 @@ struct ath10k_pci { */ u32 (*targ_cpu_to_ce_addr)(struct ath10k *ar, u32 addr); + struct ce_attr *attr; + struct ce_pipe_config *pipe_config; + struct ce_service_to_pipe *serv_to_pipe; + /* Keep this entry in the last, memory for struct ath10k_ahb is * allocated (ahb support enabled case) in the continuation of * this struct. */ - struct ath10k_ahb ahb[0]; + struct ath10k_ahb ahb[]; - struct ce_attr *attr; - struct ce_pipe_config *pipe_config; - struct ce_service_to_pipe *serv_to_pipe; }; static inline struct ath10k_pci *ath10k_pci_priv(struct ath10k *ar) From 52b776fa592178c3dc341a93fec7bc760b38cc15 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Thu, 7 May 2020 17:43:18 +0100 Subject: [PATCH 15/20] ath11k: remove redundant initialization of pointer info Pointer info is being assigned twice, once at the start of the function and secondly when it is just about to be accessed. Remove the redundant initialization and keep the original assignment to info that is close to the memcpy that uses it. Addresses-Coverity: ("Unused value") Signed-off-by: Colin Ian King Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20200507164318.56570-1-colin.king@canonical.com --- drivers/net/wireless/ath/ath11k/mac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index 5ffe55801ca4..4e1185a4cd01 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -3693,7 +3693,7 @@ static int __ath11k_set_antenna(struct ath11k *ar, u32 tx_ant, u32 rx_ant) int ath11k_mac_tx_mgmt_pending_free(int buf_id, void *skb, void *ctx) { struct sk_buff *msdu = skb; - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(msdu); + struct ieee80211_tx_info *info; struct ath11k *ar = ctx; struct ath11k_base *ab = ar->ab; From c8ffcd122760612c1fac45c44d008a3fe8b2cbb4 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Fri, 8 May 2020 07:53:23 +0000 Subject: [PATCH 16/20] ath11k: convert to devm_platform_get_and_ioremap_resource Use the helper function that wraps the calls to platform_get_resource() and devm_ioremap_resource() together. Signed-off-by: Wei Yongjun Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20200508075323.81128-1-weiyongjun1@huawei.com --- drivers/net/wireless/ath/ath11k/ahb.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/ahb.c b/drivers/net/wireless/ath/ath11k/ahb.c index ef1038aa5692..30092841ac46 100644 --- a/drivers/net/wireless/ath/ath11k/ahb.c +++ b/drivers/net/wireless/ath/ath11k/ahb.c @@ -914,13 +914,7 @@ static int ath11k_ahb_probe(struct platform_device *pdev) return -EINVAL; } - mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!mem_res) { - dev_err(&pdev->dev, "failed to get IO memory resource\n"); - return -ENXIO; - } - - mem = devm_ioremap_resource(&pdev->dev, mem_res); + mem = devm_platform_get_and_ioremap_resource(pdev, 0, &mem_res); if (IS_ERR(mem)) { dev_err(&pdev->dev, "ioremap error\n"); return PTR_ERR(mem); From 104f3d95d8d633ceebcef811c5c7c3ba56bedc7f Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Thu, 7 May 2020 10:11:20 -0500 Subject: [PATCH 17/20] wil6210: Replace zero-length array with flexible-array The current codebase makes use of the zero-length array language extension to the C90 standard, but the preferred mechanism to declare variable-length types such as these ones is a flexible array member[1][2], introduced in C99: struct foo { int stuff; struct boo array[]; }; By making use of the mechanism above, we will get a compiler warning in case the flexible array does not occur last in the structure, which will help us prevent some kind of undefined behavior bugs from being inadvertently introduced[3] to the codebase from now on. Also, notice that, dynamic memory allocations won't be affected by this change: "Flexible array members have incomplete type, and so the sizeof operator may not be applied. As a quirk of the original implementation of zero-length arrays, sizeof evaluates to zero."[1] sizeof(flexible-array-member) triggers a warning because flexible array members have incomplete type[1]. There are some instances of code in which the sizeof operator is being incorrectly/erroneously applied to zero-length arrays and the result is zero. Such instances may be hiding some bugs. So, this work (flexible-array member conversions) will also help to get completely rid of those sorts of issues. This issue was found with the help of Coccinelle. [1] https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html [2] https://github.com/KSPP/linux/issues/21 [3] commit 76497732932f ("cxgb3/l2t: Fix undefined behaviour") Signed-off-by: Gustavo A. R. Silva Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20200507151120.GA4469@embeddedor --- drivers/net/wireless/ath/wil6210/fw.h | 16 ++++---- drivers/net/wireless/ath/wil6210/wmi.c | 2 +- drivers/net/wireless/ath/wil6210/wmi.h | 56 +++++++++++++------------- 3 files changed, 37 insertions(+), 37 deletions(-) diff --git a/drivers/net/wireless/ath/wil6210/fw.h b/drivers/net/wireless/ath/wil6210/fw.h index 540fa1607794..440614d61156 100644 --- a/drivers/net/wireless/ath/wil6210/fw.h +++ b/drivers/net/wireless/ath/wil6210/fw.h @@ -33,7 +33,7 @@ struct wil_fw_record_head { */ struct wil_fw_record_data { /* type == wil_fw_type_data */ __le32 addr; - __le32 data[0]; /* [data_size], see above */ + __le32 data[]; /* [data_size], see above */ } __packed; /* fill with constant @value, @size bytes starting from @addr */ @@ -61,7 +61,7 @@ struct wil_fw_record_capabilities { /* type == wil_fw_type_comment */ /* identifies capabilities record */ struct wil_fw_record_comment_hdr hdr; /* capabilities (variable size), see enum wmi_fw_capability */ - u8 capabilities[0]; + u8 capabilities[]; } __packed; /* FW VIF concurrency encoded inside a comment record @@ -80,7 +80,7 @@ struct wil_fw_concurrency_combo { u8 n_diff_channels; /* total number of different channels allowed */ u8 same_bi; /* for APs, 1 if all APs must have same BI */ /* keep last - concurrency limits, variable size by n_limits */ - struct wil_fw_concurrency_limit limits[0]; + struct wil_fw_concurrency_limit limits[]; } __packed; struct wil_fw_record_concurrency { /* type == wil_fw_type_comment */ @@ -93,7 +93,7 @@ struct wil_fw_record_concurrency { /* type == wil_fw_type_comment */ /* number of concurrency combinations that follow */ __le16 n_combos; /* keep last - combinations, variable size by n_combos */ - struct wil_fw_concurrency_combo combos[0]; + struct wil_fw_concurrency_combo combos[]; } __packed; /* brd file info encoded inside a comment record */ @@ -108,7 +108,7 @@ struct wil_fw_record_brd_file { /* type == wil_fw_type_comment */ /* identifies brd file record */ struct wil_fw_record_comment_hdr hdr; __le32 version; - struct brd_info brd_info[0]; + struct brd_info brd_info[]; } __packed; /* perform action @@ -116,7 +116,7 @@ struct wil_fw_record_brd_file { /* type == wil_fw_type_comment */ */ struct wil_fw_record_action { /* type == wil_fw_type_action */ __le32 action; /* action to perform: reset, wait for fw ready etc. */ - __le32 data[0]; /* action specific, [data_size], see above */ + __le32 data[]; /* action specific, [data_size], see above */ } __packed; /* data block for struct wil_fw_record_direct_write */ @@ -179,7 +179,7 @@ struct wil_fw_record_gateway_data { /* type == wil_fw_type_gateway_data */ #define WIL_FW_GW_CTL_BUSY BIT(29) /* gateway busy performing operation */ #define WIL_FW_GW_CTL_RUN BIT(30) /* start gateway operation */ __le32 command; - struct wil_fw_data_gw data[0]; /* total size [data_size], see above */ + struct wil_fw_data_gw data[]; /* total size [data_size], see above */ } __packed; /* 4-dword gateway */ @@ -201,7 +201,7 @@ struct wil_fw_record_gateway_data4 { /* type == wil_fw_type_gateway_data4 */ __le32 gateway_cmd_addr; __le32 gateway_ctrl_address; /* same logic as for 1-dword gw */ __le32 command; - struct wil_fw_data_gw4 data[0]; /* total size [data_size], see above */ + struct wil_fw_data_gw4 data[]; /* total size [data_size], see above */ } __packed; #endif /* __WIL_FW_H__ */ diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c index 23e1ed6a9d6d..c7136ce567ee 100644 --- a/drivers/net/wireless/ath/wil6210/wmi.c +++ b/drivers/net/wireless/ath/wil6210/wmi.c @@ -222,7 +222,7 @@ struct auth_no_hdr { __le16 auth_transaction; __le16 status_code; /* possibly followed by Challenge text */ - u8 variable[0]; + u8 variable[]; } __packed; u8 led_polarity = LED_POLARITY_LOW_ACTIVE; diff --git a/drivers/net/wireless/ath/wil6210/wmi.h b/drivers/net/wireless/ath/wil6210/wmi.h index 5bba45c1de48..9affa4525609 100644 --- a/drivers/net/wireless/ath/wil6210/wmi.h +++ b/drivers/net/wireless/ath/wil6210/wmi.h @@ -530,7 +530,7 @@ struct wmi_update_ft_ies_cmd { /* Length of the FT IEs */ __le16 ie_len; u8 reserved[2]; - u8 ie_info[0]; + u8 ie_info[]; } __packed; /* WMI_SET_PROBED_SSID_CMDID */ @@ -575,7 +575,7 @@ struct wmi_set_appie_cmd { u8 reserved; /* Length of the IE to be added to MGMT frame */ __le16 ie_len; - u8 ie_info[0]; + u8 ie_info[]; } __packed; /* WMI_PXMT_RANGE_CFG_CMDID */ @@ -850,7 +850,7 @@ struct wmi_pcp_start_cmd { struct wmi_sw_tx_req_cmd { u8 dst_mac[WMI_MAC_LEN]; __le16 len; - u8 payload[0]; + u8 payload[]; } __packed; /* WMI_SW_TX_REQ_EXT_CMDID */ @@ -861,7 +861,7 @@ struct wmi_sw_tx_req_ext_cmd { /* Channel to use, 0xFF for currently active channel */ u8 channel; u8 reserved[5]; - u8 payload[0]; + u8 payload[]; } __packed; /* WMI_VRING_SWITCH_TIMING_CONFIG_CMDID */ @@ -1423,7 +1423,7 @@ struct wmi_rf_xpm_write_cmd { u8 verify; u8 reserved1[3]; /* actual size=num_bytes */ - u8 data_bytes[0]; + u8 data_bytes[]; } __packed; /* Possible modes for temperature measurement */ @@ -1572,7 +1572,7 @@ struct wmi_tof_session_start_cmd { u8 aoa_type; __le16 num_of_dest; u8 reserved[4]; - struct wmi_ftm_dest_info ftm_dest_info[0]; + struct wmi_ftm_dest_info ftm_dest_info[]; } __packed; /* WMI_TOF_CFG_RESPONDER_CMDID */ @@ -1766,7 +1766,7 @@ struct wmi_internal_fw_ioctl_cmd { /* payload max size is WMI_MAX_IOCTL_PAYLOAD_SIZE * Must be the last member of the struct */ - __le32 payload[0]; + __le32 payload[]; } __packed; /* WMI_INTERNAL_FW_IOCTL_EVENTID */ @@ -1778,7 +1778,7 @@ struct wmi_internal_fw_ioctl_event { /* payload max size is WMI_MAX_IOCTL_REPLY_PAYLOAD_SIZE * Must be the last member of the struct */ - __le32 payload[0]; + __le32 payload[]; } __packed; /* WMI_INTERNAL_FW_EVENT_EVENTID */ @@ -1788,7 +1788,7 @@ struct wmi_internal_fw_event_event { /* payload max size is WMI_MAX_INTERNAL_EVENT_PAYLOAD_SIZE * Must be the last member of the struct */ - __le32 payload[0]; + __le32 payload[]; } __packed; /* WMI_SET_VRING_PRIORITY_WEIGHT_CMDID */ @@ -1818,7 +1818,7 @@ struct wmi_set_vring_priority_cmd { */ u8 num_of_vrings; u8 reserved[3]; - struct wmi_vring_priority vring_priority[0]; + struct wmi_vring_priority vring_priority[]; } __packed; /* WMI_BF_CONTROL_CMDID - deprecated */ @@ -1910,7 +1910,7 @@ struct wmi_bf_control_ex_cmd { u8 each_mcs_cfg_size; u8 reserved1; /* Configuration for each MCS */ - struct wmi_bf_control_ex_mcs each_mcs_cfg[0]; + struct wmi_bf_control_ex_mcs each_mcs_cfg[]; } __packed; /* WMI_LINK_STATS_CMD */ @@ -2192,7 +2192,7 @@ struct wmi_fw_ver_event { /* FW capabilities info * Must be the last member of the struct */ - __le32 fw_capabilities[0]; + __le32 fw_capabilities[]; } __packed; /* WMI_GET_RF_STATUS_EVENTID */ @@ -2270,7 +2270,7 @@ struct wmi_mac_addr_resp_event { struct wmi_eapol_rx_event { u8 src_mac[WMI_MAC_LEN]; __le16 eapol_len; - u8 eapol[0]; + u8 eapol[]; } __packed; /* WMI_READY_EVENTID */ @@ -2343,7 +2343,7 @@ struct wmi_connect_event { u8 aid; u8 reserved2[2]; /* not in use */ - u8 assoc_info[0]; + u8 assoc_info[]; } __packed; /* disconnect_reason */ @@ -2376,7 +2376,7 @@ struct wmi_disconnect_event { /* last assoc req may passed to host - not in used */ u8 assoc_resp_len; /* last assoc req may passed to host - not in used */ - u8 assoc_info[0]; + u8 assoc_info[]; } __packed; /* WMI_SCAN_COMPLETE_EVENTID */ @@ -2400,7 +2400,7 @@ struct wmi_ft_auth_status_event { u8 reserved[3]; u8 mac_addr[WMI_MAC_LEN]; __le16 ie_len; - u8 ie_info[0]; + u8 ie_info[]; } __packed; /* WMI_FT_REASSOC_STATUS_EVENTID */ @@ -2418,7 +2418,7 @@ struct wmi_ft_reassoc_status_event { __le16 reassoc_req_ie_len; __le16 reassoc_resp_ie_len; u8 reserved[4]; - u8 ie_info[0]; + u8 ie_info[]; } __packed; /* wmi_rx_mgmt_info */ @@ -2461,7 +2461,7 @@ struct wmi_stop_sched_scan_event { struct wmi_sched_scan_result_event { struct wmi_rx_mgmt_info info; - u8 payload[0]; + u8 payload[]; } __packed; /* WMI_ACS_PASSIVE_SCAN_COMPLETE_EVENT */ @@ -2492,7 +2492,7 @@ struct wmi_acs_passive_scan_complete_event { __le16 filled; u8 num_scanned_channels; u8 reserved; - struct scan_acs_info scan_info_list[0]; + struct scan_acs_info scan_info_list[]; } __packed; /* WMI_BA_STATUS_EVENTID */ @@ -2751,7 +2751,7 @@ struct wmi_rf_xpm_read_result_event { u8 status; u8 reserved[3]; /* requested num_bytes of data */ - u8 data_bytes[0]; + u8 data_bytes[]; } __packed; /* EVENT: WMI_RF_XPM_WRITE_RESULT_EVENTID */ @@ -2769,7 +2769,7 @@ struct wmi_tx_mgmt_packet_event { /* WMI_RX_MGMT_PACKET_EVENTID */ struct wmi_rx_mgmt_packet_event { struct wmi_rx_mgmt_info info; - u8 payload[0]; + u8 payload[]; } __packed; /* WMI_ECHO_RSP_EVENTID */ @@ -2969,7 +2969,7 @@ struct wmi_rs_cfg_ex_cmd { u8 each_mcs_cfg_size; u8 reserved[3]; /* Configuration for each MCS */ - struct wmi_rs_cfg_ex_mcs each_mcs_cfg[0]; + struct wmi_rs_cfg_ex_mcs each_mcs_cfg[]; } __packed; /* WMI_RS_CFG_EX_EVENTID */ @@ -3178,7 +3178,7 @@ struct wmi_get_detailed_rs_res_ex_event { u8 each_mcs_results_size; u8 reserved1[3]; /* Results for each MCS */ - struct wmi_rs_results_ex_mcs each_mcs_results[0]; + struct wmi_rs_results_ex_mcs each_mcs_results[]; } __packed; /* BRP antenna limit mode */ @@ -3320,7 +3320,7 @@ struct wmi_set_link_monitor_cmd { u8 rssi_hyst; u8 reserved[12]; u8 rssi_thresholds_list_size; - s8 rssi_thresholds_list[0]; + s8 rssi_thresholds_list[]; } __packed; /* wmi_link_monitor_event_type */ @@ -3637,7 +3637,7 @@ struct wmi_tof_ftm_per_dest_res_event { /* Measurments are from RFs, defined by the mask */ __le32 meas_rf_mask; u8 reserved0[3]; - struct wmi_responder_ftm_res responder_ftm_res[0]; + struct wmi_responder_ftm_res responder_ftm_res[]; } __packed; /* WMI_TOF_CFG_RESPONDER_EVENTID */ @@ -3669,7 +3669,7 @@ struct wmi_tof_channel_info_event { /* data report length */ u8 len; /* data report payload */ - u8 report[0]; + u8 report[]; } __packed; /* WMI_TOF_SET_TX_RX_OFFSET_EVENTID */ @@ -4085,7 +4085,7 @@ struct wmi_link_stats_event { u8 has_next; u8 reserved[5]; /* a stream of wmi_link_stats_record_s */ - u8 payload[0]; + u8 payload[]; } __packed; /* WMI_LINK_STATS_EVENT */ @@ -4094,7 +4094,7 @@ struct wmi_link_stats_record { u8 record_type_id; u8 reserved; __le16 record_size; - u8 record[0]; + u8 record[]; } __packed; /* WMI_LINK_STATS_TYPE_BASIC */ From 012f81456818dfb49d2939373b163945da3a4032 Mon Sep 17 00:00:00 2001 From: Pradeep Kumar Chitrapu Date: Tue, 12 May 2020 10:42:02 +0300 Subject: [PATCH 18/20] ath11k: fix htt stats module not handle multiple skbs HTT EXT stats comes in stream of TLVs spanning over multiple messages. Currently completion is being sent for each message which is creating a race where stats_req is being accessed for filling in second message after the memory is already freed in release operation. Fix this by issuing completion once all the messages are received and processed. Driver knows this info from DONE bit set in htt msg. Also fix locking required for htt stats. Co-developed-by: Miles Hu Signed-off-by: Miles Hu Signed-off-by: Pradeep Kumar Chitrapu Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/1589221074-28778-1-git-send-email-pradeepc@codeaurora.org --- .../net/wireless/ath/ath11k/debug_htt_stats.c | 50 +++++++++++++++---- drivers/net/wireless/ath/ath11k/dp.h | 1 + 2 files changed, 40 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/debug_htt_stats.c b/drivers/net/wireless/ath/ath11k/debug_htt_stats.c index 5db0c27de475..6b532dc99c98 100644 --- a/drivers/net/wireless/ath/ath11k/debug_htt_stats.c +++ b/drivers/net/wireless/ath/ath11k/debug_htt_stats.c @@ -4306,6 +4306,7 @@ void ath11k_dbg_htt_ext_stats_handler(struct ath11k_base *ab, u32 len; u64 cookie; int ret; + bool send_completion = false; u8 pdev_id; msg = (struct ath11k_htt_extd_stats_msg *)skb->data; @@ -4330,11 +4331,11 @@ void ath11k_dbg_htt_ext_stats_handler(struct ath11k_base *ab, return; spin_lock_bh(&ar->debug.htt_stats.lock); - if (stats_req->done) { - spin_unlock_bh(&ar->debug.htt_stats.lock); - return; - } - stats_req->done = true; + + stats_req->done = FIELD_GET(HTT_T2H_EXT_STATS_INFO1_DONE, msg->info1); + if (stats_req->done) + send_completion = true; + spin_unlock_bh(&ar->debug.htt_stats.lock); len = FIELD_GET(HTT_T2H_EXT_STATS_INFO1_LENGTH, msg->info1); @@ -4344,7 +4345,8 @@ void ath11k_dbg_htt_ext_stats_handler(struct ath11k_base *ab, if (ret) ath11k_warn(ab, "Failed to parse tlv %d\n", ret); - complete(&stats_req->cmpln); + if (send_completion) + complete(&stats_req->cmpln); } static ssize_t ath11k_read_htt_stats_type(struct file *file, @@ -4497,28 +4499,54 @@ static int ath11k_open_htt_stats(struct inode *inode, struct file *file) if (type == ATH11K_DBG_HTT_EXT_STATS_RESET) return -EPERM; - stats_req = vzalloc(sizeof(*stats_req) + ATH11K_HTT_STATS_BUF_SIZE); - if (!stats_req) - return -ENOMEM; - mutex_lock(&ar->conf_mutex); + + if (ar->state != ATH11K_STATE_ON) { + ret = -ENETDOWN; + goto err_unlock; + } + + if (ar->debug.htt_stats.stats_req) { + ret = -EAGAIN; + goto err_unlock; + } + + stats_req = vzalloc(sizeof(*stats_req) + ATH11K_HTT_STATS_BUF_SIZE); + if (!stats_req) { + ret = -ENOMEM; + goto err_unlock; + } + ar->debug.htt_stats.stats_req = stats_req; stats_req->type = type; + ret = ath11k_dbg_htt_stats_req(ar); - mutex_unlock(&ar->conf_mutex); if (ret < 0) goto out; file->private_data = stats_req; + + mutex_unlock(&ar->conf_mutex); + return 0; out: vfree(stats_req); + ar->debug.htt_stats.stats_req = NULL; +err_unlock: + mutex_unlock(&ar->conf_mutex); + return ret; } static int ath11k_release_htt_stats(struct inode *inode, struct file *file) { + struct ath11k *ar = inode->i_private; + + mutex_lock(&ar->conf_mutex); vfree(file->private_data); + ar->debug.htt_stats.stats_req = NULL; + mutex_unlock(&ar->conf_mutex); + return 0; } diff --git a/drivers/net/wireless/ath/ath11k/dp.h b/drivers/net/wireless/ath/ath11k/dp.h index 222de10e4b93..058a5c1d86ff 100644 --- a/drivers/net/wireless/ath/ath11k/dp.h +++ b/drivers/net/wireless/ath/ath11k/dp.h @@ -1517,6 +1517,7 @@ struct htt_ext_stats_cfg_params { * 4 bytes. */ +#define HTT_T2H_EXT_STATS_INFO1_DONE BIT(11) #define HTT_T2H_EXT_STATS_INFO1_LENGTH GENMASK(31, 16) struct ath11k_htt_extd_stats_msg { From ec431188b4197aaccfbc6e6ece4fb88f79723635 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Thu, 7 May 2020 10:17:58 -0500 Subject: [PATCH 19/20] wcn36xx: Replace zero-length array with flexible-array The current codebase makes use of the zero-length array language extension to the C90 standard, but the preferred mechanism to declare variable-length types such as these ones is a flexible array member[1][2], introduced in C99: struct foo { int stuff; struct boo array[]; }; By making use of the mechanism above, we will get a compiler warning in case the flexible array does not occur last in the structure, which will help us prevent some kind of undefined behavior bugs from being inadvertently introduced[3] to the codebase from now on. Also, notice that, dynamic memory allocations won't be affected by this change: "Flexible array members have incomplete type, and so the sizeof operator may not be applied. As a quirk of the original implementation of zero-length arrays, sizeof evaluates to zero."[1] sizeof(flexible-array-member) triggers a warning because flexible array members have incomplete type[1]. There are some instances of code in which the sizeof operator is being incorrectly/erroneously applied to zero-length arrays and the result is zero. Such instances may be hiding some bugs. So, this work (flexible-array member conversions) will also help to get completely rid of those sorts of issues. This issue was found with the help of Coccinelle. [1] https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html [2] https://github.com/KSPP/linux/issues/21 [3] commit 76497732932f ("cxgb3/l2t: Fix undefined behaviour") Signed-off-by: Gustavo A. R. Silva Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20200507151758.GA4962@embeddedor --- drivers/net/wireless/ath/wcn36xx/hal.h | 4 ++-- drivers/net/wireless/ath/wcn36xx/testmode.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/wcn36xx/hal.h b/drivers/net/wireless/ath/wcn36xx/hal.h index 6ba0fd57c951..aab5a58616fc 100644 --- a/drivers/net/wireless/ath/wcn36xx/hal.h +++ b/drivers/net/wireless/ath/wcn36xx/hal.h @@ -2240,7 +2240,7 @@ struct wcn36xx_hal_process_ptt_msg_req_msg { struct wcn36xx_hal_msg_header header; /* Actual FTM Command body */ - u8 ptt_msg[0]; + u8 ptt_msg[]; } __packed; struct wcn36xx_hal_process_ptt_msg_rsp_msg { @@ -2249,7 +2249,7 @@ struct wcn36xx_hal_process_ptt_msg_rsp_msg { /* FTM Command response status */ u32 ptt_msg_resp_status; /* Actual FTM Command body */ - u8 ptt_msg[0]; + u8 ptt_msg[]; } __packed; struct update_edca_params_req_msg { diff --git a/drivers/net/wireless/ath/wcn36xx/testmode.h b/drivers/net/wireless/ath/wcn36xx/testmode.h index 4c6cfdb46580..09d68fab9add 100644 --- a/drivers/net/wireless/ath/wcn36xx/testmode.h +++ b/drivers/net/wireless/ath/wcn36xx/testmode.h @@ -20,7 +20,7 @@ struct ftm_rsp_msg { u16 msg_id; u16 msg_body_length; u32 resp_status; - u8 msg_response[0]; + u8 msg_response[]; } __packed; /* The request buffer of FTM which contains a byte of command and the request */ From 25ca180ad380a0c7286442a922e7fbcc6a9f6083 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Wed, 13 May 2020 22:14:54 +0200 Subject: [PATCH 20/20] ath11k: Fix some resource leaks in error path in 'ath11k_thermal_register()' If 'thermal_cooling_device_register()' fails, we must undo what has been allocated so far. So we must go to 'err_thermal_destroy' instead of returning directly In case of error in 'ath11k_thermal_register()', the previous 'thermal_cooling_device_register()' call must also be undone. Move the 'ar->thermal.cdev = cdev' a few lines above in order for this to be done in 'ath11k_thermal_unregister()' which is called in the error handling path. Fixes: 2a63bbca06b2 ("ath11k: add thermal cooling device support") Signed-off-by: Christophe JAILLET Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20200513201454.258111-1-christophe.jaillet@wanadoo.fr --- drivers/net/wireless/ath/ath11k/thermal.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/thermal.c b/drivers/net/wireless/ath/ath11k/thermal.c index 259dddbda2c7..5a7e150c621b 100644 --- a/drivers/net/wireless/ath/ath11k/thermal.c +++ b/drivers/net/wireless/ath/ath11k/thermal.c @@ -174,9 +174,12 @@ int ath11k_thermal_register(struct ath11k_base *sc) if (IS_ERR(cdev)) { ath11k_err(sc, "failed to setup thermal device result: %ld\n", PTR_ERR(cdev)); - return -EINVAL; + ret = -EINVAL; + goto err_thermal_destroy; } + ar->thermal.cdev = cdev; + ret = sysfs_create_link(&ar->hw->wiphy->dev.kobj, &cdev->device.kobj, "cooling_device"); if (ret) { @@ -184,7 +187,6 @@ int ath11k_thermal_register(struct ath11k_base *sc) goto err_thermal_destroy; } - ar->thermal.cdev = cdev; if (!IS_REACHABLE(CONFIG_HWMON)) return 0;