[PATCH v2 00/33] staging/wfx: usual maintenance
From: Jérôme Pouiller Hi, The following PR contains now usual maintenance for the wfx driver. I have more-or-less sorted the patches by importance: - the first ones and the two last ones are fixes for a few corner-cases reported by users - the patches 9 and 10 add support for CSA and TDLS - then the end of the series is mostly cosmetics and nitpicking I have wait longer than I initially wanted before to send this PR. It is because didn't want to conflict with the PR currently in review[1] to relocate this driver into the main tree. However, this PR started to be very large and nothing seems to move on main-tree side so I decided to not wait longer. Kalle, I am going to send a new version of [1] as soon as this PR will be accepted. I hope you will have time to review it one day :-). [1] https://lore.kernel.org/all/20210315132501.441681-1-jerome.pouil...@silabs.com/ v2: - Add patches 32 and 33 to solve a possible race when device is misconfigured - Fix C99 comments (Kari) - Replace "API 3.8" by "firmware API 3.8" (Kari) - Fix wording "aligned with first argument" instead of "aligned with opening parenthesis" Jérôme Pouiller (33): staging: wfx: use abbreviated message for "incorrect sequence" staging: wfx: do not send CAB while scanning staging: wfx: ignore PS when STA/AP share same channel staging: wfx: wait for SCAN_CMPL after a SCAN_STOP staging: wfx: avoid possible lock-up during scan staging: wfx: drop unused argument from hif_scan() staging: wfx: fix atomic accesses in wfx_tx_queue_empty() staging: wfx: take advantage of wfx_tx_queue_empty() staging: wfx: declare support for TDLS staging: wfx: fix support for CSA staging: wfx: relax the PDS existence constraint staging: wfx: simplify API coherency check staging: wfx: update with the firmware API 3.8 staging: wfx: uniformize counter names staging: wfx: fix misleading 'rate_id' usage staging: wfx: declare variables at beginning of functions staging: wfx: simplify hif_join() staging: wfx: reorder function for slightly better eye candy staging: wfx: fix error names staging: wfx: apply naming rules in hif_tx_mib.c staging: wfx: remove unused definition staging: wfx: remove useless debug statement staging: wfx: fix space after cast operator staging: wfx: remove references to WFxxx in comments staging: wfx: update files descriptions staging: wfx: reformat comment staging: wfx: avoid c99 comments staging: wfx: fix comments styles staging: wfx: remove useless comments after #endif staging: wfx: explain the purpose of wfx_send_pds() staging: wfx: indent functions arguments staging: wfx: ensure IRQ is ready before enabling it staging: wfx: early exit of PDS is not correct drivers/staging/wfx/bh.c | 33 +++ drivers/staging/wfx/bh.h | 4 +- drivers/staging/wfx/bus_sdio.c| 29 +++--- drivers/staging/wfx/bus_spi.c | 22 ++--- drivers/staging/wfx/data_rx.c | 7 +- drivers/staging/wfx/data_rx.h | 4 +- drivers/staging/wfx/data_tx.c | 87 + drivers/staging/wfx/data_tx.h | 6 +- drivers/staging/wfx/debug.c | 54 ++- drivers/staging/wfx/debug.h | 2 +- drivers/staging/wfx/fwio.c| 26 ++--- drivers/staging/wfx/fwio.h| 2 +- drivers/staging/wfx/hif_api_cmd.h | 14 +-- drivers/staging/wfx/hif_api_general.h | 25 ++--- drivers/staging/wfx/hif_api_mib.h | 85 drivers/staging/wfx/hif_rx.c | 23 ++--- drivers/staging/wfx/hif_rx.h | 3 +- drivers/staging/wfx/hif_tx.c | 61 +--- drivers/staging/wfx/hif_tx.h | 6 +- drivers/staging/wfx/hif_tx_mib.c | 14 +-- drivers/staging/wfx/hif_tx_mib.h | 2 +- drivers/staging/wfx/hwio.c| 6 +- drivers/staging/wfx/hwio.h| 20 ++-- drivers/staging/wfx/key.c | 30 +++--- drivers/staging/wfx/key.h | 4 +- drivers/staging/wfx/main.c| 37 +-- drivers/staging/wfx/main.h| 3 +- drivers/staging/wfx/queue.c | 43 drivers/staging/wfx/queue.h | 6 +- drivers/staging/wfx/scan.c| 55 +++ drivers/staging/wfx/scan.h| 4 +- drivers/staging/wfx/sta.c | 135 +++--- drivers/staging/wfx/sta.h | 8 +- drivers/staging/wfx/traces.h | 2 +- drivers/staging/wfx/wfx.h | 14 ++- 35 files changed, 469 insertions(+), 407 deletions(-) -- 2.33.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 01/33] staging: wfx: use abbreviated message for "incorrect sequence"
From: Jérôme Pouiller The wfx driver checks carefully the coherency of of the DTIM notifications. We have noticed several times some small inconsistencies from the firmware on these notification. They have never been critical. However on the driver side they lead to big fat warnings. Worse, if these warning are displayed on UART console, they can be long to display (several hundreds of millisecs). Since, this warning is generated from a work queue, it can delay all the workqueue users. Especially, it can drastically slow down the frame management of the driver and then generate errors that are serious this time (eg. an overflow of the indication queue of the device). Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/sta.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c index cb7e8abdf43c..a236e5bb6914 100644 --- a/drivers/staging/wfx/sta.c +++ b/drivers/staging/wfx/sta.c @@ -631,8 +631,9 @@ void wfx_suspend_resume_mc(struct wfx_vif *wvif, enum sta_notify_cmd notify_cmd) { if (notify_cmd != STA_NOTIFY_AWAKE) return; - WARN(!wfx_tx_queues_has_cab(wvif), "incorrect sequence"); - WARN(wvif->after_dtim_tx_allowed, "incorrect sequence"); + if (!wfx_tx_queues_has_cab(wvif) || wvif->after_dtim_tx_allowed) + dev_warn(wvif->wdev->dev, "incorrect sequence (%d CAB in queue)", +wfx_tx_queues_has_cab(wvif)); wvif->after_dtim_tx_allowed = true; wfx_bh_request_tx(wvif->wdev); } -- 2.33.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 02/33] staging: wfx: do not send CAB while scanning
From: Jérôme Pouiller During the scan requests, the Tx traffic is suspended. This lock is shared by all the network interfaces. So, a scan request on one interface will block the traffic on a second interface. This causes trouble when the queued traffic contains CAB (Content After DTIM Beacon) since this traffic cannot be delayed. It could be possible to make the lock local to each interface. But It would only push the problem further. The device won't be able to send the CAB before the end of the scan. So, this patch just ignore the DTIM indication when a scan is in progress. The firmware will send another indication on the next DTIM and this time the system will be able to send the traffic just behind the beacon. The only drawback of this solution is that the stations connected to the AP will wait for traffic after the DTIM for nothing. But since the case is really rare it is not a big deal. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/sta.c | 11 +++ 1 file changed, 11 insertions(+) diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c index a236e5bb6914..5de9ccf02285 100644 --- a/drivers/staging/wfx/sta.c +++ b/drivers/staging/wfx/sta.c @@ -629,8 +629,19 @@ int wfx_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set) void wfx_suspend_resume_mc(struct wfx_vif *wvif, enum sta_notify_cmd notify_cmd) { + struct wfx_vif *wvif_it; + if (notify_cmd != STA_NOTIFY_AWAKE) return; + + /* Device won't be able to honor CAB if a scan is in progress on any +* interface. Prefer to skip this DTIM and wait for the next one. +*/ + wvif_it = NULL; + while ((wvif_it = wvif_iterate(wvif->wdev, wvif_it)) != NULL) + if (mutex_is_locked(&wvif_it->scan_lock)) + return; + if (!wfx_tx_queues_has_cab(wvif) || wvif->after_dtim_tx_allowed) dev_warn(wvif->wdev->dev, "incorrect sequence (%d CAB in queue)", wfx_tx_queues_has_cab(wvif)); -- 2.33.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 03/33] staging: wfx: ignore PS when STA/AP share same channel
From: Jérôme Pouiller When multiple interface are in use. One is always AP while the other is always station. When the two interface use the same channel, it makes no sense to enabled Power Saving (PS) on the station. Indeed, because of the AP, the device will be kept awake on this channel anyway. In add, when multiple interface are in use, mac80211 does not update the PS information and delegate to the driver responsibility to do the right thing. Thus, in the current code, when the user enable PS in this configuration, the driver finally enable PS-Poll which is probably not what the user expected. This patch detect this case and applies a sane configuration in all cases. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/sta.c | 32 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c index 5de9ccf02285..aff0559653bf 100644 --- a/drivers/staging/wfx/sta.c +++ b/drivers/staging/wfx/sta.c @@ -154,18 +154,26 @@ static int wfx_get_ps_timeout(struct wfx_vif *wvif, bool *enable_ps) chan0 = wdev_to_wvif(wvif->wdev, 0)->vif->bss_conf.chandef.chan; if (wdev_to_wvif(wvif->wdev, 1)) chan1 = wdev_to_wvif(wvif->wdev, 1)->vif->bss_conf.chandef.chan; - if (chan0 && chan1 && chan0->hw_value != chan1->hw_value && - wvif->vif->type != NL80211_IFTYPE_AP) { - // It is necessary to enable powersave if channels - // are different. - if (enable_ps) - *enable_ps = true; - if (wvif->wdev->force_ps_timeout > -1) - return wvif->wdev->force_ps_timeout; - else if (wfx_api_older_than(wvif->wdev, 3, 2)) - return 0; - else - return 30; + if (chan0 && chan1 && wvif->vif->type != NL80211_IFTYPE_AP) { + if (chan0->hw_value == chan1->hw_value) { + // It is useless to enable PS if channels are the same. + if (enable_ps) + *enable_ps = false; + if (wvif->vif->bss_conf.assoc && wvif->vif->bss_conf.ps) + dev_info(wvif->wdev->dev, "ignoring requested PS mode"); + return -1; + } else { + // It is necessary to enable PS if channels + // are different. + if (enable_ps) + *enable_ps = true; + if (wvif->wdev->force_ps_timeout > -1) + return wvif->wdev->force_ps_timeout; + else if (wfx_api_older_than(wvif->wdev, 3, 2)) + return 0; + else + return 30; + } } if (enable_ps) *enable_ps = wvif->vif->bss_conf.ps; -- 2.33.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 04/33] staging: wfx: wait for SCAN_CMPL after a SCAN_STOP
From: Jérôme Pouiller When the device has finished a scan request, it send a scan complete ("SCAN_COMPL") indication. It is also possible to abort a scan request with a "SCAN_STOP" message. A SCAN_COMPL is also send in this case. The driver limits the delay to make a scan request. A timeout happens almost never but is theoretically possible. Currently, if it happens the driver does not wait for the SCAN_COMPL. Then, when the driver starts the next scan request, the device may return -EBUSY (scan requests often occur back-to-back). This patch give a chance to the device to send a SCAN_COMPL after a scan timeout. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/scan.c | 24 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/drivers/staging/wfx/scan.c b/drivers/staging/wfx/scan.c index fb47c7cddf2f..1e03b130049b 100644 --- a/drivers/staging/wfx/scan.c +++ b/drivers/staging/wfx/scan.c @@ -58,23 +58,31 @@ static int send_scan_req(struct wfx_vif *wvif, reinit_completion(&wvif->scan_complete); ret = hif_scan(wvif, req, start_idx, i - start_idx, &timeout); if (ret) { - wfx_tx_unlock(wvif->wdev); - return -EIO; + ret = -EIO; + goto err_scan_start; } ret = wait_for_completion_timeout(&wvif->scan_complete, timeout); - if (req->channels[start_idx]->max_power != wvif->vif->bss_conf.txpower) - hif_set_output_power(wvif, wvif->vif->bss_conf.txpower); - wfx_tx_unlock(wvif->wdev); if (!ret) { dev_notice(wvif->wdev->dev, "scan timeout\n"); hif_stop_scan(wvif); - return -ETIMEDOUT; + ret = wait_for_completion_timeout(&wvif->scan_complete, 1 * HZ); + if (!ret) + dev_err(wvif->wdev->dev, "scan didn't stop\n"); + ret = -ETIMEDOUT; + goto err_timeout; } if (wvif->scan_abort) { dev_notice(wvif->wdev->dev, "scan abort\n"); - return -ECONNABORTED; + ret = -ECONNABORTED; + goto err_timeout; } - return i - start_idx; + ret = i - start_idx; +err_timeout: + if (req->channels[start_idx]->max_power != wvif->vif->bss_conf.txpower) + hif_set_output_power(wvif, wvif->vif->bss_conf.txpower); +err_scan_start: + wfx_tx_unlock(wvif->wdev); + return ret; } /* -- 2.33.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 06/33] staging: wfx: drop unused argument from hif_scan()
From: Jérôme Pouiller It is no more necessary to compute the expected duration of the scan request. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/hif_tx.c | 9 + drivers/staging/wfx/hif_tx.h | 2 +- drivers/staging/wfx/scan.c | 2 +- 3 files changed, 3 insertions(+), 10 deletions(-) diff --git a/drivers/staging/wfx/hif_tx.c b/drivers/staging/wfx/hif_tx.c index 63b437261eb7..14b7e047916e 100644 --- a/drivers/staging/wfx/hif_tx.c +++ b/drivers/staging/wfx/hif_tx.c @@ -227,14 +227,13 @@ int hif_write_mib(struct wfx_dev *wdev, int vif_id, u16 mib_id, } int hif_scan(struct wfx_vif *wvif, struct cfg80211_scan_request *req, -int chan_start_idx, int chan_num, int *timeout) +int chan_start_idx, int chan_num) { int ret, i; struct hif_msg *hif; size_t buf_len = sizeof(struct hif_req_start_scan_alt) + chan_num * sizeof(u8); struct hif_req_start_scan_alt *body = wfx_alloc_hif(buf_len, &hif); - int tmo_chan_fg, tmo_chan_bg, tmo; WARN(chan_num > HIF_API_MAX_NB_CHANNELS, "invalid params"); WARN(req->n_ssids > HIF_API_MAX_NB_SSIDS, "invalid params"); @@ -269,12 +268,6 @@ int hif_scan(struct wfx_vif *wvif, struct cfg80211_scan_request *req, body->num_of_probe_requests = 2; body->probe_delay = 100; } - tmo_chan_bg = le32_to_cpu(body->max_channel_time) * USEC_PER_TU; - tmo_chan_fg = 512 * USEC_PER_TU + body->probe_delay; - tmo_chan_fg *= body->num_of_probe_requests; - tmo = chan_num * max(tmo_chan_bg, tmo_chan_fg) + 512 * USEC_PER_TU; - if (timeout) - *timeout = usecs_to_jiffies(tmo); wfx_fill_header(hif, wvif->id, HIF_REQ_ID_START_SCAN, buf_len); ret = wfx_cmd_send(wvif->wdev, hif, NULL, 0, false); diff --git a/drivers/staging/wfx/hif_tx.h b/drivers/staging/wfx/hif_tx.h index 3521c545ae6b..46eed6cfa247 100644 --- a/drivers/staging/wfx/hif_tx.h +++ b/drivers/staging/wfx/hif_tx.h @@ -40,7 +40,7 @@ int hif_read_mib(struct wfx_dev *wdev, int vif_id, u16 mib_id, int hif_write_mib(struct wfx_dev *wdev, int vif_id, u16 mib_id, void *buf, size_t buf_size); int hif_scan(struct wfx_vif *wvif, struct cfg80211_scan_request *req80211, -int chan_start, int chan_num, int *timeout); +int chan_start, int chan_num); int hif_stop_scan(struct wfx_vif *wvif); int hif_join(struct wfx_vif *wvif, const struct ieee80211_bss_conf *conf, struct ieee80211_channel *channel, const u8 *ssid, int ssidlen); diff --git a/drivers/staging/wfx/scan.c b/drivers/staging/wfx/scan.c index 695b06974194..9e2d08317c9e 100644 --- a/drivers/staging/wfx/scan.c +++ b/drivers/staging/wfx/scan.c @@ -56,7 +56,7 @@ static int send_scan_req(struct wfx_vif *wvif, wfx_tx_lock_flush(wvif->wdev); wvif->scan_abort = false; reinit_completion(&wvif->scan_complete); - ret = hif_scan(wvif, req, start_idx, i - start_idx, NULL); + ret = hif_scan(wvif, req, start_idx, i - start_idx); if (ret) { wfx_tx_unlock(wvif->wdev); return -EIO; -- 2.33.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 07/33] staging: wfx: fix atomic accesses in wfx_tx_queue_empty()
From: Jérôme Pouiller Checking if a skb_queue is empty is not an atomic operation. We should take some precautions to do it. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/queue.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/wfx/queue.c b/drivers/staging/wfx/queue.c index 31c37f69c295..fa272c120f1c 100644 --- a/drivers/staging/wfx/queue.c +++ b/drivers/staging/wfx/queue.c @@ -86,7 +86,8 @@ void wfx_tx_queues_check_empty(struct wfx_vif *wvif) bool wfx_tx_queue_empty(struct wfx_vif *wvif, struct wfx_queue *queue) { - return skb_queue_empty(&queue->normal) && skb_queue_empty(&queue->cab); + return skb_queue_empty_lockless(&queue->normal) && + skb_queue_empty_lockless(&queue->cab); } static void __wfx_tx_queue_drop(struct wfx_vif *wvif, -- 2.33.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 08/33] staging: wfx: take advantage of wfx_tx_queue_empty()
From: Jérôme Pouiller wfx_tx_queues_check_empty() can be slightly simplified by calling wfx_tx_queue_empty(). Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/queue.c | 21 ++--- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/drivers/staging/wfx/queue.c b/drivers/staging/wfx/queue.c index fa272c120f1c..0ab207237d9f 100644 --- a/drivers/staging/wfx/queue.c +++ b/drivers/staging/wfx/queue.c @@ -73,23 +73,22 @@ void wfx_tx_queues_init(struct wfx_vif *wvif) } } -void wfx_tx_queues_check_empty(struct wfx_vif *wvif) -{ - int i; - - for (i = 0; i < IEEE80211_NUM_ACS; ++i) { - WARN_ON(atomic_read(&wvif->tx_queue[i].pending_frames)); - WARN_ON(!skb_queue_empty_lockless(&wvif->tx_queue[i].normal)); - WARN_ON(!skb_queue_empty_lockless(&wvif->tx_queue[i].cab)); - } -} - bool wfx_tx_queue_empty(struct wfx_vif *wvif, struct wfx_queue *queue) { return skb_queue_empty_lockless(&queue->normal) && skb_queue_empty_lockless(&queue->cab); } +void wfx_tx_queues_check_empty(struct wfx_vif *wvif) +{ + int i; + + for (i = 0; i < IEEE80211_NUM_ACS; ++i) { + WARN_ON(atomic_read(&wvif->tx_queue[i].pending_frames)); + WARN_ON(!wfx_tx_queue_empty(wvif, &wvif->tx_queue[i])); + } +} + static void __wfx_tx_queue_drop(struct wfx_vif *wvif, struct sk_buff_head *skb_queue, struct sk_buff_head *dropped) -- 2.33.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 10/33] staging: wfx: fix support for CSA
From: Jérôme Pouiller The WF200 is able to filter beacons. However, it uses a positive filter: any change to an IE not listed won't be reported. In current code, the changes in Channel Switch Announcement (CSA) are not reported to the host. Thus, it fixes the support for CSA in station mode. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/sta.c | 7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c index aff0559653bf..5f2f8900ce99 100644 --- a/drivers/staging/wfx/sta.c +++ b/drivers/staging/wfx/sta.c @@ -80,13 +80,18 @@ static void wfx_filter_beacon(struct wfx_vif *wvif, bool filter_beacon) .has_changed = 1, .no_longer= 1, .has_appeared = 1, + }, { + .ie_id= WLAN_EID_CHANNEL_SWITCH, + .has_changed = 1, + .no_longer= 1, + .has_appeared = 1, } }; if (!filter_beacon) { hif_beacon_filter_control(wvif, 0, 1); } else { - hif_set_beacon_filter_table(wvif, 3, filter_ies); + hif_set_beacon_filter_table(wvif, ARRAY_SIZE(filter_ies), filter_ies); hif_beacon_filter_control(wvif, HIF_BEACON_FILTER_ENABLE, 0); } } -- 2.33.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 05/33] staging: wfx: avoid possible lock-up during scan
From: Jérôme Pouiller If the environment is noisy, the device may take time to send scan requests. Thus, scan requests durations > 5s have already been observed. During the scan, traffic is neither received, neither sent. From the user point-of-view, the traffic is frozen for a long time. This patch reworks the scan processing. It gives to the device a smaller time budget than previously. However, it does not expect the scan to be complete and it is able to send another scan request to finish the work. A big part of the patch aims to avoid an infinite loop if the device goes crazy. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/hif_rx.c | 3 ++- drivers/staging/wfx/scan.c | 48 ++-- drivers/staging/wfx/scan.h | 2 +- drivers/staging/wfx/wfx.h| 1 + 4 files changed, 33 insertions(+), 21 deletions(-) diff --git a/drivers/staging/wfx/hif_rx.c b/drivers/staging/wfx/hif_rx.c index 9fca7f26372a..a60c4a4ba935 100644 --- a/drivers/staging/wfx/hif_rx.c +++ b/drivers/staging/wfx/hif_rx.c @@ -175,13 +175,14 @@ static int hif_scan_complete_indication(struct wfx_dev *wdev, const void *buf) { struct wfx_vif *wvif = wdev_to_wvif(wdev, hif->interface); + const struct hif_ind_scan_cmpl *body = buf; if (!wvif) { dev_warn(wdev->dev, "%s: received event for non-existent vif\n", __func__); return -EIO; } - wfx_scan_complete(wvif); + wfx_scan_complete(wvif, body->num_channels_completed); return 0; } diff --git a/drivers/staging/wfx/scan.c b/drivers/staging/wfx/scan.c index 1e03b130049b..695b06974194 100644 --- a/drivers/staging/wfx/scan.c +++ b/drivers/staging/wfx/scan.c @@ -41,7 +41,7 @@ static int update_probe_tmpl(struct wfx_vif *wvif, static int send_scan_req(struct wfx_vif *wvif, struct cfg80211_scan_request *req, int start_idx) { - int i, ret, timeout; + int i, ret; struct ieee80211_channel *ch_start, *ch_cur; for (i = start_idx; i < req->n_channels; i++) { @@ -56,31 +56,31 @@ static int send_scan_req(struct wfx_vif *wvif, wfx_tx_lock_flush(wvif->wdev); wvif->scan_abort = false; reinit_completion(&wvif->scan_complete); - ret = hif_scan(wvif, req, start_idx, i - start_idx, &timeout); + ret = hif_scan(wvif, req, start_idx, i - start_idx, NULL); if (ret) { - ret = -EIO; - goto err_scan_start; + wfx_tx_unlock(wvif->wdev); + return -EIO; } - ret = wait_for_completion_timeout(&wvif->scan_complete, timeout); + ret = wait_for_completion_timeout(&wvif->scan_complete, 1 * HZ); if (!ret) { - dev_notice(wvif->wdev->dev, "scan timeout\n"); hif_stop_scan(wvif); ret = wait_for_completion_timeout(&wvif->scan_complete, 1 * HZ); - if (!ret) - dev_err(wvif->wdev->dev, "scan didn't stop\n"); + dev_dbg(wvif->wdev->dev, "scan timeout (%d channels done)\n", + wvif->scan_nb_chan_done); + } + if (!ret) { + dev_err(wvif->wdev->dev, "scan didn't stop\n"); ret = -ETIMEDOUT; - goto err_timeout; - } - if (wvif->scan_abort) { + } else if (wvif->scan_abort) { dev_notice(wvif->wdev->dev, "scan abort\n"); ret = -ECONNABORTED; - goto err_timeout; + } else if (wvif->scan_nb_chan_done > i - start_idx) { + ret = -EIO; + } else { + ret = wvif->scan_nb_chan_done; } - ret = i - start_idx; -err_timeout: if (req->channels[start_idx]->max_power != wvif->vif->bss_conf.txpower) hif_set_output_power(wvif, wvif->vif->bss_conf.txpower); -err_scan_start: wfx_tx_unlock(wvif->wdev); return ret; } @@ -94,7 +94,7 @@ void wfx_hw_scan_work(struct work_struct *work) { struct wfx_vif *wvif = container_of(work, struct wfx_vif, scan_work); struct ieee80211_scan_request *hw_req = wvif->scan_req; - int chan_cur, ret; + int chan_cur, ret, err; mutex_lock(&wvif->wdev->conf_mutex); mutex_lock(&wvif->scan_lock); @@ -105,11 +105,20 @@ void wfx_hw_scan_work(struct work_struct *work) } update_probe_tmpl(wvif, &hw_req->req); chan_cur = 0; + err = 0; do { ret = send_scan_req(wvif, &hw_req->req, chan_cur); - if (ret > 0) + if (ret > 0) { chan_cur += ret; - } while (ret > 0 && chan_cur < hw_req->req.n_channels); + err = 0; + } + if (!ret) + err++; + if (err > 2) { + dev_err(wvif->wdev->dev, "scan has not been able to start\n"); +
[PATCH v2 09/33] staging: wfx: declare support for TDLS
From: Jérôme Pouiller Since the firmware API 3.8, the device is able to support TDLS. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/main.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/staging/wfx/main.c b/drivers/staging/wfx/main.c index 4b9fdf99981b..0a9d02d1af2f 100644 --- a/drivers/staging/wfx/main.c +++ b/drivers/staging/wfx/main.c @@ -440,6 +440,9 @@ int wfx_probe(struct wfx_dev *wdev) wdev->hw->wiphy->n_addresses = ARRAY_SIZE(wdev->addresses); wdev->hw->wiphy->addresses = wdev->addresses; + if (!wfx_api_older_than(wdev, 3, 8)) + wdev->hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS; + err = ieee80211_register_hw(wdev->hw); if (err) goto err1; -- 2.33.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 11/33] staging: wfx: relax the PDS existence constraint
From: Jérôme Pouiller The PDS file contains antenna parameters. The file is specific to each hardware design. Normally, the board designer should add a line in the of_device_id table with his own antenna parameters. Until, now the absence of PDS file is a hard fatal error. However, during the development, in most of the cases, an empty PDS file is sufficient to start WiFi communication. This patch keep an error, but allow the user to play with the device. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/main.c | 6 ++ 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/staging/wfx/main.c b/drivers/staging/wfx/main.c index 0a9d02d1af2f..b790d8573de6 100644 --- a/drivers/staging/wfx/main.c +++ b/drivers/staging/wfx/main.c @@ -220,7 +220,7 @@ static int wfx_send_pdata_pds(struct wfx_dev *wdev) ret = request_firmware(&pds, wdev->pdata.file_pds, wdev->dev); if (ret) { - dev_err(wdev->dev, "can't load PDS file %s\n", + dev_err(wdev->dev, "can't load antenna parameters (PDS file %s). The device may be unstable.\n", wdev->pdata.file_pds); goto err1; } @@ -395,9 +395,7 @@ int wfx_probe(struct wfx_dev *wdev) dev_dbg(wdev->dev, "sending configuration file %s\n", wdev->pdata.file_pds); - err = wfx_send_pdata_pds(wdev); - if (err < 0) - goto err0; + wfx_send_pdata_pds(wdev); wdev->poll_irq = false; err = wdev->hwbus_ops->irq_subscribe(wdev->hwbus_priv); -- 2.33.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 12/33] staging: wfx: simplify API coherency check
From: Jérôme Pouiller The 'channel' argument of hif_join() should never be NULL. hif_join() does not have the responsibility to recover bug of caller. A call to WARN() at the beginning of the function reminds this constraint to the developer. In current code, if the argument channel is NULL, memory leaks. The new code just emit a warning and does not give the illusion that it is supported (and indeed a Oops will probably raise a few lines below). Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/hif_tx.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/wfx/hif_tx.c b/drivers/staging/wfx/hif_tx.c index 14b7e047916e..6ffbae32028b 100644 --- a/drivers/staging/wfx/hif_tx.c +++ b/drivers/staging/wfx/hif_tx.c @@ -299,10 +299,9 @@ int hif_join(struct wfx_vif *wvif, const struct ieee80211_bss_conf *conf, WARN_ON(!conf->beacon_int); WARN_ON(!conf->basic_rates); + WARN_ON(!channel); WARN_ON(sizeof(body->ssid) < ssidlen); WARN(!conf->ibss_joined && !ssidlen, "joining an unknown BSS"); - if (WARN_ON(!channel)) - return -EINVAL; if (!hif) return -ENOMEM; body->infrastructure_bss_mode = !conf->ibss_joined; -- 2.33.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 13/33] staging: wfx: update with the firmware API 3.8
From: Jérôme Pouiller The firmware API 3.8 introduces new statistic counters. These changes are backward compatible. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/debug.c | 3 +++ drivers/staging/wfx/hif_api_mib.h | 5 - 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/staging/wfx/debug.c b/drivers/staging/wfx/debug.c index eedada78c25f..e67ca0d818ba 100644 --- a/drivers/staging/wfx/debug.c +++ b/drivers/staging/wfx/debug.c @@ -109,6 +109,9 @@ static int wfx_counters_show(struct seq_file *seq, void *v) PUT_COUNTER(rx_beacon); PUT_COUNTER(miss_beacon); + PUT_COUNTER(rx_dtim); + PUT_COUNTER(rx_dtim_aid0_clr); + PUT_COUNTER(rx_dtim_aid0_set); #undef PUT_COUNTER diff --git a/drivers/staging/wfx/hif_api_mib.h b/drivers/staging/wfx/hif_api_mib.h index ace924720ce6..b2dc47c314cc 100644 --- a/drivers/staging/wfx/hif_api_mib.h +++ b/drivers/staging/wfx/hif_api_mib.h @@ -158,7 +158,10 @@ struct hif_mib_extended_count_table { __le32 count_rx_bipmic_errors; __le32 count_rx_beacon; __le32 count_miss_beacon; - __le32 reserved[15]; + __le32 count_rx_dtim; + __le32 count_rx_dtim_aid0_clr; + __le32 count_rx_dtim_aid0_set; + __le32 reserved[12]; } __packed; struct hif_mib_count_table { -- 2.33.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 16/33] staging: wfx: declare variables at beginning of functions
From: Jérôme Pouiller For better code, we prefer to declare all the local variables at beginning of the functions. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/data_tx.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/wfx/data_tx.c b/drivers/staging/wfx/data_tx.c index caeaf836147f..00c305f192bb 100644 --- a/drivers/staging/wfx/data_tx.c +++ b/drivers/staging/wfx/data_tx.c @@ -108,6 +108,7 @@ static int wfx_tx_policy_get(struct wfx_vif *wvif, int idx; struct tx_policy_cache *cache = &wvif->tx_policy_cache; struct tx_policy wanted; + struct tx_policy *entry; wfx_tx_policy_build(wvif, &wanted, rates); @@ -121,11 +122,10 @@ static int wfx_tx_policy_get(struct wfx_vif *wvif, if (idx >= 0) { *renew = false; } else { - struct tx_policy *entry; - *renew = true; - /* If policy is not found create a new one -* using the oldest entry in "free" list + /* If policy is not found create a new one using the oldest +* entry in "free" list */ + *renew = true; entry = list_entry(cache->free.prev, struct tx_policy, link); memcpy(entry->rates, wanted.rates, sizeof(entry->rates)); entry->uploaded = false; -- 2.33.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 14/33] staging: wfx: uniformize counter names
From: Jérôme Pouiller The device provide some internal statistic counters. However, the names of counter were not very meaningful. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/debug.c | 45 - drivers/staging/wfx/hif_api_mib.h | 82 +++ 2 files changed, 64 insertions(+), 63 deletions(-) diff --git a/drivers/staging/wfx/debug.c b/drivers/staging/wfx/debug.c index e67ca0d818ba..16c3f55f1a3d 100644 --- a/drivers/staging/wfx/debug.c +++ b/drivers/staging/wfx/debug.c @@ -82,36 +82,37 @@ static int wfx_counters_show(struct seq_file *seq, void *v) le32_to_cpu(counters[0].count_##name), \ le32_to_cpu(counters[1].count_##name)) - PUT_COUNTER(tx_packets); - PUT_COUNTER(tx_multicast_frames); + PUT_COUNTER(tx_frames); + PUT_COUNTER(tx_frames_multicast); PUT_COUNTER(tx_frames_success); - PUT_COUNTER(tx_frame_failures); PUT_COUNTER(tx_frames_retried); PUT_COUNTER(tx_frames_multi_retried); + PUT_COUNTER(tx_frames_failed); + PUT_COUNTER(ack_failed); PUT_COUNTER(rts_success); - PUT_COUNTER(rts_failures); - PUT_COUNTER(ack_failures); + PUT_COUNTER(rts_failed); - PUT_COUNTER(rx_packets); + PUT_COUNTER(rx_frames); + PUT_COUNTER(rx_frames_multicast); PUT_COUNTER(rx_frames_success); - PUT_COUNTER(rx_packet_errors); - PUT_COUNTER(plcp_errors); - PUT_COUNTER(fcs_errors); - PUT_COUNTER(rx_decryption_failures); - PUT_COUNTER(rx_mic_failures); - PUT_COUNTER(rx_no_key_failures); - PUT_COUNTER(rx_frame_duplicates); - PUT_COUNTER(rx_multicast_frames); - PUT_COUNTER(rx_cmacicv_errors); - PUT_COUNTER(rx_cmac_replays); - PUT_COUNTER(rx_mgmt_ccmp_replays); + PUT_COUNTER(rx_frames_failed); + PUT_COUNTER(drop_plcp); + PUT_COUNTER(drop_fcs); + PUT_COUNTER(drop_no_key); + PUT_COUNTER(drop_decryption); + PUT_COUNTER(drop_tkip_mic); + PUT_COUNTER(drop_bip_mic); + PUT_COUNTER(drop_cmac_icv); + PUT_COUNTER(drop_cmac_replay); + PUT_COUNTER(drop_ccmp_replay); + PUT_COUNTER(drop_duplicate); - PUT_COUNTER(rx_beacon); - PUT_COUNTER(miss_beacon); - PUT_COUNTER(rx_dtim); - PUT_COUNTER(rx_dtim_aid0_clr); - PUT_COUNTER(rx_dtim_aid0_set); + PUT_COUNTER(rx_bcn_miss); + PUT_COUNTER(rx_bcn_success); + PUT_COUNTER(rx_bcn_dtim); + PUT_COUNTER(rx_bcn_dtim_aid0_clr); + PUT_COUNTER(rx_bcn_dtim_aid0_set); #undef PUT_COUNTER diff --git a/drivers/staging/wfx/hif_api_mib.h b/drivers/staging/wfx/hif_api_mib.h index b2dc47c314cc..2a741a37a90c 100644 --- a/drivers/staging/wfx/hif_api_mib.h +++ b/drivers/staging/wfx/hif_api_mib.h @@ -133,61 +133,61 @@ struct hif_mib_bcn_filter_enable { } __packed; struct hif_mib_extended_count_table { - __le32 count_plcp_errors; - __le32 count_fcs_errors; - __le32 count_tx_packets; - __le32 count_rx_packets; - __le32 count_rx_packet_errors; - __le32 count_rx_decryption_failures; - __le32 count_rx_mic_failures; - __le32 count_rx_no_key_failures; - __le32 count_tx_multicast_frames; + __le32 count_drop_plcp; + __le32 count_drop_fcs; + __le32 count_tx_frames; + __le32 count_rx_frames; + __le32 count_rx_frames_failed; + __le32 count_drop_decryption; + __le32 count_drop_tkip_mic; + __le32 count_drop_no_key; + __le32 count_tx_frames_multicast; __le32 count_tx_frames_success; - __le32 count_tx_frame_failures; + __le32 count_tx_frames_failed; __le32 count_tx_frames_retried; __le32 count_tx_frames_multi_retried; - __le32 count_rx_frame_duplicates; + __le32 count_drop_duplicate; __le32 count_rts_success; - __le32 count_rts_failures; - __le32 count_ack_failures; - __le32 count_rx_multicast_frames; + __le32 count_rts_failed; + __le32 count_ack_failed; + __le32 count_rx_frames_multicast; __le32 count_rx_frames_success; - __le32 count_rx_cmacicv_errors; - __le32 count_rx_cmac_replays; - __le32 count_rx_mgmt_ccmp_replays; - __le32 count_rx_bipmic_errors; - __le32 count_rx_beacon; - __le32 count_miss_beacon; - __le32 count_rx_dtim; - __le32 count_rx_dtim_aid0_clr; - __le32 count_rx_dtim_aid0_set; + __le32 count_drop_cmac_icv; + __le32 count_drop_cmac_replay; + __le32 count_drop_ccmp_replay; + __le32 count_drop_bip_mic; + __le32 count_rx_bcn_success; + __le32 count_rx_bcn_miss; + __le32 count_rx_bcn_dtim; + __le32 count_rx_bcn_dtim_aid0_clr; + __le32 count_rx_bcn_dtim_aid0_set; __le32 reserved[12]; } __packed; struct hif_mib_count_table { - __le32 count_plcp_errors; - __le32 count_fcs_errors; -
[PATCH v2 15/33] staging: wfx: fix misleading 'rate_id' usage
From: Jérôme Pouiller The driver sometime use the term 'rate_id' to identify a retry policy (which is in fact a series of rate IDs). This is misleading. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/data_tx.c | 15 +++ 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/drivers/staging/wfx/data_tx.c b/drivers/staging/wfx/data_tx.c index 77fb104efdec..caeaf836147f 100644 --- a/drivers/staging/wfx/data_tx.c +++ b/drivers/staging/wfx/data_tx.c @@ -285,15 +285,14 @@ static void wfx_tx_fixup_rates(struct ieee80211_tx_rate *rates) rates[i].flags &= ~IEEE80211_TX_RC_SHORT_GI; } -static u8 wfx_tx_get_rate_id(struct wfx_vif *wvif, -struct ieee80211_tx_info *tx_info) +static u8 wfx_tx_get_retry_policy_id(struct wfx_vif *wvif, +struct ieee80211_tx_info *tx_info) { bool tx_policy_renew = false; - u8 rate_id; + u8 ret; - rate_id = wfx_tx_policy_get(wvif, - tx_info->driver_rates, &tx_policy_renew); - if (rate_id == HIF_TX_RETRY_POLICY_INVALID) + ret = wfx_tx_policy_get(wvif, tx_info->driver_rates, &tx_policy_renew); + if (ret == HIF_TX_RETRY_POLICY_INVALID) dev_warn(wvif->wdev->dev, "unable to get a valid Tx policy"); if (tx_policy_renew) { @@ -301,7 +300,7 @@ static u8 wfx_tx_get_rate_id(struct wfx_vif *wvif, if (!schedule_work(&wvif->tx_policy_upload_work)) wfx_tx_unlock(wvif->wdev); } - return rate_id; + return ret; } static int wfx_tx_get_frame_format(struct ieee80211_tx_info *tx_info) @@ -382,7 +381,7 @@ static int wfx_tx_inner(struct wfx_vif *wvif, struct ieee80211_sta *sta, req->peer_sta_id = wfx_tx_get_link_id(wvif, sta, hdr); // Queue index are inverted between firmware and Linux req->queue_id = 3 - queue_id; - req->retry_policy_index = wfx_tx_get_rate_id(wvif, tx_info); + req->retry_policy_index = wfx_tx_get_retry_policy_id(wvif, tx_info); req->frame_format = wfx_tx_get_frame_format(tx_info); if (tx_info->driver_rates[0].flags & IEEE80211_TX_RC_SHORT_GI) req->short_gi = 1; -- 2.33.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 17/33] staging: wfx: simplify hif_join()
From: Jérôme Pouiller The new code is smaller. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/hif_tx.c | 5 + 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/staging/wfx/hif_tx.c b/drivers/staging/wfx/hif_tx.c index 6ffbae32028b..aea0ed55edc6 100644 --- a/drivers/staging/wfx/hif_tx.c +++ b/drivers/staging/wfx/hif_tx.c @@ -306,10 +306,7 @@ int hif_join(struct wfx_vif *wvif, const struct ieee80211_bss_conf *conf, return -ENOMEM; body->infrastructure_bss_mode = !conf->ibss_joined; body->short_preamble = conf->use_short_preamble; - if (channel->flags & IEEE80211_CHAN_NO_IR) - body->probe_for_join = 0; - else - body->probe_for_join = 1; + body->probe_for_join = !(channel->flags & IEEE80211_CHAN_NO_IR); body->channel_number = channel->hw_value; body->beacon_interval = cpu_to_le32(conf->beacon_int); body->basic_rate_set = -- 2.33.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 19/33] staging: wfx: fix error names
From: Jérôme Pouiller ENOTSUP is an alias of EOPNOTSUPP. However, EOPNOTSUPP is preferred. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/sta.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c index 5f2f8900ce99..1e8d05c4f2da 100644 --- a/drivers/staging/wfx/sta.c +++ b/drivers/staging/wfx/sta.c @@ -674,7 +674,7 @@ int wfx_ampdu_action(struct ieee80211_hw *hw, return 0; default: // Leave the firmware doing its business for tx aggregation - return -ENOTSUPP; + return -EOPNOTSUPP; } } -- 2.33.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 18/33] staging: wfx: reorder function for slightly better eye candy
From: Jérôme Pouiller For a code more eye candy, group all the unconditional assignments together. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/data_tx.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/wfx/data_tx.c b/drivers/staging/wfx/data_tx.c index 00c305f192bb..77d69ed73e28 100644 --- a/drivers/staging/wfx/data_tx.c +++ b/drivers/staging/wfx/data_tx.c @@ -376,15 +376,15 @@ static int wfx_tx_inner(struct wfx_vif *wvif, struct ieee80211_sta *sta, req->packet_id |= queue_id << 28; req->fc_offset = offset; - if (tx_info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) - req->after_dtim = 1; - req->peer_sta_id = wfx_tx_get_link_id(wvif, sta, hdr); // Queue index are inverted between firmware and Linux req->queue_id = 3 - queue_id; + req->peer_sta_id = wfx_tx_get_link_id(wvif, sta, hdr); req->retry_policy_index = wfx_tx_get_retry_policy_id(wvif, tx_info); req->frame_format = wfx_tx_get_frame_format(tx_info); if (tx_info->driver_rates[0].flags & IEEE80211_TX_RC_SHORT_GI) req->short_gi = 1; + if (tx_info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) + req->after_dtim = 1; // Auxiliary operations wfx_tx_queues_put(wvif, skb); -- 2.33.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 22/33] staging: wfx: remove useless debug statement
From: Jérôme Pouiller In the early age, it was unexpected to access a VIF that did not exist. With current code, this happens frequently. Having a trace associated on this event brings absolutely no informations. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/wfx.h | 5 + 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/staging/wfx/wfx.h b/drivers/staging/wfx/wfx.h index 56f1e4bb0b57..a8efa25a38ac 100644 --- a/drivers/staging/wfx/wfx.h +++ b/drivers/staging/wfx/wfx.h @@ -99,11 +99,8 @@ static inline struct wfx_vif *wdev_to_wvif(struct wfx_dev *wdev, int vif_id) return NULL; } vif_id = array_index_nospec(vif_id, ARRAY_SIZE(wdev->vif)); - if (!wdev->vif[vif_id]) { - dev_dbg(wdev->dev, "requesting non-allocated vif: %d\n", - vif_id); + if (!wdev->vif[vif_id]) return NULL; - } return (struct wfx_vif *) wdev->vif[vif_id]->drv_priv; } -- 2.33.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 21/33] staging: wfx: remove unused definition
From: Jérôme Pouiller The enum hif_fw_type is never used in the driver. Drop it. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/hif_api_general.h | 6 -- 1 file changed, 6 deletions(-) diff --git a/drivers/staging/wfx/hif_api_general.h b/drivers/staging/wfx/hif_api_general.h index 24188945718d..77030cecf134 100644 --- a/drivers/staging/wfx/hif_api_general.h +++ b/drivers/staging/wfx/hif_api_general.h @@ -113,12 +113,6 @@ enum hif_api_rate_index { API_RATE_NUM_ENTRIES = 22 }; -enum hif_fw_type { - HIF_FW_TYPE_ETF = 0x0, - HIF_FW_TYPE_WFM = 0x1, - HIF_FW_TYPE_WSM = 0x2 -}; - struct hif_ind_startup { // As the others, this struct is interpreted as little endian by the // device. However, this struct is also used by the driver. We prefer to -- 2.33.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 20/33] staging: wfx: apply naming rules in hif_tx_mib.c
From: Jérôme Pouiller All the functions of hif_tx_mib.c format data to be sent to the hardware. In this file, the struct to be sent is always named 'arg'. Also applies this rule to hif_set_macaddr(). Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/hif_tx_mib.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/wfx/hif_tx_mib.c b/drivers/staging/wfx/hif_tx_mib.c index 1926cf1b62be..1900b7fafd9e 100644 --- a/drivers/staging/wfx/hif_tx_mib.c +++ b/drivers/staging/wfx/hif_tx_mib.c @@ -81,12 +81,12 @@ int hif_get_counters_table(struct wfx_dev *wdev, int vif_id, int hif_set_macaddr(struct wfx_vif *wvif, u8 *mac) { - struct hif_mib_mac_address msg = { }; + struct hif_mib_mac_address arg = { }; if (mac) - ether_addr_copy(msg.mac_addr, mac); + ether_addr_copy(arg.mac_addr, mac); return hif_write_mib(wvif->wdev, wvif->id, HIF_MIB_ID_DOT11_MAC_ADDRESS, -&msg, sizeof(msg)); +&arg, sizeof(arg)); } int hif_set_rx_filter(struct wfx_vif *wvif, -- 2.33.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 23/33] staging: wfx: fix space after cast operator
From: Jérôme Pouiller checkpatch.pl reports that cast operators should not been followed by a space. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/wfx.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/wfx/wfx.h b/drivers/staging/wfx/wfx.h index a8efa25a38ac..9749602f6cdc 100644 --- a/drivers/staging/wfx/wfx.h +++ b/drivers/staging/wfx/wfx.h @@ -101,7 +101,7 @@ static inline struct wfx_vif *wdev_to_wvif(struct wfx_dev *wdev, int vif_id) vif_id = array_index_nospec(vif_id, ARRAY_SIZE(wdev->vif)); if (!wdev->vif[vif_id]) return NULL; - return (struct wfx_vif *) wdev->vif[vif_id]->drv_priv; + return (struct wfx_vif *)wdev->vif[vif_id]->drv_priv; } static inline struct wfx_vif *wvif_iterate(struct wfx_dev *wdev, -- 2.33.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 24/33] staging: wfx: remove references to WFxxx in comments
From: Jérôme Pouiller The WF200 is the only representative of the WFxxx series and the development of any successor is not expected. So, for clarity, replace occurrences of "WFxxx" with "WF200". Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/bh.c | 4 ++-- drivers/staging/wfx/bus_spi.c | 6 +++--- drivers/staging/wfx/data_tx.c | 4 ++-- drivers/staging/wfx/fwio.c| 4 ++-- drivers/staging/wfx/hif_api_cmd.h | 2 +- drivers/staging/wfx/hif_api_general.h | 2 +- drivers/staging/wfx/hif_api_mib.h | 2 +- drivers/staging/wfx/hif_rx.c | 3 +-- drivers/staging/wfx/hif_rx.h | 3 +-- drivers/staging/wfx/hif_tx.c | 12 +--- drivers/staging/wfx/hif_tx.h | 4 ++-- drivers/staging/wfx/hif_tx_mib.c | 2 +- drivers/staging/wfx/hif_tx_mib.h | 2 +- drivers/staging/wfx/main.c| 2 +- drivers/staging/wfx/sta.c | 4 +--- drivers/staging/wfx/sta.h | 2 +- drivers/staging/wfx/wfx.h | 2 +- 17 files changed, 27 insertions(+), 33 deletions(-) diff --git a/drivers/staging/wfx/bh.c b/drivers/staging/wfx/bh.c index ed53d0b45592..78fa81d82517 100644 --- a/drivers/staging/wfx/bh.c +++ b/drivers/staging/wfx/bh.c @@ -72,7 +72,7 @@ static int rx_helper(struct wfx_dev *wdev, size_t read_len, int *is_cnf) int piggyback = 0; WARN(read_len > round_down(0xFFF, 2) * sizeof(u16), -"%s: request exceed WFx capability", __func__); +"%s: request exceed the chip capability", __func__); // Add 2 to take into account piggyback size alloc_len = wdev->hwbus_ops->align_size(wdev->hwbus_priv, read_len + 2); @@ -181,7 +181,7 @@ static void tx_helper(struct wfx_dev *wdev, struct hif_msg *hif) data = hif; WARN(len > wdev->hw_caps.size_inp_ch_buf, -"%s: request exceed WFx capability: %zu > %d\n", __func__, +"%s: request exceed the chip capability: %zu > %d\n", __func__, len, wdev->hw_caps.size_inp_ch_buf); len = wdev->hwbus_ops->align_size(wdev->hwbus_priv, len); ret = wfx_data_write(wdev, data, len); diff --git a/drivers/staging/wfx/bus_spi.c b/drivers/staging/wfx/bus_spi.c index a99125d1a30d..759e085048c3 100644 --- a/drivers/staging/wfx/bus_spi.c +++ b/drivers/staging/wfx/bus_spi.c @@ -39,9 +39,9 @@ struct wfx_spi_priv { }; /* - * WFx chip read data 16bits at time and place them directly into (little - * endian) CPU register. So, chip expect byte order like "B1 B0 B3 B2" (while - * LE is "B0 B1 B2 B3" and BE is "B3 B2 B1 B0") + * The chip reads 16bits of data at time and place them directly into (little + * endian) CPU register. So, the chip expects bytes order to be "B1 B0 B3 B2" + * (while LE is "B0 B1 B2 B3" and BE is "B3 B2 B1 B0") * * A little endian host with bits_per_word == 16 should do the right job * natively. The code below to support big endian host and commonly used SPI diff --git a/drivers/staging/wfx/data_tx.c b/drivers/staging/wfx/data_tx.c index 77d69ed73e28..f141ab50f4fd 100644 --- a/drivers/staging/wfx/data_tx.c +++ b/drivers/staging/wfx/data_tx.c @@ -31,8 +31,8 @@ static int wfx_get_hw_rate(struct wfx_dev *wdev, } return rate->idx + 14; } - // WFx only support 2GHz, else band information should be retrieved - // from ieee80211_tx_info + // The device only support 2GHz, else band information should be + // retrieved from ieee80211_tx_info band = wdev->hw->wiphy->bands[NL80211_BAND_2GHZ]; if (rate->idx >= band->n_bitrates) { WARN(1, "wrong rate->idx value: %d", rate->idx); diff --git a/drivers/staging/wfx/fwio.c b/drivers/staging/wfx/fwio.c index 1b8aec02d169..7b91ac615f4a 100644 --- a/drivers/staging/wfx/fwio.c +++ b/drivers/staging/wfx/fwio.c @@ -207,8 +207,8 @@ static int upload_firmware(struct wfx_dev *wdev, const u8 *data, size_t len) if (ret < 0) return ret; - // WFx seems to not support writing 0 in this register during - // first loop + // The device seems to not support writing 0 in this register + // during first loop offs += DNLD_BLOCK_SIZE; ret = sram_reg_write(wdev, WFX_DCA_PUT, offs); if (ret < 0) diff --git a/drivers/staging/wfx/hif_api_cmd.h b/drivers/staging/wfx/hif_api_cmd.h index 58c9bb036011..553dc45142f2 100644 --- a/drivers/staging/wfx/hif_api_cmd.h +++ b/drivers/staging/wfx/hif_api_cmd.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: Apache-2.0 */ /* - * WFx hardware interface definitions + * WF200 hardware interface definitions * * Copyright (c) 2018-2020, Silicon Laboratories Inc. */ diff --git a/drivers/staging/wfx/hif_api_general.h b/drivers/staging/wfx/hif_api_general.h index 77030cecf134..714e1dd808e6 100644 --- a/drivers/staging/wfx/hif_api_genera
[PATCH v2 26/33] staging: wfx: reformat comment
From: Jérôme Pouiller The new comment takes only one line instead of three. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/sta.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c index 1e21beeed438..70e1c4d8ae2e 100644 --- a/drivers/staging/wfx/sta.c +++ b/drivers/staging/wfx/sta.c @@ -599,9 +599,7 @@ static int wfx_update_tim(struct wfx_vif *wvif) tim_ptr = skb->data + tim_offset; if (tim_offset && tim_length >= 6) { - /* Ignore DTIM count from mac80211: -* firmware handles DTIM internally. -*/ + /* Firmware handles DTIM counter internally */ tim_ptr[2] = 0; /* Set/reset aid0 bit */ -- 2.33.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 25/33] staging: wfx: update files descriptions
From: Jérôme Pouiller Each file of the driver contains a short description of its purpose. These description were a bit outdated. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/bh.h | 2 +- drivers/staging/wfx/data_rx.c | 2 +- drivers/staging/wfx/data_rx.h | 2 +- drivers/staging/wfx/data_tx.c | 2 +- drivers/staging/wfx/data_tx.h | 2 +- drivers/staging/wfx/hwio.h| 2 +- drivers/staging/wfx/key.h | 2 +- drivers/staging/wfx/queue.c | 2 +- drivers/staging/wfx/queue.h | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/staging/wfx/bh.h b/drivers/staging/wfx/bh.h index 78c49329e22a..f08c62ed039c 100644 --- a/drivers/staging/wfx/bh.h +++ b/drivers/staging/wfx/bh.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Interrupt bottom half. + * Interrupt bottom half (BH). * * Copyright (c) 2017-2020, Silicon Laboratories, Inc. * Copyright (c) 2010, ST-Ericsson diff --git a/drivers/staging/wfx/data_rx.c b/drivers/staging/wfx/data_rx.c index 385f2d42a0e2..509f45cdbab9 100644 --- a/drivers/staging/wfx/data_rx.c +++ b/drivers/staging/wfx/data_rx.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Datapath implementation. + * Data receiving implementation. * * Copyright (c) 2017-2020, Silicon Laboratories, Inc. * Copyright (c) 2010, ST-Ericsson diff --git a/drivers/staging/wfx/data_rx.h b/drivers/staging/wfx/data_rx.h index 4c0da37f2084..f79545c06130 100644 --- a/drivers/staging/wfx/data_rx.h +++ b/drivers/staging/wfx/data_rx.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Datapath implementation. + * Data receiving implementation. * * Copyright (c) 2017-2020, Silicon Laboratories, Inc. * Copyright (c) 2010, ST-Ericsson diff --git a/drivers/staging/wfx/data_tx.c b/drivers/staging/wfx/data_tx.c index f141ab50f4fd..04241422edc8 100644 --- a/drivers/staging/wfx/data_tx.c +++ b/drivers/staging/wfx/data_tx.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Datapath implementation. + * Data transmitting implementation. * * Copyright (c) 2017-2020, Silicon Laboratories, Inc. * Copyright (c) 2010, ST-Ericsson diff --git a/drivers/staging/wfx/data_tx.h b/drivers/staging/wfx/data_tx.h index 401363d6b563..7dcc9132d7cd 100644 --- a/drivers/staging/wfx/data_tx.h +++ b/drivers/staging/wfx/data_tx.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Datapath implementation. + * Data transmitting implementation. * * Copyright (c) 2017-2020, Silicon Laboratories, Inc. * Copyright (c) 2010, ST-Ericsson diff --git a/drivers/staging/wfx/hwio.h b/drivers/staging/wfx/hwio.h index 0b8e4f7157df..5e43993b14d8 100644 --- a/drivers/staging/wfx/hwio.h +++ b/drivers/staging/wfx/hwio.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Low-level API. + * Low-level I/O functions. * * Copyright (c) 2017-2020, Silicon Laboratories, Inc. * Copyright (c) 2010, ST-Ericsson diff --git a/drivers/staging/wfx/key.h b/drivers/staging/wfx/key.h index 70a44d0ca35e..dd189788acf1 100644 --- a/drivers/staging/wfx/key.h +++ b/drivers/staging/wfx/key.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Implementation of mac80211 API. + * Key management related functions. * * Copyright (c) 2017-2020, Silicon Laboratories, Inc. * Copyright (c) 2010, ST-Ericsson diff --git a/drivers/staging/wfx/queue.c b/drivers/staging/wfx/queue.c index 0ab207237d9f..e5e7595565ee 100644 --- a/drivers/staging/wfx/queue.c +++ b/drivers/staging/wfx/queue.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * O(1) TX queue with built-in allocator. + * Queue between the tx operation and the bh workqueue. * * Copyright (c) 2017-2020, Silicon Laboratories, Inc. * Copyright (c) 2010, ST-Ericsson diff --git a/drivers/staging/wfx/queue.h b/drivers/staging/wfx/queue.h index 80ba19455ef3..24b60833864b 100644 --- a/drivers/staging/wfx/queue.h +++ b/drivers/staging/wfx/queue.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * O(1) TX queue with built-in allocator. + * Queue between the tx operation and the bh workqueue. * * Copyright (c) 2017-2020, Silicon Laboratories, Inc. * Copyright (c) 2010, ST-Ericsson -- 2.33.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 29/33] staging: wfx: remove useless comments after #endif
From: Jérôme Pouiller Comments after the last #endif of header files don't bring any information and are redundant with the name of the file. Drop them. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/bh.h | 2 +- drivers/staging/wfx/data_rx.h | 2 +- drivers/staging/wfx/data_tx.h | 2 +- drivers/staging/wfx/debug.h | 2 +- drivers/staging/wfx/fwio.h| 2 +- drivers/staging/wfx/hwio.h| 2 +- drivers/staging/wfx/key.h | 2 +- drivers/staging/wfx/queue.h | 2 +- drivers/staging/wfx/scan.h| 2 +- drivers/staging/wfx/sta.h | 2 +- drivers/staging/wfx/wfx.h | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/staging/wfx/bh.h b/drivers/staging/wfx/bh.h index f08c62ed039c..6c121ce4dd3f 100644 --- a/drivers/staging/wfx/bh.h +++ b/drivers/staging/wfx/bh.h @@ -30,4 +30,4 @@ void wfx_bh_request_rx(struct wfx_dev *wdev); void wfx_bh_request_tx(struct wfx_dev *wdev); void wfx_bh_poll_irq(struct wfx_dev *wdev); -#endif /* WFX_BH_H */ +#endif diff --git a/drivers/staging/wfx/data_rx.h b/drivers/staging/wfx/data_rx.h index f79545c06130..84d0e3c0507b 100644 --- a/drivers/staging/wfx/data_rx.h +++ b/drivers/staging/wfx/data_rx.h @@ -15,4 +15,4 @@ struct hif_ind_rx; void wfx_rx_cb(struct wfx_vif *wvif, const struct hif_ind_rx *arg, struct sk_buff *skb); -#endif /* WFX_DATA_RX_H */ +#endif diff --git a/drivers/staging/wfx/data_tx.h b/drivers/staging/wfx/data_tx.h index dafd8fef44cf..15590a8faefe 100644 --- a/drivers/staging/wfx/data_tx.h +++ b/drivers/staging/wfx/data_tx.h @@ -65,4 +65,4 @@ static inline struct hif_req_tx *wfx_skb_txreq(struct sk_buff *skb) return req; } -#endif /* WFX_DATA_TX_H */ +#endif diff --git a/drivers/staging/wfx/debug.h b/drivers/staging/wfx/debug.h index 6f2f84d64c9e..4b9c49a9fffb 100644 --- a/drivers/staging/wfx/debug.h +++ b/drivers/staging/wfx/debug.h @@ -16,4 +16,4 @@ const char *get_hif_name(unsigned long id); const char *get_mib_name(unsigned long id); const char *get_reg_name(unsigned long id); -#endif /* WFX_DEBUG_H */ +#endif diff --git a/drivers/staging/wfx/fwio.h b/drivers/staging/wfx/fwio.h index 6028f92503fe..eeea61210eca 100644 --- a/drivers/staging/wfx/fwio.h +++ b/drivers/staging/wfx/fwio.h @@ -12,4 +12,4 @@ struct wfx_dev; int wfx_init_device(struct wfx_dev *wdev); -#endif /* WFX_FWIO_H */ +#endif diff --git a/drivers/staging/wfx/hwio.h b/drivers/staging/wfx/hwio.h index 9a361ed95ecb..ff09575dd1af 100644 --- a/drivers/staging/wfx/hwio.h +++ b/drivers/staging/wfx/hwio.h @@ -72,4 +72,4 @@ int control_reg_write_bits(struct wfx_dev *wdev, u32 mask, u32 val); int igpr_reg_read(struct wfx_dev *wdev, int index, u32 *val); int igpr_reg_write(struct wfx_dev *wdev, int index, u32 val); -#endif /* WFX_HWIO_H */ +#endif diff --git a/drivers/staging/wfx/key.h b/drivers/staging/wfx/key.h index dd189788acf1..2d135eff7af2 100644 --- a/drivers/staging/wfx/key.h +++ b/drivers/staging/wfx/key.h @@ -17,4 +17,4 @@ int wfx_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, struct ieee80211_vif *vif, struct ieee80211_sta *sta, struct ieee80211_key_conf *key); -#endif /* WFX_STA_H */ +#endif diff --git a/drivers/staging/wfx/queue.h b/drivers/staging/wfx/queue.h index 54b5def2e24c..edd0d018b198 100644 --- a/drivers/staging/wfx/queue.h +++ b/drivers/staging/wfx/queue.h @@ -42,4 +42,4 @@ unsigned int wfx_pending_get_pkt_us_delay(struct wfx_dev *wdev, struct sk_buff *skb); void wfx_pending_dump_old_frames(struct wfx_dev *wdev, unsigned int limit_ms); -#endif /* WFX_QUEUE_H */ +#endif diff --git a/drivers/staging/wfx/scan.h b/drivers/staging/wfx/scan.h index 562ca1321daf..78e3b984f375 100644 --- a/drivers/staging/wfx/scan.h +++ b/drivers/staging/wfx/scan.h @@ -19,4 +19,4 @@ int wfx_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, void wfx_cancel_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif); void wfx_scan_complete(struct wfx_vif *wvif, int nb_chan_done); -#endif /* WFX_SCAN_H */ +#endif diff --git a/drivers/staging/wfx/sta.h b/drivers/staging/wfx/sta.h index f359f375cc56..4d7e38be4235 100644 --- a/drivers/staging/wfx/sta.h +++ b/drivers/staging/wfx/sta.h @@ -70,4 +70,4 @@ int wfx_update_pm(struct wfx_vif *wvif); void wfx_reset(struct wfx_vif *wvif); u32 wfx_rate_mask_to_hw(struct wfx_dev *wdev, u32 rates); -#endif /* WFX_STA_H */ +#endif diff --git a/drivers/staging/wfx/wfx.h b/drivers/staging/wfx/wfx.h index a4770f59f7d2..f8df59ad1639 100644 --- a/drivers/staging/wfx/wfx.h +++ b/drivers/staging/wfx/wfx.h @@ -161,4 +161,4 @@ static inline int memzcmp(void *src, unsigned int size) return memcmp(buf, buf + 1, size - 1); } -#endif /* WFX_H */ +#endif -- 2.33.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 28/33] staging: wfx: fix comments styles
From: Jérôme Pouiller Unify all comments of the wfx driver to use the same comment style. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/bh.c | 11 +++ drivers/staging/wfx/bus_spi.c | 6 ++ drivers/staging/wfx/fwio.c| 3 +-- drivers/staging/wfx/main.h| 3 +-- drivers/staging/wfx/scan.c| 3 +-- 5 files changed, 8 insertions(+), 18 deletions(-) diff --git a/drivers/staging/wfx/bh.c b/drivers/staging/wfx/bh.c index e2d2a64ce66e..b026507c11ef 100644 --- a/drivers/staging/wfx/bh.c +++ b/drivers/staging/wfx/bh.c @@ -265,9 +265,7 @@ static void bh_work(struct work_struct *work) wdev->hif.tx_buffers_used, release_chip); } -/* - * An IRQ from chip did occur - */ +/* An IRQ from chip did occur */ void wfx_bh_request_rx(struct wfx_dev *wdev) { u32 cur, prev; @@ -285,16 +283,13 @@ void wfx_bh_request_rx(struct wfx_dev *wdev) prev, cur); } -/* - * Driver want to send data - */ +/* Driver want to send data */ void wfx_bh_request_tx(struct wfx_dev *wdev) { queue_work(system_highpri_wq, &wdev->hif.bh); } -/* - * If IRQ is not available, this function allow to manually poll the control +/* If IRQ is not available, this function allow to manually poll the control * register and simulate an IRQ ahen an event happened. * * Note that the device has a bug: If an IRQ raise while host read control diff --git a/drivers/staging/wfx/bus_spi.c b/drivers/staging/wfx/bus_spi.c index 61f73b3ebc80..55ffcd7c42e2 100644 --- a/drivers/staging/wfx/bus_spi.c +++ b/drivers/staging/wfx/bus_spi.c @@ -38,8 +38,7 @@ struct wfx_spi_priv { bool need_swab; }; -/* - * The chip reads 16bits of data at time and place them directly into (little +/* The chip reads 16bits of data at time and place them directly into (little * endian) CPU register. So, the chip expects bytes order to be "B1 B0 B3 B2" * (while LE is "B0 B1 B2 B3" and BE is "B3 B2 B1 B0") * @@ -241,8 +240,7 @@ static int wfx_spi_remove(struct spi_device *func) return 0; } -/* - * For dynamic driver binding, kernel does not use OF to match driver. It only +/* For dynamic driver binding, kernel does not use OF to match driver. It only * use modalias and modalias is a copy of 'compatible' DT node with vendor * stripped. */ diff --git a/drivers/staging/wfx/fwio.c b/drivers/staging/wfx/fwio.c index c5ba0a50b474..98a9391b2bee 100644 --- a/drivers/staging/wfx/fwio.c +++ b/drivers/staging/wfx/fwio.c @@ -69,8 +69,7 @@ static const char * const fwio_errors[] = { [ERR_MAC_KEY] = "MAC key not initialized", }; -/* - * request_firmware() allocate data using vmalloc(). It is not compatible with +/* request_firmware() allocate data using vmalloc(). It is not compatible with * underlying hardware that use DMA. Function below detect this case and * allocate a bounce buffer if necessary. * diff --git a/drivers/staging/wfx/main.h b/drivers/staging/wfx/main.h index a0db322383a3..115abd2d4378 100644 --- a/drivers/staging/wfx/main.h +++ b/drivers/staging/wfx/main.h @@ -23,8 +23,7 @@ struct wfx_platform_data { const char *file_fw; const char *file_pds; struct gpio_desc *gpio_wakeup; - /* -* if true HIF D_out is sampled on the rising edge of the clock + /* if true HIF D_out is sampled on the rising edge of the clock * (intended to be used in 50Mhz SDIO) */ bool use_rising_clk; diff --git a/drivers/staging/wfx/scan.c b/drivers/staging/wfx/scan.c index 9e2d08317c9e..668ef2c60837 100644 --- a/drivers/staging/wfx/scan.c +++ b/drivers/staging/wfx/scan.c @@ -85,8 +85,7 @@ static int send_scan_req(struct wfx_vif *wvif, return ret; } -/* - * It is not really necessary to run scan request asynchronously. However, +/* It is not really necessary to run scan request asynchronously. However, * there is a bug in "iw scan" when ieee80211_scan_completed() is called before * wfx_hw_scan() return */ -- 2.33.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 27/33] staging: wfx: avoid c99 comments
From: Jérôme Pouiller The wfx driver is a network driver. C99 comments are prohibited in this part of the kernel. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/bh.c | 18 --- drivers/staging/wfx/bus_sdio.c| 8 +-- drivers/staging/wfx/bus_spi.c | 12 +++-- drivers/staging/wfx/data_rx.c | 5 +- drivers/staging/wfx/data_tx.c | 56 ++- drivers/staging/wfx/data_tx.h | 2 +- drivers/staging/wfx/debug.c | 12 +++-- drivers/staging/wfx/fwio.c| 23 drivers/staging/wfx/hif_api_cmd.h | 12 +++-- drivers/staging/wfx/hif_api_general.h | 17 +++--- drivers/staging/wfx/hif_api_mib.h | 2 +- drivers/staging/wfx/hif_rx.c | 17 +++--- drivers/staging/wfx/hif_tx.c | 32 ++- drivers/staging/wfx/hif_tx_mib.c | 4 +- drivers/staging/wfx/hwio.c| 6 +-- drivers/staging/wfx/hwio.h| 16 +++--- drivers/staging/wfx/key.c | 4 +- drivers/staging/wfx/main.c| 13 ++--- drivers/staging/wfx/queue.c | 27 +- drivers/staging/wfx/queue.h | 2 +- drivers/staging/wfx/sta.c | 78 ++- drivers/staging/wfx/sta.h | 6 +-- drivers/staging/wfx/traces.h | 2 +- drivers/staging/wfx/wfx.h | 2 +- 24 files changed, 203 insertions(+), 173 deletions(-) diff --git a/drivers/staging/wfx/bh.c b/drivers/staging/wfx/bh.c index 78fa81d82517..e2d2a64ce66e 100644 --- a/drivers/staging/wfx/bh.c +++ b/drivers/staging/wfx/bh.c @@ -32,18 +32,20 @@ static void device_wakeup(struct wfx_dev *wdev) } for (;;) { gpiod_set_value_cansleep(wdev->pdata.gpio_wakeup, 1); - // completion.h does not provide any function to wait - // completion without consume it (a kind of - // wait_for_completion_done_timeout()). So we have to emulate - // it. + /* completion.h does not provide any function to wait +* completion without consume it (a kind of +* wait_for_completion_done_timeout()). So we have to emulate +* it. +*/ if (wait_for_completion_timeout(&wdev->hif.ctrl_ready, msecs_to_jiffies(2))) { complete(&wdev->hif.ctrl_ready); return; } else if (max_retry-- > 0) { - // Older firmwares have a race in sleep/wake-up process. - // Redo the process is sufficient to unfreeze the - // chip. + /* Older firmwares have a race in sleep/wake-up process. +* Redo the process is sufficient to unfreeze the +* chip. +*/ dev_err(wdev->dev, "timeout while wake up chip\n"); gpiod_set_value_cansleep(wdev->pdata.gpio_wakeup, 0); usleep_range(2000, 2500); @@ -74,7 +76,7 @@ static int rx_helper(struct wfx_dev *wdev, size_t read_len, int *is_cnf) WARN(read_len > round_down(0xFFF, 2) * sizeof(u16), "%s: request exceed the chip capability", __func__); - // Add 2 to take into account piggyback size + /* Add 2 to take into account piggyback size */ alloc_len = wdev->hwbus_ops->align_size(wdev->hwbus_priv, read_len + 2); skb = dev_alloc_skb(alloc_len); if (!skb) diff --git a/drivers/staging/wfx/bus_sdio.c b/drivers/staging/wfx/bus_sdio.c index e06d7e1ebe9c..eb70bef6bd6e 100644 --- a/drivers/staging/wfx/bus_sdio.c +++ b/drivers/staging/wfx/bus_sdio.c @@ -67,7 +67,7 @@ static int wfx_sdio_copy_to_io(void *priv, unsigned int reg_id, /* Use queue mode buffers */ if (reg_id == WFX_REG_IN_OUT_QUEUE) sdio_addr |= bus->buf_id_tx << 7; - // FIXME: discards 'const' qualifier for src + /* FIXME: discards 'const' qualifier for src */ ret = sdio_memcpy_toio(bus->func, sdio_addr, (void *)src, count); if (!ret && reg_id == WFX_REG_IN_OUT_QUEUE) bus->buf_id_tx = (bus->buf_id_tx + 1) % 32; @@ -198,7 +198,7 @@ static int wfx_sdio_probe(struct sdio_func *func, } else { dev_warn(&func->dev, "device is not declared in DT, features will be limited\n"); - // FIXME: ignore VID/PID and only rely on device tree + /* FIXME: ignore VID/PID and only rely on device tree */ // return -ENODEV; } @@ -210,7 +210,7 @@ static int wfx_sdio_probe(struct sdio_func *func, sdio_claim_host(func); ret = sdio_enable_func(func); - // Block of 64 bytes is more efficient than 512B for frame sizes < 4k + /* Block of 64 bytes is more efficient than 512B for frame sizes <
[PATCH v2 30/33] staging: wfx: explain the purpose of wfx_send_pds()
From: Jérôme Pouiller On first look, the goal of wfx_send_pds() is not obvious. A small explanation is welcomed. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/main.c | 15 ++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/staging/wfx/main.c b/drivers/staging/wfx/main.c index 83292544b10a..4386e9957ee6 100644 --- a/drivers/staging/wfx/main.c +++ b/drivers/staging/wfx/main.c @@ -163,7 +163,20 @@ bool wfx_api_older_than(struct wfx_dev *wdev, int major, int minor) return false; } -/* NOTE: wfx_send_pds() destroy buf */ +/* The device needs data about the antenna configuration. This information in + * provided by PDS (Platform Data Set, this is the wording used in WF200 + * documentation) files. For hardware integrators, the full process to create + * PDS files is described here: + * https:github.com/SiliconLabs/wfx-firmware/blob/master/PDS/README.md + * + * So this function aims to send PDS to the device. However, the PDS file is + * often bigger than Rx buffers of the chip, so it has to be sent in multiple + * parts. + * + * In add, the PDS data cannot be split anywhere. The PDS files contains tree + * structures. Braces are used to enter/leave a level of the tree (in a JSON + * fashion). PDS files can only been split between root nodes. + */ int wfx_send_pds(struct wfx_dev *wdev, u8 *buf, size_t len) { int ret; -- 2.33.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 31/33] staging: wfx: indent functions arguments
From: Jérôme Pouiller Function arguments must be aligned with first argument. Apply that rule. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/hif_tx_mib.c | 2 +- drivers/staging/wfx/key.c| 26 +- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/staging/wfx/hif_tx_mib.c b/drivers/staging/wfx/hif_tx_mib.c index 45e531d996bd..97e961e6bcf6 100644 --- a/drivers/staging/wfx/hif_tx_mib.c +++ b/drivers/staging/wfx/hif_tx_mib.c @@ -75,7 +75,7 @@ int hif_get_counters_table(struct wfx_dev *wdev, int vif_id, } else { return hif_read_mib(wdev, vif_id, HIF_MIB_ID_EXTENDED_COUNTERS_TABLE, arg, - sizeof(struct hif_mib_extended_count_table)); + sizeof(struct hif_mib_extended_count_table)); } } diff --git a/drivers/staging/wfx/key.c b/drivers/staging/wfx/key.c index 51a528102016..65134a174683 100644 --- a/drivers/staging/wfx/key.c +++ b/drivers/staging/wfx/key.c @@ -31,7 +31,7 @@ static void wfx_free_key(struct wfx_dev *wdev, int idx) } static u8 fill_wep_pair(struct hif_wep_pairwise_key *msg, -struct ieee80211_key_conf *key, u8 *peer_addr) + struct ieee80211_key_conf *key, u8 *peer_addr) { WARN(key->keylen > sizeof(msg->key_data), "inconsistent data"); msg->key_length = key->keylen; @@ -41,7 +41,7 @@ static u8 fill_wep_pair(struct hif_wep_pairwise_key *msg, } static u8 fill_wep_group(struct hif_wep_group_key *msg, - struct ieee80211_key_conf *key) +struct ieee80211_key_conf *key) { WARN(key->keylen > sizeof(msg->key_data), "inconsistent data"); msg->key_id = key->keyidx; @@ -51,7 +51,7 @@ static u8 fill_wep_group(struct hif_wep_group_key *msg, } static u8 fill_tkip_pair(struct hif_tkip_pairwise_key *msg, - struct ieee80211_key_conf *key, u8 *peer_addr) +struct ieee80211_key_conf *key, u8 *peer_addr) { u8 *keybuf = key->key; @@ -68,9 +68,9 @@ static u8 fill_tkip_pair(struct hif_tkip_pairwise_key *msg, } static u8 fill_tkip_group(struct hif_tkip_group_key *msg, - struct ieee80211_key_conf *key, - struct ieee80211_key_seq *seq, - enum nl80211_iftype iftype) + struct ieee80211_key_conf *key, + struct ieee80211_key_seq *seq, + enum nl80211_iftype iftype) { u8 *keybuf = key->key; @@ -93,7 +93,7 @@ static u8 fill_tkip_group(struct hif_tkip_group_key *msg, } static u8 fill_ccmp_pair(struct hif_aes_pairwise_key *msg, - struct ieee80211_key_conf *key, u8 *peer_addr) +struct ieee80211_key_conf *key, u8 *peer_addr) { WARN(key->keylen != sizeof(msg->aes_key_data), "inconsistent data"); ether_addr_copy(msg->peer_address, peer_addr); @@ -102,8 +102,8 @@ static u8 fill_ccmp_pair(struct hif_aes_pairwise_key *msg, } static u8 fill_ccmp_group(struct hif_aes_group_key *msg, - struct ieee80211_key_conf *key, - struct ieee80211_key_seq *seq) + struct ieee80211_key_conf *key, + struct ieee80211_key_seq *seq) { WARN(key->keylen != sizeof(msg->aes_key_data), "inconsistent data"); memcpy(msg->aes_key_data, key->key, key->keylen); @@ -114,7 +114,7 @@ static u8 fill_ccmp_group(struct hif_aes_group_key *msg, } static u8 fill_sms4_pair(struct hif_wapi_pairwise_key *msg, - struct ieee80211_key_conf *key, u8 *peer_addr) +struct ieee80211_key_conf *key, u8 *peer_addr) { u8 *keybuf = key->key; @@ -129,7 +129,7 @@ static u8 fill_sms4_pair(struct hif_wapi_pairwise_key *msg, } static u8 fill_sms4_group(struct hif_wapi_group_key *msg, - struct ieee80211_key_conf *key) + struct ieee80211_key_conf *key) { u8 *keybuf = key->key; @@ -143,8 +143,8 @@ static u8 fill_sms4_group(struct hif_wapi_group_key *msg, } static u8 fill_aes_cmac_group(struct hif_igtk_group_key *msg, - struct ieee80211_key_conf *key, - struct ieee80211_key_seq *seq) + struct ieee80211_key_conf *key, + struct ieee80211_key_seq *seq) { WARN(key->keylen != sizeof(msg->igtk_key_data), "inconsistent data"); memcpy(msg->igtk_key_data, key->key, key->keylen); -- 2.33.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 32/33] staging: wfx: ensure IRQ is ready before enabling it
From: Jérôme Pouiller Since commit 5561770f80b1 ("staging: wfx: repair external IRQ for SDIO"), wfx_sdio_irq_subscribe() enforce the device to use IRQs. However, there is currently a race in this code. An IRQ may happen before the IRQ has been registered. The problem has observed during debug session when the device crashes before the IRQ set up: [ 1.546] wfx-sdio mmc0:0001:1: started firmware 3.12.2 "WF200_ASIC_WFM_(Jenkins)_FW3.12.2" (API: 3.7, keyset: C0, caps: 0x0002) [ 2.559] wfx-sdio mmc0:0001:1: time out while polling control register [ 3.565] wfx-sdio mmc0:0001:1: chip is abnormally long to answer [ 6.563] wfx-sdio mmc0:0001:1: chip did not answer [ 6.568] wfx-sdio mmc0:0001:1: hardware request CONFIGURATION (0x09) on vif 2 returned error -110 [ 6.577] wfx-sdio mmc0:0001:1: PDS bytes 0 to 12: chip didn't reply (corrupted file?) [ 6.585] Unable to handle kernel NULL pointer dereference at virtual address [ 6.592] pgd = c0004000 [ 6.595] [] *pgd= [ 6.598] Internal error: Oops - BUG: 17 [#1] THUMB2 [ 6.603] Modules linked in: [ 6.606] CPU: 0 PID: 23 Comm: kworker/u2:1 Not tainted 3.18.19 #78 [ 6.612] Workqueue: kmmcd mmc_rescan [ 6.616] task: c176d100 ti: c0e5 task.ti: c0e5 [ 6.621] PC is at wake_up_process+0xa/0x14 [ 6.625] LR is at sdio_irq+0x61/0x250 [ 6.629] pc : [] lr : [] psr: 61b3 [ 6.629] sp : c0e51bd8 ip : c0e51cc8 fp : 0001 [ 6.640] r10: 0003 r9 : r8 : c0003c34 [ 6.644] r7 : c0e51bd8 r6 : c0003c30 r5 : 0001 r4 : c0e78c00 [ 6.651] r3 : r2 : r1 : 0003 r0 : [ 6.657] Flags: nZCv IRQs off FIQs on Mode SVC_32 ISA Thumb Segment kernel [ 6.664] Control: 50c53c7d Table: 11fd8059 DAC: 0015 [ 6.670] Process kworker/u2:1 (pid: 23, stack limit = 0xc0e501b0) [ 6.676] Stack: (0xc0e51bd8 to 0xc0e52000) [...] [ 6.949] [] (wake_up_process) from [] (sdio_irq+0x61/0x250) [ 6.956] [] (sdio_irq) from [] (handle_irq_event_percpu+0x17/0x92) [ 6.964] [] (handle_irq_event_percpu) from [] (handle_irq_event+0x1b/0x24) [ 6.973] [] (handle_irq_event) from [] (handle_level_irq+0x5d/0x76) [ 6.981] [] (handle_level_irq) from [] (generic_handle_irq+0x13/0x1c) [ 6.989] [] (generic_handle_irq) from [] (__handle_domain_irq+0x31/0x48) [ 6.997] [] (__handle_domain_irq) from [] (ov_handle_irq+0x31/0xe0) [ 7.005] [] (ov_handle_irq) from [] (__irq_svc+0x3b/0x5c) [ 7.013] Exception stack(0xc0e51c68 to 0xc0e51cb0) [...] [ 7.038] [] (__irq_svc) from [] (wait_for_common+0x9e/0xc4) [ 7.045] [] (wait_for_common) from [] (mmc_wait_for_req+0x4b/0xdc) [ 7.053] [] (mmc_wait_for_req) from [] (mmc_wait_for_cmd+0x2f/0x34) [ 7.061] [] (mmc_wait_for_cmd) from [] (mmc_io_rw_direct_host+0x71/0xac) [ 7.070] [] (mmc_io_rw_direct_host) from [] (sdio_claim_irq+0x6b/0x116) [ 7.078] [] (sdio_claim_irq) from [] (wfx_sdio_irq_subscribe+0x19/0x94) [ 7.086] [] (wfx_sdio_irq_subscribe) from [] (wfx_probe+0x189/0x2ac) [ 7.095] [] (wfx_probe) from [] (wfx_sdio_probe+0x8f/0xcc) [ 7.102] [] (wfx_sdio_probe) from [] (sdio_bus_probe+0x5f/0xa8) [ 7.109] [] (sdio_bus_probe) from [] (driver_probe_device+0x59/0x134) [ 7.118] [] (driver_probe_device) from [] (bus_for_each_drv+0x3f/0x4a) [ 7.126] [] (bus_for_each_drv) from [] (device_attach+0x3b/0x52) [ 7.134] [] (device_attach) from [] (bus_probe_device+0x17/0x4c) [ 7.141] [] (bus_probe_device) from [] (device_add+0x2c5/0x334) [ 7.149] [] (device_add) from [] (sdio_add_func+0x23/0x44) [ 7.156] [] (sdio_add_func) from [] (mmc_attach_sdio+0x187/0x1ec) [ 7.164] [] (mmc_attach_sdio) from [] (mmc_rescan+0x18d/0x1fc) [ 7.172] [] (mmc_rescan) from [] (process_one_work+0xd7/0x170) [ 7.179] [] (process_one_work) from [] (worker_thread+0x103/0x1bc) [ 7.187] [] (worker_thread) from [] (kthread+0x7d/0x90) [ 7.194] [] (kthread) from [] (ret_from_fork+0x11/0x30) [ 7.201] Code: 2103 b580 2200 af00 (681b) 46bd [ 7.206] ---[ end trace 3ab50aced42eedb4 ]--- Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/bus_sdio.c | 21 - 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/drivers/staging/wfx/bus_sdio.c b/drivers/staging/wfx/bus_sdio.c index eb70bef6bd6e..a670176ba06f 100644 --- a/drivers/staging/wfx/bus_sdio.c +++ b/drivers/staging/wfx/bus_sdio.c @@ -120,19 +120,22 @@ static int wfx_sdio_irq_subscribe(void *priv) return ret; } - sdio_claim_host(bus->func); - cccr = sdio_f0_readb(bus->func, SDIO_CCCR_IENx, NULL); - cccr |= BIT(0); - cccr |= BIT(bus->func->num); - sdio_f0_writeb(bus->func, cccr, SDIO_CCCR_IENx, NULL); - sdio_release_host(bus->func); flags = irq_get_trigger_type(bus->of_irq); if (!flags) flags = IRQF_TRIGGER_HIGH; flags |
[PATCH v2 33/33] staging: wfx: early exit of PDS is not correct
From: Jérôme Pouiller If PDS data is not correct, the device is unlikely to work. Worse, the pinmux maybe it misconfigured and it can generate IRQ-storms. Therefore, do not try to start-up the device if PDS is invalid. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/main.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/staging/wfx/main.c b/drivers/staging/wfx/main.c index 4386e9957ee6..b24ff4b31b72 100644 --- a/drivers/staging/wfx/main.c +++ b/drivers/staging/wfx/main.c @@ -409,7 +409,9 @@ int wfx_probe(struct wfx_dev *wdev) dev_dbg(wdev->dev, "sending configuration file %s\n", wdev->pdata.file_pds); - wfx_send_pdata_pds(wdev); + err = wfx_send_pdata_pds(wdev); + if (err) + goto err0; wdev->poll_irq = false; err = wdev->hwbus_ops->irq_subscribe(wdev->hwbus_priv); -- 2.33.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v2 03/33] staging: wfx: ignore PS when STA/AP share same channel
On Mon, Sep 13, 2021 at 10:30:15AM +0200, Jerome Pouiller wrote: > diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c > index 5de9ccf02285..aff0559653bf 100644 > --- a/drivers/staging/wfx/sta.c > +++ b/drivers/staging/wfx/sta.c > @@ -154,18 +154,26 @@ static int wfx_get_ps_timeout(struct wfx_vif *wvif, > bool *enable_ps) > chan0 = wdev_to_wvif(wvif->wdev, 0)->vif->bss_conf.chandef.chan; > if (wdev_to_wvif(wvif->wdev, 1)) > chan1 = wdev_to_wvif(wvif->wdev, 1)->vif->bss_conf.chandef.chan; > - if (chan0 && chan1 && chan0->hw_value != chan1->hw_value && > - wvif->vif->type != NL80211_IFTYPE_AP) { > - // It is necessary to enable powersave if channels > - // are different. > - if (enable_ps) > - *enable_ps = true; > - if (wvif->wdev->force_ps_timeout > -1) > - return wvif->wdev->force_ps_timeout; > - else if (wfx_api_older_than(wvif->wdev, 3, 2)) > - return 0; > - else > - return 30; > + if (chan0 && chan1 && wvif->vif->type != NL80211_IFTYPE_AP) { > + if (chan0->hw_value == chan1->hw_value) { > + // It is useless to enable PS if channels are the same. > + if (enable_ps) > + *enable_ps = false; > + if (wvif->vif->bss_conf.assoc && wvif->vif->bss_conf.ps) > + dev_info(wvif->wdev->dev, "ignoring requested > PS mode"); > + return -1; I can't be happy about this -1 return or how it's handled in the caller. There is already a -1 return so it's not really a new bug, though... regards, dan carpenter ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v2 11/33] staging: wfx: relax the PDS existence constraint
On Mon, Sep 13, 2021 at 10:30:23AM +0200, Jerome Pouiller wrote: > @@ -395,9 +395,7 @@ int wfx_probe(struct wfx_dev *wdev) > > dev_dbg(wdev->dev, "sending configuration file %s\n", > wdev->pdata.file_pds); > - err = wfx_send_pdata_pds(wdev); > - if (err < 0) > - goto err0; > + wfx_send_pdata_pds(wdev); You revert this change in patch 33 so let's drop this and 33 both. regards, dan carpenter ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v2 12/33] staging: wfx: simplify API coherency check
On Mon, Sep 13, 2021 at 10:30:24AM +0200, Jerome Pouiller wrote: > From: Jérôme Pouiller > > The 'channel' argument of hif_join() should never be NULL. hif_join() > does not have the responsibility to recover bug of caller. A call to > WARN() at the beginning of the function reminds this constraint to the > developer. > > In current code, if the argument channel is NULL, memory leaks. The new > code just emit a warning and does not give the illusion that it is > supported (and indeed a Oops will probably raise a few lines below). > > Signed-off-by: Jérôme Pouiller > --- > drivers/staging/wfx/hif_tx.c | 3 +-- > 1 file changed, 1 insertion(+), 2 deletions(-) > > diff --git a/drivers/staging/wfx/hif_tx.c b/drivers/staging/wfx/hif_tx.c > index 14b7e047916e..6ffbae32028b 100644 > --- a/drivers/staging/wfx/hif_tx.c > +++ b/drivers/staging/wfx/hif_tx.c > @@ -299,10 +299,9 @@ int hif_join(struct wfx_vif *wvif, const struct > ieee80211_bss_conf *conf, > > WARN_ON(!conf->beacon_int); > WARN_ON(!conf->basic_rates); > + WARN_ON(!channel); This fine. I'm not trying to make people redo their patches especially when you're doing a great job as a maintainer. But generally these WARN_ON()s are pointless. It's never going to happen and if we try to handle all the thing which will not happen that's an impossible task. But specificically with NULL dereferences, the WARN() will generate a stack trace and also the Oops will generate a stack trace. It's duplicative. regards, dan carpenter ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v2 13/33] staging: wfx: update with the firmware API 3.8
On Mon, Sep 13, 2021 at 10:30:25AM +0200, Jerome Pouiller wrote: > From: Jérôme Pouiller > > The firmware API 3.8 introduces new statistic counters. These changes > are backward compatible. > > Signed-off-by: Jérôme Pouiller > --- > drivers/staging/wfx/debug.c | 3 +++ > drivers/staging/wfx/hif_api_mib.h | 5 - > 2 files changed, 7 insertions(+), 1 deletion(-) > > diff --git a/drivers/staging/wfx/debug.c b/drivers/staging/wfx/debug.c > index eedada78c25f..e67ca0d818ba 100644 > --- a/drivers/staging/wfx/debug.c > +++ b/drivers/staging/wfx/debug.c > @@ -109,6 +109,9 @@ static int wfx_counters_show(struct seq_file *seq, void > *v) > > PUT_COUNTER(rx_beacon); > PUT_COUNTER(miss_beacon); > + PUT_COUNTER(rx_dtim); > + PUT_COUNTER(rx_dtim_aid0_clr); > + PUT_COUNTER(rx_dtim_aid0_set); > > #undef PUT_COUNTER Not related to the patch but the PUT_COUNTER macro should be called something like PRINT_COUNTER. It's not a get/put API. regards, dan carpenter ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v2 03/33] staging: wfx: ignore PS when STA/AP share same channel
On Monday 13 September 2021 11:33:28 CEST Dan Carpenter wrote: > On Mon, Sep 13, 2021 at 10:30:15AM +0200, Jerome Pouiller wrote: > > diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c > > index 5de9ccf02285..aff0559653bf 100644 > > --- a/drivers/staging/wfx/sta.c > > +++ b/drivers/staging/wfx/sta.c > > @@ -154,18 +154,26 @@ static int wfx_get_ps_timeout(struct wfx_vif *wvif, > > bool *enable_ps) > > chan0 = wdev_to_wvif(wvif->wdev, > > 0)->vif->bss_conf.chandef.chan; > > if (wdev_to_wvif(wvif->wdev, 1)) > > chan1 = wdev_to_wvif(wvif->wdev, > > 1)->vif->bss_conf.chandef.chan; > > - if (chan0 && chan1 && chan0->hw_value != chan1->hw_value && > > - wvif->vif->type != NL80211_IFTYPE_AP) { > > - // It is necessary to enable powersave if channels > > - // are different. > > - if (enable_ps) > > - *enable_ps = true; > > - if (wvif->wdev->force_ps_timeout > -1) > > - return wvif->wdev->force_ps_timeout; > > - else if (wfx_api_older_than(wvif->wdev, 3, 2)) > > - return 0; > > - else > > - return 30; > > + if (chan0 && chan1 && wvif->vif->type != NL80211_IFTYPE_AP) { > > + if (chan0->hw_value == chan1->hw_value) { > > + // It is useless to enable PS if channels are the > > same. > > + if (enable_ps) > > + *enable_ps = false; > > + if (wvif->vif->bss_conf.assoc && > > wvif->vif->bss_conf.ps) > > + dev_info(wvif->wdev->dev, "ignoring requested > > PS mode"); > > + return -1; > > I can't be happy about this -1 return or how it's handled in the caller. > There is already a -1 return so it's not really a new bug, though... I see what you mean. However, I remember it is easy to break things here and I don't want to change that in a rush. So, I would prefer to solve that in a further PR. -- Jérôme Pouiller ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v2 03/33] staging: wfx: ignore PS when STA/AP share same channel
On Mon, Sep 13, 2021 at 12:36:25PM +0200, Jérôme Pouiller wrote: > On Monday 13 September 2021 11:33:28 CEST Dan Carpenter wrote: > > On Mon, Sep 13, 2021 at 10:30:15AM +0200, Jerome Pouiller wrote: > > > diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c > > > index 5de9ccf02285..aff0559653bf 100644 > > > --- a/drivers/staging/wfx/sta.c > > > +++ b/drivers/staging/wfx/sta.c > > > @@ -154,18 +154,26 @@ static int wfx_get_ps_timeout(struct wfx_vif *wvif, > > > bool *enable_ps) > > > chan0 = wdev_to_wvif(wvif->wdev, > > > 0)->vif->bss_conf.chandef.chan; > > > if (wdev_to_wvif(wvif->wdev, 1)) > > > chan1 = wdev_to_wvif(wvif->wdev, > > > 1)->vif->bss_conf.chandef.chan; > > > - if (chan0 && chan1 && chan0->hw_value != chan1->hw_value && > > > - wvif->vif->type != NL80211_IFTYPE_AP) { > > > - // It is necessary to enable powersave if channels > > > - // are different. > > > - if (enable_ps) > > > - *enable_ps = true; > > > - if (wvif->wdev->force_ps_timeout > -1) > > > - return wvif->wdev->force_ps_timeout; > > > - else if (wfx_api_older_than(wvif->wdev, 3, 2)) > > > - return 0; > > > - else > > > - return 30; > > > + if (chan0 && chan1 && wvif->vif->type != NL80211_IFTYPE_AP) { > > > + if (chan0->hw_value == chan1->hw_value) { > > > + // It is useless to enable PS if channels are the > > > same. > > > + if (enable_ps) > > > + *enable_ps = false; > > > + if (wvif->vif->bss_conf.assoc && > > > wvif->vif->bss_conf.ps) > > > + dev_info(wvif->wdev->dev, "ignoring > > > requested PS mode"); > > > + return -1; > > > > I can't be happy about this -1 return or how it's handled in the caller. > > There is already a -1 return so it's not really a new bug, though... > > I see what you mean. However, I remember it is easy to break things > here and I don't want to change that in a rush. So, I would prefer to > solve that in a further PR. Yes. That's fine. The return -1 was already there. regards, dan carpenter ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v3 01/32] staging: wfx: use abbreviated message for "incorrect sequence"
From: Jérôme Pouiller The wfx driver checks carefully the coherency of of the DTIM notifications. We have noticed several times some small inconsistencies from the firmware on these notification. They have never been critical. However on the driver side they lead to big fat warnings. Worse, if these warning are displayed on UART console, they can be long to display (several hundreds of millisecs). Since, this warning is generated from a work queue, it can delay all the workqueue users. Especially, it can drastically slow down the frame management of the driver and then generate errors that are serious this time (eg. an overflow of the indication queue of the device). Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/sta.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c index cb7e8abdf43c..a236e5bb6914 100644 --- a/drivers/staging/wfx/sta.c +++ b/drivers/staging/wfx/sta.c @@ -631,8 +631,9 @@ void wfx_suspend_resume_mc(struct wfx_vif *wvif, enum sta_notify_cmd notify_cmd) { if (notify_cmd != STA_NOTIFY_AWAKE) return; - WARN(!wfx_tx_queues_has_cab(wvif), "incorrect sequence"); - WARN(wvif->after_dtim_tx_allowed, "incorrect sequence"); + if (!wfx_tx_queues_has_cab(wvif) || wvif->after_dtim_tx_allowed) + dev_warn(wvif->wdev->dev, "incorrect sequence (%d CAB in queue)", +wfx_tx_queues_has_cab(wvif)); wvif->after_dtim_tx_allowed = true; wfx_bh_request_tx(wvif->wdev); } -- 2.33.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v3 00/32] staging/wfx: usual maintenance
From: Jérôme Pouiller Hi, The following PR contains now usual maintenance for the wfx driver. I have more-or-less sorted the patches by importance: - the first ones and the two last ones are fixes for a few corner-cases reported by users - the patches 9 and 10 add support for CSA and TDLS - then the end of the series is mostly cosmetics and nitpicking I have wait longer than I initially wanted before to send this PR. It is because didn't want to conflict with the PR currently in review[1] to relocate this driver into the main tree. However, this PR started to be very large and nothing seems to move on main-tree side so I decided to not wait longer. Kalle, I am going to send a new version of [1] as soon as this PR will be accepted. I hope you will have time to review it one day :-). [1] https://lore.kernel.org/all/20210315132501.441681-1-jerome.pouil...@silabs.com/ v3: - Fix patch 11 and drop patch 33 (Dan) - Fix one missing C99 comment - Drop useless WARN_ON() (Dan) v2: - Add patches 32 and 33 to solve a possible race when device is misconfigured - Fix C99 comments (Kari) - Replace "API 3.8" by "firmware API 3.8" (Kari) - Fix wording "aligned with first argument" instead of "aligned with opening parenthesis" Jérôme Pouiller (32): staging: wfx: use abbreviated message for "incorrect sequence" staging: wfx: do not send CAB while scanning staging: wfx: ignore PS when STA/AP share same channel staging: wfx: wait for SCAN_CMPL after a SCAN_STOP staging: wfx: avoid possible lock-up during scan staging: wfx: drop unused argument from hif_scan() staging: wfx: fix atomic accesses in wfx_tx_queue_empty() staging: wfx: take advantage of wfx_tx_queue_empty() staging: wfx: declare support for TDLS staging: wfx: fix support for CSA staging: wfx: relax the PDS existence constraint staging: wfx: simplify API coherency check staging: wfx: update with the firmware API 3.8 staging: wfx: uniformize counter names staging: wfx: fix misleading 'rate_id' usage staging: wfx: declare variables at beginning of functions staging: wfx: simplify hif_join() staging: wfx: reorder function for slightly better eye candy staging: wfx: fix error names staging: wfx: apply naming rules in hif_tx_mib.c staging: wfx: remove unused definition staging: wfx: remove useless debug statement staging: wfx: fix space after cast operator staging: wfx: remove references to WFxxx in comments staging: wfx: update files descriptions staging: wfx: reformat comment staging: wfx: avoid c99 comments staging: wfx: fix comments styles staging: wfx: remove useless comments after #endif staging: wfx: explain the purpose of wfx_send_pds() staging: wfx: indent functions arguments staging: wfx: ensure IRQ is ready before enabling it drivers/staging/wfx/bh.c | 37 --- drivers/staging/wfx/bh.h | 4 +- drivers/staging/wfx/bus_sdio.c| 29 +++--- drivers/staging/wfx/bus_spi.c | 22 ++--- drivers/staging/wfx/data_rx.c | 7 +- drivers/staging/wfx/data_rx.h | 4 +- drivers/staging/wfx/data_tx.c | 87 + drivers/staging/wfx/data_tx.h | 6 +- drivers/staging/wfx/debug.c | 54 ++- drivers/staging/wfx/debug.h | 2 +- drivers/staging/wfx/fwio.c| 26 ++--- drivers/staging/wfx/fwio.h| 2 +- drivers/staging/wfx/hif_api_cmd.h | 14 +-- drivers/staging/wfx/hif_api_general.h | 25 ++--- drivers/staging/wfx/hif_api_mib.h | 85 drivers/staging/wfx/hif_rx.c | 23 ++--- drivers/staging/wfx/hif_rx.h | 3 +- drivers/staging/wfx/hif_tx.c | 60 +--- drivers/staging/wfx/hif_tx.h | 6 +- drivers/staging/wfx/hif_tx_mib.c | 14 +-- drivers/staging/wfx/hif_tx_mib.h | 2 +- drivers/staging/wfx/hwio.c| 6 +- drivers/staging/wfx/hwio.h| 20 ++-- drivers/staging/wfx/key.c | 30 +++--- drivers/staging/wfx/key.h | 4 +- drivers/staging/wfx/main.c| 37 +-- drivers/staging/wfx/main.h| 3 +- drivers/staging/wfx/queue.c | 43 drivers/staging/wfx/queue.h | 6 +- drivers/staging/wfx/scan.c| 55 +++ drivers/staging/wfx/scan.h| 4 +- drivers/staging/wfx/sta.c | 135 +++--- drivers/staging/wfx/sta.h | 8 +- drivers/staging/wfx/traces.h | 2 +- drivers/staging/wfx/wfx.h | 14 ++- 35 files changed, 470 insertions(+), 409 deletions(-) -- 2.33.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v3 02/32] staging: wfx: do not send CAB while scanning
From: Jérôme Pouiller During the scan requests, the Tx traffic is suspended. This lock is shared by all the network interfaces. So, a scan request on one interface will block the traffic on a second interface. This causes trouble when the queued traffic contains CAB (Content After DTIM Beacon) since this traffic cannot be delayed. It could be possible to make the lock local to each interface. But It would only push the problem further. The device won't be able to send the CAB before the end of the scan. So, this patch just ignore the DTIM indication when a scan is in progress. The firmware will send another indication on the next DTIM and this time the system will be able to send the traffic just behind the beacon. The only drawback of this solution is that the stations connected to the AP will wait for traffic after the DTIM for nothing. But since the case is really rare it is not a big deal. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/sta.c | 11 +++ 1 file changed, 11 insertions(+) diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c index a236e5bb6914..5de9ccf02285 100644 --- a/drivers/staging/wfx/sta.c +++ b/drivers/staging/wfx/sta.c @@ -629,8 +629,19 @@ int wfx_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set) void wfx_suspend_resume_mc(struct wfx_vif *wvif, enum sta_notify_cmd notify_cmd) { + struct wfx_vif *wvif_it; + if (notify_cmd != STA_NOTIFY_AWAKE) return; + + /* Device won't be able to honor CAB if a scan is in progress on any +* interface. Prefer to skip this DTIM and wait for the next one. +*/ + wvif_it = NULL; + while ((wvif_it = wvif_iterate(wvif->wdev, wvif_it)) != NULL) + if (mutex_is_locked(&wvif_it->scan_lock)) + return; + if (!wfx_tx_queues_has_cab(wvif) || wvif->after_dtim_tx_allowed) dev_warn(wvif->wdev->dev, "incorrect sequence (%d CAB in queue)", wfx_tx_queues_has_cab(wvif)); -- 2.33.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v3 03/32] staging: wfx: ignore PS when STA/AP share same channel
From: Jérôme Pouiller When multiple interface are in use. One is always AP while the other is always station. When the two interface use the same channel, it makes no sense to enabled Power Saving (PS) on the station. Indeed, because of the AP, the device will be kept awake on this channel anyway. In add, when multiple interface are in use, mac80211 does not update the PS information and delegate to the driver responsibility to do the right thing. Thus, in the current code, when the user enable PS in this configuration, the driver finally enable PS-Poll which is probably not what the user expected. This patch detect this case and applies a sane configuration in all cases. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/sta.c | 32 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c index 5de9ccf02285..aff0559653bf 100644 --- a/drivers/staging/wfx/sta.c +++ b/drivers/staging/wfx/sta.c @@ -154,18 +154,26 @@ static int wfx_get_ps_timeout(struct wfx_vif *wvif, bool *enable_ps) chan0 = wdev_to_wvif(wvif->wdev, 0)->vif->bss_conf.chandef.chan; if (wdev_to_wvif(wvif->wdev, 1)) chan1 = wdev_to_wvif(wvif->wdev, 1)->vif->bss_conf.chandef.chan; - if (chan0 && chan1 && chan0->hw_value != chan1->hw_value && - wvif->vif->type != NL80211_IFTYPE_AP) { - // It is necessary to enable powersave if channels - // are different. - if (enable_ps) - *enable_ps = true; - if (wvif->wdev->force_ps_timeout > -1) - return wvif->wdev->force_ps_timeout; - else if (wfx_api_older_than(wvif->wdev, 3, 2)) - return 0; - else - return 30; + if (chan0 && chan1 && wvif->vif->type != NL80211_IFTYPE_AP) { + if (chan0->hw_value == chan1->hw_value) { + // It is useless to enable PS if channels are the same. + if (enable_ps) + *enable_ps = false; + if (wvif->vif->bss_conf.assoc && wvif->vif->bss_conf.ps) + dev_info(wvif->wdev->dev, "ignoring requested PS mode"); + return -1; + } else { + // It is necessary to enable PS if channels + // are different. + if (enable_ps) + *enable_ps = true; + if (wvif->wdev->force_ps_timeout > -1) + return wvif->wdev->force_ps_timeout; + else if (wfx_api_older_than(wvif->wdev, 3, 2)) + return 0; + else + return 30; + } } if (enable_ps) *enable_ps = wvif->vif->bss_conf.ps; -- 2.33.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v3 04/32] staging: wfx: wait for SCAN_CMPL after a SCAN_STOP
From: Jérôme Pouiller When the device has finished a scan request, it send a scan complete ("SCAN_COMPL") indication. It is also possible to abort a scan request with a "SCAN_STOP" message. A SCAN_COMPL is also send in this case. The driver limits the delay to make a scan request. A timeout happens almost never but is theoretically possible. Currently, if it happens the driver does not wait for the SCAN_COMPL. Then, when the driver starts the next scan request, the device may return -EBUSY (scan requests often occur back-to-back). This patch give a chance to the device to send a SCAN_COMPL after a scan timeout. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/scan.c | 24 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/drivers/staging/wfx/scan.c b/drivers/staging/wfx/scan.c index fb47c7cddf2f..1e03b130049b 100644 --- a/drivers/staging/wfx/scan.c +++ b/drivers/staging/wfx/scan.c @@ -58,23 +58,31 @@ static int send_scan_req(struct wfx_vif *wvif, reinit_completion(&wvif->scan_complete); ret = hif_scan(wvif, req, start_idx, i - start_idx, &timeout); if (ret) { - wfx_tx_unlock(wvif->wdev); - return -EIO; + ret = -EIO; + goto err_scan_start; } ret = wait_for_completion_timeout(&wvif->scan_complete, timeout); - if (req->channels[start_idx]->max_power != wvif->vif->bss_conf.txpower) - hif_set_output_power(wvif, wvif->vif->bss_conf.txpower); - wfx_tx_unlock(wvif->wdev); if (!ret) { dev_notice(wvif->wdev->dev, "scan timeout\n"); hif_stop_scan(wvif); - return -ETIMEDOUT; + ret = wait_for_completion_timeout(&wvif->scan_complete, 1 * HZ); + if (!ret) + dev_err(wvif->wdev->dev, "scan didn't stop\n"); + ret = -ETIMEDOUT; + goto err_timeout; } if (wvif->scan_abort) { dev_notice(wvif->wdev->dev, "scan abort\n"); - return -ECONNABORTED; + ret = -ECONNABORTED; + goto err_timeout; } - return i - start_idx; + ret = i - start_idx; +err_timeout: + if (req->channels[start_idx]->max_power != wvif->vif->bss_conf.txpower) + hif_set_output_power(wvif, wvif->vif->bss_conf.txpower); +err_scan_start: + wfx_tx_unlock(wvif->wdev); + return ret; } /* -- 2.33.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v3 05/32] staging: wfx: avoid possible lock-up during scan
From: Jérôme Pouiller If the environment is noisy, the device may take time to send scan requests. Thus, scan requests durations > 5s have already been observed. During the scan, traffic is neither received, neither sent. From the user point-of-view, the traffic is frozen for a long time. This patch reworks the scan processing. It gives to the device a smaller time budget than previously. However, it does not expect the scan to be complete and it is able to send another scan request to finish the work. A big part of the patch aims to avoid an infinite loop if the device goes crazy. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/hif_rx.c | 3 ++- drivers/staging/wfx/scan.c | 48 ++-- drivers/staging/wfx/scan.h | 2 +- drivers/staging/wfx/wfx.h| 1 + 4 files changed, 33 insertions(+), 21 deletions(-) diff --git a/drivers/staging/wfx/hif_rx.c b/drivers/staging/wfx/hif_rx.c index 9fca7f26372a..a60c4a4ba935 100644 --- a/drivers/staging/wfx/hif_rx.c +++ b/drivers/staging/wfx/hif_rx.c @@ -175,13 +175,14 @@ static int hif_scan_complete_indication(struct wfx_dev *wdev, const void *buf) { struct wfx_vif *wvif = wdev_to_wvif(wdev, hif->interface); + const struct hif_ind_scan_cmpl *body = buf; if (!wvif) { dev_warn(wdev->dev, "%s: received event for non-existent vif\n", __func__); return -EIO; } - wfx_scan_complete(wvif); + wfx_scan_complete(wvif, body->num_channels_completed); return 0; } diff --git a/drivers/staging/wfx/scan.c b/drivers/staging/wfx/scan.c index 1e03b130049b..695b06974194 100644 --- a/drivers/staging/wfx/scan.c +++ b/drivers/staging/wfx/scan.c @@ -41,7 +41,7 @@ static int update_probe_tmpl(struct wfx_vif *wvif, static int send_scan_req(struct wfx_vif *wvif, struct cfg80211_scan_request *req, int start_idx) { - int i, ret, timeout; + int i, ret; struct ieee80211_channel *ch_start, *ch_cur; for (i = start_idx; i < req->n_channels; i++) { @@ -56,31 +56,31 @@ static int send_scan_req(struct wfx_vif *wvif, wfx_tx_lock_flush(wvif->wdev); wvif->scan_abort = false; reinit_completion(&wvif->scan_complete); - ret = hif_scan(wvif, req, start_idx, i - start_idx, &timeout); + ret = hif_scan(wvif, req, start_idx, i - start_idx, NULL); if (ret) { - ret = -EIO; - goto err_scan_start; + wfx_tx_unlock(wvif->wdev); + return -EIO; } - ret = wait_for_completion_timeout(&wvif->scan_complete, timeout); + ret = wait_for_completion_timeout(&wvif->scan_complete, 1 * HZ); if (!ret) { - dev_notice(wvif->wdev->dev, "scan timeout\n"); hif_stop_scan(wvif); ret = wait_for_completion_timeout(&wvif->scan_complete, 1 * HZ); - if (!ret) - dev_err(wvif->wdev->dev, "scan didn't stop\n"); + dev_dbg(wvif->wdev->dev, "scan timeout (%d channels done)\n", + wvif->scan_nb_chan_done); + } + if (!ret) { + dev_err(wvif->wdev->dev, "scan didn't stop\n"); ret = -ETIMEDOUT; - goto err_timeout; - } - if (wvif->scan_abort) { + } else if (wvif->scan_abort) { dev_notice(wvif->wdev->dev, "scan abort\n"); ret = -ECONNABORTED; - goto err_timeout; + } else if (wvif->scan_nb_chan_done > i - start_idx) { + ret = -EIO; + } else { + ret = wvif->scan_nb_chan_done; } - ret = i - start_idx; -err_timeout: if (req->channels[start_idx]->max_power != wvif->vif->bss_conf.txpower) hif_set_output_power(wvif, wvif->vif->bss_conf.txpower); -err_scan_start: wfx_tx_unlock(wvif->wdev); return ret; } @@ -94,7 +94,7 @@ void wfx_hw_scan_work(struct work_struct *work) { struct wfx_vif *wvif = container_of(work, struct wfx_vif, scan_work); struct ieee80211_scan_request *hw_req = wvif->scan_req; - int chan_cur, ret; + int chan_cur, ret, err; mutex_lock(&wvif->wdev->conf_mutex); mutex_lock(&wvif->scan_lock); @@ -105,11 +105,20 @@ void wfx_hw_scan_work(struct work_struct *work) } update_probe_tmpl(wvif, &hw_req->req); chan_cur = 0; + err = 0; do { ret = send_scan_req(wvif, &hw_req->req, chan_cur); - if (ret > 0) + if (ret > 0) { chan_cur += ret; - } while (ret > 0 && chan_cur < hw_req->req.n_channels); + err = 0; + } + if (!ret) + err++; + if (err > 2) { + dev_err(wvif->wdev->dev, "scan has not been able to start\n"); +
[PATCH v3 06/32] staging: wfx: drop unused argument from hif_scan()
From: Jérôme Pouiller It is no more necessary to compute the expected duration of the scan request. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/hif_tx.c | 9 + drivers/staging/wfx/hif_tx.h | 2 +- drivers/staging/wfx/scan.c | 2 +- 3 files changed, 3 insertions(+), 10 deletions(-) diff --git a/drivers/staging/wfx/hif_tx.c b/drivers/staging/wfx/hif_tx.c index 63b437261eb7..14b7e047916e 100644 --- a/drivers/staging/wfx/hif_tx.c +++ b/drivers/staging/wfx/hif_tx.c @@ -227,14 +227,13 @@ int hif_write_mib(struct wfx_dev *wdev, int vif_id, u16 mib_id, } int hif_scan(struct wfx_vif *wvif, struct cfg80211_scan_request *req, -int chan_start_idx, int chan_num, int *timeout) +int chan_start_idx, int chan_num) { int ret, i; struct hif_msg *hif; size_t buf_len = sizeof(struct hif_req_start_scan_alt) + chan_num * sizeof(u8); struct hif_req_start_scan_alt *body = wfx_alloc_hif(buf_len, &hif); - int tmo_chan_fg, tmo_chan_bg, tmo; WARN(chan_num > HIF_API_MAX_NB_CHANNELS, "invalid params"); WARN(req->n_ssids > HIF_API_MAX_NB_SSIDS, "invalid params"); @@ -269,12 +268,6 @@ int hif_scan(struct wfx_vif *wvif, struct cfg80211_scan_request *req, body->num_of_probe_requests = 2; body->probe_delay = 100; } - tmo_chan_bg = le32_to_cpu(body->max_channel_time) * USEC_PER_TU; - tmo_chan_fg = 512 * USEC_PER_TU + body->probe_delay; - tmo_chan_fg *= body->num_of_probe_requests; - tmo = chan_num * max(tmo_chan_bg, tmo_chan_fg) + 512 * USEC_PER_TU; - if (timeout) - *timeout = usecs_to_jiffies(tmo); wfx_fill_header(hif, wvif->id, HIF_REQ_ID_START_SCAN, buf_len); ret = wfx_cmd_send(wvif->wdev, hif, NULL, 0, false); diff --git a/drivers/staging/wfx/hif_tx.h b/drivers/staging/wfx/hif_tx.h index 3521c545ae6b..46eed6cfa247 100644 --- a/drivers/staging/wfx/hif_tx.h +++ b/drivers/staging/wfx/hif_tx.h @@ -40,7 +40,7 @@ int hif_read_mib(struct wfx_dev *wdev, int vif_id, u16 mib_id, int hif_write_mib(struct wfx_dev *wdev, int vif_id, u16 mib_id, void *buf, size_t buf_size); int hif_scan(struct wfx_vif *wvif, struct cfg80211_scan_request *req80211, -int chan_start, int chan_num, int *timeout); +int chan_start, int chan_num); int hif_stop_scan(struct wfx_vif *wvif); int hif_join(struct wfx_vif *wvif, const struct ieee80211_bss_conf *conf, struct ieee80211_channel *channel, const u8 *ssid, int ssidlen); diff --git a/drivers/staging/wfx/scan.c b/drivers/staging/wfx/scan.c index 695b06974194..9e2d08317c9e 100644 --- a/drivers/staging/wfx/scan.c +++ b/drivers/staging/wfx/scan.c @@ -56,7 +56,7 @@ static int send_scan_req(struct wfx_vif *wvif, wfx_tx_lock_flush(wvif->wdev); wvif->scan_abort = false; reinit_completion(&wvif->scan_complete); - ret = hif_scan(wvif, req, start_idx, i - start_idx, NULL); + ret = hif_scan(wvif, req, start_idx, i - start_idx); if (ret) { wfx_tx_unlock(wvif->wdev); return -EIO; -- 2.33.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v3 07/32] staging: wfx: fix atomic accesses in wfx_tx_queue_empty()
From: Jérôme Pouiller Checking if a skb_queue is empty is not an atomic operation. We should take some precautions to do it. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/queue.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/wfx/queue.c b/drivers/staging/wfx/queue.c index 31c37f69c295..fa272c120f1c 100644 --- a/drivers/staging/wfx/queue.c +++ b/drivers/staging/wfx/queue.c @@ -86,7 +86,8 @@ void wfx_tx_queues_check_empty(struct wfx_vif *wvif) bool wfx_tx_queue_empty(struct wfx_vif *wvif, struct wfx_queue *queue) { - return skb_queue_empty(&queue->normal) && skb_queue_empty(&queue->cab); + return skb_queue_empty_lockless(&queue->normal) && + skb_queue_empty_lockless(&queue->cab); } static void __wfx_tx_queue_drop(struct wfx_vif *wvif, -- 2.33.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v3 08/32] staging: wfx: take advantage of wfx_tx_queue_empty()
From: Jérôme Pouiller wfx_tx_queues_check_empty() can be slightly simplified by calling wfx_tx_queue_empty(). Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/queue.c | 21 ++--- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/drivers/staging/wfx/queue.c b/drivers/staging/wfx/queue.c index fa272c120f1c..0ab207237d9f 100644 --- a/drivers/staging/wfx/queue.c +++ b/drivers/staging/wfx/queue.c @@ -73,23 +73,22 @@ void wfx_tx_queues_init(struct wfx_vif *wvif) } } -void wfx_tx_queues_check_empty(struct wfx_vif *wvif) -{ - int i; - - for (i = 0; i < IEEE80211_NUM_ACS; ++i) { - WARN_ON(atomic_read(&wvif->tx_queue[i].pending_frames)); - WARN_ON(!skb_queue_empty_lockless(&wvif->tx_queue[i].normal)); - WARN_ON(!skb_queue_empty_lockless(&wvif->tx_queue[i].cab)); - } -} - bool wfx_tx_queue_empty(struct wfx_vif *wvif, struct wfx_queue *queue) { return skb_queue_empty_lockless(&queue->normal) && skb_queue_empty_lockless(&queue->cab); } +void wfx_tx_queues_check_empty(struct wfx_vif *wvif) +{ + int i; + + for (i = 0; i < IEEE80211_NUM_ACS; ++i) { + WARN_ON(atomic_read(&wvif->tx_queue[i].pending_frames)); + WARN_ON(!wfx_tx_queue_empty(wvif, &wvif->tx_queue[i])); + } +} + static void __wfx_tx_queue_drop(struct wfx_vif *wvif, struct sk_buff_head *skb_queue, struct sk_buff_head *dropped) -- 2.33.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v3 09/32] staging: wfx: declare support for TDLS
From: Jérôme Pouiller Since the firmware API 3.8, the device is able to support TDLS. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/main.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/staging/wfx/main.c b/drivers/staging/wfx/main.c index 4b9fdf99981b..0a9d02d1af2f 100644 --- a/drivers/staging/wfx/main.c +++ b/drivers/staging/wfx/main.c @@ -440,6 +440,9 @@ int wfx_probe(struct wfx_dev *wdev) wdev->hw->wiphy->n_addresses = ARRAY_SIZE(wdev->addresses); wdev->hw->wiphy->addresses = wdev->addresses; + if (!wfx_api_older_than(wdev, 3, 8)) + wdev->hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS; + err = ieee80211_register_hw(wdev->hw); if (err) goto err1; -- 2.33.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v3 10/32] staging: wfx: fix support for CSA
From: Jérôme Pouiller The WF200 is able to filter beacons. However, it uses a positive filter: any change to an IE not listed won't be reported. In current code, the changes in Channel Switch Announcement (CSA) are not reported to the host. Thus, it fixes the support for CSA in station mode. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/sta.c | 7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c index aff0559653bf..5f2f8900ce99 100644 --- a/drivers/staging/wfx/sta.c +++ b/drivers/staging/wfx/sta.c @@ -80,13 +80,18 @@ static void wfx_filter_beacon(struct wfx_vif *wvif, bool filter_beacon) .has_changed = 1, .no_longer= 1, .has_appeared = 1, + }, { + .ie_id= WLAN_EID_CHANNEL_SWITCH, + .has_changed = 1, + .no_longer= 1, + .has_appeared = 1, } }; if (!filter_beacon) { hif_beacon_filter_control(wvif, 0, 1); } else { - hif_set_beacon_filter_table(wvif, 3, filter_ies); + hif_set_beacon_filter_table(wvif, ARRAY_SIZE(filter_ies), filter_ies); hif_beacon_filter_control(wvif, HIF_BEACON_FILTER_ENABLE, 0); } } -- 2.33.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v3 11/32] staging: wfx: relax the PDS existence constraint
From: Jérôme Pouiller The PDS file contains antenna parameters. The file is specific to each hardware design. Normally, the board designer should add a line in the of_device_id table with his own antenna parameters. Until, now the absence of PDS file is a hard fatal error. However, during the development, in most of the cases, an empty PDS file is sufficient to start WiFi communication. This patch keep an error, but allow the user to play with the device. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/wfx/main.c b/drivers/staging/wfx/main.c index 0a9d02d1af2f..2a759f3554c9 100644 --- a/drivers/staging/wfx/main.c +++ b/drivers/staging/wfx/main.c @@ -220,7 +220,7 @@ static int wfx_send_pdata_pds(struct wfx_dev *wdev) ret = request_firmware(&pds, wdev->pdata.file_pds, wdev->dev); if (ret) { - dev_err(wdev->dev, "can't load PDS file %s\n", + dev_err(wdev->dev, "can't load antenna parameters (PDS file %s). The device may be unstable.\n", wdev->pdata.file_pds); goto err1; } @@ -396,7 +396,7 @@ int wfx_probe(struct wfx_dev *wdev) dev_dbg(wdev->dev, "sending configuration file %s\n", wdev->pdata.file_pds); err = wfx_send_pdata_pds(wdev); - if (err < 0) + if (err < 0 && err != -ENOENT) goto err0; wdev->poll_irq = false; -- 2.33.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v3 12/32] staging: wfx: simplify API coherency check
From: Jérôme Pouiller The 'channel' argument of hif_join() should never be NULL. hif_join() does not have the responsibility to recover bug of caller. In current code, if the argument channel is NULL, memory leaks. The new code just emit a warning and does not give the illusion that it is supported (and indeed a Oops will probably raise a few lines below). Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/hif_tx.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/wfx/hif_tx.c b/drivers/staging/wfx/hif_tx.c index 14b7e047916e..fcce78bb3005 100644 --- a/drivers/staging/wfx/hif_tx.c +++ b/drivers/staging/wfx/hif_tx.c @@ -301,8 +301,6 @@ int hif_join(struct wfx_vif *wvif, const struct ieee80211_bss_conf *conf, WARN_ON(!conf->basic_rates); WARN_ON(sizeof(body->ssid) < ssidlen); WARN(!conf->ibss_joined && !ssidlen, "joining an unknown BSS"); - if (WARN_ON(!channel)) - return -EINVAL; if (!hif) return -ENOMEM; body->infrastructure_bss_mode = !conf->ibss_joined; -- 2.33.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v3 13/32] staging: wfx: update with the firmware API 3.8
From: Jérôme Pouiller The firmware API 3.8 introduces new statistic counters. These changes are backward compatible. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/debug.c | 3 +++ drivers/staging/wfx/hif_api_mib.h | 5 - 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/staging/wfx/debug.c b/drivers/staging/wfx/debug.c index eedada78c25f..e67ca0d818ba 100644 --- a/drivers/staging/wfx/debug.c +++ b/drivers/staging/wfx/debug.c @@ -109,6 +109,9 @@ static int wfx_counters_show(struct seq_file *seq, void *v) PUT_COUNTER(rx_beacon); PUT_COUNTER(miss_beacon); + PUT_COUNTER(rx_dtim); + PUT_COUNTER(rx_dtim_aid0_clr); + PUT_COUNTER(rx_dtim_aid0_set); #undef PUT_COUNTER diff --git a/drivers/staging/wfx/hif_api_mib.h b/drivers/staging/wfx/hif_api_mib.h index ace924720ce6..b2dc47c314cc 100644 --- a/drivers/staging/wfx/hif_api_mib.h +++ b/drivers/staging/wfx/hif_api_mib.h @@ -158,7 +158,10 @@ struct hif_mib_extended_count_table { __le32 count_rx_bipmic_errors; __le32 count_rx_beacon; __le32 count_miss_beacon; - __le32 reserved[15]; + __le32 count_rx_dtim; + __le32 count_rx_dtim_aid0_clr; + __le32 count_rx_dtim_aid0_set; + __le32 reserved[12]; } __packed; struct hif_mib_count_table { -- 2.33.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v3 14/32] staging: wfx: uniformize counter names
From: Jérôme Pouiller The device provide some internal statistic counters. However, the names of counter were not very meaningful. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/debug.c | 45 - drivers/staging/wfx/hif_api_mib.h | 82 +++ 2 files changed, 64 insertions(+), 63 deletions(-) diff --git a/drivers/staging/wfx/debug.c b/drivers/staging/wfx/debug.c index e67ca0d818ba..16c3f55f1a3d 100644 --- a/drivers/staging/wfx/debug.c +++ b/drivers/staging/wfx/debug.c @@ -82,36 +82,37 @@ static int wfx_counters_show(struct seq_file *seq, void *v) le32_to_cpu(counters[0].count_##name), \ le32_to_cpu(counters[1].count_##name)) - PUT_COUNTER(tx_packets); - PUT_COUNTER(tx_multicast_frames); + PUT_COUNTER(tx_frames); + PUT_COUNTER(tx_frames_multicast); PUT_COUNTER(tx_frames_success); - PUT_COUNTER(tx_frame_failures); PUT_COUNTER(tx_frames_retried); PUT_COUNTER(tx_frames_multi_retried); + PUT_COUNTER(tx_frames_failed); + PUT_COUNTER(ack_failed); PUT_COUNTER(rts_success); - PUT_COUNTER(rts_failures); - PUT_COUNTER(ack_failures); + PUT_COUNTER(rts_failed); - PUT_COUNTER(rx_packets); + PUT_COUNTER(rx_frames); + PUT_COUNTER(rx_frames_multicast); PUT_COUNTER(rx_frames_success); - PUT_COUNTER(rx_packet_errors); - PUT_COUNTER(plcp_errors); - PUT_COUNTER(fcs_errors); - PUT_COUNTER(rx_decryption_failures); - PUT_COUNTER(rx_mic_failures); - PUT_COUNTER(rx_no_key_failures); - PUT_COUNTER(rx_frame_duplicates); - PUT_COUNTER(rx_multicast_frames); - PUT_COUNTER(rx_cmacicv_errors); - PUT_COUNTER(rx_cmac_replays); - PUT_COUNTER(rx_mgmt_ccmp_replays); + PUT_COUNTER(rx_frames_failed); + PUT_COUNTER(drop_plcp); + PUT_COUNTER(drop_fcs); + PUT_COUNTER(drop_no_key); + PUT_COUNTER(drop_decryption); + PUT_COUNTER(drop_tkip_mic); + PUT_COUNTER(drop_bip_mic); + PUT_COUNTER(drop_cmac_icv); + PUT_COUNTER(drop_cmac_replay); + PUT_COUNTER(drop_ccmp_replay); + PUT_COUNTER(drop_duplicate); - PUT_COUNTER(rx_beacon); - PUT_COUNTER(miss_beacon); - PUT_COUNTER(rx_dtim); - PUT_COUNTER(rx_dtim_aid0_clr); - PUT_COUNTER(rx_dtim_aid0_set); + PUT_COUNTER(rx_bcn_miss); + PUT_COUNTER(rx_bcn_success); + PUT_COUNTER(rx_bcn_dtim); + PUT_COUNTER(rx_bcn_dtim_aid0_clr); + PUT_COUNTER(rx_bcn_dtim_aid0_set); #undef PUT_COUNTER diff --git a/drivers/staging/wfx/hif_api_mib.h b/drivers/staging/wfx/hif_api_mib.h index b2dc47c314cc..2a741a37a90c 100644 --- a/drivers/staging/wfx/hif_api_mib.h +++ b/drivers/staging/wfx/hif_api_mib.h @@ -133,61 +133,61 @@ struct hif_mib_bcn_filter_enable { } __packed; struct hif_mib_extended_count_table { - __le32 count_plcp_errors; - __le32 count_fcs_errors; - __le32 count_tx_packets; - __le32 count_rx_packets; - __le32 count_rx_packet_errors; - __le32 count_rx_decryption_failures; - __le32 count_rx_mic_failures; - __le32 count_rx_no_key_failures; - __le32 count_tx_multicast_frames; + __le32 count_drop_plcp; + __le32 count_drop_fcs; + __le32 count_tx_frames; + __le32 count_rx_frames; + __le32 count_rx_frames_failed; + __le32 count_drop_decryption; + __le32 count_drop_tkip_mic; + __le32 count_drop_no_key; + __le32 count_tx_frames_multicast; __le32 count_tx_frames_success; - __le32 count_tx_frame_failures; + __le32 count_tx_frames_failed; __le32 count_tx_frames_retried; __le32 count_tx_frames_multi_retried; - __le32 count_rx_frame_duplicates; + __le32 count_drop_duplicate; __le32 count_rts_success; - __le32 count_rts_failures; - __le32 count_ack_failures; - __le32 count_rx_multicast_frames; + __le32 count_rts_failed; + __le32 count_ack_failed; + __le32 count_rx_frames_multicast; __le32 count_rx_frames_success; - __le32 count_rx_cmacicv_errors; - __le32 count_rx_cmac_replays; - __le32 count_rx_mgmt_ccmp_replays; - __le32 count_rx_bipmic_errors; - __le32 count_rx_beacon; - __le32 count_miss_beacon; - __le32 count_rx_dtim; - __le32 count_rx_dtim_aid0_clr; - __le32 count_rx_dtim_aid0_set; + __le32 count_drop_cmac_icv; + __le32 count_drop_cmac_replay; + __le32 count_drop_ccmp_replay; + __le32 count_drop_bip_mic; + __le32 count_rx_bcn_success; + __le32 count_rx_bcn_miss; + __le32 count_rx_bcn_dtim; + __le32 count_rx_bcn_dtim_aid0_clr; + __le32 count_rx_bcn_dtim_aid0_set; __le32 reserved[12]; } __packed; struct hif_mib_count_table { - __le32 count_plcp_errors; - __le32 count_fcs_errors; -
[PATCH v3 15/32] staging: wfx: fix misleading 'rate_id' usage
From: Jérôme Pouiller The driver sometime use the term 'rate_id' to identify a retry policy (which is in fact a series of rate IDs). This is misleading. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/data_tx.c | 15 +++ 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/drivers/staging/wfx/data_tx.c b/drivers/staging/wfx/data_tx.c index 77fb104efdec..caeaf836147f 100644 --- a/drivers/staging/wfx/data_tx.c +++ b/drivers/staging/wfx/data_tx.c @@ -285,15 +285,14 @@ static void wfx_tx_fixup_rates(struct ieee80211_tx_rate *rates) rates[i].flags &= ~IEEE80211_TX_RC_SHORT_GI; } -static u8 wfx_tx_get_rate_id(struct wfx_vif *wvif, -struct ieee80211_tx_info *tx_info) +static u8 wfx_tx_get_retry_policy_id(struct wfx_vif *wvif, +struct ieee80211_tx_info *tx_info) { bool tx_policy_renew = false; - u8 rate_id; + u8 ret; - rate_id = wfx_tx_policy_get(wvif, - tx_info->driver_rates, &tx_policy_renew); - if (rate_id == HIF_TX_RETRY_POLICY_INVALID) + ret = wfx_tx_policy_get(wvif, tx_info->driver_rates, &tx_policy_renew); + if (ret == HIF_TX_RETRY_POLICY_INVALID) dev_warn(wvif->wdev->dev, "unable to get a valid Tx policy"); if (tx_policy_renew) { @@ -301,7 +300,7 @@ static u8 wfx_tx_get_rate_id(struct wfx_vif *wvif, if (!schedule_work(&wvif->tx_policy_upload_work)) wfx_tx_unlock(wvif->wdev); } - return rate_id; + return ret; } static int wfx_tx_get_frame_format(struct ieee80211_tx_info *tx_info) @@ -382,7 +381,7 @@ static int wfx_tx_inner(struct wfx_vif *wvif, struct ieee80211_sta *sta, req->peer_sta_id = wfx_tx_get_link_id(wvif, sta, hdr); // Queue index are inverted between firmware and Linux req->queue_id = 3 - queue_id; - req->retry_policy_index = wfx_tx_get_rate_id(wvif, tx_info); + req->retry_policy_index = wfx_tx_get_retry_policy_id(wvif, tx_info); req->frame_format = wfx_tx_get_frame_format(tx_info); if (tx_info->driver_rates[0].flags & IEEE80211_TX_RC_SHORT_GI) req->short_gi = 1; -- 2.33.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v3 16/32] staging: wfx: declare variables at beginning of functions
From: Jérôme Pouiller For better code, we prefer to declare all the local variables at beginning of the functions. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/data_tx.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/wfx/data_tx.c b/drivers/staging/wfx/data_tx.c index caeaf836147f..00c305f192bb 100644 --- a/drivers/staging/wfx/data_tx.c +++ b/drivers/staging/wfx/data_tx.c @@ -108,6 +108,7 @@ static int wfx_tx_policy_get(struct wfx_vif *wvif, int idx; struct tx_policy_cache *cache = &wvif->tx_policy_cache; struct tx_policy wanted; + struct tx_policy *entry; wfx_tx_policy_build(wvif, &wanted, rates); @@ -121,11 +122,10 @@ static int wfx_tx_policy_get(struct wfx_vif *wvif, if (idx >= 0) { *renew = false; } else { - struct tx_policy *entry; - *renew = true; - /* If policy is not found create a new one -* using the oldest entry in "free" list + /* If policy is not found create a new one using the oldest +* entry in "free" list */ + *renew = true; entry = list_entry(cache->free.prev, struct tx_policy, link); memcpy(entry->rates, wanted.rates, sizeof(entry->rates)); entry->uploaded = false; -- 2.33.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v3 17/32] staging: wfx: simplify hif_join()
From: Jérôme Pouiller The new code is smaller. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/hif_tx.c | 5 + 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/staging/wfx/hif_tx.c b/drivers/staging/wfx/hif_tx.c index fcce78bb3005..c5ab1c2e1e07 100644 --- a/drivers/staging/wfx/hif_tx.c +++ b/drivers/staging/wfx/hif_tx.c @@ -305,10 +305,7 @@ int hif_join(struct wfx_vif *wvif, const struct ieee80211_bss_conf *conf, return -ENOMEM; body->infrastructure_bss_mode = !conf->ibss_joined; body->short_preamble = conf->use_short_preamble; - if (channel->flags & IEEE80211_CHAN_NO_IR) - body->probe_for_join = 0; - else - body->probe_for_join = 1; + body->probe_for_join = !(channel->flags & IEEE80211_CHAN_NO_IR); body->channel_number = channel->hw_value; body->beacon_interval = cpu_to_le32(conf->beacon_int); body->basic_rate_set = -- 2.33.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v3 18/32] staging: wfx: reorder function for slightly better eye candy
From: Jérôme Pouiller For a code more eye candy, group all the unconditional assignments together. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/data_tx.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/wfx/data_tx.c b/drivers/staging/wfx/data_tx.c index 00c305f192bb..77d69ed73e28 100644 --- a/drivers/staging/wfx/data_tx.c +++ b/drivers/staging/wfx/data_tx.c @@ -376,15 +376,15 @@ static int wfx_tx_inner(struct wfx_vif *wvif, struct ieee80211_sta *sta, req->packet_id |= queue_id << 28; req->fc_offset = offset; - if (tx_info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) - req->after_dtim = 1; - req->peer_sta_id = wfx_tx_get_link_id(wvif, sta, hdr); // Queue index are inverted between firmware and Linux req->queue_id = 3 - queue_id; + req->peer_sta_id = wfx_tx_get_link_id(wvif, sta, hdr); req->retry_policy_index = wfx_tx_get_retry_policy_id(wvif, tx_info); req->frame_format = wfx_tx_get_frame_format(tx_info); if (tx_info->driver_rates[0].flags & IEEE80211_TX_RC_SHORT_GI) req->short_gi = 1; + if (tx_info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) + req->after_dtim = 1; // Auxiliary operations wfx_tx_queues_put(wvif, skb); -- 2.33.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v3 19/32] staging: wfx: fix error names
From: Jérôme Pouiller ENOTSUP is an alias of EOPNOTSUPP. However, EOPNOTSUPP is preferred. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/sta.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c index 5f2f8900ce99..1e8d05c4f2da 100644 --- a/drivers/staging/wfx/sta.c +++ b/drivers/staging/wfx/sta.c @@ -674,7 +674,7 @@ int wfx_ampdu_action(struct ieee80211_hw *hw, return 0; default: // Leave the firmware doing its business for tx aggregation - return -ENOTSUPP; + return -EOPNOTSUPP; } } -- 2.33.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v3 20/32] staging: wfx: apply naming rules in hif_tx_mib.c
From: Jérôme Pouiller All the functions of hif_tx_mib.c format data to be sent to the hardware. In this file, the struct to be sent is always named 'arg'. Also applies this rule to hif_set_macaddr(). Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/hif_tx_mib.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/wfx/hif_tx_mib.c b/drivers/staging/wfx/hif_tx_mib.c index 1926cf1b62be..1900b7fafd9e 100644 --- a/drivers/staging/wfx/hif_tx_mib.c +++ b/drivers/staging/wfx/hif_tx_mib.c @@ -81,12 +81,12 @@ int hif_get_counters_table(struct wfx_dev *wdev, int vif_id, int hif_set_macaddr(struct wfx_vif *wvif, u8 *mac) { - struct hif_mib_mac_address msg = { }; + struct hif_mib_mac_address arg = { }; if (mac) - ether_addr_copy(msg.mac_addr, mac); + ether_addr_copy(arg.mac_addr, mac); return hif_write_mib(wvif->wdev, wvif->id, HIF_MIB_ID_DOT11_MAC_ADDRESS, -&msg, sizeof(msg)); +&arg, sizeof(arg)); } int hif_set_rx_filter(struct wfx_vif *wvif, -- 2.33.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v3 21/32] staging: wfx: remove unused definition
From: Jérôme Pouiller The enum hif_fw_type is never used in the driver. Drop it. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/hif_api_general.h | 6 -- 1 file changed, 6 deletions(-) diff --git a/drivers/staging/wfx/hif_api_general.h b/drivers/staging/wfx/hif_api_general.h index 24188945718d..77030cecf134 100644 --- a/drivers/staging/wfx/hif_api_general.h +++ b/drivers/staging/wfx/hif_api_general.h @@ -113,12 +113,6 @@ enum hif_api_rate_index { API_RATE_NUM_ENTRIES = 22 }; -enum hif_fw_type { - HIF_FW_TYPE_ETF = 0x0, - HIF_FW_TYPE_WFM = 0x1, - HIF_FW_TYPE_WSM = 0x2 -}; - struct hif_ind_startup { // As the others, this struct is interpreted as little endian by the // device. However, this struct is also used by the driver. We prefer to -- 2.33.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v3 22/32] staging: wfx: remove useless debug statement
From: Jérôme Pouiller In the early age, it was unexpected to access a VIF that did not exist. With current code, this happens frequently. Having a trace associated on this event brings absolutely no informations. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/wfx.h | 5 + 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/staging/wfx/wfx.h b/drivers/staging/wfx/wfx.h index 56f1e4bb0b57..a8efa25a38ac 100644 --- a/drivers/staging/wfx/wfx.h +++ b/drivers/staging/wfx/wfx.h @@ -99,11 +99,8 @@ static inline struct wfx_vif *wdev_to_wvif(struct wfx_dev *wdev, int vif_id) return NULL; } vif_id = array_index_nospec(vif_id, ARRAY_SIZE(wdev->vif)); - if (!wdev->vif[vif_id]) { - dev_dbg(wdev->dev, "requesting non-allocated vif: %d\n", - vif_id); + if (!wdev->vif[vif_id]) return NULL; - } return (struct wfx_vif *) wdev->vif[vif_id]->drv_priv; } -- 2.33.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v3 23/32] staging: wfx: fix space after cast operator
From: Jérôme Pouiller checkpatch.pl reports that cast operators should not been followed by a space. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/wfx.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/wfx/wfx.h b/drivers/staging/wfx/wfx.h index a8efa25a38ac..9749602f6cdc 100644 --- a/drivers/staging/wfx/wfx.h +++ b/drivers/staging/wfx/wfx.h @@ -101,7 +101,7 @@ static inline struct wfx_vif *wdev_to_wvif(struct wfx_dev *wdev, int vif_id) vif_id = array_index_nospec(vif_id, ARRAY_SIZE(wdev->vif)); if (!wdev->vif[vif_id]) return NULL; - return (struct wfx_vif *) wdev->vif[vif_id]->drv_priv; + return (struct wfx_vif *)wdev->vif[vif_id]->drv_priv; } static inline struct wfx_vif *wvif_iterate(struct wfx_dev *wdev, -- 2.33.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v3 24/32] staging: wfx: remove references to WFxxx in comments
From: Jérôme Pouiller The WF200 is the only representative of the WFxxx series and the development of any successor is not expected. So, for clarity, replace occurrences of "WFxxx" with "WF200". Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/bh.c | 4 ++-- drivers/staging/wfx/bus_spi.c | 6 +++--- drivers/staging/wfx/data_tx.c | 4 ++-- drivers/staging/wfx/fwio.c| 4 ++-- drivers/staging/wfx/hif_api_cmd.h | 2 +- drivers/staging/wfx/hif_api_general.h | 2 +- drivers/staging/wfx/hif_api_mib.h | 2 +- drivers/staging/wfx/hif_rx.c | 3 +-- drivers/staging/wfx/hif_rx.h | 3 +-- drivers/staging/wfx/hif_tx.c | 12 +--- drivers/staging/wfx/hif_tx.h | 4 ++-- drivers/staging/wfx/hif_tx_mib.c | 2 +- drivers/staging/wfx/hif_tx_mib.h | 2 +- drivers/staging/wfx/main.c| 2 +- drivers/staging/wfx/sta.c | 4 +--- drivers/staging/wfx/sta.h | 2 +- drivers/staging/wfx/wfx.h | 2 +- 17 files changed, 27 insertions(+), 33 deletions(-) diff --git a/drivers/staging/wfx/bh.c b/drivers/staging/wfx/bh.c index ed53d0b45592..78fa81d82517 100644 --- a/drivers/staging/wfx/bh.c +++ b/drivers/staging/wfx/bh.c @@ -72,7 +72,7 @@ static int rx_helper(struct wfx_dev *wdev, size_t read_len, int *is_cnf) int piggyback = 0; WARN(read_len > round_down(0xFFF, 2) * sizeof(u16), -"%s: request exceed WFx capability", __func__); +"%s: request exceed the chip capability", __func__); // Add 2 to take into account piggyback size alloc_len = wdev->hwbus_ops->align_size(wdev->hwbus_priv, read_len + 2); @@ -181,7 +181,7 @@ static void tx_helper(struct wfx_dev *wdev, struct hif_msg *hif) data = hif; WARN(len > wdev->hw_caps.size_inp_ch_buf, -"%s: request exceed WFx capability: %zu > %d\n", __func__, +"%s: request exceed the chip capability: %zu > %d\n", __func__, len, wdev->hw_caps.size_inp_ch_buf); len = wdev->hwbus_ops->align_size(wdev->hwbus_priv, len); ret = wfx_data_write(wdev, data, len); diff --git a/drivers/staging/wfx/bus_spi.c b/drivers/staging/wfx/bus_spi.c index a99125d1a30d..759e085048c3 100644 --- a/drivers/staging/wfx/bus_spi.c +++ b/drivers/staging/wfx/bus_spi.c @@ -39,9 +39,9 @@ struct wfx_spi_priv { }; /* - * WFx chip read data 16bits at time and place them directly into (little - * endian) CPU register. So, chip expect byte order like "B1 B0 B3 B2" (while - * LE is "B0 B1 B2 B3" and BE is "B3 B2 B1 B0") + * The chip reads 16bits of data at time and place them directly into (little + * endian) CPU register. So, the chip expects bytes order to be "B1 B0 B3 B2" + * (while LE is "B0 B1 B2 B3" and BE is "B3 B2 B1 B0") * * A little endian host with bits_per_word == 16 should do the right job * natively. The code below to support big endian host and commonly used SPI diff --git a/drivers/staging/wfx/data_tx.c b/drivers/staging/wfx/data_tx.c index 77d69ed73e28..f141ab50f4fd 100644 --- a/drivers/staging/wfx/data_tx.c +++ b/drivers/staging/wfx/data_tx.c @@ -31,8 +31,8 @@ static int wfx_get_hw_rate(struct wfx_dev *wdev, } return rate->idx + 14; } - // WFx only support 2GHz, else band information should be retrieved - // from ieee80211_tx_info + // The device only support 2GHz, else band information should be + // retrieved from ieee80211_tx_info band = wdev->hw->wiphy->bands[NL80211_BAND_2GHZ]; if (rate->idx >= band->n_bitrates) { WARN(1, "wrong rate->idx value: %d", rate->idx); diff --git a/drivers/staging/wfx/fwio.c b/drivers/staging/wfx/fwio.c index 1b8aec02d169..7b91ac615f4a 100644 --- a/drivers/staging/wfx/fwio.c +++ b/drivers/staging/wfx/fwio.c @@ -207,8 +207,8 @@ static int upload_firmware(struct wfx_dev *wdev, const u8 *data, size_t len) if (ret < 0) return ret; - // WFx seems to not support writing 0 in this register during - // first loop + // The device seems to not support writing 0 in this register + // during first loop offs += DNLD_BLOCK_SIZE; ret = sram_reg_write(wdev, WFX_DCA_PUT, offs); if (ret < 0) diff --git a/drivers/staging/wfx/hif_api_cmd.h b/drivers/staging/wfx/hif_api_cmd.h index 58c9bb036011..553dc45142f2 100644 --- a/drivers/staging/wfx/hif_api_cmd.h +++ b/drivers/staging/wfx/hif_api_cmd.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: Apache-2.0 */ /* - * WFx hardware interface definitions + * WF200 hardware interface definitions * * Copyright (c) 2018-2020, Silicon Laboratories Inc. */ diff --git a/drivers/staging/wfx/hif_api_general.h b/drivers/staging/wfx/hif_api_general.h index 77030cecf134..714e1dd808e6 100644 --- a/drivers/staging/wfx/hif_api_genera
[PATCH v3 26/32] staging: wfx: reformat comment
From: Jérôme Pouiller The new comment takes only one line instead of three. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/sta.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c index 1e21beeed438..70e1c4d8ae2e 100644 --- a/drivers/staging/wfx/sta.c +++ b/drivers/staging/wfx/sta.c @@ -599,9 +599,7 @@ static int wfx_update_tim(struct wfx_vif *wvif) tim_ptr = skb->data + tim_offset; if (tim_offset && tim_length >= 6) { - /* Ignore DTIM count from mac80211: -* firmware handles DTIM internally. -*/ + /* Firmware handles DTIM counter internally */ tim_ptr[2] = 0; /* Set/reset aid0 bit */ -- 2.33.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v3 25/32] staging: wfx: update files descriptions
From: Jérôme Pouiller Each file of the driver contains a short description of its purpose. These description were a bit outdated. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/bh.h | 2 +- drivers/staging/wfx/data_rx.c | 2 +- drivers/staging/wfx/data_rx.h | 2 +- drivers/staging/wfx/data_tx.c | 2 +- drivers/staging/wfx/data_tx.h | 2 +- drivers/staging/wfx/hwio.h| 2 +- drivers/staging/wfx/key.h | 2 +- drivers/staging/wfx/queue.c | 2 +- drivers/staging/wfx/queue.h | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/staging/wfx/bh.h b/drivers/staging/wfx/bh.h index 78c49329e22a..f08c62ed039c 100644 --- a/drivers/staging/wfx/bh.h +++ b/drivers/staging/wfx/bh.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Interrupt bottom half. + * Interrupt bottom half (BH). * * Copyright (c) 2017-2020, Silicon Laboratories, Inc. * Copyright (c) 2010, ST-Ericsson diff --git a/drivers/staging/wfx/data_rx.c b/drivers/staging/wfx/data_rx.c index 385f2d42a0e2..509f45cdbab9 100644 --- a/drivers/staging/wfx/data_rx.c +++ b/drivers/staging/wfx/data_rx.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Datapath implementation. + * Data receiving implementation. * * Copyright (c) 2017-2020, Silicon Laboratories, Inc. * Copyright (c) 2010, ST-Ericsson diff --git a/drivers/staging/wfx/data_rx.h b/drivers/staging/wfx/data_rx.h index 4c0da37f2084..f79545c06130 100644 --- a/drivers/staging/wfx/data_rx.h +++ b/drivers/staging/wfx/data_rx.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Datapath implementation. + * Data receiving implementation. * * Copyright (c) 2017-2020, Silicon Laboratories, Inc. * Copyright (c) 2010, ST-Ericsson diff --git a/drivers/staging/wfx/data_tx.c b/drivers/staging/wfx/data_tx.c index f141ab50f4fd..04241422edc8 100644 --- a/drivers/staging/wfx/data_tx.c +++ b/drivers/staging/wfx/data_tx.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Datapath implementation. + * Data transmitting implementation. * * Copyright (c) 2017-2020, Silicon Laboratories, Inc. * Copyright (c) 2010, ST-Ericsson diff --git a/drivers/staging/wfx/data_tx.h b/drivers/staging/wfx/data_tx.h index 401363d6b563..7dcc9132d7cd 100644 --- a/drivers/staging/wfx/data_tx.h +++ b/drivers/staging/wfx/data_tx.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Datapath implementation. + * Data transmitting implementation. * * Copyright (c) 2017-2020, Silicon Laboratories, Inc. * Copyright (c) 2010, ST-Ericsson diff --git a/drivers/staging/wfx/hwio.h b/drivers/staging/wfx/hwio.h index 0b8e4f7157df..5e43993b14d8 100644 --- a/drivers/staging/wfx/hwio.h +++ b/drivers/staging/wfx/hwio.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Low-level API. + * Low-level I/O functions. * * Copyright (c) 2017-2020, Silicon Laboratories, Inc. * Copyright (c) 2010, ST-Ericsson diff --git a/drivers/staging/wfx/key.h b/drivers/staging/wfx/key.h index 70a44d0ca35e..dd189788acf1 100644 --- a/drivers/staging/wfx/key.h +++ b/drivers/staging/wfx/key.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Implementation of mac80211 API. + * Key management related functions. * * Copyright (c) 2017-2020, Silicon Laboratories, Inc. * Copyright (c) 2010, ST-Ericsson diff --git a/drivers/staging/wfx/queue.c b/drivers/staging/wfx/queue.c index 0ab207237d9f..e5e7595565ee 100644 --- a/drivers/staging/wfx/queue.c +++ b/drivers/staging/wfx/queue.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * O(1) TX queue with built-in allocator. + * Queue between the tx operation and the bh workqueue. * * Copyright (c) 2017-2020, Silicon Laboratories, Inc. * Copyright (c) 2010, ST-Ericsson diff --git a/drivers/staging/wfx/queue.h b/drivers/staging/wfx/queue.h index 80ba19455ef3..24b60833864b 100644 --- a/drivers/staging/wfx/queue.h +++ b/drivers/staging/wfx/queue.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * O(1) TX queue with built-in allocator. + * Queue between the tx operation and the bh workqueue. * * Copyright (c) 2017-2020, Silicon Laboratories, Inc. * Copyright (c) 2010, ST-Ericsson -- 2.33.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v3 28/32] staging: wfx: fix comments styles
From: Jérôme Pouiller Unify all comments of the wfx driver to use the same comment style. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/bh.c | 11 +++ drivers/staging/wfx/bus_spi.c | 6 ++ drivers/staging/wfx/fwio.c| 3 +-- drivers/staging/wfx/main.h| 3 +-- drivers/staging/wfx/scan.c| 3 +-- 5 files changed, 8 insertions(+), 18 deletions(-) diff --git a/drivers/staging/wfx/bh.c b/drivers/staging/wfx/bh.c index e956b5a5ccac..a0f9d1b53019 100644 --- a/drivers/staging/wfx/bh.c +++ b/drivers/staging/wfx/bh.c @@ -265,9 +265,7 @@ static void bh_work(struct work_struct *work) wdev->hif.tx_buffers_used, release_chip); } -/* - * An IRQ from chip did occur - */ +/* An IRQ from chip did occur */ void wfx_bh_request_rx(struct wfx_dev *wdev) { u32 cur, prev; @@ -285,16 +283,13 @@ void wfx_bh_request_rx(struct wfx_dev *wdev) prev, cur); } -/* - * Driver want to send data - */ +/* Driver want to send data */ void wfx_bh_request_tx(struct wfx_dev *wdev) { queue_work(system_highpri_wq, &wdev->hif.bh); } -/* - * If IRQ is not available, this function allow to manually poll the control +/* If IRQ is not available, this function allow to manually poll the control * register and simulate an IRQ ahen an event happened. * * Note that the device has a bug: If an IRQ raise while host read control diff --git a/drivers/staging/wfx/bus_spi.c b/drivers/staging/wfx/bus_spi.c index 61f73b3ebc80..55ffcd7c42e2 100644 --- a/drivers/staging/wfx/bus_spi.c +++ b/drivers/staging/wfx/bus_spi.c @@ -38,8 +38,7 @@ struct wfx_spi_priv { bool need_swab; }; -/* - * The chip reads 16bits of data at time and place them directly into (little +/* The chip reads 16bits of data at time and place them directly into (little * endian) CPU register. So, the chip expects bytes order to be "B1 B0 B3 B2" * (while LE is "B0 B1 B2 B3" and BE is "B3 B2 B1 B0") * @@ -241,8 +240,7 @@ static int wfx_spi_remove(struct spi_device *func) return 0; } -/* - * For dynamic driver binding, kernel does not use OF to match driver. It only +/* For dynamic driver binding, kernel does not use OF to match driver. It only * use modalias and modalias is a copy of 'compatible' DT node with vendor * stripped. */ diff --git a/drivers/staging/wfx/fwio.c b/drivers/staging/wfx/fwio.c index c5ba0a50b474..98a9391b2bee 100644 --- a/drivers/staging/wfx/fwio.c +++ b/drivers/staging/wfx/fwio.c @@ -69,8 +69,7 @@ static const char * const fwio_errors[] = { [ERR_MAC_KEY] = "MAC key not initialized", }; -/* - * request_firmware() allocate data using vmalloc(). It is not compatible with +/* request_firmware() allocate data using vmalloc(). It is not compatible with * underlying hardware that use DMA. Function below detect this case and * allocate a bounce buffer if necessary. * diff --git a/drivers/staging/wfx/main.h b/drivers/staging/wfx/main.h index a0db322383a3..115abd2d4378 100644 --- a/drivers/staging/wfx/main.h +++ b/drivers/staging/wfx/main.h @@ -23,8 +23,7 @@ struct wfx_platform_data { const char *file_fw; const char *file_pds; struct gpio_desc *gpio_wakeup; - /* -* if true HIF D_out is sampled on the rising edge of the clock + /* if true HIF D_out is sampled on the rising edge of the clock * (intended to be used in 50Mhz SDIO) */ bool use_rising_clk; diff --git a/drivers/staging/wfx/scan.c b/drivers/staging/wfx/scan.c index 9e2d08317c9e..668ef2c60837 100644 --- a/drivers/staging/wfx/scan.c +++ b/drivers/staging/wfx/scan.c @@ -85,8 +85,7 @@ static int send_scan_req(struct wfx_vif *wvif, return ret; } -/* - * It is not really necessary to run scan request asynchronously. However, +/* It is not really necessary to run scan request asynchronously. However, * there is a bug in "iw scan" when ieee80211_scan_completed() is called before * wfx_hw_scan() return */ -- 2.33.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v3 27/32] staging: wfx: avoid c99 comments
From: Jérôme Pouiller The wfx driver is a network driver. C99 comments are prohibited in this part of the kernel. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/bh.c | 22 drivers/staging/wfx/bus_sdio.c| 8 +-- drivers/staging/wfx/bus_spi.c | 12 +++-- drivers/staging/wfx/data_rx.c | 5 +- drivers/staging/wfx/data_tx.c | 56 ++- drivers/staging/wfx/data_tx.h | 2 +- drivers/staging/wfx/debug.c | 12 +++-- drivers/staging/wfx/fwio.c| 23 drivers/staging/wfx/hif_api_cmd.h | 12 +++-- drivers/staging/wfx/hif_api_general.h | 17 +++--- drivers/staging/wfx/hif_api_mib.h | 2 +- drivers/staging/wfx/hif_rx.c | 17 +++--- drivers/staging/wfx/hif_tx.c | 32 ++- drivers/staging/wfx/hif_tx_mib.c | 4 +- drivers/staging/wfx/hwio.c| 6 +-- drivers/staging/wfx/hwio.h| 16 +++--- drivers/staging/wfx/key.c | 4 +- drivers/staging/wfx/main.c| 13 ++--- drivers/staging/wfx/queue.c | 27 +- drivers/staging/wfx/queue.h | 2 +- drivers/staging/wfx/sta.c | 78 ++- drivers/staging/wfx/sta.h | 6 +-- drivers/staging/wfx/traces.h | 2 +- drivers/staging/wfx/wfx.h | 2 +- 24 files changed, 205 insertions(+), 175 deletions(-) diff --git a/drivers/staging/wfx/bh.c b/drivers/staging/wfx/bh.c index 78fa81d82517..e956b5a5ccac 100644 --- a/drivers/staging/wfx/bh.c +++ b/drivers/staging/wfx/bh.c @@ -32,18 +32,20 @@ static void device_wakeup(struct wfx_dev *wdev) } for (;;) { gpiod_set_value_cansleep(wdev->pdata.gpio_wakeup, 1); - // completion.h does not provide any function to wait - // completion without consume it (a kind of - // wait_for_completion_done_timeout()). So we have to emulate - // it. + /* completion.h does not provide any function to wait +* completion without consume it (a kind of +* wait_for_completion_done_timeout()). So we have to emulate +* it. +*/ if (wait_for_completion_timeout(&wdev->hif.ctrl_ready, msecs_to_jiffies(2))) { complete(&wdev->hif.ctrl_ready); return; } else if (max_retry-- > 0) { - // Older firmwares have a race in sleep/wake-up process. - // Redo the process is sufficient to unfreeze the - // chip. + /* Older firmwares have a race in sleep/wake-up process. +* Redo the process is sufficient to unfreeze the +* chip. +*/ dev_err(wdev->dev, "timeout while wake up chip\n"); gpiod_set_value_cansleep(wdev->pdata.gpio_wakeup, 0); usleep_range(2000, 2500); @@ -74,7 +76,7 @@ static int rx_helper(struct wfx_dev *wdev, size_t read_len, int *is_cnf) WARN(read_len > round_down(0xFFF, 2) * sizeof(u16), "%s: request exceed the chip capability", __func__); - // Add 2 to take into account piggyback size + /* Add 2 to take into account piggyback size */ alloc_len = wdev->hwbus_ops->align_size(wdev->hwbus_priv, read_len + 2); skb = dev_alloc_skb(alloc_len); if (!skb) @@ -119,7 +121,7 @@ static int rx_helper(struct wfx_dev *wdev, size_t read_len, int *is_cnf) } skb_put(skb, le16_to_cpu(hif->len)); - // wfx_handle_rx takes care on SKB livetime + /* wfx_handle_rx takes care on SKB livetime */ wfx_handle_rx(wdev, skb); if (!wdev->hif.tx_buffers_used) wake_up(&wdev->hif.tx_buffers_empty); @@ -148,7 +150,7 @@ static int bh_work_rx(struct wfx_dev *wdev, int max_msg, int *num_cnf) ctrl_reg = 0; if (!(ctrl_reg & CTRL_NEXT_LEN_MASK)) return i; - // ctrl_reg units are 16bits words + /* ctrl_reg units are 16bits words */ len = (ctrl_reg & CTRL_NEXT_LEN_MASK) * 2; piggyback = rx_helper(wdev, len, num_cnf); if (piggyback < 0) diff --git a/drivers/staging/wfx/bus_sdio.c b/drivers/staging/wfx/bus_sdio.c index e06d7e1ebe9c..eb70bef6bd6e 100644 --- a/drivers/staging/wfx/bus_sdio.c +++ b/drivers/staging/wfx/bus_sdio.c @@ -67,7 +67,7 @@ static int wfx_sdio_copy_to_io(void *priv, unsigned int reg_id, /* Use queue mode buffers */ if (reg_id == WFX_REG_IN_OUT_QUEUE) sdio_addr |= bus->buf_id_tx << 7; - // FIXME: discards 'const' qualifier for src + /* FIXME: discards 'const' qualifier for src */ ret = sdio
[PATCH v3 29/32] staging: wfx: remove useless comments after #endif
From: Jérôme Pouiller Comments after the last #endif of header files don't bring any information and are redundant with the name of the file. Drop them. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/bh.h | 2 +- drivers/staging/wfx/data_rx.h | 2 +- drivers/staging/wfx/data_tx.h | 2 +- drivers/staging/wfx/debug.h | 2 +- drivers/staging/wfx/fwio.h| 2 +- drivers/staging/wfx/hwio.h| 2 +- drivers/staging/wfx/key.h | 2 +- drivers/staging/wfx/queue.h | 2 +- drivers/staging/wfx/scan.h| 2 +- drivers/staging/wfx/sta.h | 2 +- drivers/staging/wfx/wfx.h | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/staging/wfx/bh.h b/drivers/staging/wfx/bh.h index f08c62ed039c..6c121ce4dd3f 100644 --- a/drivers/staging/wfx/bh.h +++ b/drivers/staging/wfx/bh.h @@ -30,4 +30,4 @@ void wfx_bh_request_rx(struct wfx_dev *wdev); void wfx_bh_request_tx(struct wfx_dev *wdev); void wfx_bh_poll_irq(struct wfx_dev *wdev); -#endif /* WFX_BH_H */ +#endif diff --git a/drivers/staging/wfx/data_rx.h b/drivers/staging/wfx/data_rx.h index f79545c06130..84d0e3c0507b 100644 --- a/drivers/staging/wfx/data_rx.h +++ b/drivers/staging/wfx/data_rx.h @@ -15,4 +15,4 @@ struct hif_ind_rx; void wfx_rx_cb(struct wfx_vif *wvif, const struct hif_ind_rx *arg, struct sk_buff *skb); -#endif /* WFX_DATA_RX_H */ +#endif diff --git a/drivers/staging/wfx/data_tx.h b/drivers/staging/wfx/data_tx.h index dafd8fef44cf..15590a8faefe 100644 --- a/drivers/staging/wfx/data_tx.h +++ b/drivers/staging/wfx/data_tx.h @@ -65,4 +65,4 @@ static inline struct hif_req_tx *wfx_skb_txreq(struct sk_buff *skb) return req; } -#endif /* WFX_DATA_TX_H */ +#endif diff --git a/drivers/staging/wfx/debug.h b/drivers/staging/wfx/debug.h index 6f2f84d64c9e..4b9c49a9fffb 100644 --- a/drivers/staging/wfx/debug.h +++ b/drivers/staging/wfx/debug.h @@ -16,4 +16,4 @@ const char *get_hif_name(unsigned long id); const char *get_mib_name(unsigned long id); const char *get_reg_name(unsigned long id); -#endif /* WFX_DEBUG_H */ +#endif diff --git a/drivers/staging/wfx/fwio.h b/drivers/staging/wfx/fwio.h index 6028f92503fe..eeea61210eca 100644 --- a/drivers/staging/wfx/fwio.h +++ b/drivers/staging/wfx/fwio.h @@ -12,4 +12,4 @@ struct wfx_dev; int wfx_init_device(struct wfx_dev *wdev); -#endif /* WFX_FWIO_H */ +#endif diff --git a/drivers/staging/wfx/hwio.h b/drivers/staging/wfx/hwio.h index 9a361ed95ecb..ff09575dd1af 100644 --- a/drivers/staging/wfx/hwio.h +++ b/drivers/staging/wfx/hwio.h @@ -72,4 +72,4 @@ int control_reg_write_bits(struct wfx_dev *wdev, u32 mask, u32 val); int igpr_reg_read(struct wfx_dev *wdev, int index, u32 *val); int igpr_reg_write(struct wfx_dev *wdev, int index, u32 val); -#endif /* WFX_HWIO_H */ +#endif diff --git a/drivers/staging/wfx/key.h b/drivers/staging/wfx/key.h index dd189788acf1..2d135eff7af2 100644 --- a/drivers/staging/wfx/key.h +++ b/drivers/staging/wfx/key.h @@ -17,4 +17,4 @@ int wfx_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, struct ieee80211_vif *vif, struct ieee80211_sta *sta, struct ieee80211_key_conf *key); -#endif /* WFX_STA_H */ +#endif diff --git a/drivers/staging/wfx/queue.h b/drivers/staging/wfx/queue.h index 54b5def2e24c..edd0d018b198 100644 --- a/drivers/staging/wfx/queue.h +++ b/drivers/staging/wfx/queue.h @@ -42,4 +42,4 @@ unsigned int wfx_pending_get_pkt_us_delay(struct wfx_dev *wdev, struct sk_buff *skb); void wfx_pending_dump_old_frames(struct wfx_dev *wdev, unsigned int limit_ms); -#endif /* WFX_QUEUE_H */ +#endif diff --git a/drivers/staging/wfx/scan.h b/drivers/staging/wfx/scan.h index 562ca1321daf..78e3b984f375 100644 --- a/drivers/staging/wfx/scan.h +++ b/drivers/staging/wfx/scan.h @@ -19,4 +19,4 @@ int wfx_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, void wfx_cancel_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif); void wfx_scan_complete(struct wfx_vif *wvif, int nb_chan_done); -#endif /* WFX_SCAN_H */ +#endif diff --git a/drivers/staging/wfx/sta.h b/drivers/staging/wfx/sta.h index f359f375cc56..4d7e38be4235 100644 --- a/drivers/staging/wfx/sta.h +++ b/drivers/staging/wfx/sta.h @@ -70,4 +70,4 @@ int wfx_update_pm(struct wfx_vif *wvif); void wfx_reset(struct wfx_vif *wvif); u32 wfx_rate_mask_to_hw(struct wfx_dev *wdev, u32 rates); -#endif /* WFX_STA_H */ +#endif diff --git a/drivers/staging/wfx/wfx.h b/drivers/staging/wfx/wfx.h index a4770f59f7d2..f8df59ad1639 100644 --- a/drivers/staging/wfx/wfx.h +++ b/drivers/staging/wfx/wfx.h @@ -161,4 +161,4 @@ static inline int memzcmp(void *src, unsigned int size) return memcmp(buf, buf + 1, size - 1); } -#endif /* WFX_H */ +#endif -- 2.33.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v3 30/32] staging: wfx: explain the purpose of wfx_send_pds()
From: Jérôme Pouiller On first look, the goal of wfx_send_pds() is not obvious. A small explanation is welcomed. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/main.c | 15 ++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/staging/wfx/main.c b/drivers/staging/wfx/main.c index e5e852ddf9c3..858d778cc589 100644 --- a/drivers/staging/wfx/main.c +++ b/drivers/staging/wfx/main.c @@ -163,7 +163,20 @@ bool wfx_api_older_than(struct wfx_dev *wdev, int major, int minor) return false; } -/* NOTE: wfx_send_pds() destroy buf */ +/* The device needs data about the antenna configuration. This information in + * provided by PDS (Platform Data Set, this is the wording used in WF200 + * documentation) files. For hardware integrators, the full process to create + * PDS files is described here: + * https:github.com/SiliconLabs/wfx-firmware/blob/master/PDS/README.md + * + * So this function aims to send PDS to the device. However, the PDS file is + * often bigger than Rx buffers of the chip, so it has to be sent in multiple + * parts. + * + * In add, the PDS data cannot be split anywhere. The PDS files contains tree + * structures. Braces are used to enter/leave a level of the tree (in a JSON + * fashion). PDS files can only been split between root nodes. + */ int wfx_send_pds(struct wfx_dev *wdev, u8 *buf, size_t len) { int ret; -- 2.33.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v3 31/32] staging: wfx: indent functions arguments
From: Jérôme Pouiller Function arguments must be aligned with first argument. Apply that rule. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/hif_tx_mib.c | 2 +- drivers/staging/wfx/key.c| 26 +- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/staging/wfx/hif_tx_mib.c b/drivers/staging/wfx/hif_tx_mib.c index 45e531d996bd..97e961e6bcf6 100644 --- a/drivers/staging/wfx/hif_tx_mib.c +++ b/drivers/staging/wfx/hif_tx_mib.c @@ -75,7 +75,7 @@ int hif_get_counters_table(struct wfx_dev *wdev, int vif_id, } else { return hif_read_mib(wdev, vif_id, HIF_MIB_ID_EXTENDED_COUNTERS_TABLE, arg, - sizeof(struct hif_mib_extended_count_table)); + sizeof(struct hif_mib_extended_count_table)); } } diff --git a/drivers/staging/wfx/key.c b/drivers/staging/wfx/key.c index 51a528102016..65134a174683 100644 --- a/drivers/staging/wfx/key.c +++ b/drivers/staging/wfx/key.c @@ -31,7 +31,7 @@ static void wfx_free_key(struct wfx_dev *wdev, int idx) } static u8 fill_wep_pair(struct hif_wep_pairwise_key *msg, -struct ieee80211_key_conf *key, u8 *peer_addr) + struct ieee80211_key_conf *key, u8 *peer_addr) { WARN(key->keylen > sizeof(msg->key_data), "inconsistent data"); msg->key_length = key->keylen; @@ -41,7 +41,7 @@ static u8 fill_wep_pair(struct hif_wep_pairwise_key *msg, } static u8 fill_wep_group(struct hif_wep_group_key *msg, - struct ieee80211_key_conf *key) +struct ieee80211_key_conf *key) { WARN(key->keylen > sizeof(msg->key_data), "inconsistent data"); msg->key_id = key->keyidx; @@ -51,7 +51,7 @@ static u8 fill_wep_group(struct hif_wep_group_key *msg, } static u8 fill_tkip_pair(struct hif_tkip_pairwise_key *msg, - struct ieee80211_key_conf *key, u8 *peer_addr) +struct ieee80211_key_conf *key, u8 *peer_addr) { u8 *keybuf = key->key; @@ -68,9 +68,9 @@ static u8 fill_tkip_pair(struct hif_tkip_pairwise_key *msg, } static u8 fill_tkip_group(struct hif_tkip_group_key *msg, - struct ieee80211_key_conf *key, - struct ieee80211_key_seq *seq, - enum nl80211_iftype iftype) + struct ieee80211_key_conf *key, + struct ieee80211_key_seq *seq, + enum nl80211_iftype iftype) { u8 *keybuf = key->key; @@ -93,7 +93,7 @@ static u8 fill_tkip_group(struct hif_tkip_group_key *msg, } static u8 fill_ccmp_pair(struct hif_aes_pairwise_key *msg, - struct ieee80211_key_conf *key, u8 *peer_addr) +struct ieee80211_key_conf *key, u8 *peer_addr) { WARN(key->keylen != sizeof(msg->aes_key_data), "inconsistent data"); ether_addr_copy(msg->peer_address, peer_addr); @@ -102,8 +102,8 @@ static u8 fill_ccmp_pair(struct hif_aes_pairwise_key *msg, } static u8 fill_ccmp_group(struct hif_aes_group_key *msg, - struct ieee80211_key_conf *key, - struct ieee80211_key_seq *seq) + struct ieee80211_key_conf *key, + struct ieee80211_key_seq *seq) { WARN(key->keylen != sizeof(msg->aes_key_data), "inconsistent data"); memcpy(msg->aes_key_data, key->key, key->keylen); @@ -114,7 +114,7 @@ static u8 fill_ccmp_group(struct hif_aes_group_key *msg, } static u8 fill_sms4_pair(struct hif_wapi_pairwise_key *msg, - struct ieee80211_key_conf *key, u8 *peer_addr) +struct ieee80211_key_conf *key, u8 *peer_addr) { u8 *keybuf = key->key; @@ -129,7 +129,7 @@ static u8 fill_sms4_pair(struct hif_wapi_pairwise_key *msg, } static u8 fill_sms4_group(struct hif_wapi_group_key *msg, - struct ieee80211_key_conf *key) + struct ieee80211_key_conf *key) { u8 *keybuf = key->key; @@ -143,8 +143,8 @@ static u8 fill_sms4_group(struct hif_wapi_group_key *msg, } static u8 fill_aes_cmac_group(struct hif_igtk_group_key *msg, - struct ieee80211_key_conf *key, - struct ieee80211_key_seq *seq) + struct ieee80211_key_conf *key, + struct ieee80211_key_seq *seq) { WARN(key->keylen != sizeof(msg->igtk_key_data), "inconsistent data"); memcpy(msg->igtk_key_data, key->key, key->keylen); -- 2.33.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v3 32/32] staging: wfx: ensure IRQ is ready before enabling it
From: Jérôme Pouiller Since commit 5561770f80b1 ("staging: wfx: repair external IRQ for SDIO"), wfx_sdio_irq_subscribe() enforce the device to use IRQs. However, there is currently a race in this code. An IRQ may happen before the IRQ has been registered. The problem has observed during debug session when the device crashes before the IRQ set up: [ 1.546] wfx-sdio mmc0:0001:1: started firmware 3.12.2 "WF200_ASIC_WFM_(Jenkins)_FW3.12.2" (API: 3.7, keyset: C0, caps: 0x0002) [ 2.559] wfx-sdio mmc0:0001:1: time out while polling control register [ 3.565] wfx-sdio mmc0:0001:1: chip is abnormally long to answer [ 6.563] wfx-sdio mmc0:0001:1: chip did not answer [ 6.568] wfx-sdio mmc0:0001:1: hardware request CONFIGURATION (0x09) on vif 2 returned error -110 [ 6.577] wfx-sdio mmc0:0001:1: PDS bytes 0 to 12: chip didn't reply (corrupted file?) [ 6.585] Unable to handle kernel NULL pointer dereference at virtual address [ 6.592] pgd = c0004000 [ 6.595] [] *pgd= [ 6.598] Internal error: Oops - BUG: 17 [#1] THUMB2 [ 6.603] Modules linked in: [ 6.606] CPU: 0 PID: 23 Comm: kworker/u2:1 Not tainted 3.18.19 #78 [ 6.612] Workqueue: kmmcd mmc_rescan [ 6.616] task: c176d100 ti: c0e5 task.ti: c0e5 [ 6.621] PC is at wake_up_process+0xa/0x14 [ 6.625] LR is at sdio_irq+0x61/0x250 [ 6.629] pc : [] lr : [] psr: 61b3 [ 6.629] sp : c0e51bd8 ip : c0e51cc8 fp : 0001 [ 6.640] r10: 0003 r9 : r8 : c0003c34 [ 6.644] r7 : c0e51bd8 r6 : c0003c30 r5 : 0001 r4 : c0e78c00 [ 6.651] r3 : r2 : r1 : 0003 r0 : [ 6.657] Flags: nZCv IRQs off FIQs on Mode SVC_32 ISA Thumb Segment kernel [ 6.664] Control: 50c53c7d Table: 11fd8059 DAC: 0015 [ 6.670] Process kworker/u2:1 (pid: 23, stack limit = 0xc0e501b0) [ 6.676] Stack: (0xc0e51bd8 to 0xc0e52000) [...] [ 6.949] [] (wake_up_process) from [] (sdio_irq+0x61/0x250) [ 6.956] [] (sdio_irq) from [] (handle_irq_event_percpu+0x17/0x92) [ 6.964] [] (handle_irq_event_percpu) from [] (handle_irq_event+0x1b/0x24) [ 6.973] [] (handle_irq_event) from [] (handle_level_irq+0x5d/0x76) [ 6.981] [] (handle_level_irq) from [] (generic_handle_irq+0x13/0x1c) [ 6.989] [] (generic_handle_irq) from [] (__handle_domain_irq+0x31/0x48) [ 6.997] [] (__handle_domain_irq) from [] (ov_handle_irq+0x31/0xe0) [ 7.005] [] (ov_handle_irq) from [] (__irq_svc+0x3b/0x5c) [ 7.013] Exception stack(0xc0e51c68 to 0xc0e51cb0) [...] [ 7.038] [] (__irq_svc) from [] (wait_for_common+0x9e/0xc4) [ 7.045] [] (wait_for_common) from [] (mmc_wait_for_req+0x4b/0xdc) [ 7.053] [] (mmc_wait_for_req) from [] (mmc_wait_for_cmd+0x2f/0x34) [ 7.061] [] (mmc_wait_for_cmd) from [] (mmc_io_rw_direct_host+0x71/0xac) [ 7.070] [] (mmc_io_rw_direct_host) from [] (sdio_claim_irq+0x6b/0x116) [ 7.078] [] (sdio_claim_irq) from [] (wfx_sdio_irq_subscribe+0x19/0x94) [ 7.086] [] (wfx_sdio_irq_subscribe) from [] (wfx_probe+0x189/0x2ac) [ 7.095] [] (wfx_probe) from [] (wfx_sdio_probe+0x8f/0xcc) [ 7.102] [] (wfx_sdio_probe) from [] (sdio_bus_probe+0x5f/0xa8) [ 7.109] [] (sdio_bus_probe) from [] (driver_probe_device+0x59/0x134) [ 7.118] [] (driver_probe_device) from [] (bus_for_each_drv+0x3f/0x4a) [ 7.126] [] (bus_for_each_drv) from [] (device_attach+0x3b/0x52) [ 7.134] [] (device_attach) from [] (bus_probe_device+0x17/0x4c) [ 7.141] [] (bus_probe_device) from [] (device_add+0x2c5/0x334) [ 7.149] [] (device_add) from [] (sdio_add_func+0x23/0x44) [ 7.156] [] (sdio_add_func) from [] (mmc_attach_sdio+0x187/0x1ec) [ 7.164] [] (mmc_attach_sdio) from [] (mmc_rescan+0x18d/0x1fc) [ 7.172] [] (mmc_rescan) from [] (process_one_work+0xd7/0x170) [ 7.179] [] (process_one_work) from [] (worker_thread+0x103/0x1bc) [ 7.187] [] (worker_thread) from [] (kthread+0x7d/0x90) [ 7.194] [] (kthread) from [] (ret_from_fork+0x11/0x30) [ 7.201] Code: 2103 b580 2200 af00 (681b) 46bd [ 7.206] ---[ end trace 3ab50aced42eedb4 ]--- Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/bus_sdio.c | 21 - 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/drivers/staging/wfx/bus_sdio.c b/drivers/staging/wfx/bus_sdio.c index eb70bef6bd6e..a670176ba06f 100644 --- a/drivers/staging/wfx/bus_sdio.c +++ b/drivers/staging/wfx/bus_sdio.c @@ -120,19 +120,22 @@ static int wfx_sdio_irq_subscribe(void *priv) return ret; } - sdio_claim_host(bus->func); - cccr = sdio_f0_readb(bus->func, SDIO_CCCR_IENx, NULL); - cccr |= BIT(0); - cccr |= BIT(bus->func->num); - sdio_f0_writeb(bus->func, cccr, SDIO_CCCR_IENx, NULL); - sdio_release_host(bus->func); flags = irq_get_trigger_type(bus->of_irq); if (!flags) flags = IRQF_TRIGGER_HIGH; flags |
Re: [PATCH v3 00/32] staging/wfx: usual maintenance
On Mon, Sep 13, 2021 at 03:01:31PM +0200, Jerome Pouiller wrote: > From: Jérôme Pouiller > > Hi, > > The following PR contains now usual maintenance for the wfx driver. I have > more-or-less sorted the patches by importance: > - the first ones and the two last ones are fixes for a few corner-cases > reported by users > - the patches 9 and 10 add support for CSA and TDLS > - then the end of the series is mostly cosmetics and nitpicking > > I have wait longer than I initially wanted before to send this PR. It is > because didn't want to conflict with the PR currently in review[1] to > relocate this driver into the main tree. However, this PR started to be > very large and nothing seems to move on main-tree side so I decided to not > wait longer. > > Kalle, I am going to send a new version of [1] as soon as this PR will be > accepted. I hope you will have time to review it one day :-). > > [1] > https://lore.kernel.org/all/20210315132501.441681-1-jerome.pouil...@silabs.com/ > > v3: > - Fix patch 11 and drop patch 33 (Dan) > - Fix one missing C99 comment > - Drop useless WARN_ON() (Dan) Thanks! Only dropping patch 11 and 33 was really required, but I'm happy you dropped the WARN_ON() as well. regards, dan carpenter ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v2 1/1] binder: fix freeze race
On Fri, Sep 10, 2021 at 12:15 AM Greg KH wrote: > > On Thu, Sep 09, 2021 at 11:17:42PM -0700, Li Li wrote: > > On Thu, Sep 9, 2021 at 10:38 PM Greg KH wrote: > > > > > > On Thu, Sep 09, 2021 at 08:53:16PM -0700, Li Li wrote: > > > > struct binder_frozen_status_info { > > > > __u32pid; > > > > + > > > > + /* process received sync transactions since last frozen > > > > + * bit 0: received sync transaction after being frozen > > > > + * bit 1: new pending sync transaction during freezing > > > > + */ > > > > __u32sync_recv; > > > > > > You just changed a user/kernel api here, did you just break existing > > > userspace applications? If not, how did that not happen? > > > > > > > That's a good question. This design does keep backward compatibility. > > > > The existing userspace applications call ioctl(BINDER_GET_FROZEN_INFO) > > to check if there's sync or async binder transactions sent to a frozen > > process. > > > > If the existing userspace app runs on a new kernel, a sync binder call > > still sets bit 1 of sync_recv (as it's a bool variable) so the ioctl > > will return the expected value (TRUE). The app just doesn't check bit > > 1 intentionally so it doesn't have the ability to tell if there's a > > race - this behavior is aligned with what happens on an old kernel as > > the old kernel doesn't have bit 1 set at all. > > > > The bit 1 of sync_recv enables new userspace app the ability to tell > > 1) there's a sync binder transaction happened when being frozen - same > > as before; and 2) if that sync binder transaction happens exactly when > > there's a race - a new information for rollback decision. > > Ah, can you add that to the changelog text to make it more obvious? > Sure, added that to V3, plus other minor improvements listed in the cover letter. Please let me know if there's anything else I should continue to improve. https://lore.kernel.org/lkml/20210910164210.2282716-1-dua...@chromium.org/ BTW, I had a stress test running, repeatedly freezing and unfreezing a couple apps every second, which at the same time initiates new binder transactions in a loop. The overnight stress test during the past weekend showed positive results. Without this kernel patch, the reply transaction will fail in tens of iterations. With this kernel patch and the corresponding user space fix (rescheduling the freeze op to next second in case race happens), the stress test runs for 24hrs without a single failure. Thanks, Li ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[driver-core:debugfs_cleanup] BUILD SUCCESS 473082c5bbad92c5909ccf75fb28df699b94de82
tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git debugfs_cleanup branch HEAD: 473082c5bbad92c5909ccf75fb28df699b94de82 fs: make d_path-like functions all have unsigned size elapsed time: 730m configs tested: 157 configs skipped: 3 The following configs have been built successfully. More configs may be tested in the coming days. gcc tested configs: arm defconfig arm64allyesconfig arm allyesconfig arm64 defconfig arm allmodconfig i386 randconfig-c001-20210913 s390 debug_defconfig powerpc bluestone_defconfig powerpc mpc8560_ads_defconfig mips rs90_defconfig arm pxa168_defconfig powerpc skiroot_defconfig arm omap2plus_defconfig arm moxart_defconfig arc haps_hs_smp_defconfig arm pcm027_defconfig arm ezx_defconfig um defconfig arm lpc18xx_defconfig powerpc obs600_defconfig m68k m5249evb_defconfig s390 alldefconfig sh ul2_defconfig powerpc maple_defconfig sh apsh4a3a_defconfig arm omap1_defconfig mips bmips_be_defconfig xtensa virt_defconfig arm u8500_defconfig powerpc wii_defconfig powerpc tqm8560_defconfig arm corgi_defconfig powerpc cm5200_defconfig ia64 bigsur_defconfig xtensa alldefconfig arm colibri_pxa300_defconfig mips ip27_defconfig sparc64 defconfig powerpc microwatt_defconfig sh polaris_defconfig arm rpc_defconfig arm am200epdkit_defconfig mipsnlm_xlr_defconfig xtensa nommu_kc705_defconfig nds32alldefconfig powerpc bamboo_defconfig mipsjmr3927_defconfig mips loongson3_defconfig powerpc allnoconfig riscvnommu_k210_defconfig mipsmaltaup_defconfig powerpc storcenter_defconfig armqcom_defconfig um x86_64_defconfig csky alldefconfig arcnsim_700_defconfig arm simpad_defconfig armpleb_defconfig m68k sun3x_defconfig h8300h8300h-sim_defconfig armdove_defconfig armneponset_defconfig shsh7785lcr_defconfig sh rts7751r2d1_defconfig openrisc alldefconfig m68kmvme16x_defconfig powerpc ep8248e_defconfig powerpc arches_defconfig riscv defconfig arm axm55xx_defconfig mips mtx1_defconfig sh se7712_defconfig arm netwinder_defconfig arc tb10x_defconfig powerpc tqm8548_defconfig h8300 h8s-sim_defconfig sh landisk_defconfig m68km5307c3_defconfig powerpc akebono_defconfig armclps711x_defconfig sh kfr2r09_defconfig sh sdk7786_defconfig mips rbtx49xx_defconfig x86_64 randconfig-c001-20210913 arm randconfig-c002-20210913 ia64 allmodconfig ia64defconfig ia64 allyesconfig m68k allmodconfig m68kdefconfig m68k allyesconfig nios2 defconfig arc allyesconfig nds32 allnoconfig nds32 defconfig nios2allyesconfig cskydefconfig alpha defconfig alphaallyesconfig h8300allyesconfig arc
[staging:staging-next] BUILD SUCCESS 0af8efc197d70cd69bf620069e3d94d1da25a8de
tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git staging-next branch HEAD: 0af8efc197d70cd69bf620069e3d94d1da25a8de staging: r8188eu: remove rtl8188e_set_hal_ops() elapsed time: 815m configs tested: 116 configs skipped: 3 The following configs have been built successfully. More configs may be tested in the coming days. gcc tested configs: arm defconfig arm64allyesconfig arm64 defconfig arm allyesconfig arm allmodconfig i386 randconfig-c001-20210913 arm aspeed_g4_defconfig m68kq40_defconfig armkeystone_defconfig powerpc canyonlands_defconfig mipse55_defconfig powerpc maple_defconfig sh apsh4a3a_defconfig arm omap1_defconfig mips bmips_be_defconfig arm corgi_defconfig powerpc cm5200_defconfig ia64 bigsur_defconfig xtensa alldefconfig arm davinci_all_defconfig powerpc redwood_defconfig arm netwinder_defconfig powerpccell_defconfig mips maltasmvp_defconfig nds32alldefconfig powerpc bamboo_defconfig mipsjmr3927_defconfig mips loongson3_defconfig riscvnommu_k210_defconfig mipsmaltaup_defconfig powerpc storcenter_defconfig arm bcm2835_defconfig m68k atari_defconfig sh secureedge5410_defconfig sh se7721_defconfig x86_64 randconfig-c001-20210913 arm randconfig-c002-20210913 ia64 allmodconfig ia64defconfig ia64 allyesconfig m68k allmodconfig m68kdefconfig m68k allyesconfig nios2 defconfig arc allyesconfig nds32 allnoconfig nds32 defconfig nios2allyesconfig cskydefconfig alpha defconfig alphaallyesconfig h8300allyesconfig arc defconfig sh allmodconfig xtensa allyesconfig parisc defconfig s390 allyesconfig s390 allmodconfig parisc allyesconfig s390defconfig i386 allyesconfig sparcallyesconfig sparc defconfig i386defconfig mips allyesconfig mips allmodconfig powerpc allyesconfig powerpc allmodconfig powerpc allnoconfig x86_64 randconfig-a002-20210913 x86_64 randconfig-a003-20210913 x86_64 randconfig-a006-20210913 x86_64 randconfig-a004-20210913 x86_64 randconfig-a005-20210913 x86_64 randconfig-a001-20210913 i386 randconfig-a004-20210913 i386 randconfig-a005-20210913 i386 randconfig-a002-20210913 i386 randconfig-a006-20210913 i386 randconfig-a003-20210913 i386 randconfig-a001-20210913 arc randconfig-r043-20210913 riscvallyesconfig riscvnommu_virt_defconfig riscv allnoconfig riscv defconfig riscv rv32_defconfig riscvallmodconfig um x86_64_defconfig um i386_defconfig x86_64 allyesconfig x86_64rhel-8.3-kselftests x86_64 defconfig x86_64 rhel-8.3 x86_64 kexec clang tested configs: riscvrandconfig-c006-20210913 x86_64 randconfig-c007-20210913 mips randconfig-c004-20210913 powerpc randconfig-c003-20210913 i386 randconfig-c001
Re: [PATCH v3 1/1] binder: fix freeze race
On Fri, Sep 10, 2021 at 9:42 AM Li Li wrote: > > From: Li Li > > Currently cgroup freezer is used to freeze the application threads, and > BINDER_FREEZE is used to freeze the corresponding binder interface. > There's already a mechanism in ioctl(BINDER_FREEZE) to wait for any > existing transactions to drain out before actually freezing the binder > interface. > > But freezing an app requires 2 steps, freezing the binder interface with > ioctl(BINDER_FREEZE) and then freezing the application main threads with > cgroupfs. This is not an atomic operation. The following race issue > might happen. > > 1) Binder interface is frozen by ioctl(BINDER_FREEZE); > 2) Main thread A initiates a new sync binder transaction to process B; > 3) Main thread A is frozen by "echo 1 > cgroup.freeze"; > 4) The response from process B reaches the frozen thread, which will > unexpectedly fail. > > This patch provides a mechanism to check if there's any new pending > transaction happening between ioctl(BINDER_FREEZE) and freezing the > main thread. If there's any, the main thread freezing operation can > be rolled back to finish the pending transaction. > > Furthermore, the response might reach the binder driver before the > rollback actually happens. That will still cause failed transaction. > > As the other process doesn't wait for another response of the response, > the response transaction failure can be fixed by treating the response > transaction like an oneway/async one, allowing it to reach the frozen > thread. And it will be consumed when the thread gets unfrozen later. > > NOTE: This patch reuses the existing definition of struct > binder_frozen_status_info but expands the bit assignments of __u32 > member sync_recv. > > To ensure backward compatibility, bit 0 of sync_recv still indicates > there's an outstanding sync binder transaction. This patch adds new > information to bit 1 of sync_recv, indicating the binder transaction > happens exactly when there's a race. > > If an existing userspace app runs on a new kernel, a sync binder call > will set bit 0 of sync_recv so ioctl(BINDER_GET_FROZEN_INFO) still > return the expected value (true). The app just doesn't check bit 1 > intentionally so it doesn't have the ability to tell if there's a race. > This behavior is aligned with what happens on an old kernel which > doesn't set bit 1 at all. > > A new userspace app can 1) check bit 0 to know if there's a sync binder > transaction happened when being frozen - same as before; and 2) check > bit 1 to know if that sync binder transaction happened exactly when > there's a race - a new information for rollback decision. > > Fixes: 432ff1e91694 ("binder: BINDER_FREEZE ioctl") > Test: stress test with apps being frozen and initiating binder calls at > the same time, confirmed the pending transactions succeeded. > Signed-off-by: Li Li Acked-by: Todd Kjos > --- > drivers/android/binder.c| 35 - > drivers/android/binder_internal.h | 2 ++ > include/uapi/linux/android/binder.h | 7 ++ > 3 files changed, 38 insertions(+), 6 deletions(-) > > diff --git a/drivers/android/binder.c b/drivers/android/binder.c > index d9030cb6b1e4..1a68c2f590cf 100644 > --- a/drivers/android/binder.c > +++ b/drivers/android/binder.c > @@ -3038,9 +3038,8 @@ static void binder_transaction(struct binder_proc *proc, > if (reply) { > binder_enqueue_thread_work(thread, tcomplete); > binder_inner_proc_lock(target_proc); > - if (target_thread->is_dead || target_proc->is_frozen) { > - return_error = target_thread->is_dead ? > - BR_DEAD_REPLY : BR_FROZEN_REPLY; > + if (target_thread->is_dead) { > + return_error = BR_DEAD_REPLY; > binder_inner_proc_unlock(target_proc); > goto err_dead_proc_or_thread; > } > @@ -4648,6 +4647,22 @@ static int binder_ioctl_get_node_debug_info(struct > binder_proc *proc, > return 0; > } > > +static bool binder_txns_pending_ilocked(struct binder_proc *proc) > +{ > + struct rb_node *n; > + struct binder_thread *thread; > + > + if (proc->outstanding_txns > 0) > + return true; > + > + for (n = rb_first(&proc->threads); n; n = rb_next(n)) { > + thread = rb_entry(n, struct binder_thread, rb_node); > + if (thread->transaction_stack) > + return true; > + } > + return false; > +} > + > static int binder_ioctl_freeze(struct binder_freeze_info *info, >struct binder_proc *target_proc) > { > @@ -4679,8 +4694,13 @@ static int binder_ioctl_freeze(struct > binder_freeze_info *info, > (!target_proc->outstanding_txns), > msecs_to_jiffies(info->timeout_ms)); > > - if (!ret && target_proc->outstanding_txns) >
[staging:staging-testing] BUILD SUCCESS 8757f705d936ad9579110aa621995172539aa16b
tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git staging-testing branch HEAD: 8757f705d936ad9579110aa621995172539aa16b staging: vchiq_dev: cleanup code alignment issues elapsed time: 729m configs tested: 132 configs skipped: 3 The following configs have been built successfully. More configs may be tested in the coming days. gcc tested configs: arm defconfig arm64allyesconfig arm64 defconfig arm allyesconfig arm allmodconfig i386 randconfig-c001-20210913 powerpc motionpro_defconfig arm axm55xx_defconfig powerpc mpc8540_ads_defconfig m68km5307c3_defconfig powerpc ppc6xx_defconfig mips loongson1b_defconfig powerpc taishan_defconfig arm s3c2410_defconfig armmps2_defconfig xtensa cadence_csp_defconfig arm davinci_all_defconfig powerpc redwood_defconfig arm netwinder_defconfig powerpccell_defconfig mips maltasmvp_defconfig sh defconfig mips ip27_defconfig powerpc katmai_defconfig powerpc tqm8555_defconfig arm ixp4xx_defconfig mips sb1250_swarm_defconfig xtensa virt_defconfig sparc64 alldefconfig xtensa iss_defconfig openriscor1ksim_defconfig sh kfr2r09_defconfig powerpc linkstation_defconfig mips bigsur_defconfig mipsmaltaup_defconfig arcnsim_700_defconfig arm mxs_defconfig powerpc iss476-smp_defconfig arm bcm2835_defconfig m68k atari_defconfig sh secureedge5410_defconfig sh se7721_defconfig arm aspeed_g5_defconfig riscvnommu_virt_defconfig xtensa audio_kc705_defconfig alpha defconfig s390 alldefconfig h8300allyesconfig armneponset_defconfig powerpc stx_gp3_defconfig arm viper_defconfig mips cobalt_defconfig shedosk7705_defconfig x86_64 randconfig-c001-20210913 arm randconfig-c002-20210913 ia64 allmodconfig ia64defconfig ia64 allyesconfig m68k allmodconfig m68kdefconfig m68k allyesconfig nios2 defconfig arc allyesconfig nds32 allnoconfig nds32 defconfig nios2allyesconfig cskydefconfig alphaallyesconfig arc defconfig sh allmodconfig xtensa allyesconfig parisc defconfig s390 allyesconfig s390 allmodconfig parisc allyesconfig s390defconfig i386 allyesconfig sparcallyesconfig sparc defconfig i386defconfig mips allyesconfig mips allmodconfig powerpc allmodconfig powerpc allnoconfig powerpc allyesconfig x86_64 randconfig-a002-20210913 x86_64 randconfig-a003-20210913 x86_64 randconfig-a006-20210913 x86_64 randconfig-a004-20210913 x86_64 randconfig-a005-20210913 x86_64 randconfig-a001-20210913 i386 randconfig-a004-20210913 i386 randconfig-a005-20210913 i386 randconfig-a002-20210913 i386 randconfig-a006-20210913 i386 randconfig-a003-20210913 i386 randconfig-a001-20210913 arc randconfig-r043-20210913 riscvnommu_k210_defconfig riscvallyesconfig riscv