From patchwork Sun Sep 8 08:32:45 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maya Erez X-Patchwork-Id: 11136849 X-Patchwork-Delegate: kvalo@adurom.com Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B90E913B1 for ; Sun, 8 Sep 2019 08:39:17 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id A395F21479 for ; Sun, 8 Sep 2019 08:39:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727413AbfIHIjQ (ORCPT ); Sun, 8 Sep 2019 04:39:16 -0400 Received: from alexa-out-ams-02.qualcomm.com ([185.23.61.163]:7970 "EHLO alexa-out-ams-02.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727362AbfIHIjP (ORCPT ); Sun, 8 Sep 2019 04:39:15 -0400 Received: from ironmsg03-ams.qualcomm.com ([10.251.56.4]) by alexa-out-ams-02.qualcomm.com with ESMTP; 08 Sep 2019 10:33:04 +0200 Received: from lx-merez1.mea.qualcomm.com ([10.18.173.103]) by ironmsg03-ams.qualcomm.com with ESMTP; 08 Sep 2019 10:32:59 +0200 From: Maya Erez To: Kalle Valo Cc: Dedy Lansky , linux-wireless@vger.kernel.org, wil6210@qti.qualcomm.com, Maya Erez Subject: [PATCH 01/11] wil6210: add wil_netif_rx() helper function Date: Sun, 8 Sep 2019 11:32:45 +0300 Message-Id: <1567931575-27984-2-git-send-email-merez@codeaurora.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1567931575-27984-1-git-send-email-merez@codeaurora.org> References: <1567931575-27984-1-git-send-email-merez@codeaurora.org> Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Dedy Lansky Move common part of wil_netif_rx_any into new helper function and add support for non-gro receive using netif_rx_ni. Signed-off-by: Dedy Lansky Signed-off-by: Maya Erez --- drivers/net/wireless/ath/wil6210/txrx.c | 60 ++++++++++++++++++++------------- drivers/net/wireless/ath/wil6210/txrx.h | 2 ++ 2 files changed, 38 insertions(+), 24 deletions(-) diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c index 8b01ef8..b6253fc 100644 --- a/drivers/net/wireless/ath/wil6210/txrx.c +++ b/drivers/net/wireless/ath/wil6210/txrx.c @@ -728,21 +728,19 @@ static void wil_get_netif_rx_params(struct sk_buff *skb, int *cid, * Pass Rx packet to the netif. Update statistics. * Called in softirq context (NAPI poll). */ -void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev) +void wil_netif_rx(struct sk_buff *skb, struct net_device *ndev, int cid, + struct wil_net_stats *stats, bool gro) { gro_result_t rc = GRO_NORMAL; struct wil6210_vif *vif = ndev_to_vif(ndev); struct wil6210_priv *wil = ndev_to_wil(ndev); struct wireless_dev *wdev = vif_to_wdev(vif); unsigned int len = skb->len; - int cid; - int security; u8 *sa, *da = wil_skb_get_da(skb); /* here looking for DA, not A1, thus Rxdesc's 'mcast' indication * is not suitable, need to look at data */ int mcast = is_multicast_ether_addr(da); - struct wil_net_stats *stats; struct sk_buff *xmit_skb = NULL; static const char * const gro_res_str[] = { [GRO_MERGED] = "GRO_MERGED", @@ -753,25 +751,6 @@ void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev) [GRO_CONSUMED] = "GRO_CONSUMED", }; - wil->txrx_ops.get_netif_rx_params(skb, &cid, &security); - - stats = &wil->sta[cid].stats; - - skb_orphan(skb); - - if (security && (wil->txrx_ops.rx_crypto_check(wil, skb) != 0)) { - rc = GRO_DROP; - dev_kfree_skb(skb); - stats->rx_replay++; - goto stats; - } - - /* check errors reported by HW and update statistics */ - if (unlikely(wil->txrx_ops.rx_error_check(wil, skb, stats))) { - dev_kfree_skb(skb); - return; - } - if (wdev->iftype == NL80211_IFTYPE_STATION) { sa = wil_skb_get_sa(skb); if (mcast && ether_addr_equal(sa, ndev->dev_addr)) { @@ -817,7 +796,10 @@ void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev) if (skb) { /* deliver to local stack */ skb->protocol = eth_type_trans(skb, ndev); skb->dev = ndev; - rc = napi_gro_receive(&wil->napi_rx, skb); + if (gro) + rc = napi_gro_receive(&wil->napi_rx, skb); + else + netif_rx_ni(skb); wil_dbg_txrx(wil, "Rx complete %d bytes => %s\n", len, gro_res_str[rc]); } @@ -837,6 +819,36 @@ void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev) } } +void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev) +{ + int cid, security; + struct wil6210_priv *wil = ndev_to_wil(ndev); + struct wil_net_stats *stats; + + wil->txrx_ops.get_netif_rx_params(skb, &cid, &security); + + stats = &wil->sta[cid].stats; + + skb_orphan(skb); + + if (security && (wil->txrx_ops.rx_crypto_check(wil, skb) != 0)) { + dev_kfree_skb(skb); + ndev->stats.rx_dropped++; + stats->rx_replay++; + stats->rx_dropped++; + wil_dbg_txrx(wil, "Rx drop %d bytes\n", skb->len); + return; + } + + /* check errors reported by HW and update statistics */ + if (unlikely(wil->txrx_ops.rx_error_check(wil, skb, stats))) { + dev_kfree_skb(skb); + return; + } + + wil_netif_rx(skb, ndev, cid, stats, true); +} + /** * Proceed all completed skb's from Rx VRING * diff --git a/drivers/net/wireless/ath/wil6210/txrx.h b/drivers/net/wireless/ath/wil6210/txrx.h index c0da134..fceb251 100644 --- a/drivers/net/wireless/ath/wil6210/txrx.h +++ b/drivers/net/wireless/ath/wil6210/txrx.h @@ -646,6 +646,8 @@ static inline void wil_skb_set_cid(struct sk_buff *skb, u8 cid) } void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev); +void wil_netif_rx(struct sk_buff *skb, struct net_device *ndev, int cid, + struct wil_net_stats *stats, bool gro); void wil_rx_reorder(struct wil6210_priv *wil, struct sk_buff *skb); void wil_rx_bar(struct wil6210_priv *wil, struct wil6210_vif *vif, u8 cid, u8 tid, u16 seq); From patchwork Sun Sep 8 08:32:46 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maya Erez X-Patchwork-Id: 11136843 X-Patchwork-Delegate: kvalo@adurom.com Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3AC9C1395 for ; Sun, 8 Sep 2019 08:39:14 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 1C04121479 for ; Sun, 8 Sep 2019 08:39:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727379AbfIHIjN (ORCPT ); Sun, 8 Sep 2019 04:39:13 -0400 Received: from alexa-out-ams-02.qualcomm.com ([185.23.61.163]:51394 "EHLO alexa-out-ams-02.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727362AbfIHIjM (ORCPT ); Sun, 8 Sep 2019 04:39:12 -0400 X-Greylist: delayed 365 seconds by postgrey-1.27 at vger.kernel.org; Sun, 08 Sep 2019 04:39:09 EDT Received: from ironmsg03-ams.qualcomm.com ([10.251.56.4]) by alexa-out-ams-02.qualcomm.com with ESMTP; 08 Sep 2019 10:33:03 +0200 Received: from lx-merez1.mea.qualcomm.com ([10.18.173.103]) by ironmsg03-ams.qualcomm.com with ESMTP; 08 Sep 2019 10:33:00 +0200 From: Maya Erez To: Kalle Valo Cc: Maya Erez , linux-wireless@vger.kernel.org, wil6210@qti.qualcomm.com Subject: [PATCH 02/11] wil6210: add support for pci linkdown recovery Date: Sun, 8 Sep 2019 11:32:46 +0300 Message-Id: <1567931575-27984-3-git-send-email-merez@codeaurora.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1567931575-27984-1-git-send-email-merez@codeaurora.org> References: <1567931575-27984-1-git-send-email-merez@codeaurora.org> Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org Some platforms can notify on pci linkdown events. Add pci linkdown recovery flow, invoked upon pci linkdown notification. A new wil6210 status flag is added, wil_status_pci_linkdown, to prevent pci suspend / resume until the recovery is completed. After the pci link is recovered in the platform pci recovery callback the device is being reset and the interface and AP mode states are restored. Signed-off-by: Maya Erez --- drivers/net/wireless/ath/wil6210/main.c | 31 +++++-- drivers/net/wireless/ath/wil6210/pcie_bus.c | 107 ++++++++++++++++++++++++ drivers/net/wireless/ath/wil6210/pm.c | 6 ++ drivers/net/wireless/ath/wil6210/wil6210.h | 6 ++ drivers/net/wireless/ath/wil6210/wil_platform.h | 8 ++ 5 files changed, 149 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c index 173561f..0f270b8 100644 --- a/drivers/net/wireless/ath/wil6210/main.c +++ b/drivers/net/wireless/ath/wil6210/main.c @@ -533,22 +533,16 @@ bool wil_is_recovery_blocked(struct wil6210_priv *wil) return no_fw_recovery && (wil->recovery_state == fw_recovery_pending); } -static void wil_fw_error_worker(struct work_struct *work) +void wil_fw_recovery(struct wil6210_priv *wil) { - struct wil6210_priv *wil = container_of(work, struct wil6210_priv, - fw_error_worker); struct net_device *ndev = wil->main_ndev; struct wireless_dev *wdev; - wil_dbg_misc(wil, "fw error worker\n"); + wil_dbg_misc(wil, "fw recovery\n"); - if (!ndev || !(ndev->flags & IFF_UP)) { - wil_info(wil, "No recovery - interface is down\n"); - return; - } wdev = ndev->ieee80211_ptr; - /* increment @recovery_count if less then WIL6210_FW_RECOVERY_TO + /* increment @recovery_count if less than WIL6210_FW_RECOVERY_TO * passed since last recovery attempt */ if (time_is_after_jiffies(wil->last_fw_recovery + @@ -608,6 +602,22 @@ static void wil_fw_error_worker(struct work_struct *work) rtnl_unlock(); } +static void wil_fw_error_worker(struct work_struct *work) +{ + struct wil6210_priv *wil = container_of(work, struct wil6210_priv, + fw_error_worker); + struct net_device *ndev = wil->main_ndev; + + wil_dbg_misc(wil, "fw error worker\n"); + + if (!ndev || !(ndev->flags & IFF_UP)) { + wil_info(wil, "No recovery - interface is down\n"); + return; + } + + wil_fw_recovery(wil); +} + static int wil_find_free_ring(struct wil6210_priv *wil) { int i; @@ -720,6 +730,8 @@ int wil_priv_init(struct wil6210_priv *wil) INIT_WORK(&wil->wmi_event_worker, wmi_event_worker); INIT_WORK(&wil->fw_error_worker, wil_fw_error_worker); + INIT_WORK(&wil->pci_linkdown_recovery_worker, + wil_pci_linkdown_recovery_worker); INIT_LIST_HEAD(&wil->pending_wmi_ev); spin_lock_init(&wil->wmi_ev_lock); @@ -836,6 +848,7 @@ void wil_priv_deinit(struct wil6210_priv *wil) wil_set_recovery_state(wil, fw_recovery_idle); cancel_work_sync(&wil->fw_error_worker); + cancel_work_sync(&wil->pci_linkdown_recovery_worker); wmi_event_flush(wil); destroy_workqueue(wil->wq_service); destroy_workqueue(wil->wmi_wq); diff --git a/drivers/net/wireless/ath/wil6210/pcie_bus.c b/drivers/net/wireless/ath/wil6210/pcie_bus.c index 9f5a914..cd417fa 100644 --- a/drivers/net/wireless/ath/wil6210/pcie_bus.c +++ b/drivers/net/wireless/ath/wil6210/pcie_bus.c @@ -296,6 +296,107 @@ static int wil_platform_rop_fw_recovery(void *wil_handle) return 0; } +void wil_pci_linkdown_recovery_worker(struct work_struct *work) +{ + struct wil6210_priv *wil = container_of(work, struct wil6210_priv, + pci_linkdown_recovery_worker); + int rc, i; + struct wil6210_vif *vif; + struct net_device *ndev = wil->main_ndev; + + wil_dbg_misc(wil, "starting pci_linkdown recovery\n"); + + rtnl_lock(); + mutex_lock(&wil->mutex); + down_write(&wil->mem_lock); + clear_bit(wil_status_fwready, wil->status); + set_bit(wil_status_pci_linkdown, wil->status); + set_bit(wil_status_resetting, wil->status); + up_write(&wil->mem_lock); + + if (test_and_clear_bit(wil_status_napi_en, wil->status)) { + napi_disable(&wil->napi_rx); + napi_disable(&wil->napi_tx); + } + + mutex_unlock(&wil->mutex); + rtnl_unlock(); + + mutex_lock(&wil->mutex); + + mutex_lock(&wil->vif_mutex); + wil_p2p_stop_radio_operations(wil); + wil_abort_scan_all_vifs(wil, false); + mutex_unlock(&wil->vif_mutex); + + for (i = 0; i < wil->max_vifs; i++) { + vif = wil->vifs[i]; + if (vif) { + cancel_work_sync(&vif->disconnect_worker); + wil6210_disconnect(vif, NULL, + WLAN_REASON_DEAUTH_LEAVING); + } + } + + wmi_event_flush(wil); + flush_workqueue(wil->wq_service); + flush_workqueue(wil->wmi_wq); + + /* Recover PCIe */ + if (wil->platform_ops.pci_linkdown_recovery) { + rc = wil->platform_ops.pci_linkdown_recovery( + wil->platform_handle); + if (rc) { + wil_err(wil, + "platform device failed to recover from pci linkdown (%d)\n", + rc); + goto out; + } + } else { + wil_err(wil, + "platform device doesn't support pci_linkdown recovery\n"); + goto out; + } + + if (!ndev || !(ndev->flags & IFF_UP)) { + wil_reset(wil, false); + mutex_unlock(&wil->mutex); + } else { + mutex_unlock(&wil->mutex); + wil->recovery_state = fw_recovery_pending; + wil_fw_recovery(wil); + } + + return; + +out: + mutex_unlock(&wil->mutex); +} + +static int wil_platform_rop_notify(void *wil_handle, + enum wil_platform_notif notif) +{ + struct wil6210_priv *wil = wil_handle; + + if (!wil) + return -EINVAL; + + switch (notif) { + case WIL_PLATFORM_NOTIF_PCI_LINKDOWN: + wil_info(wil, "received WIL_PLATFORM_NOTIF_PCI_LINKDOWN\n"); + clear_bit(wil_status_fwready, wil->status); + set_bit(wil_status_resetting, wil->status); + set_bit(wil_status_pci_linkdown, wil->status); + + schedule_work(&wil->pci_linkdown_recovery_worker); + break; + default: + break; + } + + return 0; +} + static void wil_platform_ops_uninit(struct wil6210_priv *wil) { if (wil->platform_ops.uninit) @@ -311,6 +412,7 @@ static int wil_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) const struct wil_platform_rops rops = { .ramdump = wil_platform_rop_ramdump, .fw_recovery = wil_platform_rop_fw_recovery, + .notify = wil_platform_rop_notify, }; u32 bar_size = pci_resource_len(pdev, 0); int dma_addr_size[] = {64, 48, 40, 32}; /* keep descending order */ @@ -548,6 +650,11 @@ static int wil6210_resume(struct device *dev, bool is_runtime) struct wil6210_priv *wil = pci_get_drvdata(pdev); bool keep_radio_on, active_ifaces; + if (test_bit(wil_status_pci_linkdown, wil->status)) { + wil_dbg_pm(wil, "ignore resume during pci linkdown\n"); + return 0; + } + wil_dbg_pm(wil, "resume: %s\n", is_runtime ? "runtime" : "system"); mutex_lock(&wil->vif_mutex); diff --git a/drivers/net/wireless/ath/wil6210/pm.c b/drivers/net/wireless/ath/wil6210/pm.c index 56143e7..bc642d0 100644 --- a/drivers/net/wireless/ath/wil6210/pm.c +++ b/drivers/net/wireless/ath/wil6210/pm.c @@ -101,6 +101,12 @@ int wil_can_suspend(struct wil6210_priv *wil, bool is_runtime) goto out; } + if (test_bit(wil_status_pci_linkdown, wil->status)) { + wil_dbg_pm(wil, "Delay suspend during pci linkdown\n"); + rc = -EBUSY; + goto out; + } + mutex_lock(&wil->vif_mutex); active_ifaces = wil_has_active_ifaces(wil, true, false); mutex_unlock(&wil->vif_mutex); diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h index ecda3ca..6463310 100644 --- a/drivers/net/wireless/ath/wil6210/wil6210.h +++ b/drivers/net/wireless/ath/wil6210/wil6210.h @@ -661,6 +661,7 @@ enum { /* for wil6210_priv.status */ wil_status_suspending, /* suspend in progress */ wil_status_suspended, /* suspend completed, device is suspended */ wil_status_resuming, /* resume in progress */ + wil_status_pci_linkdown, /* pci linkdown occurred */ wil_status_last /* keep last */ }; @@ -1059,6 +1060,8 @@ struct wil6210_priv { u32 max_agg_wsize; u32 max_ampdu_size; + + struct work_struct pci_linkdown_recovery_worker; }; #define wil_to_wiphy(i) (i->wiphy) @@ -1354,6 +1357,9 @@ void wil6210_disconnect_complete(struct wil6210_vif *vif, const u8 *bssid, void wil_init_txrx_ops(struct wil6210_priv *wil); +void wil_fw_recovery(struct wil6210_priv *wil); +void wil_pci_linkdown_recovery_worker(struct work_struct *work); + /* TX API */ int wil_ring_init_tx(struct wil6210_vif *vif, int cid); int wil_vring_init_bcast(struct wil6210_vif *vif, int id, int size); diff --git a/drivers/net/wireless/ath/wil6210/wil_platform.h b/drivers/net/wireless/ath/wil6210/wil_platform.h index bca0906..20f69e8 100644 --- a/drivers/net/wireless/ath/wil6210/wil_platform.h +++ b/drivers/net/wireless/ath/wil6210/wil_platform.h @@ -27,6 +27,10 @@ enum wil_platform_event { WIL_PLATFORM_EVT_POST_SUSPEND = 4, }; +enum wil_platform_notif { + WIL_PLATFORM_NOTIF_PCI_LINKDOWN = 0, +}; + enum wil_platform_features { WIL_PLATFORM_FEATURE_FW_EXT_CLK_CONTROL = 0, WIL_PLATFORM_FEATURE_TRIPLE_MSI = 1, @@ -52,6 +56,7 @@ struct wil_platform_ops { int (*notify)(void *handle, enum wil_platform_event evt); int (*get_capa)(void *handle); void (*set_features)(void *handle, int features); + int (*pci_linkdown_recovery)(void *handle); }; /** @@ -63,10 +68,13 @@ struct wil_platform_ops { * @fw_recovery: start a firmware recovery process. Called as * part of a crash recovery process which may include other * related platform subsystems. + * @notify: get notifications from the Platform driver, such as + * pci linkdown */ struct wil_platform_rops { int (*ramdump)(void *wil_handle, void *buf, uint32_t size); int (*fw_recovery)(void *wil_handle); + int (*notify)(void *wil_handle, enum wil_platform_notif notif); }; /** From patchwork Sun Sep 8 08:32:47 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maya Erez X-Patchwork-Id: 11136845 X-Patchwork-Delegate: kvalo@adurom.com Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id ABC8C1395 for ; Sun, 8 Sep 2019 08:39:15 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 9682921479 for ; Sun, 8 Sep 2019 08:39:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727397AbfIHIjO (ORCPT ); Sun, 8 Sep 2019 04:39:14 -0400 Received: from alexa-out-ams-02.qualcomm.com ([185.23.61.163]:7549 "EHLO alexa-out-ams-02.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725832AbfIHIjN (ORCPT ); Sun, 8 Sep 2019 04:39:13 -0400 Received: from ironmsg03-ams.qualcomm.com ([10.251.56.4]) by alexa-out-ams-02.qualcomm.com with ESMTP; 08 Sep 2019 10:33:04 +0200 Received: from lx-merez1.mea.qualcomm.com ([10.18.173.103]) by ironmsg03-ams.qualcomm.com with ESMTP; 08 Sep 2019 10:33:00 +0200 From: Maya Erez To: Kalle Valo Cc: Dedy Lansky , linux-wireless@vger.kernel.org, wil6210@qti.qualcomm.com, Maya Erez Subject: [PATCH 03/11] wil6210: add debugfs to show PMC ring content Date: Sun, 8 Sep 2019 11:32:47 +0300 Message-Id: <1567931575-27984-4-git-send-email-merez@codeaurora.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1567931575-27984-1-git-send-email-merez@codeaurora.org> References: <1567931575-27984-1-git-send-email-merez@codeaurora.org> Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Dedy Lansky PMC is a hardware debug mechanism which allows capturing real time debug data and stream it to host memory. The driver allocates memory buffers and set them inside PMC ring of descriptors. Add pmcring debugfs that application can use to read the binary content of descriptors inside the PMC ring (cat pmcring). Signed-off-by: Dedy Lansky Signed-off-by: Maya Erez --- drivers/net/wireless/ath/wil6210/debugfs.c | 13 +++++++++++++ drivers/net/wireless/ath/wil6210/pmc.c | 26 ++++++++++++++++++++++++++ drivers/net/wireless/ath/wil6210/pmc.h | 1 + 3 files changed, 40 insertions(+) diff --git a/drivers/net/wireless/ath/wil6210/debugfs.c b/drivers/net/wireless/ath/wil6210/debugfs.c index fd3b2b3..50dc30e 100644 --- a/drivers/net/wireless/ath/wil6210/debugfs.c +++ b/drivers/net/wireless/ath/wil6210/debugfs.c @@ -959,6 +959,18 @@ static ssize_t wil_read_pmccfg(struct file *file, char __user *user_buf, .llseek = wil_pmc_llseek, }; +static int wil_pmcring_seq_open(struct inode *inode, struct file *file) +{ + return single_open(file, wil_pmcring_read, inode->i_private); +} + +static const struct file_operations fops_pmcring = { + .open = wil_pmcring_seq_open, + .release = single_release, + .read = seq_read, + .llseek = seq_lseek, +}; + /*---tx_mgmt---*/ /* Write mgmt frame to this file to send it */ static ssize_t wil_write_file_txmgmt(struct file *file, const char __user *buf, @@ -2371,6 +2383,7 @@ static void wil6210_debugfs_init_blobs(struct wil6210_priv *wil, {"back", 0644, &fops_back}, {"pmccfg", 0644, &fops_pmccfg}, {"pmcdata", 0444, &fops_pmcdata}, + {"pmcring", 0444, &fops_pmcring}, {"temp", 0444, &temp_fops}, {"freq", 0444, &freq_fops}, {"link", 0444, &link_fops}, diff --git a/drivers/net/wireless/ath/wil6210/pmc.c b/drivers/net/wireless/ath/wil6210/pmc.c index c49f798..4b7ac14 100644 --- a/drivers/net/wireless/ath/wil6210/pmc.c +++ b/drivers/net/wireless/ath/wil6210/pmc.c @@ -18,6 +18,7 @@ #include #include #include +#include #include "wmi.h" #include "wil6210.h" #include "txrx.h" @@ -431,3 +432,28 @@ loff_t wil_pmc_llseek(struct file *filp, loff_t off, int whence) return newpos; } + +int wil_pmcring_read(struct seq_file *s, void *data) +{ + struct wil6210_priv *wil = s->private; + struct pmc_ctx *pmc = &wil->pmc; + size_t pmc_ring_size = + sizeof(struct vring_rx_desc) * pmc->num_descriptors; + + mutex_lock(&pmc->lock); + + if (!wil_is_pmc_allocated(pmc)) { + wil_err(wil, "error, pmc is not allocated!\n"); + pmc->last_cmd_status = -EPERM; + mutex_unlock(&pmc->lock); + return -EPERM; + } + + wil_dbg_misc(wil, "pmcring_read: size %zu\n", pmc_ring_size); + + seq_write(s, pmc->pring_va, pmc_ring_size); + + mutex_unlock(&pmc->lock); + + return 0; +} diff --git a/drivers/net/wireless/ath/wil6210/pmc.h b/drivers/net/wireless/ath/wil6210/pmc.h index bebc8d5..92b8c4d 100644 --- a/drivers/net/wireless/ath/wil6210/pmc.h +++ b/drivers/net/wireless/ath/wil6210/pmc.h @@ -25,3 +25,4 @@ void wil_pmc_alloc(struct wil6210_priv *wil, int wil_pmc_last_cmd_status(struct wil6210_priv *wil); ssize_t wil_pmc_read(struct file *, char __user *, size_t, loff_t *); loff_t wil_pmc_llseek(struct file *filp, loff_t off, int whence); +int wil_pmcring_read(struct seq_file *s, void *data); From patchwork Sun Sep 8 08:32:48 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maya Erez X-Patchwork-Id: 11136851 X-Patchwork-Delegate: kvalo@adurom.com Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 281AB13B1 for ; Sun, 8 Sep 2019 08:39:19 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 0103221479 for ; Sun, 8 Sep 2019 08:39:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727429AbfIHIjR (ORCPT ); Sun, 8 Sep 2019 04:39:17 -0400 Received: from alexa-out-ams-02.qualcomm.com ([185.23.61.163]:51394 "EHLO alexa-out-ams-02.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727365AbfIHIjQ (ORCPT ); Sun, 8 Sep 2019 04:39:16 -0400 X-Greylist: delayed 365 seconds by postgrey-1.27 at vger.kernel.org; Sun, 08 Sep 2019 04:39:09 EDT Received: from ironmsg03-ams.qualcomm.com ([10.251.56.4]) by alexa-out-ams-02.qualcomm.com with ESMTP; 08 Sep 2019 10:33:04 +0200 Received: from lx-merez1.mea.qualcomm.com ([10.18.173.103]) by ironmsg03-ams.qualcomm.com with ESMTP; 08 Sep 2019 10:33:01 +0200 From: Maya Erez To: Kalle Valo Cc: Ahmad Masri , linux-wireless@vger.kernel.org, wil6210@qti.qualcomm.com, Maya Erez Subject: [PATCH 04/11] wil6210: fix PTK re-key race Date: Sun, 8 Sep 2019 11:32:48 +0300 Message-Id: <1567931575-27984-5-git-send-email-merez@codeaurora.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1567931575-27984-1-git-send-email-merez@codeaurora.org> References: <1567931575-27984-1-git-send-email-merez@codeaurora.org> Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Ahmad Masri Fix a race between cfg80211 add_key call and transmitting of 4/4 EAP packet. In case the transmit is delayed until after the add key takes place, message 4/4 will be encrypted with the new key, and the receiver side (AP) will drop it due to MIC error. Wil6210 will monitor and look for the transmitted packet 4/4 eap key. In case add_key takes place before the transmission completed, then wil6210 will let the FW store the key and wil6210 will notify the FW to use the PTK key only after 4/4 eap packet transmission was completed. Signed-off-by: Ahmad Masri Signed-off-by: Maya Erez --- drivers/net/wireless/ath/wil6210/cfg80211.c | 15 ++- drivers/net/wireless/ath/wil6210/main.c | 4 + drivers/net/wireless/ath/wil6210/netdev.c | 3 + drivers/net/wireless/ath/wil6210/txrx.c | 184 +++++++++++++++++++++++++++ drivers/net/wireless/ath/wil6210/txrx.h | 40 ++++++ drivers/net/wireless/ath/wil6210/txrx_edma.c | 4 + drivers/net/wireless/ath/wil6210/wil6210.h | 15 +++ drivers/net/wireless/ath/wil6210/wmi.c | 11 +- drivers/net/wireless/ath/wil6210/wmi.h | 3 + 9 files changed, 276 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c index 1883690..c70854e 100644 --- a/drivers/net/wireless/ath/wil6210/cfg80211.c +++ b/drivers/net/wireless/ath/wil6210/cfg80211.c @@ -331,6 +331,8 @@ static int wil_rf_sector_set_selected(struct wiphy *wiphy, [WMI_KEY_USE_PAIRWISE] = "PTK", [WMI_KEY_USE_RX_GROUP] = "RX_GTK", [WMI_KEY_USE_TX_GROUP] = "TX_GTK", + [WMI_KEY_USE_STORE_PTK] = "STORE_PTK", + [WMI_KEY_USE_APPLY_PTK] = "APPLY_PTK", }; int wil_iftype_nl2wmi(enum nl80211_iftype type) @@ -542,7 +544,7 @@ static int wil_cfg80211_get_station(struct wiphy *wiphy, /* * Find @idx-th active STA for specific MID for station dump. */ -static int wil_find_cid_by_idx(struct wil6210_priv *wil, u8 mid, int idx) +int wil_find_cid_by_idx(struct wil6210_priv *wil, u8 mid, int idx) { int i; @@ -1554,6 +1556,7 @@ void wil_set_crypto_rx(u8 key_index, enum wmi_key_usage key_usage, return; switch (key_usage) { + case WMI_KEY_USE_STORE_PTK: case WMI_KEY_USE_PAIRWISE: for (tid = 0; tid < WIL_STA_TID_NUM; tid++) { cc = &cs->tid_crypto_rx[tid].key_id[key_index]; @@ -1651,6 +1654,16 @@ static int wil_cfg80211_add_key(struct wiphy *wiphy, return -EINVAL; } + spin_lock_bh(&wil->eap_lock); + if (pairwise && wdev->iftype == NL80211_IFTYPE_STATION && + (vif->ptk_rekey_state == WIL_REKEY_M3_RECEIVED || + vif->ptk_rekey_state == WIL_REKEY_WAIT_M4_SENT)) { + key_usage = WMI_KEY_USE_STORE_PTK; + vif->ptk_rekey_state = WIL_REKEY_WAIT_M4_SENT; + wil_dbg_misc(wil, "Store EAPOL key\n"); + } + spin_unlock_bh(&wil->eap_lock); + rc = wmi_add_cipher_key(vif, key_index, mac_addr, params->key_len, params->key, key_usage); if (!rc && !IS_ERR(cs)) { diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c index 0f270b8..2c3a192 100644 --- a/drivers/net/wireless/ath/wil6210/main.c +++ b/drivers/net/wireless/ath/wil6210/main.c @@ -373,6 +373,7 @@ static void _wil6210_disconnect_complete(struct wil6210_vif *vif, } clear_bit(wil_vif_fwconnecting, vif->status); clear_bit(wil_vif_ft_roam, vif->status); + vif->ptk_rekey_state = WIL_REKEY_IDLE; break; case NL80211_IFTYPE_AP: @@ -736,6 +737,8 @@ int wil_priv_init(struct wil6210_priv *wil) INIT_LIST_HEAD(&wil->pending_wmi_ev); spin_lock_init(&wil->wmi_ev_lock); spin_lock_init(&wil->net_queue_lock); + spin_lock_init(&wil->eap_lock); + init_waitqueue_head(&wil->wq); init_rwsem(&wil->mem_lock); @@ -1667,6 +1670,7 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw) cancel_work_sync(&vif->disconnect_worker); wil6210_disconnect(vif, NULL, WLAN_REASON_DEAUTH_LEAVING); + vif->ptk_rekey_state = WIL_REKEY_IDLE; } } wil_bcast_fini_all(wil); diff --git a/drivers/net/wireless/ath/wil6210/netdev.c b/drivers/net/wireless/ath/wil6210/netdev.c index 59f041d..a2eca54 100644 --- a/drivers/net/wireless/ath/wil6210/netdev.c +++ b/drivers/net/wireless/ath/wil6210/netdev.c @@ -218,6 +218,7 @@ static void wil_vif_deinit(struct wil6210_vif *vif) cancel_work_sync(&vif->p2p.delayed_listen_work); wil_probe_client_flush(vif); cancel_work_sync(&vif->probe_client_worker); + cancel_work_sync(&vif->enable_tx_key_worker); } void wil_vif_free(struct wil6210_vif *vif) @@ -284,6 +285,7 @@ static void wil_vif_init(struct wil6210_vif *vif) INIT_WORK(&vif->probe_client_worker, wil_probe_client_worker); INIT_WORK(&vif->disconnect_worker, wil_disconnect_worker); INIT_WORK(&vif->p2p.delayed_listen_work, wil_p2p_delayed_listen_work); + INIT_WORK(&vif->enable_tx_key_worker, wil_enable_tx_key_worker); INIT_LIST_HEAD(&vif->probe_client_pending); @@ -540,6 +542,7 @@ void wil_vif_remove(struct wil6210_priv *wil, u8 mid) cancel_work_sync(&vif->disconnect_worker); wil_probe_client_flush(vif); cancel_work_sync(&vif->probe_client_worker); + cancel_work_sync(&vif->enable_tx_key_worker); /* for VIFs, ndev will be freed by destructor after RTNL is unlocked. * the main interface will be freed in wil_if_free, we need to keep it * a bit longer so logging macros will work. diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c index b6253fc..cb13652 100644 --- a/drivers/net/wireless/ath/wil6210/txrx.c +++ b/drivers/net/wireless/ath/wil6210/txrx.c @@ -725,6 +725,182 @@ static void wil_get_netif_rx_params(struct sk_buff *skb, int *cid, } /* + * Check if skb is ptk eapol key message + * + * returns a pointer to the start of the eapol key structure, NULL + * if frame is not PTK eapol key + */ +static struct wil_eapol_key *wil_is_ptk_eapol_key(struct wil6210_priv *wil, + struct sk_buff *skb) +{ + u8 *buf; + const struct wil_1x_hdr *hdr; + struct wil_eapol_key *key; + u16 key_info; + int len = skb->len; + + if (!skb_mac_header_was_set(skb)) { + wil_err(wil, "mac header was not set\n"); + return NULL; + } + + len -= skb_mac_offset(skb); + + if (len < sizeof(struct ethhdr) + sizeof(struct wil_1x_hdr) + + sizeof(struct wil_eapol_key)) + return NULL; + + buf = skb_mac_header(skb) + sizeof(struct ethhdr); + + hdr = (const struct wil_1x_hdr *)buf; + if (hdr->type != WIL_1X_TYPE_EAPOL_KEY) + return NULL; + + key = (struct wil_eapol_key *)(buf + sizeof(struct wil_1x_hdr)); + if (key->type != WIL_EAPOL_KEY_TYPE_WPA && + key->type != WIL_EAPOL_KEY_TYPE_RSN) + return NULL; + + key_info = be16_to_cpu(key->key_info); + if (!(key_info & WIL_KEY_INFO_KEY_TYPE)) /* check if pairwise */ + return NULL; + + return key; +} + +static bool wil_skb_is_eap_3(struct wil6210_priv *wil, struct sk_buff *skb) +{ + struct wil_eapol_key *key; + u16 key_info; + + key = wil_is_ptk_eapol_key(wil, skb); + if (!key) + return false; + + key_info = be16_to_cpu(key->key_info); + if (key_info & (WIL_KEY_INFO_MIC | + WIL_KEY_INFO_ENCR_KEY_DATA)) { + /* 3/4 of 4-Way Handshake */ + wil_dbg_misc(wil, "EAPOL key message 3\n"); + return true; + } + /* 1/4 of 4-Way Handshake */ + wil_dbg_misc(wil, "EAPOL key message 1\n"); + + return false; +} + +static bool wil_skb_is_eap_4(struct wil6210_priv *wil, struct sk_buff *skb) +{ + struct wil_eapol_key *key; + u32 *nonce, i; + + key = wil_is_ptk_eapol_key(wil, skb); + if (!key) + return false; + + nonce = (u32 *)key->key_nonce; + for (i = 0; i < WIL_EAP_NONCE_LEN / sizeof(u32); i++, nonce++) { + if (*nonce != 0) { + /* message 2/4 */ + wil_dbg_misc(wil, "EAPOL key message 2\n"); + return false; + } + } + wil_dbg_misc(wil, "EAPOL key message 4\n"); + + return true; +} + +void wil_enable_tx_key_worker(struct work_struct *work) +{ + struct wil6210_vif *vif = container_of(work, + struct wil6210_vif, enable_tx_key_worker); + struct wil6210_priv *wil = vif_to_wil(vif); + int rc, cid; + + rtnl_lock(); + if (vif->ptk_rekey_state != WIL_REKEY_WAIT_M4_SENT) { + wil_dbg_misc(wil, "Invalid rekey state = %d\n", + vif->ptk_rekey_state); + rtnl_unlock(); + return; + } + + cid = wil_find_cid_by_idx(wil, vif->mid, 0); + if (!wil_cid_valid(wil, cid)) { + wil_err(wil, "Invalid cid = %d\n", cid); + rtnl_unlock(); + return; + } + + wil_dbg_misc(wil, "Apply PTK key after eapol was sent out\n"); + rc = wmi_add_cipher_key(vif, 0, wil->sta[cid].addr, 0, NULL, + WMI_KEY_USE_APPLY_PTK); + + vif->ptk_rekey_state = WIL_REKEY_IDLE; + rtnl_unlock(); + + if (rc) + wil_err(wil, "Apply PTK key failed %d\n", rc); +} + +void wil_tx_complete_handle_eapol(struct wil6210_vif *vif, struct sk_buff *skb) +{ + struct wil6210_priv *wil = vif_to_wil(vif); + struct wireless_dev *wdev = vif_to_wdev(vif); + bool q = false; + + if (wdev->iftype != NL80211_IFTYPE_STATION || + !test_bit(WMI_FW_CAPABILITY_SPLIT_REKEY, wil->fw_capabilities)) + return; + + /* check if skb is an EAP message 4/4 */ + if (!wil_skb_is_eap_4(wil, skb)) + return; + + spin_lock_bh(&wil->eap_lock); + switch (vif->ptk_rekey_state) { + case WIL_REKEY_IDLE: + /* ignore idle state, can happen due to M4 retransmission */ + break; + case WIL_REKEY_M3_RECEIVED: + vif->ptk_rekey_state = WIL_REKEY_IDLE; + break; + case WIL_REKEY_WAIT_M4_SENT: + q = true; + break; + default: + wil_err(wil, "Unknown rekey state = %d", + vif->ptk_rekey_state); + } + spin_unlock_bh(&wil->eap_lock); + + if (q) { + q = queue_work(wil->wmi_wq, &vif->enable_tx_key_worker); + wil_dbg_misc(wil, "queue_work of enable_tx_key_worker -> %d\n", + q); + } +} + +static void wil_rx_handle_eapol(struct wil6210_vif *vif, struct sk_buff *skb) +{ + struct wil6210_priv *wil = vif_to_wil(vif); + struct wireless_dev *wdev = vif_to_wdev(vif); + + if (wdev->iftype != NL80211_IFTYPE_STATION || + !test_bit(WMI_FW_CAPABILITY_SPLIT_REKEY, wil->fw_capabilities)) + return; + + /* check if skb is a EAP message 3/4 */ + if (!wil_skb_is_eap_3(wil, skb)) + return; + + if (vif->ptk_rekey_state == WIL_REKEY_IDLE) + vif->ptk_rekey_state = WIL_REKEY_M3_RECEIVED; +} + +/* * Pass Rx packet to the netif. Update statistics. * Called in softirq context (NAPI poll). */ @@ -796,6 +972,10 @@ void wil_netif_rx(struct sk_buff *skb, struct net_device *ndev, int cid, if (skb) { /* deliver to local stack */ skb->protocol = eth_type_trans(skb, ndev); skb->dev = ndev; + + if (skb->protocol == cpu_to_be16(ETH_P_PAE)) + wil_rx_handle_eapol(vif, skb); + if (gro) rc = napi_gro_receive(&wil->napi_rx, skb); else @@ -2332,6 +2512,10 @@ int wil_tx_complete(struct wil6210_vif *vif, int ringid) if (stats) stats->tx_errors++; } + + if (skb->protocol == cpu_to_be16(ETH_P_PAE)) + wil_tx_complete_handle_eapol(vif, skb); + wil_consume_skb(skb, d->dma.error == 0); } memset(ctx, 0, sizeof(*ctx)); diff --git a/drivers/net/wireless/ath/wil6210/txrx.h b/drivers/net/wireless/ath/wil6210/txrx.h index fceb251..5120475b 100644 --- a/drivers/net/wireless/ath/wil6210/txrx.h +++ b/drivers/net/wireless/ath/wil6210/txrx.h @@ -423,6 +423,46 @@ struct vring_rx_mac { #define RX_DMA_STATUS_PHY_INFO BIT(6) #define RX_DMA_STATUS_FFM BIT(7) /* EtherType Flex Filter Match */ +/* IEEE 802.11, 8.5.2 EAPOL-Key frames */ +#define WIL_KEY_INFO_KEY_TYPE BIT(3) /* val of 1 = Pairwise, 0 = Group key */ + +#define WIL_KEY_INFO_MIC BIT(8) +#define WIL_KEY_INFO_ENCR_KEY_DATA BIT(12) /* for rsn only */ + +#define WIL_EAP_NONCE_LEN 32 +#define WIL_EAP_KEY_RSC_LEN 8 +#define WIL_EAP_REPLAY_COUNTER_LEN 8 +#define WIL_EAP_KEY_IV_LEN 16 +#define WIL_EAP_KEY_ID_LEN 8 + +enum { + WIL_1X_TYPE_EAP_PACKET = 0, + WIL_1X_TYPE_EAPOL_START = 1, + WIL_1X_TYPE_EAPOL_LOGOFF = 2, + WIL_1X_TYPE_EAPOL_KEY = 3, +}; + +#define WIL_EAPOL_KEY_TYPE_RSN 2 +#define WIL_EAPOL_KEY_TYPE_WPA 254 + +struct wil_1x_hdr { + u8 version; + u8 type; + __be16 length; + /* followed by data */ +} __packed; + +struct wil_eapol_key { + u8 type; + __be16 key_info; + __be16 key_length; + u8 replay_counter[WIL_EAP_REPLAY_COUNTER_LEN]; + u8 key_nonce[WIL_EAP_NONCE_LEN]; + u8 key_iv[WIL_EAP_KEY_IV_LEN]; + u8 key_rsc[WIL_EAP_KEY_RSC_LEN]; + u8 key_id[WIL_EAP_KEY_ID_LEN]; +} __packed; + struct vring_rx_dma { u32 d0; struct wil_ring_dma_addr addr; diff --git a/drivers/net/wireless/ath/wil6210/txrx_edma.c b/drivers/net/wireless/ath/wil6210/txrx_edma.c index 29a9a24..f313041 100644 --- a/drivers/net/wireless/ath/wil6210/txrx_edma.c +++ b/drivers/net/wireless/ath/wil6210/txrx_edma.c @@ -1257,6 +1257,10 @@ int wil_tx_sring_handler(struct wil6210_priv *wil, if (stats) stats->tx_errors++; } + + if (skb->protocol == cpu_to_be16(ETH_P_PAE)) + wil_tx_complete_handle_eapol(vif, skb); + wil_consume_skb(skb, msg.status == 0); } memset(ctx, 0, sizeof(*ctx)); diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h index 6463310..dd0c87a 100644 --- a/drivers/net/wireless/ath/wil6210/wil6210.h +++ b/drivers/net/wireless/ath/wil6210/wil6210.h @@ -732,6 +732,12 @@ enum wil_sta_status { wil_sta_connected = 2, }; +enum wil_rekey_state { + WIL_REKEY_IDLE = 0, + WIL_REKEY_M3_RECEIVED = 1, + WIL_REKEY_WAIT_M4_SENT = 2, +}; + /** * struct wil_sta_info - data for peer * @@ -880,6 +886,10 @@ struct wil6210_vif { int net_queue_stopped; /* netif_tx_stop_all_queues invoked */ bool fw_stats_ready; /* per-cid statistics are ready inside sta_info */ u64 fw_stats_tsf; /* measurement timestamp */ + + /* PTK rekey race prevention, this is relevant to station mode only */ + enum wil_rekey_state ptk_rekey_state; + struct work_struct enable_tx_key_worker; }; /** @@ -980,6 +990,7 @@ struct wil6210_priv { */ spinlock_t wmi_ev_lock; spinlock_t net_queue_lock; /* guarding stop/wake netif queue */ + spinlock_t eap_lock; /* guarding access to eap rekey fields */ struct napi_struct napi_rx; struct napi_struct napi_tx; struct net_device napi_ndev; /* dummy net_device serving all VIFs */ @@ -1229,6 +1240,7 @@ int wil_ps_update(struct wil6210_priv *wil, void wil_refresh_fw_capabilities(struct wil6210_priv *wil); void wil_mbox_ring_le2cpus(struct wil6210_mbox_ring *r); int wil_find_cid(struct wil6210_priv *wil, u8 mid, const u8 *mac); +int wil_find_cid_by_idx(struct wil6210_priv *wil, u8 mid, int idx); void wil_set_ethtoolops(struct net_device *ndev); struct fw_map *wil_find_fw_mapping(const char *section); @@ -1354,6 +1366,7 @@ void wil6210_disconnect_complete(struct wil6210_vif *vif, const u8 *bssid, void wil_probe_client_flush(struct wil6210_vif *vif); void wil_probe_client_worker(struct work_struct *work); void wil_disconnect_worker(struct work_struct *work); +void wil_enable_tx_key_worker(struct work_struct *work); void wil_init_txrx_ops(struct wil6210_priv *wil); @@ -1373,6 +1386,8 @@ void wil_update_net_queues_bh(struct wil6210_priv *wil, struct wil6210_vif *vif, struct wil_ring *ring, bool check_stop); netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev); int wil_tx_complete(struct wil6210_vif *vif, int ringid); +void wil_tx_complete_handle_eapol(struct wil6210_vif *vif, + struct sk_buff *skb); void wil6210_unmask_irq_tx(struct wil6210_priv *wil); void wil6210_unmask_irq_tx_edma(struct wil6210_priv *wil); diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c index 5760d14..73fe9bf 100644 --- a/drivers/net/wireless/ath/wil6210/wmi.c +++ b/drivers/net/wireless/ath/wil6210/wmi.c @@ -2438,10 +2438,17 @@ int wmi_add_cipher_key(struct wil6210_vif *vif, u8 key_index, .key_len = key_len, }; - if (!key || (key_len > sizeof(cmd.key))) + if (key_len > sizeof(cmd.key)) return -EINVAL; - memcpy(cmd.key, key, key_len); + /* key len = 0 is allowed only for usage of WMI_KEY_USE_APPLY */ + if ((key_len == 0 || !key) && + key_usage != WMI_KEY_USE_APPLY_PTK) + return -EINVAL; + + if (key) + memcpy(cmd.key, key, key_len); + if (mac_addr) memcpy(cmd.mac, mac_addr, WMI_MAC_LEN); diff --git a/drivers/net/wireless/ath/wil6210/wmi.h b/drivers/net/wireless/ath/wil6210/wmi.h index d75022b..a2f7034 100644 --- a/drivers/net/wireless/ath/wil6210/wmi.h +++ b/drivers/net/wireless/ath/wil6210/wmi.h @@ -109,6 +109,7 @@ enum wmi_fw_capability { WMI_FW_CAPABILITY_CHANNEL_4 = 26, WMI_FW_CAPABILITY_IPA = 27, WMI_FW_CAPABILITY_TEMPERATURE_ALL_RF = 30, + WMI_FW_CAPABILITY_SPLIT_REKEY = 31, WMI_FW_CAPABILITY_MAX, }; @@ -421,6 +422,8 @@ enum wmi_key_usage { WMI_KEY_USE_PAIRWISE = 0x00, WMI_KEY_USE_RX_GROUP = 0x01, WMI_KEY_USE_TX_GROUP = 0x02, + WMI_KEY_USE_STORE_PTK = 0x03, + WMI_KEY_USE_APPLY_PTK = 0x04, }; struct wmi_add_cipher_key_cmd { From patchwork Sun Sep 8 08:32:49 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maya Erez X-Patchwork-Id: 11136855 X-Patchwork-Delegate: kvalo@adurom.com Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 52B6B13B1 for ; Sun, 8 Sep 2019 08:39:22 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 3C8AF20863 for ; Sun, 8 Sep 2019 08:39:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727454AbfIHIjU (ORCPT ); Sun, 8 Sep 2019 04:39:20 -0400 Received: from alexa-out-ams-02.qualcomm.com ([185.23.61.163]:7549 "EHLO alexa-out-ams-02.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725832AbfIHIjQ (ORCPT ); Sun, 8 Sep 2019 04:39:16 -0400 Received: from ironmsg03-ams.qualcomm.com ([10.251.56.4]) by alexa-out-ams-02.qualcomm.com with ESMTP; 08 Sep 2019 10:33:04 +0200 Received: from lx-merez1.mea.qualcomm.com ([10.18.173.103]) by ironmsg03-ams.qualcomm.com with ESMTP; 08 Sep 2019 10:33:01 +0200 From: Maya Erez To: Kalle Valo Cc: Dedy Lansky , linux-wireless@vger.kernel.org, wil6210@qti.qualcomm.com, Maya Erez Subject: [PATCH 05/11] wil6210: make sure DR bit is read before rest of the status message Date: Sun, 8 Sep 2019 11:32:49 +0300 Message-Id: <1567931575-27984-6-git-send-email-merez@codeaurora.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1567931575-27984-1-git-send-email-merez@codeaurora.org> References: <1567931575-27984-1-git-send-email-merez@codeaurora.org> Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Dedy Lansky Due to compiler optimization, it's possible that dr_bit (descriptor ready) is read last from the status message. Due to race condition between HW writing the status message and driver reading it, other fields that were read earlier (before dr_bit) could have invalid values. Fix this by explicitly reading the dr_bit first and then using rmb before reading the rest of the status message. Signed-off-by: Dedy Lansky Signed-off-by: Maya Erez --- drivers/net/wireless/ath/wil6210/txrx_edma.c | 30 +++++++++++++++++----------- drivers/net/wireless/ath/wil6210/txrx_edma.h | 6 ------ 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/net/wireless/ath/wil6210/txrx_edma.c b/drivers/net/wireless/ath/wil6210/txrx_edma.c index f313041..f21b2fa 100644 --- a/drivers/net/wireless/ath/wil6210/txrx_edma.c +++ b/drivers/net/wireless/ath/wil6210/txrx_edma.c @@ -221,10 +221,17 @@ static int wil_ring_alloc_skb_edma(struct wil6210_priv *wil, } static inline -void wil_get_next_rx_status_msg(struct wil_status_ring *sring, void *msg) +void wil_get_next_rx_status_msg(struct wil_status_ring *sring, u8 *dr_bit, + void *msg) { - memcpy(msg, (void *)(sring->va + (sring->elem_size * sring->swhead)), - sring->elem_size); + struct wil_rx_status_compressed *_msg; + + _msg = (struct wil_rx_status_compressed *) + (sring->va + (sring->elem_size * sring->swhead)); + *dr_bit = WIL_GET_BITS(_msg->d0, 31, 31); + /* make sure dr_bit is read before the rest of status msg */ + rmb(); + memcpy(msg, (void *)_msg, sring->elem_size); } static inline void wil_sring_advance_swhead(struct wil_status_ring *sring) @@ -587,8 +594,7 @@ static bool wil_is_rx_idle_edma(struct wil6210_priv *wil) if (!sring->va) continue; - wil_get_next_rx_status_msg(sring, msg); - dr_bit = wil_rx_status_get_desc_rdy_bit(msg); + wil_get_next_rx_status_msg(sring, &dr_bit, msg); /* Check if there are unhandled RX status messages */ if (dr_bit == sring->desc_rdy_pol) @@ -878,8 +884,7 @@ static struct sk_buff *wil_sring_reap_rx_edma(struct wil6210_priv *wil, BUILD_BUG_ON(sizeof(struct wil_rx_status_extended) > sizeof(skb->cb)); again: - wil_get_next_rx_status_msg(sring, msg); - dr_bit = wil_rx_status_get_desc_rdy_bit(msg); + wil_get_next_rx_status_msg(sring, &dr_bit, msg); /* Completed handling all the ready status messages */ if (dr_bit != sring->desc_rdy_pol) @@ -1135,12 +1140,15 @@ static int wil_tx_desc_map_edma(union wil_tx_desc *desc, } static inline void -wil_get_next_tx_status_msg(struct wil_status_ring *sring, +wil_get_next_tx_status_msg(struct wil_status_ring *sring, u8 *dr_bit, struct wil_ring_tx_status *msg) { struct wil_ring_tx_status *_msg = (struct wil_ring_tx_status *) (sring->va + (sring->elem_size * sring->swhead)); + *dr_bit = _msg->desc_ready >> TX_STATUS_DESC_READY_POS; + /* make sure dr_bit is read before the rest of status msg */ + rmb(); *msg = *_msg; } @@ -1169,8 +1177,7 @@ int wil_tx_sring_handler(struct wil6210_priv *wil, int used_before_complete; int used_new; - wil_get_next_tx_status_msg(sring, &msg); - dr_bit = msg.desc_ready >> TX_STATUS_DESC_READY_POS; + wil_get_next_tx_status_msg(sring, &dr_bit, &msg); /* Process completion messages while DR bit has the expected polarity */ while (dr_bit == sring->desc_rdy_pol) { @@ -1293,8 +1300,7 @@ int wil_tx_sring_handler(struct wil6210_priv *wil, wil_sring_advance_swhead(sring); - wil_get_next_tx_status_msg(sring, &msg); - dr_bit = msg.desc_ready >> TX_STATUS_DESC_READY_POS; + wil_get_next_tx_status_msg(sring, &dr_bit, &msg); } /* shall we wake net queues? */ diff --git a/drivers/net/wireless/ath/wil6210/txrx_edma.h b/drivers/net/wireless/ath/wil6210/txrx_edma.h index 724d223..136c51c 100644 --- a/drivers/net/wireless/ath/wil6210/txrx_edma.h +++ b/drivers/net/wireless/ath/wil6210/txrx_edma.h @@ -421,12 +421,6 @@ static inline u8 wil_rx_status_get_tid(void *msg) return val & WIL_RX_EDMA_DLPF_LU_MISS_CID_TID_MASK; } -static inline int wil_rx_status_get_desc_rdy_bit(void *msg) -{ - return WIL_GET_BITS(((struct wil_rx_status_compressed *)msg)->d0, - 31, 31); -} - static inline int wil_rx_status_get_eop(void *msg) /* EoP = End of Packet */ { return WIL_GET_BITS(((struct wil_rx_status_compressed *)msg)->d0, From patchwork Sun Sep 8 08:32:50 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maya Erez X-Patchwork-Id: 11136853 X-Patchwork-Delegate: kvalo@adurom.com Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A84FB1395 for ; Sun, 8 Sep 2019 08:39:20 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 936A621479 for ; Sun, 8 Sep 2019 08:39:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727444AbfIHIjT (ORCPT ); Sun, 8 Sep 2019 04:39:19 -0400 Received: from alexa-out-ams-02.qualcomm.com ([185.23.61.163]:7970 "EHLO alexa-out-ams-02.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727407AbfIHIjR (ORCPT ); Sun, 8 Sep 2019 04:39:17 -0400 Received: from ironmsg03-ams.qualcomm.com ([10.251.56.4]) by alexa-out-ams-02.qualcomm.com with ESMTP; 08 Sep 2019 10:33:04 +0200 Received: from lx-merez1.mea.qualcomm.com ([10.18.173.103]) by ironmsg03-ams.qualcomm.com with ESMTP; 08 Sep 2019 10:33:02 +0200 From: Maya Erez To: Kalle Valo Cc: Alexei Avshalom Lazar , linux-wireless@vger.kernel.org, wil6210@qti.qualcomm.com, Maya Erez Subject: [PATCH 06/11] wil6210: verify cid value is valid Date: Sun, 8 Sep 2019 11:32:50 +0300 Message-Id: <1567931575-27984-7-git-send-email-merez@codeaurora.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1567931575-27984-1-git-send-email-merez@codeaurora.org> References: <1567931575-27984-1-git-send-email-merez@codeaurora.org> Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Alexei Avshalom Lazar cid value is not being verified in wmi_evt_delba(), verification is added. Signed-off-by: Alexei Avshalom Lazar Signed-off-by: Maya Erez --- drivers/net/wireless/ath/wil6210/wmi.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c index 73fe9bf..88d9e5a 100644 --- a/drivers/net/wireless/ath/wil6210/wmi.c +++ b/drivers/net/wireless/ath/wil6210/wmi.c @@ -1332,6 +1332,12 @@ static void wmi_evt_delba(struct wil6210_vif *vif, int id, void *d, int len) cid = evt->cid; tid = evt->tid; } + + if (!wil_cid_valid(wil, cid)) { + wil_err(wil, "DELBA: Invalid CID %d\n", cid); + return; + } + wil_dbg_wmi(wil, "DELBA MID %d CID %d TID %d from %s reason %d\n", vif->mid, cid, tid, evt->from_initiator ? "originator" : "recipient", From patchwork Sun Sep 8 08:32:51 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maya Erez X-Patchwork-Id: 11136847 X-Patchwork-Delegate: kvalo@adurom.com Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D58B51395 for ; Sun, 8 Sep 2019 08:39:16 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id C0BFB21479 for ; Sun, 8 Sep 2019 08:39:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727403AbfIHIjP (ORCPT ); Sun, 8 Sep 2019 04:39:15 -0400 Received: from alexa-out-ams-02.qualcomm.com ([185.23.61.163]:7549 "EHLO alexa-out-ams-02.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727195AbfIHIjO (ORCPT ); Sun, 8 Sep 2019 04:39:14 -0400 Received: from ironmsg03-ams.qualcomm.com ([10.251.56.4]) by alexa-out-ams-02.qualcomm.com with ESMTP; 08 Sep 2019 10:33:04 +0200 Received: from lx-merez1.mea.qualcomm.com ([10.18.173.103]) by ironmsg03-ams.qualcomm.com with ESMTP; 08 Sep 2019 10:33:03 +0200 From: Maya Erez To: Kalle Valo Cc: Dedy Lansky , linux-wireless@vger.kernel.org, wil6210@qti.qualcomm.com, Maya Erez Subject: [PATCH 07/11] wil6210: properly initialize discovery_expired_work Date: Sun, 8 Sep 2019 11:32:51 +0300 Message-Id: <1567931575-27984-8-git-send-email-merez@codeaurora.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1567931575-27984-1-git-send-email-merez@codeaurora.org> References: <1567931575-27984-1-git-send-email-merez@codeaurora.org> Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Dedy Lansky Upon driver rmmod, cancel_work_sync() can be invoked on p2p.discovery_expired_work before this work struct was initialized. This causes a WARN_ON with newer kernel version. Add initialization of discovery_expired_work inside wil_vif_init(). Signed-off-by: Dedy Lansky Signed-off-by: Maya Erez --- drivers/net/wireless/ath/wil6210/netdev.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/ath/wil6210/netdev.c b/drivers/net/wireless/ath/wil6210/netdev.c index a2eca54..a87bb84 100644 --- a/drivers/net/wireless/ath/wil6210/netdev.c +++ b/drivers/net/wireless/ath/wil6210/netdev.c @@ -284,6 +284,7 @@ static void wil_vif_init(struct wil6210_vif *vif) INIT_WORK(&vif->probe_client_worker, wil_probe_client_worker); INIT_WORK(&vif->disconnect_worker, wil_disconnect_worker); + INIT_WORK(&vif->p2p.discovery_expired_work, wil_p2p_listen_expired); INIT_WORK(&vif->p2p.delayed_listen_work, wil_p2p_delayed_listen_work); INIT_WORK(&vif->enable_tx_key_worker, wil_enable_tx_key_worker); From patchwork Sun Sep 8 08:32:52 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maya Erez X-Patchwork-Id: 11136857 X-Patchwork-Delegate: kvalo@adurom.com Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 5FD7113B1 for ; Sun, 8 Sep 2019 08:39:23 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 4ACEE21479 for ; Sun, 8 Sep 2019 08:39:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727486AbfIHIjW (ORCPT ); Sun, 8 Sep 2019 04:39:22 -0400 Received: from alexa-out-ams-02.qualcomm.com ([185.23.61.163]:51394 "EHLO alexa-out-ams-02.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727418AbfIHIjS (ORCPT ); Sun, 8 Sep 2019 04:39:18 -0400 X-Greylist: delayed 365 seconds by postgrey-1.27 at vger.kernel.org; Sun, 08 Sep 2019 04:39:09 EDT Received: from ironmsg03-ams.qualcomm.com ([10.251.56.4]) by alexa-out-ams-02.qualcomm.com with ESMTP; 08 Sep 2019 10:33:04 +0200 Received: from lx-merez1.mea.qualcomm.com ([10.18.173.103]) by ironmsg03-ams.qualcomm.com with ESMTP; 08 Sep 2019 10:33:03 +0200 From: Maya Erez To: Kalle Valo Cc: Maya Erez , linux-wireless@vger.kernel.org, wil6210@qti.qualcomm.com Subject: [PATCH 08/11] wil6210: report boottime_ns in scan results Date: Sun, 8 Sep 2019 11:32:52 +0300 Message-Id: <1567931575-27984-9-git-send-email-merez@codeaurora.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1567931575-27984-1-git-send-email-merez@codeaurora.org> References: <1567931575-27984-1-git-send-email-merez@codeaurora.org> Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org Call cfg80211_inform_bss_frame_data to report cfg80211 on the boottime_ns in order to prevent the scan results filtering due to aging. Signed-off-by: Maya Erez --- drivers/net/wireless/ath/wil6210/wmi.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c index 88d9e5a..153b844 100644 --- a/drivers/net/wireless/ath/wil6210/wmi.c +++ b/drivers/net/wireless/ath/wil6210/wmi.c @@ -878,6 +878,12 @@ static void wmi_evt_rx_mgmt(struct wil6210_vif *vif, int id, void *d, int len) if (ieee80211_is_beacon(fc) || ieee80211_is_probe_resp(fc)) { struct cfg80211_bss *bss; + struct cfg80211_inform_bss bss_data = { + .chan = channel, + .scan_width = NL80211_BSS_CHAN_WIDTH_20, + .signal = signal, + .boottime_ns = ktime_to_ns(ktime_get_boottime()), + }; u64 tsf = le64_to_cpu(rx_mgmt_frame->u.beacon.timestamp); u16 cap = le16_to_cpu(rx_mgmt_frame->u.beacon.capab_info); u16 bi = le16_to_cpu(rx_mgmt_frame->u.beacon.beacon_int); @@ -892,8 +898,9 @@ static void wmi_evt_rx_mgmt(struct wil6210_vif *vif, int id, void *d, int len) wil_dbg_wmi(wil, "Capability info : 0x%04x\n", cap); - bss = cfg80211_inform_bss_frame(wiphy, channel, rx_mgmt_frame, - d_len, signal, GFP_KERNEL); + bss = cfg80211_inform_bss_frame_data(wiphy, &bss_data, + rx_mgmt_frame, + d_len, GFP_KERNEL); if (bss) { wil_dbg_wmi(wil, "Added BSS %pM\n", rx_mgmt_frame->bssid); @@ -1391,6 +1398,10 @@ static void wmi_evt_delba(struct wil6210_vif *vif, int id, void *d, int len) __le16 fc; u32 d_len; struct cfg80211_bss *bss; + struct cfg80211_inform_bss bss_data = { + .scan_width = NL80211_BSS_CHAN_WIDTH_20, + .boottime_ns = ktime_to_ns(ktime_get_boottime()), + }; if (flen < 0) { wil_err(wil, "sched scan result event too short, len %d\n", @@ -1433,8 +1444,10 @@ static void wmi_evt_delba(struct wil6210_vif *vif, int id, void *d, int len) return; } - bss = cfg80211_inform_bss_frame(wiphy, channel, rx_mgmt_frame, - d_len, signal, GFP_KERNEL); + bss_data.signal = signal; + bss_data.chan = channel; + bss = cfg80211_inform_bss_frame_data(wiphy, &bss_data, rx_mgmt_frame, + d_len, GFP_KERNEL); if (bss) { wil_dbg_wmi(wil, "Added BSS %pM\n", rx_mgmt_frame->bssid); cfg80211_put_bss(wiphy, bss); From patchwork Sun Sep 8 08:32:53 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maya Erez X-Patchwork-Id: 11136861 X-Patchwork-Delegate: kvalo@adurom.com Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id EDA3B1395 for ; Sun, 8 Sep 2019 08:39:26 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id D780320863 for ; Sun, 8 Sep 2019 08:39:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727497AbfIHIjZ (ORCPT ); Sun, 8 Sep 2019 04:39:25 -0400 Received: from alexa-out-ams-02.qualcomm.com ([185.23.61.163]:7549 "EHLO alexa-out-ams-02.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727422AbfIHIjS (ORCPT ); Sun, 8 Sep 2019 04:39:18 -0400 Received: from ironmsg03-ams.qualcomm.com ([10.251.56.4]) by alexa-out-ams-02.qualcomm.com with ESMTP; 08 Sep 2019 10:33:05 +0200 Received: from lx-merez1.mea.qualcomm.com ([10.18.173.103]) by ironmsg03-ams.qualcomm.com with ESMTP; 08 Sep 2019 10:33:04 +0200 From: Maya Erez To: Kalle Valo Cc: Lior David , linux-wireless@vger.kernel.org, wil6210@qti.qualcomm.com, Maya Erez Subject: [PATCH 09/11] wil6210: use writel_relaxed in wil_debugfs_iomem_x32_set Date: Sun, 8 Sep 2019 11:32:53 +0300 Message-Id: <1567931575-27984-10-git-send-email-merez@codeaurora.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1567931575-27984-1-git-send-email-merez@codeaurora.org> References: <1567931575-27984-1-git-send-email-merez@codeaurora.org> Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Lior David writel_relaxed can be used in wil_debugfs_iomem_x32_set since there is a wmb call immediately after. Signed-off-by: Lior David Signed-off-by: Maya Erez --- drivers/net/wireless/ath/wil6210/debugfs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/wil6210/debugfs.c b/drivers/net/wireless/ath/wil6210/debugfs.c index 50dc30e..304b4d4 100644 --- a/drivers/net/wireless/ath/wil6210/debugfs.c +++ b/drivers/net/wireless/ath/wil6210/debugfs.c @@ -393,7 +393,8 @@ static int wil_debugfs_iomem_x32_set(void *data, u64 val) if (ret < 0) return ret; - writel(val, (void __iomem *)d->offset); + writel_relaxed(val, (void __iomem *)d->offset); + wmb(); /* make sure write propagated to HW */ wil_pm_runtime_put(wil); From patchwork Sun Sep 8 08:32:54 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maya Erez X-Patchwork-Id: 11136863 X-Patchwork-Delegate: kvalo@adurom.com Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id BADF91708 for ; Sun, 8 Sep 2019 08:39:28 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id A6E3721479 for ; Sun, 8 Sep 2019 08:39:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727504AbfIHIj1 (ORCPT ); Sun, 8 Sep 2019 04:39:27 -0400 Received: from alexa-out-ams-02.qualcomm.com ([185.23.61.163]:7549 "EHLO alexa-out-ams-02.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727443AbfIHIjU (ORCPT ); Sun, 8 Sep 2019 04:39:20 -0400 Received: from ironmsg03-ams.qualcomm.com ([10.251.56.4]) by alexa-out-ams-02.qualcomm.com with ESMTP; 08 Sep 2019 10:33:06 +0200 Received: from lx-merez1.mea.qualcomm.com ([10.18.173.103]) by ironmsg03-ams.qualcomm.com with ESMTP; 08 Sep 2019 10:33:04 +0200 From: Maya Erez To: Kalle Valo Cc: Lior David , linux-wireless@vger.kernel.org, wil6210@qti.qualcomm.com, Maya Erez Subject: [PATCH 10/11] wil6210: fix RX short frame check Date: Sun, 8 Sep 2019 11:32:54 +0300 Message-Id: <1567931575-27984-11-git-send-email-merez@codeaurora.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1567931575-27984-1-git-send-email-merez@codeaurora.org> References: <1567931575-27984-1-git-send-email-merez@codeaurora.org> Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Lior David The short frame check in wil_sring_reap_rx_edma uses skb->len which store the maximum frame length. Fix this to use dmalen which is the actual length of the received frame. Signed-off-by: Lior David Signed-off-by: Maya Erez --- drivers/net/wireless/ath/wil6210/txrx_edma.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/wil6210/txrx_edma.c b/drivers/net/wireless/ath/wil6210/txrx_edma.c index f21b2fa..04d576d 100644 --- a/drivers/net/wireless/ath/wil6210/txrx_edma.c +++ b/drivers/net/wireless/ath/wil6210/txrx_edma.c @@ -964,8 +964,8 @@ static struct sk_buff *wil_sring_reap_rx_edma(struct wil6210_priv *wil, } stats = &wil->sta[cid].stats; - if (unlikely(skb->len < ETH_HLEN)) { - wil_dbg_txrx(wil, "Short frame, len = %d\n", skb->len); + if (unlikely(dmalen < ETH_HLEN)) { + wil_dbg_txrx(wil, "Short frame, len = %d\n", dmalen); stats->rx_short_frame++; rxdata->skipping = true; goto skipping; From patchwork Sun Sep 8 08:32:55 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maya Erez X-Patchwork-Id: 11136859 X-Patchwork-Delegate: kvalo@adurom.com Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 250C71395 for ; Sun, 8 Sep 2019 08:39:25 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 04AFD21479 for ; Sun, 8 Sep 2019 08:39:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727494AbfIHIjX (ORCPT ); Sun, 8 Sep 2019 04:39:23 -0400 Received: from alexa-out-ams-02.qualcomm.com ([185.23.61.163]:7970 "EHLO alexa-out-ams-02.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727423AbfIHIjT (ORCPT ); Sun, 8 Sep 2019 04:39:19 -0400 Received: from ironmsg03-ams.qualcomm.com ([10.251.56.4]) by alexa-out-ams-02.qualcomm.com with ESMTP; 08 Sep 2019 10:33:06 +0200 Received: from lx-merez1.mea.qualcomm.com ([10.18.173.103]) by ironmsg03-ams.qualcomm.com with ESMTP; 08 Sep 2019 10:33:05 +0200 From: Maya Erez To: Kalle Valo Cc: Lior David , linux-wireless@vger.kernel.org, wil6210@qti.qualcomm.com, Maya Erez Subject: [PATCH 11/11] wil6210: ignore reset errors for FW during probe Date: Sun, 8 Sep 2019 11:32:55 +0300 Message-Id: <1567931575-27984-12-git-send-email-merez@codeaurora.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1567931575-27984-1-git-send-email-merez@codeaurora.org> References: <1567931575-27984-1-git-send-email-merez@codeaurora.org> Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Lior David There are special kinds of FW such as WMI only which are used for testing, diagnostics and other specific scenario. Such FW is loaded during driver probe and the driver disallows enabling any network interface, to avoid operational issues. In many cases it is used to debug early versions of FW with new features, which sometimes fail on startup. Currently when such FW fails to load (for example, because of init failure), the driver probe would fail and shutdown the device making it difficult to debug the early failure. To fix this, ignore load failures in WMI only FW and allow driver probe to succeed, making it possible to continue and debug the FW load failure. Signed-off-by: Lior David Signed-off-by: Maya Erez --- drivers/net/wireless/ath/wil6210/pcie_bus.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/wil6210/pcie_bus.c b/drivers/net/wireless/ath/wil6210/pcie_bus.c index cd417fa..904dcfa 100644 --- a/drivers/net/wireless/ath/wil6210/pcie_bus.c +++ b/drivers/net/wireless/ath/wil6210/pcie_bus.c @@ -537,7 +537,7 @@ static int wil_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) mutex_unlock(&wil->mutex); if (rc) { wil_err(wil, "failed to load WMI only FW\n"); - goto if_remove; + /* ignore the error to allow debugging */ } } @@ -557,8 +557,6 @@ static int wil_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) return 0; -if_remove: - wil_if_remove(wil); bus_disable: wil_if_pcie_disable(wil); err_iounmap: