Re: [PATCH] staging: wfx: fix reset GPIO polarity
On Wednesday 4 December 2019 17:59:46 CET Michał Mirosław wrote: > Driver inverts meaning of GPIO_ACTIVE_LOW/HIGH. Fix it to prevent > confusion. > > Signed-off-by: Michał Mirosław > --- > drivers/staging/wfx/bus_spi.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/drivers/staging/wfx/bus_spi.c b/drivers/staging/wfx/bus_spi.c > index ab0cda1e124f..73d0157a86ba 100644 > --- a/drivers/staging/wfx/bus_spi.c > +++ b/drivers/staging/wfx/bus_spi.c > @@ -199,9 +199,9 @@ static int wfx_spi_probe(struct spi_device *func) > if (!bus->gpio_reset) { > dev_warn(>dev, "try to load firmware anyway\n"); > } else { > - gpiod_set_value(bus->gpio_reset, 0); > - udelay(100); > gpiod_set_value(bus->gpio_reset, 1); > + udelay(100); > + gpiod_set_value(bus->gpio_reset, 0); > udelay(2000); > } Hello Michał, I did not find real consensus in kernel code. My personal taste would be to keep this gpio "ACTIVE_HIGH" and rename it gpio_nreset. What do you think about it? (in add, this solution would explicitly change the name of the DT attribute instead of changing the semantic of the existing attribute) -- Jérôme Pouiller ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH] staging: wfx: fix reset GPIO polarity
On Thursday 5 December 2019 15:49:55 CET Michał Mirosław wrote: > On Thu, Dec 05, 2019 at 02:08:23PM +0000, Jérôme Pouiller wrote: > > On Wednesday 4 December 2019 17:59:46 CET Michał Mirosław wrote: > > > Driver inverts meaning of GPIO_ACTIVE_LOW/HIGH. Fix it to prevent > > > confusion. > > > > > > Signed-off-by: Michał Mirosław > > > --- > > > drivers/staging/wfx/bus_spi.c | 4 ++-- > > > 1 file changed, 2 insertions(+), 2 deletions(-) > > > > > > diff --git a/drivers/staging/wfx/bus_spi.c b/drivers/staging/wfx/bus_spi.c > > > index ab0cda1e124f..73d0157a86ba 100644 > > > --- a/drivers/staging/wfx/bus_spi.c > > > +++ b/drivers/staging/wfx/bus_spi.c > > > @@ -199,9 +199,9 @@ static int wfx_spi_probe(struct spi_device *func) > > > if (!bus->gpio_reset) { > > > dev_warn(>dev, "try to load firmware anyway\n"); > > > } else { > > > - gpiod_set_value(bus->gpio_reset, 0); > > > - udelay(100); > > > gpiod_set_value(bus->gpio_reset, 1); > > > + udelay(100); > > > + gpiod_set_value(bus->gpio_reset, 0); > > > udelay(2000); > > > } > > Hello Michał, > > > > I did not find real consensus in kernel code. My personal taste would > > be to keep this gpio "ACTIVE_HIGH" and rename it gpio_nreset. What do > > you think about it? > > > > (in add, this solution would explicitly change the name of the DT > > attribute instead of changing the semantic of the existing attribute) > > As a user (board developer) I would expect that DT describes the > GPIO meaning directly: so when I specify GPIO_ACTIVE_HIGH flag I also > wire up the board so that outputing 1 would match the active state of > the chip's signal (that might be inverted for some reason). I think we > should stick to what is said in Documentation/devicetree/bindings/gpio.txt > (section 1.1). > > Since this is a new driver in kernel I would prefer to fix it at the start. > Changing the name of the GPIO would also be ok, but since there is no DT > binding yet, I guess there will come up an issue of 'compatible' string > format that does not match 'vendor,chip' now, so we can use the difference > for backwards compatibility with out-of-tree driver if needed. Current 'compatible' string is "silabs,wfx-spi" (for now, it is the same for out-of-tree and in-tree driver). And indeed, "wfx" does not names a chip. The three chips currently supported are wf200, wf200s and wfm200. Since the driver provides DT bindings for SPI and SDIO buses, I think we have to keep the "-spi" suffix. So compatible strings should be "silabs,wf200-spi", "silabs,wf200s-spi" and "silabs,wfm200-spi", right? So we could fix the semantic of gpios-reset and keep the backward compatibility. Looks perfect. I can make this change in my next pull-request (but if you submit a patch, it will probably go faster :) ). -- Jérôme Pouiller ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH 07/55] staging: wfx: ensure that retry policy always fallbacks to MCS0 / 1Mbps
On Monday 16 December 2019 19:08:39 CET Felix Fietkau wrote: > On 2019-12-16 18:03, Jérôme Pouiller wrote: > > From: Jérôme Pouiller > > > > When not using HT mode, minstrel always includes 1Mbps as fallback rate. > > But, when using HT mode, this fallback is not included. Yet, it seems > > that it could save some frames. So, this patch add it unconditionally. > > > > Signed-off-by: Jérôme Pouiller > Are you sure that's a good idea? Sometimes a little packet loss can be > preferable over a larger amount of airtime wasted through using really > low rates. Especially when you consider bufferbloat. Hello Felix, I have observed that, in some circumstances, TCP throughput was far better with 802.11g than with 802.11n. I found that 802.11n had more Tx failures. These failures have big impacts on the congestion window. When the congestion window is low, it impacts the capacity of aggregation of the link. Thus, it does not help to improve the congestion windows. By investigating deeper, it appears that the minstrel (used by 802.11g) always add rate 1Mbps to the rate list while minstrel_ht (used by 802.11n) don't (compare minstrel_update_rates() and minstrel_ht_update_rates()). This difference seems to be correlated to the difference of TCP throughput I can observe. I did some search in git history and I did not find any explanation for this difference between minstrel and minstrel_ht (however, it seems you are the right person to ask :) ). I didn't find why it would be efficient on minstrel and inefficient on minstrel_ht. And since this change fix the issue that I observed, I have tried to apply it and wait for feedback. -- Jérôme Pouiller ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 40/55] staging: wfx: simplify hif_set_pm() usage
From: Jérôme Pouiller The struct hif_req_set_pm_mode comes from hardware API. It is not intended to be manipulated in upper layers of the driver. So, this patch relocate the handling of this struct to hif_set_pm() (the low level function). Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/hif_tx.c | 10 -- drivers/staging/wfx/hif_tx.h | 2 +- drivers/staging/wfx/sta.c| 25 + 3 files changed, 18 insertions(+), 19 deletions(-) diff --git a/drivers/staging/wfx/hif_tx.c b/drivers/staging/wfx/hif_tx.c index 6fb98ddbc0e2..9cbf9d916f5f 100644 --- a/drivers/staging/wfx/hif_tx.c +++ b/drivers/staging/wfx/hif_tx.c @@ -360,13 +360,19 @@ int hif_set_edca_queue_params(struct wfx_vif *wvif, return ret; } -int hif_set_pm(struct wfx_vif *wvif, const struct hif_req_set_pm_mode *arg) +int hif_set_pm(struct wfx_vif *wvif, bool ps, int dynamic_ps_timeout) { int ret; struct hif_msg *hif; struct hif_req_set_pm_mode *body = wfx_alloc_hif(sizeof(*body), ); - memcpy(body, arg, sizeof(*body)); + if (ps) { + body->pm_mode.enter_psm = 1; + // Firmware does not support more than 128ms + body->fast_psm_idle_period = min(dynamic_ps_timeout * 2, 255); + if (body->fast_psm_idle_period) + body->pm_mode.fast_psm = 1; + } wfx_fill_header(hif, wvif->id, HIF_REQ_ID_SET_PM_MODE, sizeof(*body)); ret = wfx_cmd_send(wvif->wdev, hif, NULL, 0, false); kfree(hif); diff --git a/drivers/staging/wfx/hif_tx.h b/drivers/staging/wfx/hif_tx.h index f61ae7b0d41c..bb5860ee6542 100644 --- a/drivers/staging/wfx/hif_tx.h +++ b/drivers/staging/wfx/hif_tx.h @@ -47,7 +47,7 @@ int hif_write_mib(struct wfx_dev *wdev, int vif_id, u16 mib_id, int hif_scan(struct wfx_vif *wvif, const struct wfx_scan_params *arg); int hif_stop_scan(struct wfx_vif *wvif); int hif_join(struct wfx_vif *wvif, const struct hif_req_join *arg); -int hif_set_pm(struct wfx_vif *wvif, const struct hif_req_set_pm_mode *arg); +int hif_set_pm(struct wfx_vif *wvif, bool ps, int dynamic_ps_timeout); int hif_set_bss_params(struct wfx_vif *wvif, const struct hif_req_set_bss_params *arg); int hif_add_key(struct wfx_dev *wdev, const struct hif_req_add_key *arg); diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c index 9eca35d91ad3..b4007afcd0c6 100644 --- a/drivers/staging/wfx/sta.c +++ b/drivers/staging/wfx/sta.c @@ -291,37 +291,30 @@ void wfx_configure_filter(struct ieee80211_hw *hw, static int wfx_update_pm(struct wfx_vif *wvif) { struct ieee80211_conf *conf = >wdev->hw->conf; - struct hif_req_set_pm_mode pm; + bool ps = conf->flags & IEEE80211_CONF_PS; + int ps_timeout = conf->dynamic_ps_timeout; + WARN_ON(conf->dynamic_ps_timeout < 0); if (wvif->state != WFX_STATE_STA || !wvif->bss_params.aid) return 0; - - memset(, 0, sizeof(pm)); - if (conf->flags & IEEE80211_CONF_PS) { - pm.pm_mode.enter_psm = 1; - // Firmware does not support more than 128ms - pm.fast_psm_idle_period = - min(conf->dynamic_ps_timeout * 2, 255); - if (pm.fast_psm_idle_period) - pm.pm_mode.fast_psm = 1; - } - + if (!ps) + ps_timeout = 0; if (wvif->edca.uapsd_mask) - pm.pm_mode.fast_psm = 0; + ps_timeout = 0; // Kernel disable PowerSave when multiple vifs are in use. In contrary, // it is absolutly necessary to enable PowerSave for WF200 // FIXME: only if channel vif0 != channel vif1 if (wvif_count(wvif->wdev) > 1) { - pm.pm_mode.enter_psm = 1; - pm.pm_mode.fast_psm = 0; + ps = true; + ps_timeout = 0; } if (!wait_for_completion_timeout(>set_pm_mode_complete, TU_TO_JIFFIES(512))) dev_warn(wvif->wdev->dev, "timeout while waiting of set_pm_mode_complete\n"); - return hif_set_pm(wvif, ); + return hif_set_pm(wvif, ps, ps_timeout); } int wfx_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, -- 2.24.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 54/55] staging: wfx: implement cancel_hw_scan()
From: Jérôme Pouiller The device provides an API to abort a scan request. Expose this feature to mac80211. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/main.c | 1 + drivers/staging/wfx/scan.c | 13 + drivers/staging/wfx/scan.h | 1 + drivers/staging/wfx/wfx.h | 1 + 4 files changed, 16 insertions(+) diff --git a/drivers/staging/wfx/main.c b/drivers/staging/wfx/main.c index cf4bcb14a12d..45c9939b7e62 100644 --- a/drivers/staging/wfx/main.c +++ b/drivers/staging/wfx/main.c @@ -135,6 +135,7 @@ static const struct ieee80211_ops wfx_ops = { .tx = wfx_tx, .conf_tx= wfx_conf_tx, .hw_scan= wfx_hw_scan, + .cancel_hw_scan = wfx_cancel_hw_scan, .sta_add= wfx_sta_add, .sta_remove = wfx_sta_remove, .sta_notify = wfx_sta_notify, diff --git a/drivers/staging/wfx/scan.c b/drivers/staging/wfx/scan.c index dde2f8868147..24061d09c404 100644 --- a/drivers/staging/wfx/scan.c +++ b/drivers/staging/wfx/scan.c @@ -54,6 +54,7 @@ static int send_scan_req(struct wfx_vif *wvif, break; } wfx_tx_lock_flush(wvif->wdev); + wvif->scan_abort = false; reinit_completion(>scan_complete); ret = hif_scan(wvif, req, start_idx, i - start_idx); if (ret < 0) @@ -68,6 +69,10 @@ static int send_scan_req(struct wfx_vif *wvif, hif_stop_scan(wvif); return -ETIMEDOUT; } + if (wvif->scan_abort) { + dev_notice(wvif->wdev->dev, "scan abort\n"); + return -ECONNABORTED; + } return i - start_idx; } @@ -115,6 +120,14 @@ int wfx_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, return 0; } +void wfx_cancel_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif) +{ + struct wfx_vif *wvif = (struct wfx_vif *)vif->drv_priv; + + wvif->scan_abort = true; + hif_stop_scan(wvif); +} + void wfx_scan_complete(struct wfx_vif *wvif, const struct hif_ind_scan_cmpl *arg) { diff --git a/drivers/staging/wfx/scan.h b/drivers/staging/wfx/scan.h index b547f1927d72..bba9f15a9ff5 100644 --- a/drivers/staging/wfx/scan.h +++ b/drivers/staging/wfx/scan.h @@ -18,6 +18,7 @@ struct wfx_vif; void wfx_hw_scan_work(struct work_struct *work); int wfx_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_scan_request *req); +void wfx_cancel_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif); void wfx_scan_complete(struct wfx_vif *wvif, const struct hif_ind_scan_cmpl *ind); diff --git a/drivers/staging/wfx/wfx.h b/drivers/staging/wfx/wfx.h index db433bee87af..0a3df382af03 100644 --- a/drivers/staging/wfx/wfx.h +++ b/drivers/staging/wfx/wfx.h @@ -127,6 +127,7 @@ struct wfx_vif { struct mutexscan_lock; struct work_struct scan_work; struct completion scan_complete; + boolscan_abort; struct ieee80211_scan_request *scan_req; struct completion set_pm_mode_complete; -- 2.24.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH 07/55] staging: wfx: ensure that retry policy always fallbacks to MCS0 / 1Mbps
On Tuesday 17 December 2019 12:20:40 CET Felix Fietkau wrote: [...] > Instead of using per-packet rate info, implement the > .sta_rate_tbl_update callback to maintain a primary tx policy used for > all non-probing non-fixed-rate packets, which you can alter while > packets using it are queued already. > The existing approach using per-packet tx_info data should then be used > only for probing or fixed-rate packets. > You then probably have to be a bit clever in the tx status path for > figuring out what rates were actually used. Indeed, I have noticed that we are are to react to any changes on the link quality. Your idea may helps a lot. Thank you. Do you know if I can safely rely on IEEE80211_TX_CTL_RATE_CTRL_PROBE and IEEE80211_TX_CTL_USE_MINRATE to detect probing and fixed-rate packets? I currently work on others parts, but I think I will try your suggestion in January. One last thing, do you know why minstrel appends the lowest rate and minstrel_ht don't? They should be identical, not? -- Jérôme Pouiller ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH 01/55] staging: wfx: fix the cache of rate policies on interface reset
On Tuesday 17 December 2019 12:52:11 CET Greg Kroah-Hartman wrote: > On Mon, Dec 16, 2019 at 05:03:33PM +0000, Jérôme Pouiller wrote: > > From: Jérôme Pouiller > > > > Device and driver maintain a cache of rate policies (aka. > > tx_retry_policy in hardware API). > > > > When hif_reset() is sent to hardware, device resets its cache of rate > > policies. In order to keep driver in sync, it is necessary to do the > > same on driver. > > > > Note, when driver tries to use a rate policy that has not been defined > > on device, data is sent at 1Mbps. So, this patch should fix abnormal > > throughput observed sometime after a reset of the interface. > > > > Signed-off-by: Jérôme Pouiller > > --- > > drivers/staging/wfx/data_tx.c | 3 +-- > > drivers/staging/wfx/data_tx.h | 1 + > > drivers/staging/wfx/sta.c | 6 +- > > 3 files changed, 7 insertions(+), 3 deletions(-) > > > > diff --git a/drivers/staging/wfx/data_tx.c b/drivers/staging/wfx/data_tx.c > > index b722e9773232..02f001dab62b 100644 > > --- a/drivers/staging/wfx/data_tx.c > > +++ b/drivers/staging/wfx/data_tx.c > > @@ -249,7 +249,7 @@ static int wfx_tx_policy_upload(struct wfx_vif *wvif) > > return 0; > > } > > > > -static void wfx_tx_policy_upload_work(struct work_struct *work) > > +void wfx_tx_policy_upload_work(struct work_struct *work) > > { > > struct wfx_vif *wvif = > > container_of(work, struct wfx_vif, tx_policy_upload_work); > > @@ -270,7 +270,6 @@ void wfx_tx_policy_init(struct wfx_vif *wvif) > > spin_lock_init(>lock); > > INIT_LIST_HEAD(>used); > > INIT_LIST_HEAD(>free); > > - INIT_WORK(>tx_policy_upload_work, wfx_tx_policy_upload_work); > > > > for (i = 0; i < HIF_MIB_NUM_TX_RATE_RETRY_POLICIES; ++i) > > list_add(>cache[i].link, >free); > > diff --git a/drivers/staging/wfx/data_tx.h b/drivers/staging/wfx/data_tx.h > > index 29faa5640516..a0f9ae69baf5 100644 > > --- a/drivers/staging/wfx/data_tx.h > > +++ b/drivers/staging/wfx/data_tx.h > > @@ -61,6 +61,7 @@ struct wfx_tx_priv { > > } __packed; > > > > void wfx_tx_policy_init(struct wfx_vif *wvif); > > +void wfx_tx_policy_upload_work(struct work_struct *work); > > > > void wfx_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, > > struct sk_buff *skb); > > diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c > > index 29848a202ab4..471dd15b227f 100644 > > --- a/drivers/staging/wfx/sta.c > > +++ b/drivers/staging/wfx/sta.c > > @@ -592,6 +592,7 @@ static void wfx_do_unjoin(struct wfx_vif *wvif) > > wfx_tx_flush(wvif->wdev); > > hif_keep_alive_period(wvif, 0); > > hif_reset(wvif, false); > > + wfx_tx_policy_init(wvif); > > hif_set_output_power(wvif, wvif->wdev->output_power * 10); > > wvif->dtim_period = 0; > > hif_set_macaddr(wvif, wvif->vif->addr); > > @@ -880,8 +881,10 @@ static int wfx_update_beaconing(struct wfx_vif *wvif) > > if (wvif->state != WFX_STATE_AP || > > wvif->beacon_int != conf->beacon_int) { > > wfx_tx_lock_flush(wvif->wdev); > > - if (wvif->state != WFX_STATE_PASSIVE) > > + if (wvif->state != WFX_STATE_PASSIVE) { > > hif_reset(wvif, false); > > + wfx_tx_policy_init(wvif); > > + } > > wvif->state = WFX_STATE_PASSIVE; > > wfx_start_ap(wvif); > > wfx_tx_unlock(wvif->wdev); > > @@ -1567,6 +1570,7 @@ int wfx_add_interface(struct ieee80211_hw *hw, struct > > ieee80211_vif *vif) > > INIT_WORK(>set_cts_work, wfx_set_cts_work); > > INIT_WORK(>unjoin_work, wfx_unjoin_work); > > > > + INIT_WORK(>tx_policy_upload_work, wfx_tx_policy_upload_work); > > mutex_unlock(>conf_mutex); > > > > hif_set_macaddr(wvif, vif->addr); > > Meta-comment here. > > I've been having to hand-edit your patches to get them to be able to > apply so far, which is fine for 1-10 patches at a time, but when staring > down a 55-patch series, that's not ok for my end. > > The problem is that your email client is turning everything into base64 > text. On it's own, that's fine, but when doing so it turns the > line-ends from unix ones, into dos line-ends. So, when git
[PATCH v2 32/55] staging: wfx: drop useless argument from wfx_set_pm()
From: Jérôme Pouiller Argument to wfx_set_pm() is always wvif->powersave_mode. So, we can simplify it. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/sta.c | 16 +++- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c index eb087b9c8097..ee1b15950389 100644 --- a/drivers/staging/wfx/sta.c +++ b/drivers/staging/wfx/sta.c @@ -326,12 +326,10 @@ void wfx_configure_filter(struct ieee80211_hw *hw, } } -static int wfx_set_pm(struct wfx_vif *wvif, - const struct hif_req_set_pm_mode *arg) +static int wfx_update_pm(struct wfx_vif *wvif) { - struct hif_req_set_pm_mode pm = *arg; + struct hif_req_set_pm_mode pm = wvif->powersave_mode; u16 uapsd_flags; - int ret; if (wvif->state != WFX_STATE_STA || !wvif->bss_params.aid) return 0; @@ -390,7 +388,7 @@ int wfx_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, if (!ret && wvif->setbssparams_done && wvif->state == WFX_STATE_STA && old_uapsd_flags != new_uapsd_flags) - ret = wfx_set_pm(wvif, >powersave_mode); + ret = wfx_update_pm(wvif); } } else { ret = -EINVAL; @@ -1014,7 +1012,7 @@ static void wfx_join_finalize(struct wfx_vif *wvif, hif_set_bss_params(wvif, >bss_params); wvif->setbssparams_done = true; wfx_set_beacon_wakeup_period_work(>set_beacon_wakeup_period_work); - wfx_set_pm(wvif, >powersave_mode); + wfx_update_pm(wvif); } } @@ -1451,7 +1449,7 @@ int wfx_config(struct ieee80211_hw *hw, u32 changed) } } if (wvif->state == WFX_STATE_STA && wvif->bss_params.aid) - wfx_set_pm(wvif, >powersave_mode); + wfx_update_pm(wvif); } wvif = wdev_to_wvif(wdev, 0); } @@ -1591,7 +1589,7 @@ int wfx_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) else hif_set_block_ack_policy(wvif, 0x00, 0x00); // Combo force powersave mode. We can re-enable it now - wfx_set_pm(wvif, >powersave_mode); + wfx_update_pm(wvif); } return 0; } @@ -1666,7 +1664,7 @@ void wfx_remove_interface(struct ieee80211_hw *hw, else hif_set_block_ack_policy(wvif, 0x00, 0x00); // Combo force powersave mode. We can re-enable it now - wfx_set_pm(wvif, >powersave_mode); + wfx_update_pm(wvif); } } -- 2.24.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 33/55] staging: wfx: remove redundant test while calling wfx_update_pm()
From: Jérôme Pouiller Condition about wvif->state and wvif->bss_params.aid is already checked at beginning of wfx_update_pm(). Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/sta.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c index ee1b15950389..91fa4d8aa37d 100644 --- a/drivers/staging/wfx/sta.c +++ b/drivers/staging/wfx/sta.c @@ -1448,8 +1448,7 @@ int wfx_config(struct ieee80211_hw *hw, u32 changed) 2, 255); } } - if (wvif->state == WFX_STATE_STA && wvif->bss_params.aid) - wfx_update_pm(wvif); + wfx_update_pm(wvif); } wvif = wdev_to_wvif(wdev, 0); } -- 2.24.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 52/55] staging: wfx: delayed_unjoin cannot happen
From: Jérôme Pouiller Original code allows to detect an unjoin request during a scan and delaying the unjoin request. However, it is far easier to just block the unjoin request until the end of the scan request. In fact, it is already the case since scan and unjoin are protected by conf_mutex. So, currently, the handling of delayed_unjoin is just dead code. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/scan.c | 7 +-- drivers/staging/wfx/sta.c | 14 -- drivers/staging/wfx/wfx.h | 1 - 3 files changed, 1 insertion(+), 21 deletions(-) diff --git a/drivers/staging/wfx/scan.c b/drivers/staging/wfx/scan.c index 540009b72240..bdbce6926e91 100644 --- a/drivers/staging/wfx/scan.c +++ b/drivers/staging/wfx/scan.c @@ -95,12 +95,7 @@ void wfx_hw_scan_work(struct work_struct *work) mutex_unlock(>wdev->conf_mutex); mutex_unlock(>scan_lock); __ieee80211_scan_completed_compat(wvif->wdev->hw, ret < 0); - if (wvif->delayed_unjoin) { - wvif->delayed_unjoin = false; - wfx_tx_lock(wvif->wdev); - if (!schedule_work(>unjoin_work)) - wfx_tx_unlock(wvif->wdev); - } else if (wvif->delayed_link_loss) { + if (wvif->delayed_link_loss) { wvif->delayed_link_loss = false; wfx_cqm_bssloss_sm(wvif, 1, 0, 0); } diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c index 4354bb8081c5..7ae763e96455 100644 --- a/drivers/staging/wfx/sta.c +++ b/drivers/staging/wfx/sta.c @@ -66,10 +66,6 @@ void wfx_cqm_bssloss_sm(struct wfx_vif *wvif, int init, int good, int bad) wvif->delayed_link_loss = 0; cancel_work_sync(>bss_params_work); - /* If we have a pending unjoin */ - if (wvif->delayed_unjoin) - goto end; - if (init) { schedule_delayed_work(>bss_loss_work, HZ); wvif->bss_loss_state = 0; @@ -501,16 +497,6 @@ static void wfx_do_unjoin(struct wfx_vif *wvif) { mutex_lock(>wdev->conf_mutex); - if (!mutex_trylock(>scan_lock)) { - if (wvif->delayed_unjoin) - dev_dbg(wvif->wdev->dev, - "delayed unjoin is already scheduled\n"); - else - wvif->delayed_unjoin = true; - goto done; - } - mutex_unlock(>scan_lock); - wvif->delayed_link_loss = false; if (!wvif->state) diff --git a/drivers/staging/wfx/wfx.h b/drivers/staging/wfx/wfx.h index b5f763c3fac7..5e7c911db024 100644 --- a/drivers/staging/wfx/wfx.h +++ b/drivers/staging/wfx/wfx.h @@ -122,7 +122,6 @@ struct wfx_vif { struct work_struct set_cts_work; int join_complete_status; - booldelayed_unjoin; struct work_struct unjoin_work; /* avoid some operations in parallel with scan */ -- 2.24.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 31/55] staging: wfx: declare wfx_set_pm() static
From: Jérôme Pouiller wfx_set_pm() is now only used by sta.c. It can be declared static. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/sta.c | 57 --- drivers/staging/wfx/sta.h | 1 - 2 files changed, 30 insertions(+), 28 deletions(-) diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c index fb45aa66fc56..eb087b9c8097 100644 --- a/drivers/staging/wfx/sta.c +++ b/drivers/staging/wfx/sta.c @@ -326,6 +326,36 @@ void wfx_configure_filter(struct ieee80211_hw *hw, } } +static int wfx_set_pm(struct wfx_vif *wvif, + const struct hif_req_set_pm_mode *arg) +{ + struct hif_req_set_pm_mode pm = *arg; + u16 uapsd_flags; + int ret; + + if (wvif->state != WFX_STATE_STA || !wvif->bss_params.aid) + return 0; + + memcpy(_flags, >uapsd_info, sizeof(uapsd_flags)); + + if (uapsd_flags != 0) + pm.pm_mode.fast_psm = 0; + + // Kernel disable PowerSave when multiple vifs are in use. In contrary, + // it is absolutly necessary to enable PowerSave for WF200 + // FIXME: only if channel vif0 != channel vif1 + if (wvif_count(wvif->wdev) > 1) { + pm.pm_mode.enter_psm = 1; + pm.pm_mode.fast_psm = 0; + } + + if (!wait_for_completion_timeout(>set_pm_mode_complete, +msecs_to_jiffies(300))) + dev_warn(wvif->wdev->dev, +"timeout while waiting of set_pm_mode_complete\n"); + return hif_set_pm(wvif, ); +} + int wfx_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u16 queue, const struct ieee80211_tx_queue_params *params) { @@ -371,33 +401,6 @@ int wfx_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, return ret; } -int wfx_set_pm(struct wfx_vif *wvif, const struct hif_req_set_pm_mode *arg) -{ - struct hif_req_set_pm_mode pm = *arg; - u16 uapsd_flags; - - if (wvif->state != WFX_STATE_STA || !wvif->bss_params.aid) - return 0; - - memcpy(_flags, >uapsd_info, sizeof(uapsd_flags)); - - if (uapsd_flags != 0) - pm.pm_mode.fast_psm = 0; - - // Kernel disable PowerSave when multiple vifs are in use. In contrary, - // it is absolutly necessary to enable PowerSave for WF200 - if (wvif_count(wvif->wdev) > 1) { - pm.pm_mode.enter_psm = 1; - pm.pm_mode.fast_psm = 0; - } - - if (!wait_for_completion_timeout(>set_pm_mode_complete, -msecs_to_jiffies(300))) - dev_warn(wvif->wdev->dev, -"timeout while waiting of set_pm_mode_complete\n"); - return hif_set_pm(wvif, ); -} - int wfx_set_rts_threshold(struct ieee80211_hw *hw, u32 value) { struct wfx_dev *wdev = hw->priv; diff --git a/drivers/staging/wfx/sta.h b/drivers/staging/wfx/sta.h index 721b7cee9c10..4719807bc25a 100644 --- a/drivers/staging/wfx/sta.h +++ b/drivers/staging/wfx/sta.h @@ -97,7 +97,6 @@ void wfx_suspend_resume(struct wfx_vif *wvif, // Other Helpers void wfx_cqm_bssloss_sm(struct wfx_vif *wvif, int init, int good, int bad); void wfx_update_filtering(struct wfx_vif *wvif); -int wfx_set_pm(struct wfx_vif *wvif, const struct hif_req_set_pm_mode *arg); int wfx_fwd_probe_req(struct wfx_vif *wvif, bool enable); #endif /* WFX_STA_H */ -- 2.24.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 39/55] staging: wfx: simplify hif_set_uapsd_info() usage
From: Jérôme Pouiller It is useless to keep uapsd_info in struct wfx_vif. This structure can be rebuilt just before to be sent. In add, the struct hif_mib_set_uapsd_information comes from hardware API. It is not intended to be manipulated in upper layers of the driver. So, this patch relocates the handling of this struct to hif_set_uapsd_info() (the low level function). Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/hif_tx_mib.h | 15 +--- drivers/staging/wfx/sta.c| 42 ++-- drivers/staging/wfx/wfx.h| 1 - 3 files changed, 14 insertions(+), 44 deletions(-) diff --git a/drivers/staging/wfx/hif_tx_mib.h b/drivers/staging/wfx/hif_tx_mib.h index 9be74881c56c..d77765f75f10 100644 --- a/drivers/staging/wfx/hif_tx_mib.h +++ b/drivers/staging/wfx/hif_tx_mib.h @@ -238,12 +238,21 @@ static inline int hif_use_multi_tx_conf(struct wfx_dev *wdev, , sizeof(arg)); } -static inline int hif_set_uapsd_info(struct wfx_vif *wvif, -struct hif_mib_set_uapsd_information *arg) +static inline int hif_set_uapsd_info(struct wfx_vif *wvif, unsigned long val) { + struct hif_mib_set_uapsd_information arg = { }; + + if (val & BIT(IEEE80211_AC_VO)) + arg.trig_voice = 1; + if (val & BIT(IEEE80211_AC_VI)) + arg.trig_video = 1; + if (val & BIT(IEEE80211_AC_BE)) + arg.trig_be = 1; + if (val & BIT(IEEE80211_AC_BK)) + arg.trig_bckgrnd = 1; return hif_write_mib(wvif->wdev, wvif->id, HIF_MIB_ID_SET_UAPSD_INFORMATION, -arg, sizeof(*arg)); +, sizeof(arg)); } static inline int hif_erp_use_protection(struct wfx_vif *wvif, bool enable) diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c index e59560f499ea..9eca35d91ad3 100644 --- a/drivers/staging/wfx/sta.c +++ b/drivers/staging/wfx/sta.c @@ -112,44 +112,6 @@ void wfx_cqm_bssloss_sm(struct wfx_vif *wvif, int init, int good, int bad) mutex_unlock(>bss_loss_lock); } -static int wfx_set_uapsd_param(struct wfx_vif *wvif, - const struct wfx_edca_params *arg) -{ - /* Here's the mapping AC [queue, bit] -* VO [0,3], VI [1, 2], BE [2, 1], BK [3, 0] -*/ - - if (arg->uapsd_mask & BIT(IEEE80211_AC_VO)) - wvif->uapsd_info.trig_voice = 1; - else - wvif->uapsd_info.trig_voice = 0; - - if (arg->uapsd_mask & BIT(IEEE80211_AC_VI)) - wvif->uapsd_info.trig_video = 1; - else - wvif->uapsd_info.trig_video = 0; - - if (arg->uapsd_mask & BIT(IEEE80211_AC_BE)) - wvif->uapsd_info.trig_be = 1; - else - wvif->uapsd_info.trig_be = 0; - - if (arg->uapsd_mask & BIT(IEEE80211_AC_BK)) - wvif->uapsd_info.trig_bckgrnd = 1; - else - wvif->uapsd_info.trig_bckgrnd = 0; - - /* Currently pseudo U-APSD operation is not supported, so setting -* MinAutoTriggerInterval, MaxAutoTriggerInterval and -* AutoTriggerStep to 0 -*/ - wvif->uapsd_info.min_auto_trigger_interval = 0; - wvif->uapsd_info.max_auto_trigger_interval = 0; - wvif->uapsd_info.auto_trigger_step = 0; - - return hif_set_uapsd_info(wvif, >uapsd_info); -} - int wfx_fwd_probe_req(struct wfx_vif *wvif, bool enable) { wvif->fwd_probe_req = enable; @@ -382,7 +344,7 @@ int wfx_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, hif_set_edca_queue_params(wvif, edca); if (wvif->vif->type == NL80211_IFTYPE_STATION) { - wfx_set_uapsd_param(wvif, >edca); + hif_set_uapsd_info(wvif, wvif->edca.uapsd_mask); if (wvif->setbssparams_done && wvif->state == WFX_STATE_STA) wfx_update_pm(wvif); } @@ -1552,7 +1514,7 @@ int wfx_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) hif_set_edca_queue_params(wvif, >edca.params[i]); } wvif->edca.uapsd_mask = 0; - wfx_set_uapsd_param(wvif, >edca); + hif_set_uapsd_info(wvif, wvif->edca.uapsd_mask); wfx_tx_policy_init(wvif); wvif = NULL; diff --git a/drivers/staging/wfx/wfx.h b/drivers/staging/wfx/wfx.h index c82d29764d66..ff29163436b6 100644 --- a/drivers/staging/wfx/wfx.h +++ b/drivers/staging/wfx/wfx.h @@ -114,7 +114,6 @@ struct wfx_vif { boolsetbssparams_done; struct wfx_ht_info ht_info; struct wfx_edca_params edca; - struct hif_mib_set_uapsd_information uapsd_info; struct hif_req_set_bss_params bss_params; struct work_struct bss_params_work; struct work_struct
[PATCH v2 28/55] staging: wfx: better naming for hif_mib_set_association_mode->greenfield
From: Jérôme Pouiller Current name "mixed_or_greenfield_type" does not allow to know if "true" means "mixed" of "greenfield". It is possible to use a better name and drop "enum hif_tx_mode". Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/hif_api_mib.h | 8 ++-- drivers/staging/wfx/sta.c | 2 +- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/drivers/staging/wfx/hif_api_mib.h b/drivers/staging/wfx/hif_api_mib.h index 34e4310ad71f..1603b3074bf7 100644 --- a/drivers/staging/wfx/hif_api_mib.h +++ b/drivers/staging/wfx/hif_api_mib.h @@ -395,11 +395,6 @@ struct hif_mib_non_erp_protection { u8 reserved2[3]; } __packed; -enum hif_tx_mode { - HIF_TX_MODE_MIXED= 0x0, - HIF_TX_MODE_GREENFIELD = 0x1 -}; - enum hif_tmplt { HIF_TMPLT_PRBREQ = 0x0, HIF_TMPLT_BCN = 0x1, @@ -474,7 +469,8 @@ struct hif_mib_set_association_mode { u8reserved1:4; u8short_preamble:1; u8reserved2:7; - u8mixed_or_greenfield_type; + u8greenfield:1; + u8reserved3:7; u8mpdu_start_spacing; u32 basic_rate_set; } __packed; diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c index e5c933678c47..939c64f108ed 100644 --- a/drivers/staging/wfx/sta.c +++ b/drivers/staging/wfx/sta.c @@ -996,7 +996,7 @@ static void wfx_join_finalize(struct wfx_vif *wvif, association_mode.spacing = 1; association_mode.short_preamble = info->use_short_preamble; association_mode.basic_rate_set = cpu_to_le32(wfx_rate_mask_to_hw(wvif->wdev, info->basic_rates)); - association_mode.mixed_or_greenfield_type = wfx_ht_greenfield(>ht_info); + association_mode.greenfield = wfx_ht_greenfield(>ht_info); association_mode.mpdu_start_spacing = wfx_ht_ampdu_density(>ht_info); wfx_cqm_bssloss_sm(wvif, 0, 0, 0); -- 2.24.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 48/55] staging: wfx: introduce update_probe_tmpl()
From: Jérôme Pouiller Simplify wfx_hw_scan() by splitting out the update of the probe request. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/scan.c | 59 -- 1 file changed, 31 insertions(+), 28 deletions(-) diff --git a/drivers/staging/wfx/scan.c b/drivers/staging/wfx/scan.c index 122da87bbf92..8b184efad0cf 100644 --- a/drivers/staging/wfx/scan.c +++ b/drivers/staging/wfx/scan.c @@ -49,6 +49,27 @@ static int wfx_scan_start(struct wfx_vif *wvif, return 0; } +static int update_probe_tmpl(struct wfx_vif *wvif, +struct cfg80211_scan_request *req) +{ + struct hif_mib_template_frame *tmpl; + struct sk_buff *skb; + + skb = ieee80211_probereq_get(wvif->wdev->hw, wvif->vif->addr, +NULL, 0, req->ie_len); + if (!skb) + return -ENOMEM; + + skb_put_data(skb, req->ie, req->ie_len); + skb_push(skb, 4); + tmpl = (struct hif_mib_template_frame *)skb->data; + tmpl->frame_type = HIF_TMPLT_PRBREQ; + tmpl->frame_length = cpu_to_le16(skb->len - 4); + hif_set_template_frame(wvif, tmpl); + dev_kfree_skb(skb); + return 0; +} + int wfx_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_scan_request *hw_req) @@ -56,9 +77,7 @@ int wfx_hw_scan(struct ieee80211_hw *hw, struct wfx_dev *wdev = hw->priv; struct wfx_vif *wvif = (struct wfx_vif *) vif->drv_priv; struct cfg80211_scan_request *req = _req->req; - struct sk_buff *skb; int i, ret; - struct hif_mib_template_frame *p; if (!wvif) return -EINVAL; @@ -72,29 +91,15 @@ int wfx_hw_scan(struct ieee80211_hw *hw, if (req->n_ssids > HIF_API_MAX_NB_SSIDS) return -EINVAL; - skb = ieee80211_probereq_get(hw, wvif->vif->addr, NULL, 0, req->ie_len); - if (!skb) - return -ENOMEM; - - if (req->ie_len) - memcpy(skb_put(skb, req->ie_len), req->ie, req->ie_len); - mutex_lock(>conf_mutex); - p = (struct hif_mib_template_frame *)skb_push(skb, 4); - p->frame_type = HIF_TMPLT_PRBREQ; - p->frame_length = cpu_to_le16(skb->len - 4); - ret = hif_set_template_frame(wvif, p); - skb_pull(skb, 4); - - if (!ret) - /* Host want to be the probe responder. */ - ret = wfx_fwd_probe_req(wvif, true); - if (ret) { - mutex_unlock(>conf_mutex); - dev_kfree_skb(skb); - return ret; - } + ret = update_probe_tmpl(wvif, req); + if (ret) + goto failed; + + ret = wfx_fwd_probe_req(wvif, true); + if (ret) + goto failed; wfx_tx_lock_flush(wdev); @@ -114,13 +119,11 @@ int wfx_hw_scan(struct ieee80211_hw *hw, dst->ssid_length = req->ssids[i].ssid_len; ++wvif->scan.n_ssids; } + schedule_work(>scan.work); +failed: mutex_unlock(>conf_mutex); - - if (skb) - dev_kfree_skb(skb); - schedule_work(>scan.work); - return 0; + return ret; } void wfx_scan_work(struct work_struct *work) -- 2.24.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 55/55] staging: wfx: update TODO
From: Jérôme Pouiller Update the TODO list of wfx driver with a more precise list of items. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/TODO | 81 +--- 1 file changed, 67 insertions(+), 14 deletions(-) diff --git a/drivers/staging/wfx/TODO b/drivers/staging/wfx/TODO index e44772289af8..6b1cdd24afc9 100644 --- a/drivers/staging/wfx/TODO +++ b/drivers/staging/wfx/TODO @@ -1,17 +1,70 @@ This is a list of things that need to be done to get this driver out of the staging directory. - - I have to take a decision about secure link support. I can: - - drop completely - - keep it in an external patch (my preferred option) - - replace call to mbedtls with kernel crypto API (necessitate a -bunch of work) - - pull mbedtls in kernel (non-realistic) - - - mac80211 interface does not (yet) have expected quality to be placed -outside of staging: - - Some processings are redundant with mac80211 ones - - Many members from wfx_dev/wfx_vif can be retrieved from mac80211 -structures - - Some functions are too complex - - ... + - Allocation of "link ids" is too complex. Allocation/release of link ids from +sta_add()/sta_remove() should be sufficient. + + - The path for packets with IEEE80211_TX_CTL_SEND_AFTER_DTIM flags should be +cleaned up. Currently, the process involve multiple work structs and a +timer. It could be simplifed. In add, the requeue mechanism triggers more +frequently than it should. + + - All structures defined in hif_api_*.h are intended to sent/received to/from +hardware. All their members whould be declared __le32 or __le16. These +structs should only been used in files named hif_* (and maybe in data_*.c). +The upper layers (sta.c, scan.c etc...) should manage mac80211 structures. +See: + https://lore.kernel.org/lkml/2019202852.gx26...@zeniv.linux.org.uk + + - Once previous item done, it will be possible to audit the driver with +`sparse'. It will probably find tons of problems with big endian +architectures. + + - hif_api_*.h whave been imported from firmware code. Some of the structures +are never used in driver. + + - Driver try to maintains power save status of the stations. However, this +work is already done by mac80211. sta_asleep_mask and pspoll_mask should be +dropped. + + - wfx_tx_queues_get() should be reworked. It currently try compute itself the +QoS policy. However, firmware already do the job. Firmware would prefer to +have a few packets in each queue and be able to choose itself which queue to +use. + + - As suggested by Felix, rate control could be improved following this idea: +https://lore.kernel.org/lkml/3099559.gv3Q75KnN1@pc-42/ + + - When driver is about to loose BSS, it forge its own Null Func request (see +wfx_cqm_bssloss_sm()). It should use mechanism provided by mac80211. + + - AP is actually is setup after a call to wfx_bss_info_changed(). Yet, +ieee80211_ops provide callback start_ap(). + + - The current process for joining a network is incredibly complex. Should be +reworked. + + - Monitoring mode is not implemented despite being mandatory by mac80211. + + - "compatible" value are not correct. They should be "vendor,chip". See: + https://lore.kernel.org/driverdev-devel/5226570.CMH5hVlZcI@pc-42 + + - The "state" field from wfx_vif should be replaced by "vif->type". + + - It seems that wfx_upload_keys() is useless. + + - "event_queue" from wfx_vif seems overkill. These event are rare and they + probably could be handled in a simpler fashion. + + - Feature called "secure link" should be either developed (using kernel +crypto API) or dropped. + + - In wfx_cmd_send(), "async" allow to send command without waiting the reply. +It may help in some situation, but it is not yet used. In add, it may cause +some trouble: + https://lore.kernel.org/driverdev-devel/alpine.DEB.2.21.1910041317381.2992@hadrien/ +So, fix it (by replacing the mutex with a semaphore) or drop it. + + - Chip support P2P, but driver does not implement it. + + - Chip support kind of Mesh, but driver does not implement it. -- 2.24.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 49/55] staging: wfx: simplify hif_set_template_frame() usage
From: Jérôme Pouiller The structure hif_mib_template_frame come from hardware API. It is not intended to be manipulated in upper layers of the driver. In add, the current code for hif_set_template_frame() is dumb. All the difficult task is left to the caller. So, there is code to factorize here. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/hif_tx_mib.h | 11 ++- drivers/staging/wfx/scan.c | 7 +-- drivers/staging/wfx/sta.c| 29 +++-- 3 files changed, 18 insertions(+), 29 deletions(-) diff --git a/drivers/staging/wfx/hif_tx_mib.h b/drivers/staging/wfx/hif_tx_mib.h index d77765f75f10..b1eeda2a3ab3 100644 --- a/drivers/staging/wfx/hif_tx_mib.h +++ b/drivers/staging/wfx/hif_tx_mib.h @@ -130,8 +130,17 @@ static inline int hif_set_operational_mode(struct wfx_dev *wdev, } static inline int hif_set_template_frame(struct wfx_vif *wvif, -struct hif_mib_template_frame *arg) +struct sk_buff *skb, +u8 frame_type, int init_rate) { + struct hif_mib_template_frame *arg; + + skb_push(skb, 4); + arg = (struct hif_mib_template_frame *)skb->data; + skb_pull(skb, 4); + arg->init_rate = init_rate; + arg->frame_type = frame_type; + arg->frame_length = cpu_to_le16(skb->len); return hif_write_mib(wvif->wdev, wvif->id, HIF_MIB_ID_TEMPLATE_FRAME, arg, sizeof(*arg)); } diff --git a/drivers/staging/wfx/scan.c b/drivers/staging/wfx/scan.c index 8b184efad0cf..c82c04ff5d06 100644 --- a/drivers/staging/wfx/scan.c +++ b/drivers/staging/wfx/scan.c @@ -52,7 +52,6 @@ static int wfx_scan_start(struct wfx_vif *wvif, static int update_probe_tmpl(struct wfx_vif *wvif, struct cfg80211_scan_request *req) { - struct hif_mib_template_frame *tmpl; struct sk_buff *skb; skb = ieee80211_probereq_get(wvif->wdev->hw, wvif->vif->addr, @@ -61,11 +60,7 @@ static int update_probe_tmpl(struct wfx_vif *wvif, return -ENOMEM; skb_put_data(skb, req->ie, req->ie_len); - skb_push(skb, 4); - tmpl = (struct hif_mib_template_frame *)skb->data; - tmpl->frame_type = HIF_TMPLT_PRBREQ; - tmpl->frame_length = cpu_to_le16(skb->len - 4); - hif_set_template_frame(wvif, tmpl); + hif_set_template_frame(wvif, skb, HIF_TMPLT_PRBREQ, 0); dev_kfree_skb(skb); return 0; } diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c index 19ca13543a25..ba3e81fd477b 100644 --- a/drivers/staging/wfx/sta.c +++ b/drivers/staging/wfx/sta.c @@ -831,32 +831,20 @@ static int wfx_update_beaconing(struct wfx_vif *wvif) static int wfx_upload_beacon(struct wfx_vif *wvif) { - int ret = 0; - struct sk_buff *skb = NULL; + struct sk_buff *skb; struct ieee80211_mgmt *mgmt; - struct hif_mib_template_frame *p; if (wvif->vif->type == NL80211_IFTYPE_STATION || wvif->vif->type == NL80211_IFTYPE_MONITOR || wvif->vif->type == NL80211_IFTYPE_UNSPECIFIED) - goto done; + return 0; skb = ieee80211_beacon_get(wvif->wdev->hw, wvif->vif); - if (!skb) return -ENOMEM; + hif_set_template_frame(wvif, skb, HIF_TMPLT_BCN, + API_RATE_INDEX_B_1MBPS); - p = (struct hif_mib_template_frame *) skb_push(skb, 4); - p->frame_type = HIF_TMPLT_BCN; - p->init_rate = API_RATE_INDEX_B_1MBPS; /* 1Mbps DSSS */ - p->frame_length = cpu_to_le16(skb->len - 4); - - ret = hif_set_template_frame(wvif, p); - - skb_pull(skb, 4); - - if (ret) - goto done; /* TODO: Distill probe resp; remove TIM and any other beacon-specific * IEs */ @@ -864,14 +852,11 @@ static int wfx_upload_beacon(struct wfx_vif *wvif) mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP); - p->frame_type = HIF_TMPLT_PRBRES; - - ret = hif_set_template_frame(wvif, p); + hif_set_template_frame(wvif, skb, HIF_TMPLT_PRBRES, + API_RATE_INDEX_B_1MBPS); wfx_fwd_probe_req(wvif, false); - -done: dev_kfree_skb(skb); - return ret; + return 0; } static int wfx_is_ht(const struct wfx_ht_info *ht_info) -- 2.24.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 43/55] staging: wfx: simplify hif_set_edca_queue_params() usage
From: Jérôme Pouiller The struct hif_req_edca_queue_params comes from hardware API. It is not intended to be manipulated in upper layers of the driver. So, this patch: 1. relocate the handling of this struct in hif_set_edca_queue_params() (the low level function) 2. replace it in wfx_vif by the mac80211 equivalent: struct ieee80211_tx_queue_params Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/hif_tx.c | 20 +--- drivers/staging/wfx/hif_tx.h | 5 +++-- drivers/staging/wfx/queue.c | 6 +++--- drivers/staging/wfx/sta.c| 18 ++ drivers/staging/wfx/wfx.h| 4 +++- 5 files changed, 24 insertions(+), 29 deletions(-) diff --git a/drivers/staging/wfx/hif_tx.c b/drivers/staging/wfx/hif_tx.c index 9cbf9d916f5f..259b49b99098 100644 --- a/drivers/staging/wfx/hif_tx.c +++ b/drivers/staging/wfx/hif_tx.c @@ -340,19 +340,25 @@ int hif_remove_key(struct wfx_dev *wdev, int idx) return ret; } -int hif_set_edca_queue_params(struct wfx_vif *wvif, - const struct hif_req_edca_queue_params *arg) +int hif_set_edca_queue_params(struct wfx_vif *wvif, u16 queue, + const struct ieee80211_tx_queue_params *arg) { int ret; struct hif_msg *hif; struct hif_req_edca_queue_params *body = wfx_alloc_hif(sizeof(*body), ); - // NOTE: queues numerotation are not the same between WFx and Linux - memcpy(body, arg, sizeof(*body)); - cpu_to_le16s(>cw_min); - cpu_to_le16s(>cw_max); - cpu_to_le16s(>tx_op_limit); + WARN_ON(arg->aifs > 255); + body->aifsn = arg->aifs; + body->cw_min = cpu_to_le16(arg->cw_min); + body->cw_max = cpu_to_le16(arg->cw_max); + body->tx_op_limit = cpu_to_le16(arg->txop * USEC_PER_TXOP); + body->queue_id = 3 - queue; + // API 2.0 has changed queue IDs values + if (wfx_api_older_than(wvif->wdev, 2, 0) && queue == IEEE80211_AC_BE) + body->queue_id = HIF_QUEUE_ID_BACKGROUND; + if (wfx_api_older_than(wvif->wdev, 2, 0) && queue == IEEE80211_AC_BK) + body->queue_id = HIF_QUEUE_ID_BESTEFFORT; wfx_fill_header(hif, wvif->id, HIF_REQ_ID_EDCA_QUEUE_PARAMS, sizeof(*body)); 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 bb5860ee6542..d88019421fbc 100644 --- a/drivers/staging/wfx/hif_tx.h +++ b/drivers/staging/wfx/hif_tx.h @@ -12,6 +12,7 @@ #include "hif_api_cmd.h" +struct ieee80211_tx_queue_params; struct wfx_dev; struct wfx_vif; @@ -52,8 +53,8 @@ int hif_set_bss_params(struct wfx_vif *wvif, const struct hif_req_set_bss_params *arg); int hif_add_key(struct wfx_dev *wdev, const struct hif_req_add_key *arg); int hif_remove_key(struct wfx_dev *wdev, int idx); -int hif_set_edca_queue_params(struct wfx_vif *wvif, - const struct hif_req_edca_queue_params *arg); +int hif_set_edca_queue_params(struct wfx_vif *wvif, u16 queue, + const struct ieee80211_tx_queue_params *arg); int hif_start(struct wfx_vif *wvif, const struct hif_req_start *arg); int hif_beacon_transmit(struct wfx_vif *wvif, bool enable); int hif_map_link(struct wfx_vif *wvif, u8 *mac_addr, int flags, int sta_id); diff --git a/drivers/staging/wfx/queue.c b/drivers/staging/wfx/queue.c index 16216afe6cfc..abfbad7c9f75 100644 --- a/drivers/staging/wfx/queue.c +++ b/drivers/staging/wfx/queue.c @@ -443,7 +443,7 @@ static int wfx_get_prio_queue(struct wfx_vif *wvif, { static const int urgent = BIT(WFX_LINK_ID_AFTER_DTIM) | BIT(WFX_LINK_ID_UAPSD); - struct hif_req_edca_queue_params *edca; + const struct ieee80211_tx_queue_params *edca; unsigned int score, best = -1; int winner = -1; int i; @@ -458,7 +458,7 @@ static int wfx_get_prio_queue(struct wfx_vif *wvif, if (!queued) continue; *total += queued; - score = ((edca->aifsn + edca->cw_min) << 16) + + score = ((edca->aifs + edca->cw_min) << 16) + ((edca->cw_max - edca->cw_min) * (get_random_int() & 0x)); if (score < best && (winner < 0 || i != 3)) { @@ -595,7 +595,7 @@ struct hif_msg *wfx_tx_queues_get(struct wfx_dev *wdev) wvif->pspoll_mask &= ~BIT(tx_priv->raw_link_id); /* allow bursting if txop is set */ - if (wvif->edca_params[queue_num].tx_op_limit) + if (wvif->edca_params[queue_num].txop) burst = (int)wfx_tx_queue_get_num_queued(queue,
[PATCH v2 47/55] staging: wfx: simplify hif_scan() usage
From: Jérôme Pouiller The structures hif_req_start_scan and hif_ssid_def come from hardware API. It is not intended to be manipulated in upper layers of the driver. So, this patch relocate handling of theses structures to hif_scan() (the low level function). This change also allows to drop struct wfx_scan_params. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/hif_tx.c | 76 ++-- drivers/staging/wfx/hif_tx.h | 10 ++--- drivers/staging/wfx/scan.c | 54 - drivers/staging/wfx/wfx.h| 1 + 4 files changed, 59 insertions(+), 82 deletions(-) diff --git a/drivers/staging/wfx/hif_tx.c b/drivers/staging/wfx/hif_tx.c index 259b49b99098..8a34a52dd5b9 100644 --- a/drivers/staging/wfx/hif_tx.c +++ b/drivers/staging/wfx/hif_tx.c @@ -220,41 +220,59 @@ int hif_write_mib(struct wfx_dev *wdev, int vif_id, u16 mib_id, void *val, return ret; } -int hif_scan(struct wfx_vif *wvif, const struct wfx_scan_params *arg) +int hif_scan(struct wfx_vif *wvif, struct cfg80211_scan_request *req, +int chan_start_idx, int chan_num) { int ret, i; struct hif_msg *hif; - struct hif_ssid_def *ssids; - size_t buf_len = sizeof(struct hif_req_start_scan) + - arg->scan_req.num_of_channels * sizeof(u8) + - arg->scan_req.num_of_ssids * sizeof(struct hif_ssid_def); - struct hif_req_start_scan *body = wfx_alloc_hif(buf_len, ); - u8 *ptr = (u8 *) body + sizeof(*body); - - WARN(arg->scan_req.num_of_channels > HIF_API_MAX_NB_CHANNELS, "invalid params"); - WARN(arg->scan_req.num_of_ssids > 2, "invalid params"); - WARN(arg->scan_req.band > 1, "invalid params"); - - // FIXME: This API is unnecessary complex, fixing NumOfChannels and - // adding a member SsidDef at end of struct hif_req_start_scan would - // simplify that a lot. - memcpy(body, >scan_req, sizeof(*body)); - cpu_to_le32s(>min_channel_time); - cpu_to_le32s(>max_channel_time); - cpu_to_le32s(>tx_power_level); - memcpy(ptr, arg->ssids, - arg->scan_req.num_of_ssids * sizeof(struct hif_ssid_def)); - ssids = (struct hif_ssid_def *) ptr; - for (i = 0; i < body->num_of_ssids; ++i) - cpu_to_le32s([i].ssid_length); - ptr += arg->scan_req.num_of_ssids * sizeof(struct hif_ssid_def); - memcpy(ptr, arg->ch, arg->scan_req.num_of_channels * sizeof(u8)); - ptr += arg->scan_req.num_of_channels * sizeof(u8); - WARN(buf_len != ptr - (u8 *) body, "allocation size mismatch"); + 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, ); + 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"); + + compiletime_assert(IEEE80211_MAX_SSID_LEN == HIF_API_SSID_SIZE, + "API inconsistency"); + for (i = 0; i < req->n_ssids; i++) { + memcpy(body->ssid_def[i].ssid, req->ssids[i].ssid, + IEEE80211_MAX_SSID_LEN); + body->ssid_def[i].ssid_length = + cpu_to_le32(req->ssids[i].ssid_len); + } + body->num_of_ssids = HIF_API_MAX_NB_SSIDS; + // Background scan is always a good idea + body->scan_type.type = 1; + body->scan_flags.fbg = 1; + body->tx_power_level = + cpu_to_le32(req->channels[chan_start_idx]->max_power); + body->num_of_channels = chan_num; + for (i = 0; i < chan_num; i++) + body->channel_list[i] = + req->channels[i + chan_start_idx]->hw_value; + if (req->no_cck) + body->max_transmit_rate = API_RATE_INDEX_G_6MBPS; + else + body->max_transmit_rate = API_RATE_INDEX_B_1MBPS; + if (req->channels[chan_start_idx]->flags & IEEE80211_CHAN_NO_IR) { + body->min_channel_time = cpu_to_le32(50); + body->max_channel_time = cpu_to_le32(150); + } else { + body->min_channel_time = cpu_to_le32(10); + body->max_channel_time = cpu_to_le32(50); + 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); + wfx_fill_header(hif, wvif->id, HIF_REQ_ID_START_SCAN, buf_len); ret = wfx_cmd
[PATCH v2 50/55] staging: wfx: rewrite wfx_hw_scan()
From: Jérôme Pouiller Scan requests from mac80211 must be splitted in a few hardware requests (it is necessary to split channels with active scan and channels with passive scan). Current code schedules a work_struct for each hardware request and one delayed_work to handle scan timeout. It is far simpler to run send all the hardware requests synchronously and replace delayed_work with a simple wait_for_completion_timeout(). Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/hif_rx.c | 2 +- drivers/staging/wfx/scan.c | 225 ++- drivers/staging/wfx/scan.h | 23 +--- drivers/staging/wfx/sta.c| 39 ++ drivers/staging/wfx/wfx.h| 4 +- 5 files changed, 81 insertions(+), 212 deletions(-) diff --git a/drivers/staging/wfx/hif_rx.c b/drivers/staging/wfx/hif_rx.c index 8a3ccdc60b7d..408967a4c457 100644 --- a/drivers/staging/wfx/hif_rx.c +++ b/drivers/staging/wfx/hif_rx.c @@ -206,7 +206,7 @@ static int hif_scan_complete_indication(struct wfx_dev *wdev, const struct hif_ind_scan_cmpl *body = buf; WARN_ON(!wvif); - wfx_scan_complete_cb(wvif, body); + wfx_scan_complete(wvif, body); return 0; } diff --git a/drivers/staging/wfx/scan.c b/drivers/staging/wfx/scan.c index c82c04ff5d06..b73e61e8da46 100644 --- a/drivers/staging/wfx/scan.c +++ b/drivers/staging/wfx/scan.c @@ -22,33 +22,6 @@ static void __ieee80211_scan_completed_compat(struct ieee80211_hw *hw, ieee80211_scan_completed(hw, ); } -static void wfx_scan_restart_delayed(struct wfx_vif *wvif) -{ - if (wvif->delayed_unjoin) { - wvif->delayed_unjoin = false; - if (!schedule_work(>unjoin_work)) - wfx_tx_unlock(wvif->wdev); - } else if (wvif->delayed_link_loss) { - wvif->delayed_link_loss = 0; - wfx_cqm_bssloss_sm(wvif, 1, 0, 0); - } -} - -static int wfx_scan_start(struct wfx_vif *wvif, - int chan_start_idx, int chan_num) -{ - int tmo; - - if (wvif->state == WFX_STATE_PRE_STA) - return -EBUSY; - - atomic_set(>scan.in_progress, 1); - - tmo = hif_scan(wvif, wvif->scan.req, chan_start_idx, chan_num); - schedule_delayed_work(>scan.timeout, tmo); - return 0; -} - static int update_probe_tmpl(struct wfx_vif *wvif, struct cfg80211_scan_request *req) { @@ -65,153 +38,81 @@ static int update_probe_tmpl(struct wfx_vif *wvif, return 0; } -int wfx_hw_scan(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_scan_request *hw_req) +static int send_scan_req(struct wfx_vif *wvif, +struct cfg80211_scan_request *req, int start_idx) +{ + int i, ret, timeout; + struct ieee80211_channel *ch_start, *ch_cur; + + for (i = start_idx; i < req->n_channels; i++) { + ch_start = req->channels[start_idx]; + ch_cur = req->channels[i]; + WARN(ch_cur->band != NL80211_BAND_2GHZ, "band not supported"); + if (ch_cur->max_power != ch_start->max_power) + break; + if ((ch_cur->flags ^ ch_start->flags) & IEEE80211_CHAN_NO_IR) + break; + } + wfx_tx_lock_flush(wvif->wdev); + reinit_completion(>scan_complete); + ret = hif_scan(wvif, req, start_idx, i - start_idx); + if (ret < 0) + return ret; + timeout = ret; + ret = wait_for_completion_timeout(>scan_complete, timeout); + if (req->channels[start_idx]->max_power != wvif->wdev->output_power) + hif_set_output_power(wvif, wvif->wdev->output_power * 10); + wfx_tx_unlock(wvif->wdev); + if (!ret) { + dev_notice(wvif->wdev->dev, "scan timeout\n"); + hif_stop_scan(wvif); + return -ETIMEDOUT; + } + return i - start_idx; +} + +int wfx_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_scan_request *hw_req) { struct wfx_dev *wdev = hw->priv; struct wfx_vif *wvif = (struct wfx_vif *) vif->drv_priv; - struct cfg80211_scan_request *req = _req->req; - int i, ret; + int chan_cur, ret; - if (!wvif) - return -EINVAL; + WARN_ON(hw_req->req.n_channels > HIF_API_MAX_NB_CHANNELS); - if (wvif->state == WFX_STATE_AP) + if (vif->type == NL80211_IFTYPE_AP) return -EOPNOTSUPP; - if (req->n_ssids == 1 && !req->ssids[0].ssid_len) - req->n_ssids = 0; - - if (req->n_ssids > HIF_API_MAX_NB_SSIDS) - return -EINVAL; + if (wvif->state == WFX_STATE_PRE_STA) + retur
[PATCH v2 35/55] staging: wfx: do not try to save call to hif_set_pm()
From: Jérôme Pouiller Current code try to not exchange data with device if it is not necessary. However, it seems that the additional code does not provide any gain. So, we prefer to keep a simpler code. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/sta.c | 7 +-- 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c index c57135f77572..dcb4693ec980 100644 --- a/drivers/staging/wfx/sta.c +++ b/drivers/staging/wfx/sta.c @@ -371,14 +371,11 @@ int wfx_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct wfx_dev *wdev = hw->priv; struct wfx_vif *wvif = (struct wfx_vif *) vif->drv_priv; int ret = 0; - /* To prevent re-applying PM request OID again and again*/ - u16 old_uapsd_flags, new_uapsd_flags; struct hif_req_edca_queue_params *edca; mutex_lock(>conf_mutex); if (queue < hw->queues) { - old_uapsd_flags = *((u16 *) >uapsd_info); edca = >edca.params[queue]; wvif->edca.uapsd_enable[queue] = params->uapsd; @@ -395,10 +392,8 @@ int wfx_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, if (wvif->vif->type == NL80211_IFTYPE_STATION) { ret = wfx_set_uapsd_param(wvif, >edca); - new_uapsd_flags = *((u16 *) >uapsd_info); if (!ret && wvif->setbssparams_done && - wvif->state == WFX_STATE_STA && - old_uapsd_flags != new_uapsd_flags) + wvif->state == WFX_STATE_STA) ret = wfx_update_pm(wvif); } } else { -- 2.24.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 36/55] staging: wfx: fix pm_mode timeout
From: Jérôme Pouiller Maximum request time (how long a request wait for the medium) is set in firmware to 512TU 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 dcb4693ec980..42b0d01d85cc 100644 --- a/drivers/staging/wfx/sta.c +++ b/drivers/staging/wfx/sta.c @@ -359,7 +359,7 @@ static int wfx_update_pm(struct wfx_vif *wvif) } if (!wait_for_completion_timeout(>set_pm_mode_complete, -msecs_to_jiffies(300))) +TU_TO_JIFFIES(512))) dev_warn(wvif->wdev->dev, "timeout while waiting of set_pm_mode_complete\n"); return hif_set_pm(wvif, ); -- 2.24.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 29/55] staging: wfx: simplify handling of tx_lock in wfx_do_join()
From: Jérôme Pouiller In the old days, wfx_do_join() could be called from different contexts. Now that wfx_do_join() is called only from one place, it is cleaner to keep lock and unlock of data inside the function. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/sta.c | 9 - 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c index 939c64f108ed..62e65493a4fe 100644 --- a/drivers/staging/wfx/sta.c +++ b/drivers/staging/wfx/sta.c @@ -644,7 +644,6 @@ static void wfx_set_mfp(struct wfx_vif *wvif, hif_set_mfp(wvif, mfpc, mfpr); } -/* MUST be called with tx_lock held! It will be unlocked for us. */ static void wfx_do_join(struct wfx_vif *wvif) { const u8 *bssid; @@ -659,6 +658,8 @@ static void wfx_do_join(struct wfx_vif *wvif) conf->basic_rates), }; + wfx_tx_lock_flush(wvif->wdev); + if (wvif->channel->flags & IEEE80211_CHAN_NO_IR) join.probe_for_join = 0; @@ -1180,10 +1181,8 @@ void wfx_bss_info_changed(struct ieee80211_hw *hw, } mutex_unlock(>conf_mutex); - if (do_join) { - wfx_tx_lock_flush(wdev); - wfx_do_join(wvif); /* Will unlock it for us */ - } + if (do_join) + wfx_do_join(wvif); } static void wfx_ps_notify(struct wfx_vif *wvif, enum sta_notify_cmd notify_cmd, -- 2.24.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 38/55] staging: wfx: prefer a bitmask instead of an array of boolean
From: Jérôme Pouiller It is easier to manipulate a int than an array of booleans. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/sta.c | 17 +++-- drivers/staging/wfx/sta.h | 2 +- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c index 045d3916ada8..e59560f499ea 100644 --- a/drivers/staging/wfx/sta.c +++ b/drivers/staging/wfx/sta.c @@ -119,22 +119,22 @@ static int wfx_set_uapsd_param(struct wfx_vif *wvif, * VO [0,3], VI [1, 2], BE [2, 1], BK [3, 0] */ - if (arg->uapsd_enable[IEEE80211_AC_VO]) + if (arg->uapsd_mask & BIT(IEEE80211_AC_VO)) wvif->uapsd_info.trig_voice = 1; else wvif->uapsd_info.trig_voice = 0; - if (arg->uapsd_enable[IEEE80211_AC_VI]) + if (arg->uapsd_mask & BIT(IEEE80211_AC_VI)) wvif->uapsd_info.trig_video = 1; else wvif->uapsd_info.trig_video = 0; - if (arg->uapsd_enable[IEEE80211_AC_BE]) + if (arg->uapsd_mask & BIT(IEEE80211_AC_BE)) wvif->uapsd_info.trig_be = 1; else wvif->uapsd_info.trig_be = 0; - if (arg->uapsd_enable[IEEE80211_AC_BK]) + if (arg->uapsd_mask & BIT(IEEE80211_AC_BK)) wvif->uapsd_info.trig_bckgrnd = 1; else wvif->uapsd_info.trig_bckgrnd = 0; @@ -330,7 +330,6 @@ static int wfx_update_pm(struct wfx_vif *wvif) { struct ieee80211_conf *conf = >wdev->hw->conf; struct hif_req_set_pm_mode pm; - u16 uapsd_flags; if (wvif->state != WFX_STATE_STA || !wvif->bss_params.aid) return 0; @@ -345,9 +344,7 @@ static int wfx_update_pm(struct wfx_vif *wvif) pm.pm_mode.fast_psm = 1; } - memcpy(_flags, >uapsd_info, sizeof(uapsd_flags)); - - if (uapsd_flags != 0) + if (wvif->edca.uapsd_mask) pm.pm_mode.fast_psm = 0; // Kernel disable PowerSave when multiple vifs are in use. In contrary, @@ -375,7 +372,7 @@ int wfx_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, WARN_ON(queue >= hw->queues); mutex_lock(>conf_mutex); - wvif->edca.uapsd_enable[queue] = params->uapsd; + assign_bit(queue, >edca.uapsd_mask, params->uapsd); edca = >edca.params[queue]; edca->aifsn = params->aifs; edca->cw_min = params->cw_min; @@ -1552,9 +1549,9 @@ int wfx_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) for (i = 0; i < IEEE80211_NUM_ACS; i++) { memcpy(>edca.params[i], _edca_params[i], sizeof(default_edca_params[i])); - wvif->edca.uapsd_enable[i] = false; hif_set_edca_queue_params(wvif, >edca.params[i]); } + wvif->edca.uapsd_mask = 0; wfx_set_uapsd_param(wvif, >edca); wfx_tx_policy_init(wvif); diff --git a/drivers/staging/wfx/sta.h b/drivers/staging/wfx/sta.h index 4719807bc25a..74755f6fa030 100644 --- a/drivers/staging/wfx/sta.h +++ b/drivers/staging/wfx/sta.h @@ -37,7 +37,7 @@ struct wfx_hif_event { struct wfx_edca_params { /* NOTE: index is a linux queue id. */ struct hif_req_edca_queue_params params[IEEE80211_NUM_ACS]; - bool uapsd_enable[IEEE80211_NUM_ACS]; + unsigned long uapsd_mask; }; struct wfx_grp_addr_table { -- 2.24.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 46/55] staging: wfx: drop useless wfx_scan_complete()
From: Jérôme Pouiller Since wfx_scan_complete() is now only called from wfx_scan_complete_cb(), it make sense to merge the both functions. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/scan.c | 9 ++--- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/drivers/staging/wfx/scan.c b/drivers/staging/wfx/scan.c index 397fe511d34a..c043f2f79541 100644 --- a/drivers/staging/wfx/scan.c +++ b/drivers/staging/wfx/scan.c @@ -228,12 +228,6 @@ void wfx_scan_work(struct work_struct *work) schedule_work(>scan.work); } -static void wfx_scan_complete(struct wfx_vif *wvif) -{ - up(>scan.lock); - wfx_scan_work(>scan.work); -} - void wfx_scan_complete_cb(struct wfx_vif *wvif, const struct hif_ind_scan_cmpl *arg) { @@ -257,6 +251,7 @@ void wfx_scan_timeout(struct work_struct *work) wvif->scan.curr = wvif->scan.end; hif_stop_scan(wvif); } - wfx_scan_complete(wvif); + up(>scan.lock); + wfx_scan_work(>scan.work); } } -- 2.24.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 37/55] staging: wfx: simplify wfx_conf_tx()
From: Jérôme Pouiller Error management of wfx_conf_tx() can be simplified. In add, the hardware command "hif_set_edca_queue_params" never returns any error. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/sta.c | 44 ++- 1 file changed, 16 insertions(+), 28 deletions(-) diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c index 42b0d01d85cc..045d3916ada8 100644 --- a/drivers/staging/wfx/sta.c +++ b/drivers/staging/wfx/sta.c @@ -370,39 +370,27 @@ int wfx_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, { struct wfx_dev *wdev = hw->priv; struct wfx_vif *wvif = (struct wfx_vif *) vif->drv_priv; - int ret = 0; struct hif_req_edca_queue_params *edca; - mutex_lock(>conf_mutex); - - if (queue < hw->queues) { - edca = >edca.params[queue]; - - wvif->edca.uapsd_enable[queue] = params->uapsd; - edca->aifsn = params->aifs; - edca->cw_min = params->cw_min; - edca->cw_max = params->cw_max; - edca->tx_op_limit = params->txop * TXOP_UNIT; - edca->allowed_medium_time = 0; - ret = hif_set_edca_queue_params(wvif, edca); - if (ret) { - ret = -EINVAL; - goto out; - } + WARN_ON(queue >= hw->queues); - if (wvif->vif->type == NL80211_IFTYPE_STATION) { - ret = wfx_set_uapsd_param(wvif, >edca); - if (!ret && wvif->setbssparams_done && - wvif->state == WFX_STATE_STA) - ret = wfx_update_pm(wvif); - } - } else { - ret = -EINVAL; + mutex_lock(>conf_mutex); + wvif->edca.uapsd_enable[queue] = params->uapsd; + edca = >edca.params[queue]; + edca->aifsn = params->aifs; + edca->cw_min = params->cw_min; + edca->cw_max = params->cw_max; + edca->tx_op_limit = params->txop * TXOP_UNIT; + edca->allowed_medium_time = 0; + hif_set_edca_queue_params(wvif, edca); + + if (wvif->vif->type == NL80211_IFTYPE_STATION) { + wfx_set_uapsd_param(wvif, >edca); + if (wvif->setbssparams_done && wvif->state == WFX_STATE_STA) + wfx_update_pm(wvif); } - -out: mutex_unlock(>conf_mutex); - return ret; + return 0; } int wfx_set_rts_threshold(struct ieee80211_hw *hw, u32 value) -- 2.24.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 26/55] staging: wfx: improve API of hif_req_join->infrastructure_bss_mode
From: Jérôme Pouiller In fact "mode" is a boolean that indicates if IBSS mode is used. This patch fixes the name and uses a more adapted memory representation. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/hif_api_cmd.h | 8 ++-- drivers/staging/wfx/sta.c | 2 +- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/drivers/staging/wfx/hif_api_cmd.h b/drivers/staging/wfx/hif_api_cmd.h index 4ce3bb51cf04..e848bd3073a2 100644 --- a/drivers/staging/wfx/hif_api_cmd.h +++ b/drivers/staging/wfx/hif_api_cmd.h @@ -377,11 +377,6 @@ struct hif_cnf_edca_queue_params { u32 status; } __packed; -enum hif_ap_mode { - HIF_MODE_IBSS = 0x0, - HIF_MODE_BSS = 0x1 -}; - enum hif_preamble { HIF_PREAMBLE_LONG = 0x0, HIF_PREAMBLE_SHORT = 0x1, @@ -396,7 +391,8 @@ struct hif_join_flags { } __packed; struct hif_req_join { - u8mode; + u8infrastructure_bss_mode:1; + u8reserved1:7; u8band; u16 channel_number; u8bssid[ETH_ALEN]; diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c index b4bb5b653e64..23ec7a4a926b 100644 --- a/drivers/staging/wfx/sta.c +++ b/drivers/staging/wfx/sta.c @@ -651,7 +651,7 @@ static void wfx_do_join(struct wfx_vif *wvif) struct ieee80211_bss_conf *conf = >vif->bss_conf; struct cfg80211_bss *bss = NULL; struct hif_req_join join = { - .mode = conf->ibss_joined ? HIF_MODE_IBSS : HIF_MODE_BSS, + .infrastructure_bss_mode = !conf->ibss_joined, .preamble_type = conf->use_short_preamble ? HIF_PREAMBLE_SHORT : HIF_PREAMBLE_LONG, .probe_for_join = 1, .atim_window = 0, -- 2.24.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 44/55] staging: wfx: hif_scan() never fails
From: Jérôme Pouiller If scan fails, status is returned in hif_ind_scan_cmpl. hif_scan always return a success. So, we can simplify the code. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/scan.c | 20 ++-- drivers/staging/wfx/scan.h | 1 - 2 files changed, 2 insertions(+), 19 deletions(-) diff --git a/drivers/staging/wfx/scan.c b/drivers/staging/wfx/scan.c index 4b95e6a97df7..cdccb67cb30e 100644 --- a/drivers/staging/wfx/scan.c +++ b/drivers/staging/wfx/scan.c @@ -36,7 +36,6 @@ static void wfx_scan_restart_delayed(struct wfx_vif *wvif) static int wfx_scan_start(struct wfx_vif *wvif, struct wfx_scan_params *scan) { - int ret; int tmo = 500; if (wvif->state == WFX_STATE_PRE_STA) @@ -48,15 +47,8 @@ static int wfx_scan_start(struct wfx_vif *wvif, struct wfx_scan_params *scan) atomic_set(>wdev->scan_in_progress, 1); schedule_delayed_work(>scan.timeout, msecs_to_jiffies(tmo)); - ret = hif_scan(wvif, scan); - if (ret) { - wfx_scan_failed_cb(wvif); - atomic_set(>scan.in_progress, 0); - atomic_set(>wdev->scan_in_progress, 0); - cancel_delayed_work_sync(>scan.timeout); - wfx_scan_restart_delayed(wvif); - } - return ret; + hif_scan(wvif, scan); + return 0; } int wfx_hw_scan(struct ieee80211_hw *hw, @@ -245,14 +237,6 @@ static void wfx_scan_complete(struct wfx_vif *wvif) wfx_scan_work(>scan.work); } -void wfx_scan_failed_cb(struct wfx_vif *wvif) -{ - if (cancel_delayed_work_sync(>scan.timeout) > 0) { - wvif->scan.status = -EIO; - schedule_work(>scan.timeout.work); - } -} - void wfx_scan_complete_cb(struct wfx_vif *wvif, const struct hif_ind_scan_cmpl *arg) { diff --git a/drivers/staging/wfx/scan.h b/drivers/staging/wfx/scan.h index c7c0ab178c87..e71e5f0f522e 100644 --- a/drivers/staging/wfx/scan.h +++ b/drivers/staging/wfx/scan.h @@ -38,6 +38,5 @@ void wfx_scan_work(struct work_struct *work); void wfx_scan_timeout(struct work_struct *work); void wfx_scan_complete_cb(struct wfx_vif *wvif, const struct hif_ind_scan_cmpl *arg); -void wfx_scan_failed_cb(struct wfx_vif *wvif); #endif /* WFX_SCAN_H */ -- 2.24.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 45/55] staging: wfx: device already handle sleep mode during scan
From: Jérôme Pouiller The device is not allowed to enter in sleep mode during scan. However, this is already handled by the device. So driver does not have to care about it. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/bh.c | 3 +-- drivers/staging/wfx/scan.c | 3 --- drivers/staging/wfx/wfx.h | 1 - 3 files changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/staging/wfx/bh.c b/drivers/staging/wfx/bh.c index 2432ba95c2f5..983c41d1fe7c 100644 --- a/drivers/staging/wfx/bh.c +++ b/drivers/staging/wfx/bh.c @@ -271,8 +271,7 @@ static void bh_work(struct work_struct *work) if (last_op_is_rx) ack_sdio_data(wdev); - if (!wdev->hif.tx_buffers_used && !work_pending(work) && - !atomic_read(>scan_in_progress)) { + if (!wdev->hif.tx_buffers_used && !work_pending(work)) { device_release(wdev); release_chip = true; } diff --git a/drivers/staging/wfx/scan.c b/drivers/staging/wfx/scan.c index cdccb67cb30e..397fe511d34a 100644 --- a/drivers/staging/wfx/scan.c +++ b/drivers/staging/wfx/scan.c @@ -44,7 +44,6 @@ static int wfx_scan_start(struct wfx_vif *wvif, struct wfx_scan_params *scan) tmo += scan->scan_req.num_of_channels * ((20 * (scan->scan_req.max_channel_time)) + 10); atomic_set(>scan.in_progress, 1); - atomic_set(>wdev->scan_in_progress, 1); schedule_delayed_work(>scan.timeout, msecs_to_jiffies(tmo)); hif_scan(wvif, scan); @@ -232,8 +231,6 @@ void wfx_scan_work(struct work_struct *work) static void wfx_scan_complete(struct wfx_vif *wvif) { up(>scan.lock); - atomic_set(>wdev->scan_in_progress, 0); - wfx_scan_work(>scan.work); } diff --git a/drivers/staging/wfx/wfx.h b/drivers/staging/wfx/wfx.h index f396a502283e..97373d047f58 100644 --- a/drivers/staging/wfx/wfx.h +++ b/drivers/staging/wfx/wfx.h @@ -60,7 +60,6 @@ struct wfx_dev { struct mutexrx_stats_lock; int output_power; - atomic_tscan_in_progress; }; struct wfx_vif { -- 2.24.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 42/55] staging: wfx: remove unnecessary EDCA initialisation
From: Jérôme Pouiller mac80211 already call wfx_conf_tx() on every VIF instanciation. So, the driver does not need to do it. Note that current code did dirty things with wvif->edca_params. This struct was initialized, but only 'queue_id' was really used. The other members are only used to store temporary values. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/sta.c | 51 +-- 1 file changed, 6 insertions(+), 45 deletions(-) diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c index d52f618062a6..3504b6b3515e 100644 --- a/drivers/staging/wfx/sta.c +++ b/drivers/staging/wfx/sta.c @@ -334,6 +334,12 @@ int wfx_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, edca->cw_max = params->cw_max; edca->tx_op_limit = params->txop * TXOP_UNIT; edca->allowed_medium_time = 0; + edca->queue_id = 3 - queue; + // API 2.0 has changed queue IDs values + if (wfx_api_older_than(wdev, 2, 0) && queue == IEEE80211_AC_BE) + edca->queue_id = HIF_QUEUE_ID_BACKGROUND; + if (wfx_api_older_than(wdev, 2, 0) && queue == IEEE80211_AC_BK) + edca->queue_id = HIF_QUEUE_ID_BESTEFFORT; hif_set_edca_queue_params(wvif, edca); if (wvif->vif->type == NL80211_IFTYPE_STATION) { @@ -1393,44 +1399,6 @@ int wfx_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) int i; struct wfx_dev *wdev = hw->priv; struct wfx_vif *wvif = (struct wfx_vif *) vif->drv_priv; - // FIXME: parameters are set by kernel juste after interface_add. - // Keep struct hif_req_edca_queue_params blank? - struct hif_req_edca_queue_params default_edca_params[] = { - [IEEE80211_AC_VO] = { - .queue_id = HIF_QUEUE_ID_VOICE, - .aifsn = 2, - .cw_min = 3, - .cw_max = 7, - .tx_op_limit = TXOP_UNIT * 47, - }, - [IEEE80211_AC_VI] = { - .queue_id = HIF_QUEUE_ID_VIDEO, - .aifsn = 2, - .cw_min = 7, - .cw_max = 15, - .tx_op_limit = TXOP_UNIT * 94, - }, - [IEEE80211_AC_BE] = { - .queue_id = HIF_QUEUE_ID_BESTEFFORT, - .aifsn = 3, - .cw_min = 15, - .cw_max = 1023, - .tx_op_limit = TXOP_UNIT * 0, - }, - [IEEE80211_AC_BK] = { - .queue_id = HIF_QUEUE_ID_BACKGROUND, - .aifsn = 7, - .cw_min = 15, - .cw_max = 1023, - .tx_op_limit = TXOP_UNIT * 0, - }, - }; - - BUILD_BUG_ON(ARRAY_SIZE(default_edca_params) != ARRAY_SIZE(wvif->edca_params)); - if (wfx_api_older_than(wdev, 2, 0)) { - default_edca_params[IEEE80211_AC_BE].queue_id = HIF_QUEUE_ID_BACKGROUND; - default_edca_params[IEEE80211_AC_BK].queue_id = HIF_QUEUE_ID_BESTEFFORT; - } vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER | IEEE80211_VIF_SUPPORTS_UAPSD | @@ -1501,13 +1469,6 @@ int wfx_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) mutex_unlock(>conf_mutex); hif_set_macaddr(wvif, vif->addr); - for (i = 0; i < IEEE80211_NUM_ACS; i++) { - memcpy(>edca_params[i], _edca_params[i], - sizeof(default_edca_params[i])); - hif_set_edca_queue_params(wvif, >edca_params[i]); - } - wvif->uapsd_mask = 0; - hif_set_uapsd_info(wvif, wvif->uapsd_mask); wfx_tx_policy_init(wvif); wvif = NULL; -- 2.24.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 51/55] staging: wfx: workaround bug with "iw scan"
From: Jérôme Pouiller mac80211 specification does not forbid hw_scan() to call ieee80211_scan_completed(). However, from userspace point of view, not all applications support this behavior. In particular, the code of iw contains a big fat warning: /* * This code has a bug, which requires creating a separate * nl80211 socket to fix: * It is possible for a NL80211_CMD_NEW_SCAN_RESULTS or * NL80211_CMD_SCAN_ABORTED message to be sent by the kernel * before (!) we listen to it, because we only start listening * after we send our scan request. [...] * Alas, the kernel doesn't do that (yet). */ So, we have to avoid to call ieee80211_scan_completed() from hw_scan() (it's a kind of unwritten rule). This patch relocates the hw_scan() process to a work_struct to fix the problem. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/scan.c | 47 -- drivers/staging/wfx/scan.h | 1 + drivers/staging/wfx/sta.c | 1 + drivers/staging/wfx/wfx.h | 2 ++ 4 files changed, 34 insertions(+), 17 deletions(-) diff --git a/drivers/staging/wfx/scan.c b/drivers/staging/wfx/scan.c index b73e61e8da46..540009b72240 100644 --- a/drivers/staging/wfx/scan.c +++ b/drivers/staging/wfx/scan.c @@ -71,23 +71,19 @@ static int send_scan_req(struct wfx_vif *wvif, return i - start_idx; } -int wfx_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - struct ieee80211_scan_request *hw_req) +/* + * 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 + */ +void wfx_hw_scan_work(struct work_struct *work) { - struct wfx_dev *wdev = hw->priv; - struct wfx_vif *wvif = (struct wfx_vif *) vif->drv_priv; + 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; - WARN_ON(hw_req->req.n_channels > HIF_API_MAX_NB_CHANNELS); - - if (vif->type == NL80211_IFTYPE_AP) - return -EOPNOTSUPP; - - if (wvif->state == WFX_STATE_PRE_STA) - return -EBUSY; - mutex_lock(>scan_lock); - mutex_lock(>conf_mutex); + mutex_lock(>wdev->conf_mutex); update_probe_tmpl(wvif, _req->req); wfx_fwd_probe_req(wvif, true); chan_cur = 0; @@ -96,18 +92,35 @@ int wfx_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, if (ret > 0) chan_cur += ret; } while (ret > 0 && chan_cur < hw_req->req.n_channels); - __ieee80211_scan_completed_compat(hw, ret < 0); - mutex_unlock(>conf_mutex); + mutex_unlock(>wdev->conf_mutex); mutex_unlock(>scan_lock); + __ieee80211_scan_completed_compat(wvif->wdev->hw, ret < 0); if (wvif->delayed_unjoin) { wvif->delayed_unjoin = false; - wfx_tx_lock(wdev); + wfx_tx_lock(wvif->wdev); if (!schedule_work(>unjoin_work)) - wfx_tx_unlock(wdev); + wfx_tx_unlock(wvif->wdev); } else if (wvif->delayed_link_loss) { wvif->delayed_link_loss = false; wfx_cqm_bssloss_sm(wvif, 1, 0, 0); } +} + +int wfx_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_scan_request *hw_req) +{ + struct wfx_vif *wvif = (struct wfx_vif *)vif->drv_priv; + + WARN_ON(hw_req->req.n_channels > HIF_API_MAX_NB_CHANNELS); + + if (vif->type == NL80211_IFTYPE_AP) + return -EOPNOTSUPP; + + if (wvif->state == WFX_STATE_PRE_STA) + return -EBUSY; + + wvif->scan_req = hw_req; + schedule_work(>scan_work); return 0; } diff --git a/drivers/staging/wfx/scan.h b/drivers/staging/wfx/scan.h index 03bc6c7e562d..b547f1927d72 100644 --- a/drivers/staging/wfx/scan.h +++ b/drivers/staging/wfx/scan.h @@ -15,6 +15,7 @@ struct wfx_dev; struct wfx_vif; +void wfx_hw_scan_work(struct work_struct *work); int wfx_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_scan_request *req); void wfx_scan_complete(struct wfx_vif *wvif, diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c index 16f5db873275..4354bb8081c5 100644 --- a/drivers/staging/wfx/sta.c +++ b/drivers/staging/wfx/sta.c @@ -1427,6 +1427,7 @@ int wfx_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) mutex_init(>scan_lock); init_completion(>scan_complete); + INIT_WORK(>scan_work, wfx_hw_scan_work); mutex_unlock(>conf_mutex); diff --git a/drivers/staging/wfx/wfx.h b/drivers/staging/wfx/wfx.h index 3356d0cbf7af..
[PATCH v2 30/55] staging: wfx: firmware already handle powersave mode during scan
From: Jérôme Pouiller When user try to launch scan while connected, it is necessary to notify the AP that we cannot receive data (using power save mode). Firmware already handles this automatically so the code in the driver is redundant and can be dropped. By edge effect, hack of scan status in wfx_set_pm() is now useless. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/scan.c | 14 -- drivers/staging/wfx/sta.c | 7 +-- 2 files changed, 1 insertion(+), 20 deletions(-) diff --git a/drivers/staging/wfx/scan.c b/drivers/staging/wfx/scan.c index cb7a1fdd0001..4b95e6a97df7 100644 --- a/drivers/staging/wfx/scan.c +++ b/drivers/staging/wfx/scan.c @@ -141,22 +141,11 @@ void wfx_scan_work(struct work_struct *work) .scan_req.scan_type.type = 0,/* Foreground */ }; struct ieee80211_channel *first; - bool first_run = (wvif->scan.begin == wvif->scan.curr && - wvif->scan.begin != wvif->scan.end); int i; down(>scan.lock); mutex_lock(>wdev->conf_mutex); - if (first_run) { - if (wvif->state == WFX_STATE_STA && - !(wvif->powersave_mode.pm_mode.enter_psm)) { - struct hif_req_set_pm_mode pm = wvif->powersave_mode; - - pm.pm_mode.enter_psm = 1; - wfx_set_pm(wvif, ); - } - } if (!wvif->scan.req || wvif->scan.curr == wvif->scan.end) { if (wvif->scan.output_power != wvif->wdev->output_power) @@ -177,9 +166,6 @@ void wfx_scan_work(struct work_struct *work) __ieee80211_scan_completed_compat(wvif->wdev->hw, wvif->scan.status ? 1 : 0); up(>scan.lock); - if (wvif->state == WFX_STATE_STA && - !(wvif->powersave_mode.pm_mode.enter_psm)) - wfx_set_pm(wvif, >powersave_mode); return; } first = *wvif->scan.curr; diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c index 62e65493a4fe..fb45aa66fc56 100644 --- a/drivers/staging/wfx/sta.c +++ b/drivers/staging/wfx/sta.c @@ -375,7 +375,6 @@ int wfx_set_pm(struct wfx_vif *wvif, const struct hif_req_set_pm_mode *arg) { struct hif_req_set_pm_mode pm = *arg; u16 uapsd_flags; - int ret; if (wvif->state != WFX_STATE_STA || !wvif->bss_params.aid) return 0; @@ -396,11 +395,7 @@ int wfx_set_pm(struct wfx_vif *wvif, const struct hif_req_set_pm_mode *arg) msecs_to_jiffies(300))) dev_warn(wvif->wdev->dev, "timeout while waiting of set_pm_mode_complete\n"); - ret = hif_set_pm(wvif, ); - // FIXME: why ? - if (-ETIMEDOUT == wvif->scan.status) - wvif->scan.status = 1; - return ret; + return hif_set_pm(wvif, ); } int wfx_set_rts_threshold(struct ieee80211_hw *hw, u32 value) -- 2.24.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 34/55] staging: wfx: drop unnecessary wvif->powersave_mode
From: Jérôme Pouiller Power save status is already available in bss_conf. So there is no reason to keep information duplicated in wvif->powersave_mode. In add, type of wvif->powersave_mode is low level struct made to communicate with device. We would like to limit usage of this kind of struct in upper layers of the driver. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/sta.c | 31 +-- drivers/staging/wfx/wfx.h | 1 - 2 files changed, 13 insertions(+), 19 deletions(-) diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c index 91fa4d8aa37d..c57135f77572 100644 --- a/drivers/staging/wfx/sta.c +++ b/drivers/staging/wfx/sta.c @@ -328,12 +328,23 @@ void wfx_configure_filter(struct ieee80211_hw *hw, static int wfx_update_pm(struct wfx_vif *wvif) { - struct hif_req_set_pm_mode pm = wvif->powersave_mode; + struct ieee80211_conf *conf = >wdev->hw->conf; + struct hif_req_set_pm_mode pm; u16 uapsd_flags; if (wvif->state != WFX_STATE_STA || !wvif->bss_params.aid) return 0; + memset(, 0, sizeof(pm)); + if (conf->flags & IEEE80211_CONF_PS) { + pm.pm_mode.enter_psm = 1; + // Firmware does not support more than 128ms + pm.fast_psm_idle_period = + min(conf->dynamic_ps_timeout * 2, 255); + if (pm.fast_psm_idle_period) + pm.pm_mode.fast_psm = 1; + } + memcpy(_flags, >uapsd_info, sizeof(uapsd_flags)); if (uapsd_flags != 0) @@ -1432,24 +1443,8 @@ int wfx_config(struct ieee80211_hw *hw, u32 changed) if (changed & IEEE80211_CONF_CHANGE_PS) { wvif = NULL; - while ((wvif = wvif_iterate(wdev, wvif)) != NULL) { - memset(>powersave_mode, 0, - sizeof(wvif->powersave_mode)); - if (conf->flags & IEEE80211_CONF_PS) { - wvif->powersave_mode.pm_mode.enter_psm = 1; - if (conf->dynamic_ps_timeout > 0) { - wvif->powersave_mode.pm_mode.fast_psm = 1; - /* -* Firmware does not support more than -* 128ms -*/ - wvif->powersave_mode.fast_psm_idle_period = - min(conf->dynamic_ps_timeout * - 2, 255); - } - } + while ((wvif = wvif_iterate(wdev, wvif)) != NULL) wfx_update_pm(wvif); - } wvif = wdev_to_wvif(wdev, 0); } diff --git a/drivers/staging/wfx/wfx.h b/drivers/staging/wfx/wfx.h index 781a8c8ba982..c82d29764d66 100644 --- a/drivers/staging/wfx/wfx.h +++ b/drivers/staging/wfx/wfx.h @@ -125,7 +125,6 @@ struct wfx_vif { struct wfx_scan scan; - struct hif_req_set_pm_mode powersave_mode; struct completion set_pm_mode_complete; struct list_headevent_queue; -- 2.24.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 14/55] staging: wfx: improve error message on unexpected confirmation
From: Jérôme Pouiller When driver receives an unexpected answer from the device, it shows "unsupported HIF ID". That message does not represent the real error. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/hif_rx.c | 7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/staging/wfx/hif_rx.c b/drivers/staging/wfx/hif_rx.c index 820de216be0c..1494ad5a507b 100644 --- a/drivers/staging/wfx/hif_rx.c +++ b/drivers/staging/wfx/hif_rx.c @@ -358,7 +358,12 @@ void wfx_handle_rx(struct wfx_dev *wdev, struct sk_buff *skb) goto free; } } - dev_err(wdev->dev, "unsupported HIF ID %02x\n", hif_id); + if (hif_id & 0x80) + dev_err(wdev->dev, "unsupported HIF indication: ID %02x\n", + hif_id); + else + dev_err(wdev->dev, "unexpected HIF confirmation: ID %02x\n", + hif_id); free: dev_kfree_skb(skb); } -- 2.24.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 12/55] staging: wfx: don't print useless error messages
From: Jérôme Pouiller During chip probing, if error does not come from secure boot (for exemple when firmware has been found), others errors probably appears. It is not necessary to say to user that the error does not come from secure boot. So, drop the message saying "no error reported by secure boot". BTW, we take the opportunity to simplify print_boot_status(). Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/fwio.c | 26 ++ 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/drivers/staging/wfx/fwio.c b/drivers/staging/wfx/fwio.c index dbf8bda71ff7..47e627bf0f8e 100644 --- a/drivers/staging/wfx/fwio.c +++ b/drivers/staging/wfx/fwio.c @@ -61,7 +61,7 @@ #define DCA_TIMEOUT 50 // milliseconds #define WAKEUP_TIMEOUT 200 // milliseconds -static const char * const fwio_error_strings[] = { +static const char * const fwio_errors[] = { [ERR_INVALID_SEC_TYPE] = "Invalid section type or wrong encryption", [ERR_SIG_VERIF_FAILED] = "Signature verification failed", [ERR_AES_CTRL_KEY] = "AES control key not initialized", @@ -220,22 +220,16 @@ static int upload_firmware(struct wfx_dev *wdev, const u8 *data, size_t len) static void print_boot_status(struct wfx_dev *wdev) { - u32 val32; + u32 reg; - sram_reg_read(wdev, WFX_STATUS_INFO, ); - if (val32 == 0x12345678) { - dev_info(wdev->dev, "no error reported by secure boot\n"); - } else { - sram_reg_read(wdev, WFX_ERR_INFO, ); - if (val32 < ARRAY_SIZE(fwio_error_strings) && - fwio_error_strings[val32]) - dev_info(wdev->dev, "secure boot error: %s\n", -fwio_error_strings[val32]); - else - dev_info(wdev->dev, -"secure boot error: Unknown (0x%02x)\n", -val32); - } + sram_reg_read(wdev, WFX_STATUS_INFO, ); + if (reg == 0x12345678) + return; + sram_reg_read(wdev, WFX_ERR_INFO, ); + if (reg < ARRAY_SIZE(fwio_errors) && fwio_errors[reg]) + dev_info(wdev->dev, "secure boot: %s\n", fwio_errors[reg]); + else + dev_info(wdev->dev, "secure boot: Error %#02x\n", reg); } static int load_firmware_secure(struct wfx_dev *wdev) -- 2.24.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 23/55] staging: wfx: fix typo in "num_of_ssi_ds"
From: Jérôme Pouiller The script that has imported API headers has made a mistake in "num_of_ssi_ds". Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/hif_api_cmd.h | 4 ++-- drivers/staging/wfx/hif_tx.c | 10 +- drivers/staging/wfx/scan.c| 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/staging/wfx/hif_api_cmd.h b/drivers/staging/wfx/hif_api_cmd.h index c15831de4ff4..90ba6e9b82ea 100644 --- a/drivers/staging/wfx/hif_api_cmd.h +++ b/drivers/staging/wfx/hif_api_cmd.h @@ -180,7 +180,7 @@ struct hif_req_start_scan { struct hif_auto_scan_param auto_scan_param; u8num_of_probe_requests; u8probe_delay; - u8num_of_ssi_ds; + u8num_of_ssids; u8num_of_channels; u32 min_channel_time; u32 max_channel_time; @@ -196,7 +196,7 @@ struct hif_start_scan_req_cstnbssid_body { struct hif_auto_scan_param auto_scan_param; u8num_of_probe_requests; u8probe_delay; - u8num_of_ssi_ds; + u8num_of_ssids; u8num_of_channels; u32 min_channel_time; u32 max_channel_time; diff --git a/drivers/staging/wfx/hif_tx.c b/drivers/staging/wfx/hif_tx.c index e8c2bd1efbac..2f74abca2b60 100644 --- a/drivers/staging/wfx/hif_tx.c +++ b/drivers/staging/wfx/hif_tx.c @@ -227,12 +227,12 @@ int hif_scan(struct wfx_vif *wvif, const struct wfx_scan_params *arg) struct hif_ssid_def *ssids; size_t buf_len = sizeof(struct hif_req_start_scan) + arg->scan_req.num_of_channels * sizeof(u8) + - arg->scan_req.num_of_ssi_ds * sizeof(struct hif_ssid_def); + arg->scan_req.num_of_ssids * sizeof(struct hif_ssid_def); struct hif_req_start_scan *body = wfx_alloc_hif(buf_len, ); u8 *ptr = (u8 *) body + sizeof(*body); WARN(arg->scan_req.num_of_channels > HIF_API_MAX_NB_CHANNELS, "invalid params"); - WARN(arg->scan_req.num_of_ssi_ds > 2, "invalid params"); + WARN(arg->scan_req.num_of_ssids > 2, "invalid params"); WARN(arg->scan_req.band > 1, "invalid params"); // FIXME: This API is unnecessary complex, fixing NumOfChannels and @@ -243,11 +243,11 @@ int hif_scan(struct wfx_vif *wvif, const struct wfx_scan_params *arg) cpu_to_le32s(>max_channel_time); cpu_to_le32s(>tx_power_level); memcpy(ptr, arg->ssids, - arg->scan_req.num_of_ssi_ds * sizeof(struct hif_ssid_def)); + arg->scan_req.num_of_ssids * sizeof(struct hif_ssid_def)); ssids = (struct hif_ssid_def *) ptr; - for (i = 0; i < body->num_of_ssi_ds; ++i) + for (i = 0; i < body->num_of_ssids; ++i) cpu_to_le32s([i].ssid_length); - ptr += arg->scan_req.num_of_ssi_ds * sizeof(struct hif_ssid_def); + ptr += arg->scan_req.num_of_ssids * sizeof(struct hif_ssid_def); memcpy(ptr, arg->ch, arg->scan_req.num_of_channels * sizeof(u8)); ptr += arg->scan_req.num_of_channels * sizeof(u8); WARN(buf_len != ptr - (u8 *) body, "allocation size mismatch"); diff --git a/drivers/staging/wfx/scan.c b/drivers/staging/wfx/scan.c index 45e78c5722ff..cb7a1fdd0001 100644 --- a/drivers/staging/wfx/scan.c +++ b/drivers/staging/wfx/scan.c @@ -204,7 +204,7 @@ void wfx_scan_work(struct work_struct *work) scan.scan_req.max_transmit_rate = API_RATE_INDEX_B_1MBPS; scan.scan_req.num_of_probe_requests = (first->flags & IEEE80211_CHAN_NO_IR) ? 0 : 2; - scan.scan_req.num_of_ssi_ds = wvif->scan.n_ssids; + scan.scan_req.num_of_ssids = wvif->scan.n_ssids; scan.ssids = >scan.ssids[0]; scan.scan_req.num_of_channels = it - wvif->scan.curr; scan.scan_req.probe_delay = 100; -- 2.24.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 10/55] staging: wfx: fix wrong error message
From: Jérôme Pouiller The driver checks that the number of retries made by the device is coherent with the rate policy. However, this check make sense only if the device has returned RETRY_EXCEEDED. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/data_tx.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/staging/wfx/data_tx.c b/drivers/staging/wfx/data_tx.c index 738a6ca5edad..32e269becd75 100644 --- a/drivers/staging/wfx/data_tx.c +++ b/drivers/staging/wfx/data_tx.c @@ -748,7 +748,9 @@ void wfx_tx_confirm_cb(struct wfx_vif *wvif, struct hif_cnf_tx *arg) rate = _info->status.rates[i]; if (rate->idx < 0) break; - if (tx_count < rate->count && arg->status && arg->ack_failures) + if (tx_count < rate->count && + arg->status == HIF_STATUS_RETRY_EXCEEDED && + arg->ack_failures) dev_dbg(wvif->wdev->dev, "all retries were not consumed: %d != %d\n", rate->count, tx_count); if (tx_count <= rate->count && tx_count && -- 2.24.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 19/55] staging: wfx: simplify variable assignment
From: Jérôme Pouiller Attribute "aborted" and argument "aborted" are both booleans. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/scan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/wfx/scan.c b/drivers/staging/wfx/scan.c index 35fcf9119f96..a6c93400a7ba 100644 --- a/drivers/staging/wfx/scan.c +++ b/drivers/staging/wfx/scan.c @@ -16,7 +16,7 @@ static void __ieee80211_scan_completed_compat(struct ieee80211_hw *hw, bool aborted) { struct cfg80211_scan_info info = { - .aborted = aborted ? 1 : 0, + .aborted = aborted, }; ieee80211_scan_completed(hw, ); -- 2.24.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 03/55] staging: wfx: fix counter overflow
From: Jérôme Pouiller Some weird behaviors were observed when connection is really good and packets are small. It appears that sometime, number of packets in queues can exceed 255 and generate an overflow in field usage_count. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/data_tx.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/wfx/data_tx.h b/drivers/staging/wfx/data_tx.h index a0f9ae69baf5..f63e5d8cf929 100644 --- a/drivers/staging/wfx/data_tx.h +++ b/drivers/staging/wfx/data_tx.h @@ -39,8 +39,8 @@ struct wfx_link_entry { struct tx_policy { struct list_head link; + int usage_count; u8 rates[12]; - u8 usage_count; u8 uploaded; }; -- 2.24.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 09/55] staging: wfx: fix hif_set_mfp() with big endian hosts
From: Jérôme Pouiller struct hif_mib_protected_mgmt_policy is an array of u8. There is no reason to swap its bytes. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/hif_tx_mib.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/wfx/hif_tx_mib.h b/drivers/staging/wfx/hif_tx_mib.h index bb091e395ff5..9be74881c56c 100644 --- a/drivers/staging/wfx/hif_tx_mib.h +++ b/drivers/staging/wfx/hif_tx_mib.h @@ -147,7 +147,6 @@ static inline int hif_set_mfp(struct wfx_vif *wvif, bool capable, bool required) } if (!required) val.unpmf_allowed = 1; - cpu_to_le32s((u32 *) ); return hif_write_mib(wvif->wdev, wvif->id, HIF_MIB_ID_PROTECTED_MGMT_POLICY, , sizeof(val)); -- 2.24.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 01/55] staging: wfx: fix the cache of rate policies on interface reset
From: Jérôme Pouiller Device and driver maintain a cache of rate policies (aka. tx_retry_policy in hardware API). When hif_reset() is sent to hardware, device resets its cache of rate policies. In order to keep driver in sync, it is necessary to do the same on driver. Note, when driver tries to use a rate policy that has not been defined on device, data is sent at 1Mbps. So, this patch should fix abnormal throughput observed sometime after a reset of the interface. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/data_tx.c | 3 +-- drivers/staging/wfx/data_tx.h | 1 + drivers/staging/wfx/sta.c | 6 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/staging/wfx/data_tx.c b/drivers/staging/wfx/data_tx.c index b722e9773232..02f001dab62b 100644 --- a/drivers/staging/wfx/data_tx.c +++ b/drivers/staging/wfx/data_tx.c @@ -249,7 +249,7 @@ static int wfx_tx_policy_upload(struct wfx_vif *wvif) return 0; } -static void wfx_tx_policy_upload_work(struct work_struct *work) +void wfx_tx_policy_upload_work(struct work_struct *work) { struct wfx_vif *wvif = container_of(work, struct wfx_vif, tx_policy_upload_work); @@ -270,7 +270,6 @@ void wfx_tx_policy_init(struct wfx_vif *wvif) spin_lock_init(>lock); INIT_LIST_HEAD(>used); INIT_LIST_HEAD(>free); - INIT_WORK(>tx_policy_upload_work, wfx_tx_policy_upload_work); for (i = 0; i < HIF_MIB_NUM_TX_RATE_RETRY_POLICIES; ++i) list_add(>cache[i].link, >free); diff --git a/drivers/staging/wfx/data_tx.h b/drivers/staging/wfx/data_tx.h index 29faa5640516..a0f9ae69baf5 100644 --- a/drivers/staging/wfx/data_tx.h +++ b/drivers/staging/wfx/data_tx.h @@ -61,6 +61,7 @@ struct wfx_tx_priv { } __packed; void wfx_tx_policy_init(struct wfx_vif *wvif); +void wfx_tx_policy_upload_work(struct work_struct *work); void wfx_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, struct sk_buff *skb); diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c index 29848a202ab4..471dd15b227f 100644 --- a/drivers/staging/wfx/sta.c +++ b/drivers/staging/wfx/sta.c @@ -592,6 +592,7 @@ static void wfx_do_unjoin(struct wfx_vif *wvif) wfx_tx_flush(wvif->wdev); hif_keep_alive_period(wvif, 0); hif_reset(wvif, false); + wfx_tx_policy_init(wvif); hif_set_output_power(wvif, wvif->wdev->output_power * 10); wvif->dtim_period = 0; hif_set_macaddr(wvif, wvif->vif->addr); @@ -880,8 +881,10 @@ static int wfx_update_beaconing(struct wfx_vif *wvif) if (wvif->state != WFX_STATE_AP || wvif->beacon_int != conf->beacon_int) { wfx_tx_lock_flush(wvif->wdev); - if (wvif->state != WFX_STATE_PASSIVE) + if (wvif->state != WFX_STATE_PASSIVE) { hif_reset(wvif, false); + wfx_tx_policy_init(wvif); + } wvif->state = WFX_STATE_PASSIVE; wfx_start_ap(wvif); wfx_tx_unlock(wvif->wdev); @@ -1567,6 +1570,7 @@ int wfx_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) INIT_WORK(>set_cts_work, wfx_set_cts_work); INIT_WORK(>unjoin_work, wfx_unjoin_work); + INIT_WORK(>tx_policy_upload_work, wfx_tx_policy_upload_work); mutex_unlock(>conf_mutex); hif_set_macaddr(wvif, vif->addr); -- 2.24.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 08/55] staging: wfx: detect race condition in WEP authentication
From: Jérôme Pouiller Current code has a special case to handle association with WEP. Before to rework the tx data handling, let's try to detect any possible misuse of this code. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/queue.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/wfx/queue.c b/drivers/staging/wfx/queue.c index c7ee90888f69..680fed31cefb 100644 --- a/drivers/staging/wfx/queue.c +++ b/drivers/staging/wfx/queue.c @@ -422,6 +422,7 @@ static bool hif_handle_tx_data(struct wfx_vif *wvif, struct sk_buff *skb, break; case do_wep: wfx_tx_lock(wvif->wdev); + WARN_ON(wvif->wep_pending_skb); wvif->wep_default_key_id = tx_priv->hw_key->keyidx; wvif->wep_pending_skb = skb; if (!schedule_work(>wep_key_work)) -- 2.24.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 02/55] staging: wfx: fix case of lack of tx_retry_policies
From: Jérôme Pouiller In some rare cases, driver may not have any available tx_retry_policies. In this case, the driver asks to mac80211 to stop sending data. However, it seems that a race is possible and a few frames can be sent to the driver. In this case, driver can't wait for free tx_retry_policies since wfx_tx() must be atomic. So, this patch fix this case by sending these frames with the special policy number 15. The firmware normally use policy 15 to send internal frames (PS-poll, beacons, etc...). So, it is not a so bad fallback. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/data_tx.c | 7 +-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/staging/wfx/data_tx.c b/drivers/staging/wfx/data_tx.c index 02f001dab62b..df3aca03b50b 100644 --- a/drivers/staging/wfx/data_tx.c +++ b/drivers/staging/wfx/data_tx.c @@ -16,7 +16,7 @@ #include "traces.h" #include "hif_tx_mib.h" -#define WFX_INVALID_RATE_ID (0xFF) +#define WFX_INVALID_RATE_ID15 #define WFX_LINK_ID_NO_ASSOC 15 #define WFX_LINK_ID_GC_TIMEOUT ((unsigned long)(10 * HZ)) @@ -202,6 +202,8 @@ static void wfx_tx_policy_put(struct wfx_vif *wvif, int idx) int usage, locked; struct tx_policy_cache *cache = >tx_policy_cache; + if (idx == WFX_INVALID_RATE_ID) + return; spin_lock_bh(>lock); locked = list_empty(>free); usage = wfx_tx_policy_release(cache, >cache[idx]); @@ -549,7 +551,8 @@ static u8 wfx_tx_get_rate_id(struct wfx_vif *wvif, rate_id = wfx_tx_policy_get(wvif, tx_info->driver_rates, _policy_renew); - WARN(rate_id == WFX_INVALID_RATE_ID, "unable to get a valid Tx policy"); + if (rate_id == WFX_INVALID_RATE_ID) + dev_warn(wvif->wdev->dev, "unable to get a valid Tx policy"); if (tx_policy_renew) { /* FIXME: It's not so optimal to stop TX queues every now and -- 2.24.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 20/55] staging: wfx: make conditions easier to read
From: Jérôme Pouiller We prefer series of simple boolean conditions than computing bitmasks. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/sta.c | 27 +++ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c index 471dd15b227f..7f4eaa8e6d84 100644 --- a/drivers/staging/wfx/sta.c +++ b/drivers/staging/wfx/sta.c @@ -1055,9 +1055,11 @@ void wfx_bss_info_changed(struct ieee80211_hw *hw, } } - if (changed & - (BSS_CHANGED_BEACON | BSS_CHANGED_AP_PROBE_RESP | -BSS_CHANGED_BSSID | BSS_CHANGED_SSID | BSS_CHANGED_IBSS)) { + if (changed & BSS_CHANGED_BEACON || + changed & BSS_CHANGED_AP_PROBE_RESP || + changed & BSS_CHANGED_BSSID || + changed & BSS_CHANGED_SSID || + changed & BSS_CHANGED_IBSS) { wvif->beacon_int = info->beacon_int; wfx_update_beaconing(wvif); wfx_upload_beacon(wvif); @@ -1095,10 +1097,11 @@ void wfx_bss_info_changed(struct ieee80211_hw *hw, if (changed & BSS_CHANGED_BSSID) do_join = true; - if (changed & - (BSS_CHANGED_ASSOC | BSS_CHANGED_BSSID | -BSS_CHANGED_IBSS | BSS_CHANGED_BASIC_RATES | -BSS_CHANGED_HT)) { + if (changed & BSS_CHANGED_ASSOC || + changed & BSS_CHANGED_BSSID || + changed & BSS_CHANGED_IBSS || + changed & BSS_CHANGED_BASIC_RATES || + changed & BSS_CHANGED_HT) { if (info->assoc) { if (wvif->state < WFX_STATE_PRE_STA) { ieee80211_connection_loss(vif); @@ -1120,9 +1123,9 @@ void wfx_bss_info_changed(struct ieee80211_hw *hw, } /* ERP Protection */ - if (changed & (BSS_CHANGED_ASSOC | - BSS_CHANGED_ERP_CTS_PROT | - BSS_CHANGED_ERP_PREAMBLE)) { + if (changed & BSS_CHANGED_ASSOC || + changed & BSS_CHANGED_ERP_CTS_PROT || + changed & BSS_CHANGED_ERP_PREAMBLE) { u32 prev_erp_info = wvif->erp_info; if (info->use_cts_prot) @@ -1139,10 +1142,10 @@ void wfx_bss_info_changed(struct ieee80211_hw *hw, schedule_work(>set_cts_work); } - if (changed & (BSS_CHANGED_ASSOC | BSS_CHANGED_ERP_SLOT)) + if (changed & BSS_CHANGED_ASSOC || changed & BSS_CHANGED_ERP_SLOT) hif_slot_time(wvif, info->use_short_slot ? 9 : 20); - if (changed & (BSS_CHANGED_ASSOC | BSS_CHANGED_CQM)) { + if (changed & BSS_CHANGED_ASSOC || changed & BSS_CHANGED_CQM) { struct hif_mib_rcpi_rssi_threshold th = { .rolling_average_count = 8, .detection = 1, -- 2.24.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 11/55] staging: wfx: increase SPI bus frequency limit
From: Jérôme Pouiller The chip has now proven that it can run at 50MHz on any boards without any problem. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/bus_spi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/wfx/bus_spi.c b/drivers/staging/wfx/bus_spi.c index ab0cda1e124f..44fc42bb43a0 100644 --- a/drivers/staging/wfx/bus_spi.c +++ b/drivers/staging/wfx/bus_spi.c @@ -183,7 +183,7 @@ static int wfx_spi_probe(struct spi_device *func) if (func->bits_per_word != 16 && func->bits_per_word != 8) dev_warn(>dev, "unusual bits/word value: %d\n", func->bits_per_word); - if (func->max_speed_hz > 4900) + if (func->max_speed_hz > 5000) dev_warn(>dev, "%dHz is a very high speed\n", func->max_speed_hz); -- 2.24.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 18/55] staging: wfx: remove useless include
From: Jérôme Pouiller hif_tx.c does not use any struct skb. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/hif_tx.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/wfx/hif_tx.c b/drivers/staging/wfx/hif_tx.c index cb7cddcb9815..e8c2bd1efbac 100644 --- a/drivers/staging/wfx/hif_tx.c +++ b/drivers/staging/wfx/hif_tx.c @@ -6,7 +6,6 @@ * Copyright (c) 2017-2019, Silicon Laboratories, Inc. * Copyright (c) 2010, ST-Ericsson */ -#include #include #include "hif_tx.h" -- 2.24.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 05/55] staging: wfx: firmware does not support more than 32 total retries
From: Jérôme Pouiller The sum of all retries for a Tx frame cannot be superior to 32. There are 4 rates at most. So this patch limits number of retries per rate to 8. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/wfx/main.c b/drivers/staging/wfx/main.c index 986a2ef678b9..3b47b6c21ea1 100644 --- a/drivers/staging/wfx/main.c +++ b/drivers/staging/wfx/main.c @@ -289,7 +289,7 @@ struct wfx_dev *wfx_init_common(struct device *dev, hw->sta_data_size = sizeof(struct wfx_sta_priv); hw->queues = 4; hw->max_rates = 8; - hw->max_rate_tries = 15; + hw->max_rate_tries = 8; hw->extra_tx_headroom = sizeof(struct hif_sl_msg_hdr) + sizeof(struct hif_msg) + sizeof(struct hif_req_tx) -- 2.24.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 24/55] staging: wfx: fix typo in "num_i_es"
From: Jérôme Pouiller The script that has imported API header has made a mistake "num_i_es". Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/hif_api_cmd.h | 2 +- drivers/staging/wfx/hif_tx.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/wfx/hif_api_cmd.h b/drivers/staging/wfx/hif_api_cmd.h index 90ba6e9b82ea..3e77fbe3d5ff 100644 --- a/drivers/staging/wfx/hif_api_cmd.h +++ b/drivers/staging/wfx/hif_api_cmd.h @@ -137,7 +137,7 @@ struct hif_ie_tlv { struct hif_req_update_ie { struct hif_ie_flags ie_flags; - u16 num_i_es; + u16 num_ies; struct hif_ie_tlv ie[]; } __packed; diff --git a/drivers/staging/wfx/hif_tx.c b/drivers/staging/wfx/hif_tx.c index 2f74abca2b60..6fb98ddbc0e2 100644 --- a/drivers/staging/wfx/hif_tx.c +++ b/drivers/staging/wfx/hif_tx.c @@ -429,7 +429,7 @@ int hif_update_ie(struct wfx_vif *wvif, const struct hif_ie_flags *target_frame, struct hif_req_update_ie *body = wfx_alloc_hif(buf_len, ); memcpy(>ie_flags, target_frame, sizeof(struct hif_ie_flags)); - body->num_i_es = cpu_to_le16(1); + body->num_ies = cpu_to_le16(1); memcpy(body->ie, ies, ies_len); wfx_fill_header(hif, wvif->id, HIF_REQ_ID_UPDATE_IE, buf_len); ret = wfx_cmd_send(wvif->wdev, hif, NULL, 0, false); -- 2.24.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 04/55] staging: wfx: use boolean appropriately
From: Jérôme Pouiller The field 'uploaded' is used as a boolean, so call it a boolean. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/data_tx.c | 4 ++-- drivers/staging/wfx/data_tx.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/wfx/data_tx.c b/drivers/staging/wfx/data_tx.c index df3aca03b50b..b726dd5e59f3 100644 --- a/drivers/staging/wfx/data_tx.c +++ b/drivers/staging/wfx/data_tx.c @@ -184,7 +184,7 @@ static int wfx_tx_policy_get(struct wfx_vif *wvif, */ entry = list_entry(cache->free.prev, struct tx_policy, link); memcpy(entry->rates, wanted.rates, sizeof(entry->rates)); - entry->uploaded = 0; + entry->uploaded = false; entry->usage_count = 0; idx = entry - cache->cache; } @@ -241,7 +241,7 @@ static int wfx_tx_policy_upload(struct wfx_vif *wvif) dst->terminate = 1; dst->count_init = 1; memcpy(>rates, src->rates, sizeof(src->rates)); - src->uploaded = 1; + src->uploaded = true; arg->num_tx_rate_policies++; } } diff --git a/drivers/staging/wfx/data_tx.h b/drivers/staging/wfx/data_tx.h index f63e5d8cf929..0fc388db62e0 100644 --- a/drivers/staging/wfx/data_tx.h +++ b/drivers/staging/wfx/data_tx.h @@ -41,7 +41,7 @@ struct tx_policy { struct list_head link; int usage_count; u8 rates[12]; - u8 uploaded; + bool uploaded; }; struct tx_policy_cache { -- 2.24.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 13/55] staging: wfx: avoid double warning when no more tx policy are available
From: Jérôme Pouiller Currently, number of available tx retry policies is checked two times. Only one is sufficient. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/data_tx.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/wfx/data_tx.c b/drivers/staging/wfx/data_tx.c index 32e269becd75..c9dea627661f 100644 --- a/drivers/staging/wfx/data_tx.c +++ b/drivers/staging/wfx/data_tx.c @@ -169,7 +169,8 @@ static int wfx_tx_policy_get(struct wfx_vif *wvif, wfx_tx_policy_build(wvif, , rates); spin_lock_bh(>lock); - if (WARN_ON(list_empty(>free))) { + if (list_empty(>free)) { + WARN(1, "unable to get a valid Tx policy"); spin_unlock_bh(>lock); return WFX_INVALID_RATE_ID; } -- 2.24.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 27/55] staging: wfx: better naming for hif_req_join->short_preamble
From: Jérôme Pouiller HIF_PREAMBLE_SHORT_LONG12 is never used. So it is possible to change "preamble_type" into a boolean and drop "enum hif_preamble". Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/hif_api_cmd.h | 16 ++-- drivers/staging/wfx/hif_api_mib.h | 5 +++-- drivers/staging/wfx/sta.c | 6 +++--- 3 files changed, 12 insertions(+), 15 deletions(-) diff --git a/drivers/staging/wfx/hif_api_cmd.h b/drivers/staging/wfx/hif_api_cmd.h index e848bd3073a2..fc078d54bfbf 100644 --- a/drivers/staging/wfx/hif_api_cmd.h +++ b/drivers/staging/wfx/hif_api_cmd.h @@ -377,12 +377,6 @@ struct hif_cnf_edca_queue_params { u32 status; } __packed; -enum hif_preamble { - HIF_PREAMBLE_LONG = 0x0, - HIF_PREAMBLE_SHORT = 0x1, - HIF_PREAMBLE_SHORT_LONG12 = 0x2 -}; - struct hif_join_flags { u8reserved1:2; u8force_no_beacon:1; @@ -397,9 +391,10 @@ struct hif_req_join { u16 channel_number; u8bssid[ETH_ALEN]; u16 atim_window; - u8preamble_type; + u8short_preamble:1; + u8reserved2:7; u8probe_for_join; - u8reserved; + u8reserved3; struct hif_join_flags join_flags; u32 ssid_length; u8ssid[HIF_API_SSID_SIZE]; @@ -462,8 +457,9 @@ struct hif_req_start { u32 reserved1; u32 beacon_interval; u8dtim_period; - u8preamble_type; - u8reserved2; + u8short_preamble:1; + u8reserved2:7; + u8reserved3; u8ssid_length; u8ssid[HIF_API_SSID_SIZE]; u32 basic_rate_set; diff --git a/drivers/staging/wfx/hif_api_mib.h b/drivers/staging/wfx/hif_api_mib.h index 94b789ceb4ff..34e4310ad71f 100644 --- a/drivers/staging/wfx/hif_api_mib.h +++ b/drivers/staging/wfx/hif_api_mib.h @@ -471,8 +471,9 @@ struct hif_mib_set_association_mode { u8mode:1; u8rateset:1; u8spacing:1; - u8reserved:4; - u8preamble_type; + u8reserved1:4; + u8short_preamble:1; + u8reserved2:7; u8mixed_or_greenfield_type; u8mpdu_start_spacing; u32 basic_rate_set; diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c index 23ec7a4a926b..e5c933678c47 100644 --- a/drivers/staging/wfx/sta.c +++ b/drivers/staging/wfx/sta.c @@ -652,7 +652,7 @@ static void wfx_do_join(struct wfx_vif *wvif) struct cfg80211_bss *bss = NULL; struct hif_req_join join = { .infrastructure_bss_mode = !conf->ibss_joined, - .preamble_type = conf->use_short_preamble ? HIF_PREAMBLE_SHORT : HIF_PREAMBLE_LONG, + .short_preamble = conf->use_short_preamble, .probe_for_join = 1, .atim_window = 0, .basic_rate_set = wfx_rate_mask_to_hw(wvif->wdev, @@ -843,7 +843,7 @@ static int wfx_start_ap(struct wfx_vif *wvif) .channel_number = wvif->channel->hw_value, .beacon_interval = conf->beacon_int, .dtim_period = conf->dtim_period, - .preamble_type = conf->use_short_preamble ? HIF_PREAMBLE_SHORT : HIF_PREAMBLE_LONG, + .short_preamble = conf->use_short_preamble, .basic_rate_set = wfx_rate_mask_to_hw(wvif->wdev, conf->basic_rates), }; @@ -994,7 +994,7 @@ static void wfx_join_finalize(struct wfx_vif *wvif, association_mode.mode = 1; association_mode.rateset = 1; association_mode.spacing = 1; - association_mode.preamble_type = info->use_short_preamble ? HIF_PREAMBLE_SHORT : HIF_PREAMBLE_LONG; + association_mode.short_preamble = info->use_short_preamble; association_mode.basic_rate_set = cpu_to_le32(wfx_rate_mask_to_hw(wvif->wdev, info->basic_rates)); association_mode.mixed_or_greenfield_type = wfx_ht_greenfield(>ht_info); association_mode.mpdu_start_spacing = wfx_ht_ampdu_density(>ht_info); -- 2.24.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 22/55] staging: wfx: ensure that received hif messages are never modified
From: Jérôme Pouiller There are no real reason to modify the data received from device. So, let's mark the arguments constant. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/data_rx.c | 8 ++- drivers/staging/wfx/data_rx.h | 4 +- drivers/staging/wfx/data_tx.c | 2 +- drivers/staging/wfx/data_tx.h | 2 +- drivers/staging/wfx/hif_rx.c | 94 +-- drivers/staging/wfx/scan.c| 3 +- drivers/staging/wfx/scan.h| 3 +- drivers/staging/wfx/secure_link.h | 8 ++- drivers/staging/wfx/sta.c | 2 +- drivers/staging/wfx/sta.h | 2 +- 10 files changed, 72 insertions(+), 56 deletions(-) diff --git a/drivers/staging/wfx/data_rx.c b/drivers/staging/wfx/data_rx.c index e7fcce8d0cc4..d460c0ffca1f 100644 --- a/drivers/staging/wfx/data_rx.c +++ b/drivers/staging/wfx/data_rx.c @@ -48,7 +48,9 @@ static int wfx_handle_pspoll(struct wfx_vif *wvif, struct sk_buff *skb) return 0; } -static int wfx_drop_encrypt_data(struct wfx_dev *wdev, struct hif_ind_rx *arg, struct sk_buff *skb) +static int wfx_drop_encrypt_data(struct wfx_dev *wdev, +const struct hif_ind_rx *arg, +struct sk_buff *skb) { struct ieee80211_hdr *frame = (struct ieee80211_hdr *) skb->data; size_t hdrlen = ieee80211_hdrlen(frame->frame_control); @@ -98,8 +100,8 @@ static int wfx_drop_encrypt_data(struct wfx_dev *wdev, struct hif_ind_rx *arg, s } -void wfx_rx_cb(struct wfx_vif *wvif, struct hif_ind_rx *arg, - struct sk_buff *skb) +void wfx_rx_cb(struct wfx_vif *wvif, + const struct hif_ind_rx *arg, struct sk_buff *skb) { int link_id = arg->rx_flags.peer_sta_id; struct ieee80211_rx_status *hdr = IEEE80211_SKB_RXCB(skb); diff --git a/drivers/staging/wfx/data_rx.h b/drivers/staging/wfx/data_rx.h index a50ce352bc5e..61c28bfd2a37 100644 --- a/drivers/staging/wfx/data_rx.h +++ b/drivers/staging/wfx/data_rx.h @@ -13,7 +13,7 @@ struct wfx_vif; struct sk_buff; -void wfx_rx_cb(struct wfx_vif *wvif, struct hif_ind_rx *arg, - struct sk_buff *skb); +void wfx_rx_cb(struct wfx_vif *wvif, + const struct hif_ind_rx *arg, struct sk_buff *skb); #endif /* WFX_DATA_RX_H */ diff --git a/drivers/staging/wfx/data_tx.c b/drivers/staging/wfx/data_tx.c index c9dea627661f..a45243a7f15f 100644 --- a/drivers/staging/wfx/data_tx.c +++ b/drivers/staging/wfx/data_tx.c @@ -720,7 +720,7 @@ void wfx_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, ieee80211_tx_status_irqsafe(wdev->hw, skb); } -void wfx_tx_confirm_cb(struct wfx_vif *wvif, struct hif_cnf_tx *arg) +void wfx_tx_confirm_cb(struct wfx_vif *wvif, const struct hif_cnf_tx *arg) { int i; int tx_count; diff --git a/drivers/staging/wfx/data_tx.h b/drivers/staging/wfx/data_tx.h index 0fc388db62e0..078d0cfc521a 100644 --- a/drivers/staging/wfx/data_tx.h +++ b/drivers/staging/wfx/data_tx.h @@ -65,7 +65,7 @@ void wfx_tx_policy_upload_work(struct work_struct *work); void wfx_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, struct sk_buff *skb); -void wfx_tx_confirm_cb(struct wfx_vif *wvif, struct hif_cnf_tx *arg); +void wfx_tx_confirm_cb(struct wfx_vif *wvif, const struct hif_cnf_tx *arg); void wfx_skb_dtor(struct wfx_dev *wdev, struct sk_buff *skb); int wfx_unmap_link(struct wfx_vif *wvif, int link_id); diff --git a/drivers/staging/wfx/hif_rx.c b/drivers/staging/wfx/hif_rx.c index 1494ad5a507b..8a3ccdc60b7d 100644 --- a/drivers/staging/wfx/hif_rx.c +++ b/drivers/staging/wfx/hif_rx.c @@ -18,8 +18,8 @@ #include "secure_link.h" #include "hif_api_cmd.h" -static int hif_generic_confirm(struct wfx_dev *wdev, struct hif_msg *hif, - void *buf) +static int hif_generic_confirm(struct wfx_dev *wdev, + const struct hif_msg *hif, const void *buf) { // All confirm messages start with status int status = le32_to_cpu(*((__le32 *) buf)); @@ -59,9 +59,10 @@ static int hif_generic_confirm(struct wfx_dev *wdev, struct hif_msg *hif, return status; } -static int hif_tx_confirm(struct wfx_dev *wdev, struct hif_msg *hif, void *buf) +static int hif_tx_confirm(struct wfx_dev *wdev, + const struct hif_msg *hif, const void *buf) { - struct hif_cnf_tx *body = buf; + const struct hif_cnf_tx *body = buf; struct wfx_vif *wvif = wdev_to_wvif(wdev, hif->interface); WARN_ON(!wvif); @@ -72,11 +73,12 @@ static int hif_tx_confirm(struct wfx_dev *wdev, struct hif_msg *hif, void *buf) return 0; } -static int hif_multi_tx_confirm(struct wfx_dev *wdev, struct hif_msg *hif, - void *buf) +static int hif_multi_tx_confirm(struct wfx_dev *wdev, + const struct hif_msg *hif, const void *buf) { -
[PATCH v2 15/55] staging: wfx: take advantage of IS_ERR_OR_NULL()
From: Jérôme Pouiller Obviously, current code can be replaced by IS_ERR_OR_NULL(). Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/wfx/main.c b/drivers/staging/wfx/main.c index 3b47b6c21ea1..cf4bcb14a12d 100644 --- a/drivers/staging/wfx/main.c +++ b/drivers/staging/wfx/main.c @@ -182,7 +182,7 @@ struct gpio_desc *wfx_get_gpio(struct device *dev, int override, } else { ret = devm_gpiod_get(dev, label, GPIOD_OUT_LOW); } - if (IS_ERR(ret) || !ret) { + if (IS_ERR_OR_NULL(ret)) { if (!ret || PTR_ERR(ret) == -ENOENT) dev_warn(dev, "gpio %s is not defined\n", label); else -- 2.24.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 25/55] staging: wfx: fix name of struct hif_req_start_scan_alt
From: Jérôme Pouiller The original name did not make any sense. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/hif_api_cmd.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/wfx/hif_api_cmd.h b/drivers/staging/wfx/hif_api_cmd.h index 3e77fbe3d5ff..4ce3bb51cf04 100644 --- a/drivers/staging/wfx/hif_api_cmd.h +++ b/drivers/staging/wfx/hif_api_cmd.h @@ -188,7 +188,7 @@ struct hif_req_start_scan { u8ssid_and_channel_lists[]; } __packed; -struct hif_start_scan_req_cstnbssid_body { +struct hif_req_start_scan_alt { u8band; struct hif_scan_type scan_type; struct hif_scan_flags scan_flags; -- 2.24.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 00/55] Improve wfx driver
From: Jérôme Pouiller Hello all, This pull request continue to clean up the wfx driver. It can be more or less divided in four parts: - 0001 to 0009 fix some issues (should be included in 5.5?) - 0010 to 0028 mostly contains cosmetics changes - 0029 to 0043 re-work power save (in station mode) and QoS - 0044 to 0054 re-work the scan process The last patch updates the TODO with a more precise list. I included references to discussions I have had on mailing lists, in order to not forget them. I started the first items of the list and I hope to be able to send another (smaller) pull request in 2-3 weeks. This series also try clarify the overall architecture: ,. |mac80211| `' ,+---+---. |sta | | | |scan| | | |main| | | ++ data_tx | | |key | | data_rx | | hif_tx_mib | queue | | | hif_tx | | | | hif_rx | | | | hif_api_* | | | ++---+---+. | bh| fwio | | secure_link || +++ | hwio| +-+ | bus_sdio | | bus_spi | |hwbus| `-' ,-. | sdio/spi | +-+ | hardware | `-' It try to make a clear separation between functions that take care of hardware communication (hif_*) and functions that work with mac80211 (sta.c and scan.c). v2: - Fix line ends - Update TODO with Felix idea - Add architecture schematics in cover letter Jérôme Pouiller (55): staging: wfx: fix the cache of rate policies on interface reset staging: wfx: fix case of lack of tx_retry_policies staging: wfx: fix counter overflow staging: wfx: use boolean appropriately staging: wfx: firmware does not support more than 32 total retries staging: wfx: fix rate control handling staging: wfx: ensure that retry policy always fallbacks to MCS0 / 1Mbps staging: wfx: detect race condition in WEP authentication staging: wfx: fix hif_set_mfp() with big endian hosts staging: wfx: fix wrong error message staging: wfx: increase SPI bus frequency limit staging: wfx: don't print useless error messages staging: wfx: avoid double warning when no more tx policy are available staging: wfx: improve error message on unexpected confirmation staging: wfx: take advantage of IS_ERR_OR_NULL() staging: wfx: uniformize naming rule staging: wfx: use meaningful names for CFG_BYTE_ORDER_* staging: wfx: remove useless include staging: wfx: simplify variable assignment staging: wfx: make conditions easier to read staging: wfx: ensure that traces never modify arguments staging: wfx: ensure that received hif messages are never modified staging: wfx: fix typo in "num_of_ssi_ds" staging: wfx: fix typo in "num_i_es" staging: wfx: fix name of struct hif_req_start_scan_alt staging: wfx: improve API of hif_req_join->infrastructure_bss_mode staging: wfx: better naming for hif_req_join->short_preamble staging: wfx: better naming for hif_mib_set_association_mode->greenfield staging: wfx: simplify handling of tx_lock in wfx_do_join() staging: wfx: firmware already handle powersave mode during scan staging: wfx: declare wfx_set_pm() static staging: wfx: drop useless argument from wfx_set_pm() staging: wfx: remove redundant test while calling wfx_update_pm() staging: wfx: drop unnecessary wvif->powersave_mode staging: wfx: do not try to save call to hif_set_pm() staging: wfx: fix pm_mode timeout staging: wfx: simplify wfx_conf_tx() staging: wfx: prefer a bitmask instead of an array of boolean staging: wfx: simplify hif_set_uapsd_info() usage staging: wfx: simplify hif_set_pm() usage staging: wfx: drop struct wfx_edca_params staging: wfx: remove unnecessary EDCA initialisation staging: wfx: simplify hif_set_edca_queue_params() usage staging: wfx: hif_scan() never fails staging: wfx: device already handle sleep mode during scan staging: wfx: drop useless wfx_scan_complete() staging: wfx: simplify hif_scan() usage staging: wfx: introduce update_probe_tmpl() staging: wfx: simplify hif_set_template_frame() usage staging: wfx: rewr
[PATCH v2 06/55] staging: wfx: fix rate control handling
From: Jérôme Pouiller A tx_retry_policy (the equivalent of a list of ieee80211_tx_rate in hardware API) is not able to include a rate multiple time. So currently, the driver merges the identical rates from the policy provided by minstrel (and it try to do the best choice it can in the associated flags) before to sent it to firmware. Until now, when rates are merged, field "count" is set to max(count1, count2). But, it means that the sum of retries for all rates could be far less than initial number of retries. So, this patch changes the value of field "count" to count1 + count2. Thus, sum of all retries for all rates stay the same. 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 b726dd5e59f3..46ad83b95f52 100644 --- a/drivers/staging/wfx/data_tx.c +++ b/drivers/staging/wfx/data_tx.c @@ -524,9 +524,9 @@ static void wfx_tx_fixup_rates(struct ieee80211_tx_rate *rates) for (i = 0; i < IEEE80211_TX_MAX_RATES - 1; i++) { if (rates[i + 1].idx == rates[i].idx && rates[i].idx != -1) { - rates[i].count = - max_t(int, rates[i].count, - rates[i + 1].count); + rates[i].count += rates[i + 1].count; + if (rates[i].count > 15) + rates[i].count = 15; rates[i + 1].idx = -1; rates[i + 1].count = 0; -- 2.24.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 07/55] staging: wfx: ensure that retry policy always fallbacks to MCS0 / 1Mbps
From: Jérôme Pouiller When not using HT mode, minstrel always includes 1Mbps as fallback rate. But, when using HT mode, this fallback is not included. Yet, it seems that it could save some frames. So, this patch add it unconditionally. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/data_tx.c | 11 +++ 1 file changed, 11 insertions(+) diff --git a/drivers/staging/wfx/data_tx.c b/drivers/staging/wfx/data_tx.c index 46ad83b95f52..738a6ca5edad 100644 --- a/drivers/staging/wfx/data_tx.c +++ b/drivers/staging/wfx/data_tx.c @@ -538,6 +538,17 @@ static void wfx_tx_fixup_rates(struct ieee80211_tx_rate *rates) } } } while (!finished); + // Ensure that MCS0 or 1Mbps is present at the end of the retry list + for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { + if (rates[i].idx == 0) + break; + if (rates[i].idx == -1) { + rates[i].idx = 0; + rates[i].count = 8; // == hw->max_rate_tries + rates[i].flags = rates[i - 1].flags & IEEE80211_TX_RC_MCS; + break; + } + } // All retries use long GI for (i = 1; i < IEEE80211_TX_MAX_RATES; i++) rates[i].flags &= ~IEEE80211_TX_RC_SHORT_GI; -- 2.24.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 17/55] staging: wfx: use meaningful names for CFG_BYTE_ORDER_*
From: Jérôme Pouiller This new naming allows to save a comment. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/bus_spi.c | 2 ++ drivers/staging/wfx/fwio.c| 2 +- drivers/staging/wfx/hwio.h| 15 +-- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/drivers/staging/wfx/bus_spi.c b/drivers/staging/wfx/bus_spi.c index 0a055c4041af..40bc33035de2 100644 --- a/drivers/staging/wfx/bus_spi.c +++ b/drivers/staging/wfx/bus_spi.c @@ -107,6 +107,8 @@ static int wfx_spi_copy_to_io(void *priv, unsigned int addr, cpu_to_le16s(); + // Register address and CONFIG content always use 16bit big endian + // ("BADC" order) if (bus->need_swab) swab16s(); if (bus->need_swab && addr == WFX_REG_CONFIG) diff --git a/drivers/staging/wfx/fwio.c b/drivers/staging/wfx/fwio.c index 47e627bf0f8e..9d61082c1e6c 100644 --- a/drivers/staging/wfx/fwio.c +++ b/drivers/staging/wfx/fwio.c @@ -339,7 +339,7 @@ int wfx_init_device(struct wfx_dev *wdev) ktime_t now, start; u32 reg; - reg = CFG_DIRECT_ACCESS_MODE | CFG_CPU_RESET | CFG_WORD_MODE2; + reg = CFG_DIRECT_ACCESS_MODE | CFG_CPU_RESET | CFG_BYTE_ORDER_ABCD; if (wdev->pdata.use_rising_clk) reg |= CFG_CLK_RISE_EDGE; ret = config_reg_write(wdev, reg); diff --git a/drivers/staging/wfx/hwio.h b/drivers/staging/wfx/hwio.h index b2c1a66de963..4b6ef061b40b 100644 --- a/drivers/staging/wfx/hwio.h +++ b/drivers/staging/wfx/hwio.h @@ -37,16 +37,11 @@ int ahb_reg_write(struct wfx_dev *wdev, u32 addr, u32 val); #define CFG_ERR_HOST_NO_IN_QUEUE 0x0040 #define CFG_ERR_HOST_CRC_MISS 0x0080 // only with SDIO #define CFG_SPI_IGNORE_CS 0x0080 // only with SPI -/* Bytes ordering (only writable in SPI): */ -#define CFG_WORD_MODE_MASK 0x0300 -/* - * B1,B0,B3,B2 (In SPI, register address and - * CONFIG data always use this mode) - */ -#define CFG_WORD_MODE0 0x -#define CFG_WORD_MODE1 0x0100 // B3,B2,B1,B0 -#define CFG_WORD_MODE2 0x0200 // B0,B1,B2,B3 (SDIO) -#define CFG_DIRECT_ACCESS_MODE 0x0400 // Direct or queue access mode +#define CFG_BYTE_ORDER_MASK0x0300 // only writable with SPI +#define CFG_BYTE_ORDER_BADC0x +#define CFG_BYTE_ORDER_DCBA0x0100 +#define CFG_BYTE_ORDER_ABCD0x0200 // SDIO always use this value +#define CFG_DIRECT_ACCESS_MODE 0x0400 #define CFG_PREFETCH_AHB 0x0800 #define CFG_DISABLE_CPU_CLK0x1000 #define CFG_PREFETCH_SRAM 0x2000 -- 2.24.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 53/55] staging: wfx: delayed_link_loss cannot happen
From: Jérôme Pouiller Original code allows to detect an BSS loss during a scan and delaying the handling of BSS loss. However, there it is no real problem to just make these two events mutually exclusive (there is just a performance penalty). Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/scan.c | 4 drivers/staging/wfx/sta.c | 18 +++--- drivers/staging/wfx/wfx.h | 1 - 3 files changed, 3 insertions(+), 20 deletions(-) diff --git a/drivers/staging/wfx/scan.c b/drivers/staging/wfx/scan.c index bdbce6926e91..dde2f8868147 100644 --- a/drivers/staging/wfx/scan.c +++ b/drivers/staging/wfx/scan.c @@ -95,10 +95,6 @@ void wfx_hw_scan_work(struct work_struct *work) mutex_unlock(>wdev->conf_mutex); mutex_unlock(>scan_lock); __ieee80211_scan_completed_compat(wvif->wdev->hw, ret < 0); - if (wvif->delayed_link_loss) { - wvif->delayed_link_loss = false; - wfx_cqm_bssloss_sm(wvif, 1, 0, 0); - } } int wfx_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c index 7ae763e96455..3296bc3521d5 100644 --- a/drivers/staging/wfx/sta.c +++ b/drivers/staging/wfx/sta.c @@ -63,7 +63,6 @@ void wfx_cqm_bssloss_sm(struct wfx_vif *wvif, int init, int good, int bad) int tx = 0; mutex_lock(>bss_loss_lock); - wvif->delayed_link_loss = 0; cancel_work_sync(>bss_params_work); if (init) { @@ -429,18 +428,9 @@ static void wfx_event_handler_work(struct work_struct *work) switch (event->evt.event_id) { case HIF_EVENT_IND_BSSLOST: cancel_work_sync(>unjoin_work); - if (mutex_trylock(>scan_lock)) { - wfx_cqm_bssloss_sm(wvif, 1, 0, 0); - mutex_unlock(>scan_lock); - } else { - /* Scan is in progress. Delay reporting. -* Scan complete will trigger bss_loss_work -*/ - wvif->delayed_link_loss = 1; - /* Also start a watchdog. */ - schedule_delayed_work(>bss_loss_work, - 5 * HZ); - } + mutex_lock(>scan_lock); + wfx_cqm_bssloss_sm(wvif, 1, 0, 0); + mutex_unlock(>scan_lock); break; case HIF_EVENT_IND_BSSREGAINED: wfx_cqm_bssloss_sm(wvif, 0, 0, 0); @@ -497,8 +487,6 @@ static void wfx_do_unjoin(struct wfx_vif *wvif) { mutex_lock(>wdev->conf_mutex); - wvif->delayed_link_loss = false; - if (!wvif->state) goto done; diff --git a/drivers/staging/wfx/wfx.h b/drivers/staging/wfx/wfx.h index 5e7c911db024..db433bee87af 100644 --- a/drivers/staging/wfx/wfx.h +++ b/drivers/staging/wfx/wfx.h @@ -70,7 +70,6 @@ struct wfx_vif { int id; enum wfx_state state; - int delayed_link_loss; int bss_loss_state; u32 bss_loss_confirm_id; struct mutexbss_loss_lock; -- 2.24.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 21/55] staging: wfx: ensure that traces never modify arguments
From: Jérôme Pouiller There is no reason for a trace to change any bit of the argument. So, let's make sure that is the case by declaring the arguments constant. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/traces.h | 14 -- 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/staging/wfx/traces.h b/drivers/staging/wfx/traces.h index 3f6198ab2235..30c6a13f0e22 100644 --- a/drivers/staging/wfx/traces.h +++ b/drivers/staging/wfx/traces.h @@ -153,7 +153,7 @@ hif_mib_list_enum #define hif_mib_list hif_mib_list_enum { -1, NULL } DECLARE_EVENT_CLASS(hif_data, - TP_PROTO(struct hif_msg *hif, int tx_fill_level, bool is_recv), + TP_PROTO(const struct hif_msg *hif, int tx_fill_level, bool is_recv), TP_ARGS(hif, tx_fill_level, is_recv), TP_STRUCT__entry( __field(int, tx_fill_level) @@ -203,12 +203,12 @@ DECLARE_EVENT_CLASS(hif_data, ) ); DEFINE_EVENT(hif_data, hif_send, - TP_PROTO(struct hif_msg *hif, int tx_fill_level, bool is_recv), + TP_PROTO(const struct hif_msg *hif, int tx_fill_level, bool is_recv), TP_ARGS(hif, tx_fill_level, is_recv)); #define _trace_hif_send(hif, tx_fill_level)\ trace_hif_send(hif, tx_fill_level, false) DEFINE_EVENT(hif_data, hif_recv, - TP_PROTO(struct hif_msg *hif, int tx_fill_level, bool is_recv), + TP_PROTO(const struct hif_msg *hif, int tx_fill_level, bool is_recv), TP_ARGS(hif, tx_fill_level, is_recv)); #define _trace_hif_recv(hif, tx_fill_level)\ trace_hif_recv(hif, tx_fill_level, true) @@ -359,7 +359,8 @@ TRACE_EVENT(bh_stats, trace_bh_stats(ind, req, cnf, busy, release) TRACE_EVENT(tx_stats, - TP_PROTO(struct hif_cnf_tx *tx_cnf, struct sk_buff *skb, int delay), + TP_PROTO(const struct hif_cnf_tx *tx_cnf, const struct sk_buff *skb, +int delay), TP_ARGS(tx_cnf, skb, delay), TP_STRUCT__entry( __field(int, pkt_id) @@ -375,8 +376,9 @@ TRACE_EVENT(tx_stats, // Keep sync with wfx_rates definition in main.c static const int hw_rate[] = { 0, 1, 2, 3, 6, 7, 8, 9, 10, 11, 12, 13 }; - struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); - struct ieee80211_tx_rate *rates = tx_info->driver_rates; + const struct ieee80211_tx_info *tx_info = + (const struct ieee80211_tx_info *)skb->cb; + const struct ieee80211_tx_rate *rates = tx_info->driver_rates; int i; __entry->pkt_id = tx_cnf->packet_id; -- 2.24.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 41/55] staging: wfx: drop struct wfx_edca_params
From: Jérôme Pouiller Intermediate structure wfx_edca_params does not help. This patch relocates its members directly in struct wfx_vif. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/queue.c | 4 ++-- drivers/staging/wfx/sta.c | 18 +- drivers/staging/wfx/sta.h | 6 -- drivers/staging/wfx/wfx.h | 3 ++- 4 files changed, 13 insertions(+), 18 deletions(-) diff --git a/drivers/staging/wfx/queue.c b/drivers/staging/wfx/queue.c index 680fed31cefb..16216afe6cfc 100644 --- a/drivers/staging/wfx/queue.c +++ b/drivers/staging/wfx/queue.c @@ -452,7 +452,7 @@ static int wfx_get_prio_queue(struct wfx_vif *wvif, for (i = 0; i < IEEE80211_NUM_ACS; ++i) { int queued; - edca = >edca.params[i]; + edca = >edca_params[i]; queued = wfx_tx_queue_get_num_queued(>wdev->tx_queue[i], tx_allowed_mask); if (!queued) @@ -595,7 +595,7 @@ struct hif_msg *wfx_tx_queues_get(struct wfx_dev *wdev) wvif->pspoll_mask &= ~BIT(tx_priv->raw_link_id); /* allow bursting if txop is set */ - if (wvif->edca.params[queue_num].tx_op_limit) + if (wvif->edca_params[queue_num].tx_op_limit) burst = (int)wfx_tx_queue_get_num_queued(queue, tx_allowed_mask) + 1; else burst = 1; diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c index b4007afcd0c6..d52f618062a6 100644 --- a/drivers/staging/wfx/sta.c +++ b/drivers/staging/wfx/sta.c @@ -299,7 +299,7 @@ static int wfx_update_pm(struct wfx_vif *wvif) return 0; if (!ps) ps_timeout = 0; - if (wvif->edca.uapsd_mask) + if (wvif->uapsd_mask) ps_timeout = 0; // Kernel disable PowerSave when multiple vifs are in use. In contrary, @@ -327,8 +327,8 @@ int wfx_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, WARN_ON(queue >= hw->queues); mutex_lock(>conf_mutex); - assign_bit(queue, >edca.uapsd_mask, params->uapsd); - edca = >edca.params[queue]; + assign_bit(queue, >uapsd_mask, params->uapsd); + edca = >edca_params[queue]; edca->aifsn = params->aifs; edca->cw_min = params->cw_min; edca->cw_max = params->cw_max; @@ -337,7 +337,7 @@ int wfx_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, hif_set_edca_queue_params(wvif, edca); if (wvif->vif->type == NL80211_IFTYPE_STATION) { - hif_set_uapsd_info(wvif, wvif->edca.uapsd_mask); + hif_set_uapsd_info(wvif, wvif->uapsd_mask); if (wvif->setbssparams_done && wvif->state == WFX_STATE_STA) wfx_update_pm(wvif); } @@ -1426,7 +1426,7 @@ int wfx_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) }, }; - BUILD_BUG_ON(ARRAY_SIZE(default_edca_params) != ARRAY_SIZE(wvif->edca.params)); + BUILD_BUG_ON(ARRAY_SIZE(default_edca_params) != ARRAY_SIZE(wvif->edca_params)); if (wfx_api_older_than(wdev, 2, 0)) { default_edca_params[IEEE80211_AC_BE].queue_id = HIF_QUEUE_ID_BACKGROUND; default_edca_params[IEEE80211_AC_BK].queue_id = HIF_QUEUE_ID_BESTEFFORT; @@ -1502,12 +1502,12 @@ int wfx_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) hif_set_macaddr(wvif, vif->addr); for (i = 0; i < IEEE80211_NUM_ACS; i++) { - memcpy(>edca.params[i], _edca_params[i], + memcpy(>edca_params[i], _edca_params[i], sizeof(default_edca_params[i])); - hif_set_edca_queue_params(wvif, >edca.params[i]); + hif_set_edca_queue_params(wvif, >edca_params[i]); } - wvif->edca.uapsd_mask = 0; - hif_set_uapsd_info(wvif, wvif->edca.uapsd_mask); + wvif->uapsd_mask = 0; + hif_set_uapsd_info(wvif, wvif->uapsd_mask); wfx_tx_policy_init(wvif); wvif = NULL; diff --git a/drivers/staging/wfx/sta.h b/drivers/staging/wfx/sta.h index 74755f6fa030..9595e1fc60db 100644 --- a/drivers/staging/wfx/sta.h +++ b/drivers/staging/wfx/sta.h @@ -34,12 +34,6 @@ struct wfx_hif_event { struct hif_ind_event evt; }; -struct wfx_edca_params { - /* NOTE: index is a linux queue id. */ - struct hif_req_edca_queue_params params[IEEE80211_NUM_ACS]; - unsigned long uapsd_mask; -}; - struct wfx_grp_addr_table { bool enable; int num_addresses; diff --git a/drivers/staging/wfx/wfx.h b/drivers/staging/wfx/wfx.h index ff29163436b6..5a2f8af17eb7 100644 --- a/drivers/staging/wfx/wfx.h +++ b/drivers/staging/wfx/wfx.h @@ -113,7 +113,8 @@ struct wfx_vif { int
[PATCH v2 16/55] staging: wfx: uniformize naming rule
From: Jérôme Pouiller In wfx driver, when a function is used as a struct member, its name is the name of the member prefixed with "wfx_". This patch apply this rule to wfx_spi_remove(). Also remove the useless comment above the function. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/bus_spi.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/staging/wfx/bus_spi.c b/drivers/staging/wfx/bus_spi.c index 44fc42bb43a0..0a055c4041af 100644 --- a/drivers/staging/wfx/bus_spi.c +++ b/drivers/staging/wfx/bus_spi.c @@ -223,8 +223,7 @@ static int wfx_spi_probe(struct spi_device *func) return ret; } -/* Disconnect Function to be called by SPI stack when device is disconnected */ -static int wfx_spi_disconnect(struct spi_device *func) +static int wfx_spi_remove(struct spi_device *func) { struct wfx_spi_priv *bus = spi_get_drvdata(func); @@ -263,5 +262,5 @@ struct spi_driver wfx_spi_driver = { }, .id_table = wfx_spi_id, .probe = wfx_spi_probe, - .remove = wfx_spi_disconnect, + .remove = wfx_spi_remove, }; -- 2.24.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 45/55] staging: wfx: device already handle sleep mode during scan
From: Jérôme Pouiller The device is not allowed to enter in sleep mode during scan. However, this is already handled by the device. So driver does not have to care about it. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/bh.c | 3 +-- drivers/staging/wfx/scan.c | 3 --- drivers/staging/wfx/wfx.h | 1 - 3 files changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/staging/wfx/bh.c b/drivers/staging/wfx/bh.c index 2432ba95c2f5..983c41d1fe7c 100644 --- a/drivers/staging/wfx/bh.c +++ b/drivers/staging/wfx/bh.c @@ -271,8 +271,7 @@ static void bh_work(struct work_struct *work) if (last_op_is_rx) ack_sdio_data(wdev); - if (!wdev->hif.tx_buffers_used && !work_pending(work) && - !atomic_read(>scan_in_progress)) { + if (!wdev->hif.tx_buffers_used && !work_pending(work)) { device_release(wdev); release_chip = true; } diff --git a/drivers/staging/wfx/scan.c b/drivers/staging/wfx/scan.c index cdccb67cb30e..397fe511d34a 100644 --- a/drivers/staging/wfx/scan.c +++ b/drivers/staging/wfx/scan.c @@ -44,7 +44,6 @@ static int wfx_scan_start(struct wfx_vif *wvif, struct wfx_scan_params *scan) tmo += scan->scan_req.num_of_channels * ((20 * (scan->scan_req.max_channel_time)) + 10); atomic_set(>scan.in_progress, 1); - atomic_set(>wdev->scan_in_progress, 1); schedule_delayed_work(>scan.timeout, msecs_to_jiffies(tmo)); hif_scan(wvif, scan); @@ -232,8 +231,6 @@ void wfx_scan_work(struct work_struct *work) static void wfx_scan_complete(struct wfx_vif *wvif) { up(>scan.lock); - atomic_set(>wdev->scan_in_progress, 0); - wfx_scan_work(>scan.work); } diff --git a/drivers/staging/wfx/wfx.h b/drivers/staging/wfx/wfx.h index f396a502283e..97373d047f58 100644 --- a/drivers/staging/wfx/wfx.h +++ b/drivers/staging/wfx/wfx.h @@ -60,7 +60,6 @@ struct wfx_dev { struct mutexrx_stats_lock; int output_power; - atomic_tscan_in_progress; }; struct wfx_vif { -- 2.20.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 49/55] staging: wfx: simplify hif_set_template_frame() usage
From: Jérôme Pouiller The structure hif_mib_template_frame come from hardware API. It is not intended to be manipulated in upper layers of the driver. In add, the current code for hif_set_template_frame() is dumb. All the difficult task is left to the caller. So, there is code to factorize here. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/hif_tx_mib.h | 11 ++- drivers/staging/wfx/scan.c | 7 +-- drivers/staging/wfx/sta.c| 29 +++-- 3 files changed, 18 insertions(+), 29 deletions(-) diff --git a/drivers/staging/wfx/hif_tx_mib.h b/drivers/staging/wfx/hif_tx_mib.h index d77765f75f10..b1eeda2a3ab3 100644 --- a/drivers/staging/wfx/hif_tx_mib.h +++ b/drivers/staging/wfx/hif_tx_mib.h @@ -130,8 +130,17 @@ static inline int hif_set_operational_mode(struct wfx_dev *wdev, } static inline int hif_set_template_frame(struct wfx_vif *wvif, -struct hif_mib_template_frame *arg) +struct sk_buff *skb, +u8 frame_type, int init_rate) { + struct hif_mib_template_frame *arg; + + skb_push(skb, 4); + arg = (struct hif_mib_template_frame *)skb->data; + skb_pull(skb, 4); + arg->init_rate = init_rate; + arg->frame_type = frame_type; + arg->frame_length = cpu_to_le16(skb->len); return hif_write_mib(wvif->wdev, wvif->id, HIF_MIB_ID_TEMPLATE_FRAME, arg, sizeof(*arg)); } diff --git a/drivers/staging/wfx/scan.c b/drivers/staging/wfx/scan.c index 8b184efad0cf..c82c04ff5d06 100644 --- a/drivers/staging/wfx/scan.c +++ b/drivers/staging/wfx/scan.c @@ -52,7 +52,6 @@ static int wfx_scan_start(struct wfx_vif *wvif, static int update_probe_tmpl(struct wfx_vif *wvif, struct cfg80211_scan_request *req) { - struct hif_mib_template_frame *tmpl; struct sk_buff *skb; skb = ieee80211_probereq_get(wvif->wdev->hw, wvif->vif->addr, @@ -61,11 +60,7 @@ static int update_probe_tmpl(struct wfx_vif *wvif, return -ENOMEM; skb_put_data(skb, req->ie, req->ie_len); - skb_push(skb, 4); - tmpl = (struct hif_mib_template_frame *)skb->data; - tmpl->frame_type = HIF_TMPLT_PRBREQ; - tmpl->frame_length = cpu_to_le16(skb->len - 4); - hif_set_template_frame(wvif, tmpl); + hif_set_template_frame(wvif, skb, HIF_TMPLT_PRBREQ, 0); dev_kfree_skb(skb); return 0; } diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c index 19ca13543a25..ba3e81fd477b 100644 --- a/drivers/staging/wfx/sta.c +++ b/drivers/staging/wfx/sta.c @@ -831,32 +831,20 @@ static int wfx_update_beaconing(struct wfx_vif *wvif) static int wfx_upload_beacon(struct wfx_vif *wvif) { - int ret = 0; - struct sk_buff *skb = NULL; + struct sk_buff *skb; struct ieee80211_mgmt *mgmt; - struct hif_mib_template_frame *p; if (wvif->vif->type == NL80211_IFTYPE_STATION || wvif->vif->type == NL80211_IFTYPE_MONITOR || wvif->vif->type == NL80211_IFTYPE_UNSPECIFIED) - goto done; + return 0; skb = ieee80211_beacon_get(wvif->wdev->hw, wvif->vif); - if (!skb) return -ENOMEM; + hif_set_template_frame(wvif, skb, HIF_TMPLT_BCN, + API_RATE_INDEX_B_1MBPS); - p = (struct hif_mib_template_frame *) skb_push(skb, 4); - p->frame_type = HIF_TMPLT_BCN; - p->init_rate = API_RATE_INDEX_B_1MBPS; /* 1Mbps DSSS */ - p->frame_length = cpu_to_le16(skb->len - 4); - - ret = hif_set_template_frame(wvif, p); - - skb_pull(skb, 4); - - if (ret) - goto done; /* TODO: Distill probe resp; remove TIM and any other beacon-specific * IEs */ @@ -864,14 +852,11 @@ static int wfx_upload_beacon(struct wfx_vif *wvif) mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP); - p->frame_type = HIF_TMPLT_PRBRES; - - ret = hif_set_template_frame(wvif, p); + hif_set_template_frame(wvif, skb, HIF_TMPLT_PRBRES, + API_RATE_INDEX_B_1MBPS); wfx_fwd_probe_req(wvif, false); - -done: dev_kfree_skb(skb); - return ret; + return 0; } static int wfx_is_ht(const struct wfx_ht_info *ht_info) -- 2.20.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 47/55] staging: wfx: simplify hif_scan() usage
From: Jérôme Pouiller The structures hif_req_start_scan and hif_ssid_def come from hardware API. It is not intended to be manipulated in upper layers of the driver. So, this patch relocate handling of theses structures to hif_scan() (the low level function). This change also allows to drop struct wfx_scan_params. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/hif_tx.c | 72 ++-- drivers/staging/wfx/hif_tx.h | 10 ++--- drivers/staging/wfx/scan.c | 54 --- drivers/staging/wfx/wfx.h| 1 + 4 files changed, 57 insertions(+), 80 deletions(-) diff --git a/drivers/staging/wfx/hif_tx.c b/drivers/staging/wfx/hif_tx.c index 259b49b99098..8a34a52dd5b9 100644 --- a/drivers/staging/wfx/hif_tx.c +++ b/drivers/staging/wfx/hif_tx.c @@ -220,41 +220,59 @@ int hif_write_mib(struct wfx_dev *wdev, int vif_id, u16 mib_id, void *val, return ret; } -int hif_scan(struct wfx_vif *wvif, const struct wfx_scan_params *arg) +int hif_scan(struct wfx_vif *wvif, struct cfg80211_scan_request *req, +int chan_start_idx, int chan_num) { int ret, i; struct hif_msg *hif; - struct hif_ssid_def *ssids; - size_t buf_len = sizeof(struct hif_req_start_scan) + - arg->scan_req.num_of_channels * sizeof(u8) + - arg->scan_req.num_of_ssids * sizeof(struct hif_ssid_def); - struct hif_req_start_scan *body = wfx_alloc_hif(buf_len, ); - u8 *ptr = (u8 *) body + sizeof(*body); + 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, ); + int tmo_chan_fg, tmo_chan_bg, tmo; - WARN(arg->scan_req.num_of_channels > HIF_API_MAX_NB_CHANNELS, "invalid params"); - WARN(arg->scan_req.num_of_ssids > 2, "invalid params"); - WARN(arg->scan_req.band > 1, "invalid params"); + WARN(chan_num > HIF_API_MAX_NB_CHANNELS, "invalid params"); + WARN(req->n_ssids > HIF_API_MAX_NB_SSIDS, "invalid params"); + + compiletime_assert(IEEE80211_MAX_SSID_LEN == HIF_API_SSID_SIZE, + "API inconsistency"); + for (i = 0; i < req->n_ssids; i++) { + memcpy(body->ssid_def[i].ssid, req->ssids[i].ssid, + IEEE80211_MAX_SSID_LEN); + body->ssid_def[i].ssid_length = + cpu_to_le32(req->ssids[i].ssid_len); + } + body->num_of_ssids = HIF_API_MAX_NB_SSIDS; + // Background scan is always a good idea + body->scan_type.type = 1; + body->scan_flags.fbg = 1; + body->tx_power_level = + cpu_to_le32(req->channels[chan_start_idx]->max_power); + body->num_of_channels = chan_num; + for (i = 0; i < chan_num; i++) + body->channel_list[i] = + req->channels[i + chan_start_idx]->hw_value; + if (req->no_cck) + body->max_transmit_rate = API_RATE_INDEX_G_6MBPS; + else + body->max_transmit_rate = API_RATE_INDEX_B_1MBPS; + if (req->channels[chan_start_idx]->flags & IEEE80211_CHAN_NO_IR) { + body->min_channel_time = cpu_to_le32(50); + body->max_channel_time = cpu_to_le32(150); + } else { + body->min_channel_time = cpu_to_le32(10); + body->max_channel_time = cpu_to_le32(50); + 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); - // FIXME: This API is unnecessary complex, fixing NumOfChannels and - // adding a member SsidDef at end of struct hif_req_start_scan would - // simplify that a lot. - memcpy(body, >scan_req, sizeof(*body)); - cpu_to_le32s(>min_channel_time); - cpu_to_le32s(>max_channel_time); - cpu_to_le32s(>tx_power_level); - memcpy(ptr, arg->ssids, - arg->scan_req.num_of_ssids * sizeof(struct hif_ssid_def)); - ssids = (struct hif_ssid_def *) ptr; - for (i = 0; i < body->num_of_ssids; ++i) - cpu_to_le32s([i].ssid_length); - ptr += arg->scan_req.num_of_ssids * sizeof(struct hif_ssid_def); - memcpy(ptr, arg->ch, arg->scan_req.num_of_channels * sizeof(u8)); - ptr += arg->scan_req.num_of_channels * sizeof(u8); - WARN(buf_len != ptr - (u8 *) body, "allocation size mismatch"); wfx_fill_header(hif, wvif->id, HIF_REQ_ID_START_SCAN, buf_len); ret = wfx_cmd
[PATCH 46/55] staging: wfx: drop useless wfx_scan_complete()
From: Jérôme Pouiller Since wfx_scan_complete() is now only called from wfx_scan_complete_cb(), it make sense to merge the both functions. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/scan.c | 9 ++--- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/drivers/staging/wfx/scan.c b/drivers/staging/wfx/scan.c index 397fe511d34a..c043f2f79541 100644 --- a/drivers/staging/wfx/scan.c +++ b/drivers/staging/wfx/scan.c @@ -228,12 +228,6 @@ void wfx_scan_work(struct work_struct *work) schedule_work(>scan.work); } -static void wfx_scan_complete(struct wfx_vif *wvif) -{ - up(>scan.lock); - wfx_scan_work(>scan.work); -} - void wfx_scan_complete_cb(struct wfx_vif *wvif, const struct hif_ind_scan_cmpl *arg) { @@ -257,6 +251,7 @@ void wfx_scan_timeout(struct work_struct *work) wvif->scan.curr = wvif->scan.end; hif_stop_scan(wvif); } - wfx_scan_complete(wvif); + up(>scan.lock); + wfx_scan_work(>scan.work); } } -- 2.20.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 43/55] staging: wfx: simplify hif_set_edca_queue_params() usage
From: Jérôme Pouiller The struct hif_req_edca_queue_params comes from hardware API. It is not intended to be manipulated in upper layers of the driver. So, this patch: 1. relocate the handling of this struct in hif_set_edca_queue_params() (the low level function) 2. replace it in wfx_vif by the mac80211 equivalent: struct ieee80211_tx_queue_params Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/hif_tx.c | 20 +--- drivers/staging/wfx/hif_tx.h | 5 +++-- drivers/staging/wfx/queue.c | 6 +++--- drivers/staging/wfx/sta.c| 18 ++ drivers/staging/wfx/wfx.h| 4 +++- 5 files changed, 24 insertions(+), 29 deletions(-) diff --git a/drivers/staging/wfx/hif_tx.c b/drivers/staging/wfx/hif_tx.c index 9cbf9d916f5f..259b49b99098 100644 --- a/drivers/staging/wfx/hif_tx.c +++ b/drivers/staging/wfx/hif_tx.c @@ -340,19 +340,25 @@ int hif_remove_key(struct wfx_dev *wdev, int idx) return ret; } -int hif_set_edca_queue_params(struct wfx_vif *wvif, - const struct hif_req_edca_queue_params *arg) +int hif_set_edca_queue_params(struct wfx_vif *wvif, u16 queue, + const struct ieee80211_tx_queue_params *arg) { int ret; struct hif_msg *hif; struct hif_req_edca_queue_params *body = wfx_alloc_hif(sizeof(*body), ); - // NOTE: queues numerotation are not the same between WFx and Linux - memcpy(body, arg, sizeof(*body)); - cpu_to_le16s(>cw_min); - cpu_to_le16s(>cw_max); - cpu_to_le16s(>tx_op_limit); + WARN_ON(arg->aifs > 255); + body->aifsn = arg->aifs; + body->cw_min = cpu_to_le16(arg->cw_min); + body->cw_max = cpu_to_le16(arg->cw_max); + body->tx_op_limit = cpu_to_le16(arg->txop * USEC_PER_TXOP); + body->queue_id = 3 - queue; + // API 2.0 has changed queue IDs values + if (wfx_api_older_than(wvif->wdev, 2, 0) && queue == IEEE80211_AC_BE) + body->queue_id = HIF_QUEUE_ID_BACKGROUND; + if (wfx_api_older_than(wvif->wdev, 2, 0) && queue == IEEE80211_AC_BK) + body->queue_id = HIF_QUEUE_ID_BESTEFFORT; wfx_fill_header(hif, wvif->id, HIF_REQ_ID_EDCA_QUEUE_PARAMS, sizeof(*body)); 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 bb5860ee6542..d88019421fbc 100644 --- a/drivers/staging/wfx/hif_tx.h +++ b/drivers/staging/wfx/hif_tx.h @@ -12,6 +12,7 @@ #include "hif_api_cmd.h" +struct ieee80211_tx_queue_params; struct wfx_dev; struct wfx_vif; @@ -52,8 +53,8 @@ int hif_set_bss_params(struct wfx_vif *wvif, const struct hif_req_set_bss_params *arg); int hif_add_key(struct wfx_dev *wdev, const struct hif_req_add_key *arg); int hif_remove_key(struct wfx_dev *wdev, int idx); -int hif_set_edca_queue_params(struct wfx_vif *wvif, - const struct hif_req_edca_queue_params *arg); +int hif_set_edca_queue_params(struct wfx_vif *wvif, u16 queue, + const struct ieee80211_tx_queue_params *arg); int hif_start(struct wfx_vif *wvif, const struct hif_req_start *arg); int hif_beacon_transmit(struct wfx_vif *wvif, bool enable); int hif_map_link(struct wfx_vif *wvif, u8 *mac_addr, int flags, int sta_id); diff --git a/drivers/staging/wfx/queue.c b/drivers/staging/wfx/queue.c index 16216afe6cfc..abfbad7c9f75 100644 --- a/drivers/staging/wfx/queue.c +++ b/drivers/staging/wfx/queue.c @@ -443,7 +443,7 @@ static int wfx_get_prio_queue(struct wfx_vif *wvif, { static const int urgent = BIT(WFX_LINK_ID_AFTER_DTIM) | BIT(WFX_LINK_ID_UAPSD); - struct hif_req_edca_queue_params *edca; + const struct ieee80211_tx_queue_params *edca; unsigned int score, best = -1; int winner = -1; int i; @@ -458,7 +458,7 @@ static int wfx_get_prio_queue(struct wfx_vif *wvif, if (!queued) continue; *total += queued; - score = ((edca->aifsn + edca->cw_min) << 16) + + score = ((edca->aifs + edca->cw_min) << 16) + ((edca->cw_max - edca->cw_min) * (get_random_int() & 0x)); if (score < best && (winner < 0 || i != 3)) { @@ -595,7 +595,7 @@ struct hif_msg *wfx_tx_queues_get(struct wfx_dev *wdev) wvif->pspoll_mask &= ~BIT(tx_priv->raw_link_id); /* allow bursting if txop is set */ - if (wvif->edca_params[queue_num].tx_op_limit) + if (wvif->edca_params[queue_num].txop) burst = (int)wfx_tx_queue_get_num_queued(queue,
[PATCH 44/55] staging: wfx: hif_scan() never fails
From: Jérôme Pouiller If scan fails, status is returned in hif_ind_scan_cmpl. hif_scan always return a success. So, we can simplify the code. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/scan.c | 20 ++-- drivers/staging/wfx/scan.h | 1 - 2 files changed, 2 insertions(+), 19 deletions(-) diff --git a/drivers/staging/wfx/scan.c b/drivers/staging/wfx/scan.c index 4b95e6a97df7..cdccb67cb30e 100644 --- a/drivers/staging/wfx/scan.c +++ b/drivers/staging/wfx/scan.c @@ -36,7 +36,6 @@ static void wfx_scan_restart_delayed(struct wfx_vif *wvif) static int wfx_scan_start(struct wfx_vif *wvif, struct wfx_scan_params *scan) { - int ret; int tmo = 500; if (wvif->state == WFX_STATE_PRE_STA) @@ -48,15 +47,8 @@ static int wfx_scan_start(struct wfx_vif *wvif, struct wfx_scan_params *scan) atomic_set(>wdev->scan_in_progress, 1); schedule_delayed_work(>scan.timeout, msecs_to_jiffies(tmo)); - ret = hif_scan(wvif, scan); - if (ret) { - wfx_scan_failed_cb(wvif); - atomic_set(>scan.in_progress, 0); - atomic_set(>wdev->scan_in_progress, 0); - cancel_delayed_work_sync(>scan.timeout); - wfx_scan_restart_delayed(wvif); - } - return ret; + hif_scan(wvif, scan); + return 0; } int wfx_hw_scan(struct ieee80211_hw *hw, @@ -245,14 +237,6 @@ static void wfx_scan_complete(struct wfx_vif *wvif) wfx_scan_work(>scan.work); } -void wfx_scan_failed_cb(struct wfx_vif *wvif) -{ - if (cancel_delayed_work_sync(>scan.timeout) > 0) { - wvif->scan.status = -EIO; - schedule_work(>scan.timeout.work); - } -} - void wfx_scan_complete_cb(struct wfx_vif *wvif, const struct hif_ind_scan_cmpl *arg) { diff --git a/drivers/staging/wfx/scan.h b/drivers/staging/wfx/scan.h index c7c0ab178c87..e71e5f0f522e 100644 --- a/drivers/staging/wfx/scan.h +++ b/drivers/staging/wfx/scan.h @@ -38,6 +38,5 @@ void wfx_scan_work(struct work_struct *work); void wfx_scan_timeout(struct work_struct *work); void wfx_scan_complete_cb(struct wfx_vif *wvif, const struct hif_ind_scan_cmpl *arg); -void wfx_scan_failed_cb(struct wfx_vif *wvif); #endif /* WFX_SCAN_H */ -- 2.20.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 42/55] staging: wfx: remove unnecessary EDCA initialisation
From: Jérôme Pouiller mac80211 already call wfx_conf_tx() on every VIF instanciation. So, the driver does not need to do it. Note that current code did dirty things with wvif->edca_params. This struct was initialized, but only 'queue_id' was really used. The other members are only used to store temporary values. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/sta.c | 51 +-- 1 file changed, 6 insertions(+), 45 deletions(-) diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c index d52f618062a6..3504b6b3515e 100644 --- a/drivers/staging/wfx/sta.c +++ b/drivers/staging/wfx/sta.c @@ -334,6 +334,12 @@ int wfx_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, edca->cw_max = params->cw_max; edca->tx_op_limit = params->txop * TXOP_UNIT; edca->allowed_medium_time = 0; + edca->queue_id = 3 - queue; + // API 2.0 has changed queue IDs values + if (wfx_api_older_than(wdev, 2, 0) && queue == IEEE80211_AC_BE) + edca->queue_id = HIF_QUEUE_ID_BACKGROUND; + if (wfx_api_older_than(wdev, 2, 0) && queue == IEEE80211_AC_BK) + edca->queue_id = HIF_QUEUE_ID_BESTEFFORT; hif_set_edca_queue_params(wvif, edca); if (wvif->vif->type == NL80211_IFTYPE_STATION) { @@ -1393,44 +1399,6 @@ int wfx_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) int i; struct wfx_dev *wdev = hw->priv; struct wfx_vif *wvif = (struct wfx_vif *) vif->drv_priv; - // FIXME: parameters are set by kernel juste after interface_add. - // Keep struct hif_req_edca_queue_params blank? - struct hif_req_edca_queue_params default_edca_params[] = { - [IEEE80211_AC_VO] = { - .queue_id = HIF_QUEUE_ID_VOICE, - .aifsn = 2, - .cw_min = 3, - .cw_max = 7, - .tx_op_limit = TXOP_UNIT * 47, - }, - [IEEE80211_AC_VI] = { - .queue_id = HIF_QUEUE_ID_VIDEO, - .aifsn = 2, - .cw_min = 7, - .cw_max = 15, - .tx_op_limit = TXOP_UNIT * 94, - }, - [IEEE80211_AC_BE] = { - .queue_id = HIF_QUEUE_ID_BESTEFFORT, - .aifsn = 3, - .cw_min = 15, - .cw_max = 1023, - .tx_op_limit = TXOP_UNIT * 0, - }, - [IEEE80211_AC_BK] = { - .queue_id = HIF_QUEUE_ID_BACKGROUND, - .aifsn = 7, - .cw_min = 15, - .cw_max = 1023, - .tx_op_limit = TXOP_UNIT * 0, - }, - }; - - BUILD_BUG_ON(ARRAY_SIZE(default_edca_params) != ARRAY_SIZE(wvif->edca_params)); - if (wfx_api_older_than(wdev, 2, 0)) { - default_edca_params[IEEE80211_AC_BE].queue_id = HIF_QUEUE_ID_BACKGROUND; - default_edca_params[IEEE80211_AC_BK].queue_id = HIF_QUEUE_ID_BESTEFFORT; - } vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER | IEEE80211_VIF_SUPPORTS_UAPSD | @@ -1501,13 +1469,6 @@ int wfx_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) mutex_unlock(>conf_mutex); hif_set_macaddr(wvif, vif->addr); - for (i = 0; i < IEEE80211_NUM_ACS; i++) { - memcpy(>edca_params[i], _edca_params[i], - sizeof(default_edca_params[i])); - hif_set_edca_queue_params(wvif, >edca_params[i]); - } - wvif->uapsd_mask = 0; - hif_set_uapsd_info(wvif, wvif->uapsd_mask); wfx_tx_policy_init(wvif); wvif = NULL; -- 2.20.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 48/55] staging: wfx: introduce update_probe_tmpl()
From: Jérôme Pouiller Simplify wfx_hw_scan() by splitting out the update of the probe request. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/scan.c | 57 -- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/drivers/staging/wfx/scan.c b/drivers/staging/wfx/scan.c index 122da87bbf92..8b184efad0cf 100644 --- a/drivers/staging/wfx/scan.c +++ b/drivers/staging/wfx/scan.c @@ -49,6 +49,27 @@ static int wfx_scan_start(struct wfx_vif *wvif, return 0; } +static int update_probe_tmpl(struct wfx_vif *wvif, +struct cfg80211_scan_request *req) +{ + struct hif_mib_template_frame *tmpl; + struct sk_buff *skb; + + skb = ieee80211_probereq_get(wvif->wdev->hw, wvif->vif->addr, +NULL, 0, req->ie_len); + if (!skb) + return -ENOMEM; + + skb_put_data(skb, req->ie, req->ie_len); + skb_push(skb, 4); + tmpl = (struct hif_mib_template_frame *)skb->data; + tmpl->frame_type = HIF_TMPLT_PRBREQ; + tmpl->frame_length = cpu_to_le16(skb->len - 4); + hif_set_template_frame(wvif, tmpl); + dev_kfree_skb(skb); + return 0; +} + int wfx_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_scan_request *hw_req) @@ -56,9 +77,7 @@ int wfx_hw_scan(struct ieee80211_hw *hw, struct wfx_dev *wdev = hw->priv; struct wfx_vif *wvif = (struct wfx_vif *) vif->drv_priv; struct cfg80211_scan_request *req = _req->req; - struct sk_buff *skb; int i, ret; - struct hif_mib_template_frame *p; if (!wvif) return -EINVAL; @@ -72,29 +91,15 @@ int wfx_hw_scan(struct ieee80211_hw *hw, if (req->n_ssids > HIF_API_MAX_NB_SSIDS) return -EINVAL; - skb = ieee80211_probereq_get(hw, wvif->vif->addr, NULL, 0, req->ie_len); - if (!skb) - return -ENOMEM; - - if (req->ie_len) - memcpy(skb_put(skb, req->ie_len), req->ie, req->ie_len); - mutex_lock(>conf_mutex); - p = (struct hif_mib_template_frame *)skb_push(skb, 4); - p->frame_type = HIF_TMPLT_PRBREQ; - p->frame_length = cpu_to_le16(skb->len - 4); - ret = hif_set_template_frame(wvif, p); - skb_pull(skb, 4); + ret = update_probe_tmpl(wvif, req); + if (ret) + goto failed; - if (!ret) - /* Host want to be the probe responder. */ - ret = wfx_fwd_probe_req(wvif, true); - if (ret) { - mutex_unlock(>conf_mutex); - dev_kfree_skb(skb); - return ret; - } + ret = wfx_fwd_probe_req(wvif, true); + if (ret) + goto failed; wfx_tx_lock_flush(wdev); @@ -114,13 +119,11 @@ int wfx_hw_scan(struct ieee80211_hw *hw, dst->ssid_length = req->ssids[i].ssid_len; ++wvif->scan.n_ssids; } + schedule_work(>scan.work); +failed: mutex_unlock(>conf_mutex); - - if (skb) - dev_kfree_skb(skb); - schedule_work(>scan.work); - return 0; + return ret; } void wfx_scan_work(struct work_struct *work) -- 2.20.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 38/55] staging: wfx: prefer a bitmask instead of an array of boolean
From: Jérôme Pouiller It is easier to manipulate a int than an array of booleans. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/sta.c | 17 +++-- drivers/staging/wfx/sta.h | 2 +- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c index 045d3916ada8..e59560f499ea 100644 --- a/drivers/staging/wfx/sta.c +++ b/drivers/staging/wfx/sta.c @@ -119,22 +119,22 @@ static int wfx_set_uapsd_param(struct wfx_vif *wvif, * VO [0,3], VI [1, 2], BE [2, 1], BK [3, 0] */ - if (arg->uapsd_enable[IEEE80211_AC_VO]) + if (arg->uapsd_mask & BIT(IEEE80211_AC_VO)) wvif->uapsd_info.trig_voice = 1; else wvif->uapsd_info.trig_voice = 0; - if (arg->uapsd_enable[IEEE80211_AC_VI]) + if (arg->uapsd_mask & BIT(IEEE80211_AC_VI)) wvif->uapsd_info.trig_video = 1; else wvif->uapsd_info.trig_video = 0; - if (arg->uapsd_enable[IEEE80211_AC_BE]) + if (arg->uapsd_mask & BIT(IEEE80211_AC_BE)) wvif->uapsd_info.trig_be = 1; else wvif->uapsd_info.trig_be = 0; - if (arg->uapsd_enable[IEEE80211_AC_BK]) + if (arg->uapsd_mask & BIT(IEEE80211_AC_BK)) wvif->uapsd_info.trig_bckgrnd = 1; else wvif->uapsd_info.trig_bckgrnd = 0; @@ -330,7 +330,6 @@ static int wfx_update_pm(struct wfx_vif *wvif) { struct ieee80211_conf *conf = >wdev->hw->conf; struct hif_req_set_pm_mode pm; - u16 uapsd_flags; if (wvif->state != WFX_STATE_STA || !wvif->bss_params.aid) return 0; @@ -345,9 +344,7 @@ static int wfx_update_pm(struct wfx_vif *wvif) pm.pm_mode.fast_psm = 1; } - memcpy(_flags, >uapsd_info, sizeof(uapsd_flags)); - - if (uapsd_flags != 0) + if (wvif->edca.uapsd_mask) pm.pm_mode.fast_psm = 0; // Kernel disable PowerSave when multiple vifs are in use. In contrary, @@ -375,7 +372,7 @@ int wfx_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, WARN_ON(queue >= hw->queues); mutex_lock(>conf_mutex); - wvif->edca.uapsd_enable[queue] = params->uapsd; + assign_bit(queue, >edca.uapsd_mask, params->uapsd); edca = >edca.params[queue]; edca->aifsn = params->aifs; edca->cw_min = params->cw_min; @@ -1552,9 +1549,9 @@ int wfx_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) for (i = 0; i < IEEE80211_NUM_ACS; i++) { memcpy(>edca.params[i], _edca_params[i], sizeof(default_edca_params[i])); - wvif->edca.uapsd_enable[i] = false; hif_set_edca_queue_params(wvif, >edca.params[i]); } + wvif->edca.uapsd_mask = 0; wfx_set_uapsd_param(wvif, >edca); wfx_tx_policy_init(wvif); diff --git a/drivers/staging/wfx/sta.h b/drivers/staging/wfx/sta.h index 4719807bc25a..74755f6fa030 100644 --- a/drivers/staging/wfx/sta.h +++ b/drivers/staging/wfx/sta.h @@ -37,7 +37,7 @@ struct wfx_hif_event { struct wfx_edca_params { /* NOTE: index is a linux queue id. */ struct hif_req_edca_queue_params params[IEEE80211_NUM_ACS]; - bool uapsd_enable[IEEE80211_NUM_ACS]; + unsigned long uapsd_mask; }; struct wfx_grp_addr_table { -- 2.20.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 37/55] staging: wfx: simplify wfx_conf_tx()
From: Jérôme Pouiller Error management of wfx_conf_tx() can be simplified. In add, the hardware command "hif_set_edca_queue_params" never returns any error. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/sta.c | 42 ++- 1 file changed, 15 insertions(+), 27 deletions(-) diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c index 42b0d01d85cc..045d3916ada8 100644 --- a/drivers/staging/wfx/sta.c +++ b/drivers/staging/wfx/sta.c @@ -370,39 +370,27 @@ int wfx_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, { struct wfx_dev *wdev = hw->priv; struct wfx_vif *wvif = (struct wfx_vif *) vif->drv_priv; - int ret = 0; struct hif_req_edca_queue_params *edca; + WARN_ON(queue >= hw->queues); + mutex_lock(>conf_mutex); + wvif->edca.uapsd_enable[queue] = params->uapsd; + edca = >edca.params[queue]; + edca->aifsn = params->aifs; + edca->cw_min = params->cw_min; + edca->cw_max = params->cw_max; + edca->tx_op_limit = params->txop * TXOP_UNIT; + edca->allowed_medium_time = 0; + hif_set_edca_queue_params(wvif, edca); - if (queue < hw->queues) { - edca = >edca.params[queue]; - - wvif->edca.uapsd_enable[queue] = params->uapsd; - edca->aifsn = params->aifs; - edca->cw_min = params->cw_min; - edca->cw_max = params->cw_max; - edca->tx_op_limit = params->txop * TXOP_UNIT; - edca->allowed_medium_time = 0; - ret = hif_set_edca_queue_params(wvif, edca); - if (ret) { - ret = -EINVAL; - goto out; - } - - if (wvif->vif->type == NL80211_IFTYPE_STATION) { - ret = wfx_set_uapsd_param(wvif, >edca); - if (!ret && wvif->setbssparams_done && - wvif->state == WFX_STATE_STA) - ret = wfx_update_pm(wvif); - } - } else { - ret = -EINVAL; + if (wvif->vif->type == NL80211_IFTYPE_STATION) { + wfx_set_uapsd_param(wvif, >edca); + if (wvif->setbssparams_done && wvif->state == WFX_STATE_STA) + wfx_update_pm(wvif); } - -out: mutex_unlock(>conf_mutex); - return ret; + return 0; } int wfx_set_rts_threshold(struct ieee80211_hw *hw, u32 value) -- 2.20.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 39/55] staging: wfx: simplify hif_set_uapsd_info() usage
From: Jérôme Pouiller It is useless to keep uapsd_info in struct wfx_vif. This structure can be rebuilt just before to be sent. In add, the struct hif_mib_set_uapsd_information comes from hardware API. It is not intended to be manipulated in upper layers of the driver. So, this patch relocates the handling of this struct to hif_set_uapsd_info() (the low level function). Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/hif_tx_mib.h | 15 +--- drivers/staging/wfx/sta.c| 42 ++-- drivers/staging/wfx/wfx.h| 1 - 3 files changed, 14 insertions(+), 44 deletions(-) diff --git a/drivers/staging/wfx/hif_tx_mib.h b/drivers/staging/wfx/hif_tx_mib.h index 9be74881c56c..d77765f75f10 100644 --- a/drivers/staging/wfx/hif_tx_mib.h +++ b/drivers/staging/wfx/hif_tx_mib.h @@ -238,12 +238,21 @@ static inline int hif_use_multi_tx_conf(struct wfx_dev *wdev, , sizeof(arg)); } -static inline int hif_set_uapsd_info(struct wfx_vif *wvif, -struct hif_mib_set_uapsd_information *arg) +static inline int hif_set_uapsd_info(struct wfx_vif *wvif, unsigned long val) { + struct hif_mib_set_uapsd_information arg = { }; + + if (val & BIT(IEEE80211_AC_VO)) + arg.trig_voice = 1; + if (val & BIT(IEEE80211_AC_VI)) + arg.trig_video = 1; + if (val & BIT(IEEE80211_AC_BE)) + arg.trig_be = 1; + if (val & BIT(IEEE80211_AC_BK)) + arg.trig_bckgrnd = 1; return hif_write_mib(wvif->wdev, wvif->id, HIF_MIB_ID_SET_UAPSD_INFORMATION, -arg, sizeof(*arg)); +, sizeof(arg)); } static inline int hif_erp_use_protection(struct wfx_vif *wvif, bool enable) diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c index e59560f499ea..9eca35d91ad3 100644 --- a/drivers/staging/wfx/sta.c +++ b/drivers/staging/wfx/sta.c @@ -112,44 +112,6 @@ void wfx_cqm_bssloss_sm(struct wfx_vif *wvif, int init, int good, int bad) mutex_unlock(>bss_loss_lock); } -static int wfx_set_uapsd_param(struct wfx_vif *wvif, - const struct wfx_edca_params *arg) -{ - /* Here's the mapping AC [queue, bit] -* VO [0,3], VI [1, 2], BE [2, 1], BK [3, 0] -*/ - - if (arg->uapsd_mask & BIT(IEEE80211_AC_VO)) - wvif->uapsd_info.trig_voice = 1; - else - wvif->uapsd_info.trig_voice = 0; - - if (arg->uapsd_mask & BIT(IEEE80211_AC_VI)) - wvif->uapsd_info.trig_video = 1; - else - wvif->uapsd_info.trig_video = 0; - - if (arg->uapsd_mask & BIT(IEEE80211_AC_BE)) - wvif->uapsd_info.trig_be = 1; - else - wvif->uapsd_info.trig_be = 0; - - if (arg->uapsd_mask & BIT(IEEE80211_AC_BK)) - wvif->uapsd_info.trig_bckgrnd = 1; - else - wvif->uapsd_info.trig_bckgrnd = 0; - - /* Currently pseudo U-APSD operation is not supported, so setting -* MinAutoTriggerInterval, MaxAutoTriggerInterval and -* AutoTriggerStep to 0 -*/ - wvif->uapsd_info.min_auto_trigger_interval = 0; - wvif->uapsd_info.max_auto_trigger_interval = 0; - wvif->uapsd_info.auto_trigger_step = 0; - - return hif_set_uapsd_info(wvif, >uapsd_info); -} - int wfx_fwd_probe_req(struct wfx_vif *wvif, bool enable) { wvif->fwd_probe_req = enable; @@ -382,7 +344,7 @@ int wfx_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, hif_set_edca_queue_params(wvif, edca); if (wvif->vif->type == NL80211_IFTYPE_STATION) { - wfx_set_uapsd_param(wvif, >edca); + hif_set_uapsd_info(wvif, wvif->edca.uapsd_mask); if (wvif->setbssparams_done && wvif->state == WFX_STATE_STA) wfx_update_pm(wvif); } @@ -1552,7 +1514,7 @@ int wfx_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) hif_set_edca_queue_params(wvif, >edca.params[i]); } wvif->edca.uapsd_mask = 0; - wfx_set_uapsd_param(wvif, >edca); + hif_set_uapsd_info(wvif, wvif->edca.uapsd_mask); wfx_tx_policy_init(wvif); wvif = NULL; diff --git a/drivers/staging/wfx/wfx.h b/drivers/staging/wfx/wfx.h index c82d29764d66..ff29163436b6 100644 --- a/drivers/staging/wfx/wfx.h +++ b/drivers/staging/wfx/wfx.h @@ -114,7 +114,6 @@ struct wfx_vif { boolsetbssparams_done; struct wfx_ht_info ht_info; struct wfx_edca_params edca; - struct hif_mib_set_uapsd_information uapsd_info; struct hif_req_set_bss_params bss_params; struct work_struct bss_params_work; struct work_struct
[PATCH 40/55] staging: wfx: simplify hif_set_pm() usage
From: Jérôme Pouiller The struct hif_req_set_pm_mode comes from hardware API. It is not intended to be manipulated in upper layers of the driver. So, this patch relocate the handling of this struct to hif_set_pm() (the low level function). Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/hif_tx.c | 10 -- drivers/staging/wfx/hif_tx.h | 2 +- drivers/staging/wfx/sta.c| 25 + 3 files changed, 18 insertions(+), 19 deletions(-) diff --git a/drivers/staging/wfx/hif_tx.c b/drivers/staging/wfx/hif_tx.c index 6fb98ddbc0e2..9cbf9d916f5f 100644 --- a/drivers/staging/wfx/hif_tx.c +++ b/drivers/staging/wfx/hif_tx.c @@ -360,13 +360,19 @@ int hif_set_edca_queue_params(struct wfx_vif *wvif, return ret; } -int hif_set_pm(struct wfx_vif *wvif, const struct hif_req_set_pm_mode *arg) +int hif_set_pm(struct wfx_vif *wvif, bool ps, int dynamic_ps_timeout) { int ret; struct hif_msg *hif; struct hif_req_set_pm_mode *body = wfx_alloc_hif(sizeof(*body), ); - memcpy(body, arg, sizeof(*body)); + if (ps) { + body->pm_mode.enter_psm = 1; + // Firmware does not support more than 128ms + body->fast_psm_idle_period = min(dynamic_ps_timeout * 2, 255); + if (body->fast_psm_idle_period) + body->pm_mode.fast_psm = 1; + } wfx_fill_header(hif, wvif->id, HIF_REQ_ID_SET_PM_MODE, sizeof(*body)); ret = wfx_cmd_send(wvif->wdev, hif, NULL, 0, false); kfree(hif); diff --git a/drivers/staging/wfx/hif_tx.h b/drivers/staging/wfx/hif_tx.h index f61ae7b0d41c..bb5860ee6542 100644 --- a/drivers/staging/wfx/hif_tx.h +++ b/drivers/staging/wfx/hif_tx.h @@ -47,7 +47,7 @@ int hif_write_mib(struct wfx_dev *wdev, int vif_id, u16 mib_id, int hif_scan(struct wfx_vif *wvif, const struct wfx_scan_params *arg); int hif_stop_scan(struct wfx_vif *wvif); int hif_join(struct wfx_vif *wvif, const struct hif_req_join *arg); -int hif_set_pm(struct wfx_vif *wvif, const struct hif_req_set_pm_mode *arg); +int hif_set_pm(struct wfx_vif *wvif, bool ps, int dynamic_ps_timeout); int hif_set_bss_params(struct wfx_vif *wvif, const struct hif_req_set_bss_params *arg); int hif_add_key(struct wfx_dev *wdev, const struct hif_req_add_key *arg); diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c index 9eca35d91ad3..b4007afcd0c6 100644 --- a/drivers/staging/wfx/sta.c +++ b/drivers/staging/wfx/sta.c @@ -291,37 +291,30 @@ void wfx_configure_filter(struct ieee80211_hw *hw, static int wfx_update_pm(struct wfx_vif *wvif) { struct ieee80211_conf *conf = >wdev->hw->conf; - struct hif_req_set_pm_mode pm; + bool ps = conf->flags & IEEE80211_CONF_PS; + int ps_timeout = conf->dynamic_ps_timeout; + WARN_ON(conf->dynamic_ps_timeout < 0); if (wvif->state != WFX_STATE_STA || !wvif->bss_params.aid) return 0; - - memset(, 0, sizeof(pm)); - if (conf->flags & IEEE80211_CONF_PS) { - pm.pm_mode.enter_psm = 1; - // Firmware does not support more than 128ms - pm.fast_psm_idle_period = - min(conf->dynamic_ps_timeout * 2, 255); - if (pm.fast_psm_idle_period) - pm.pm_mode.fast_psm = 1; - } - + if (!ps) + ps_timeout = 0; if (wvif->edca.uapsd_mask) - pm.pm_mode.fast_psm = 0; + ps_timeout = 0; // Kernel disable PowerSave when multiple vifs are in use. In contrary, // it is absolutly necessary to enable PowerSave for WF200 // FIXME: only if channel vif0 != channel vif1 if (wvif_count(wvif->wdev) > 1) { - pm.pm_mode.enter_psm = 1; - pm.pm_mode.fast_psm = 0; + ps = true; + ps_timeout = 0; } if (!wait_for_completion_timeout(>set_pm_mode_complete, TU_TO_JIFFIES(512))) dev_warn(wvif->wdev->dev, "timeout while waiting of set_pm_mode_complete\n"); - return hif_set_pm(wvif, ); + return hif_set_pm(wvif, ps, ps_timeout); } int wfx_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, -- 2.20.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 41/55] staging: wfx: drop struct wfx_edca_params
From: Jérôme Pouiller Intermediate structure wfx_edca_params does not help. This patch relocates its members directly in struct wfx_vif. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/queue.c | 4 ++-- drivers/staging/wfx/sta.c | 18 +- drivers/staging/wfx/sta.h | 6 -- drivers/staging/wfx/wfx.h | 3 ++- 4 files changed, 13 insertions(+), 18 deletions(-) diff --git a/drivers/staging/wfx/queue.c b/drivers/staging/wfx/queue.c index 680fed31cefb..16216afe6cfc 100644 --- a/drivers/staging/wfx/queue.c +++ b/drivers/staging/wfx/queue.c @@ -452,7 +452,7 @@ static int wfx_get_prio_queue(struct wfx_vif *wvif, for (i = 0; i < IEEE80211_NUM_ACS; ++i) { int queued; - edca = >edca.params[i]; + edca = >edca_params[i]; queued = wfx_tx_queue_get_num_queued(>wdev->tx_queue[i], tx_allowed_mask); if (!queued) @@ -595,7 +595,7 @@ struct hif_msg *wfx_tx_queues_get(struct wfx_dev *wdev) wvif->pspoll_mask &= ~BIT(tx_priv->raw_link_id); /* allow bursting if txop is set */ - if (wvif->edca.params[queue_num].tx_op_limit) + if (wvif->edca_params[queue_num].tx_op_limit) burst = (int)wfx_tx_queue_get_num_queued(queue, tx_allowed_mask) + 1; else burst = 1; diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c index b4007afcd0c6..d52f618062a6 100644 --- a/drivers/staging/wfx/sta.c +++ b/drivers/staging/wfx/sta.c @@ -299,7 +299,7 @@ static int wfx_update_pm(struct wfx_vif *wvif) return 0; if (!ps) ps_timeout = 0; - if (wvif->edca.uapsd_mask) + if (wvif->uapsd_mask) ps_timeout = 0; // Kernel disable PowerSave when multiple vifs are in use. In contrary, @@ -327,8 +327,8 @@ int wfx_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, WARN_ON(queue >= hw->queues); mutex_lock(>conf_mutex); - assign_bit(queue, >edca.uapsd_mask, params->uapsd); - edca = >edca.params[queue]; + assign_bit(queue, >uapsd_mask, params->uapsd); + edca = >edca_params[queue]; edca->aifsn = params->aifs; edca->cw_min = params->cw_min; edca->cw_max = params->cw_max; @@ -337,7 +337,7 @@ int wfx_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, hif_set_edca_queue_params(wvif, edca); if (wvif->vif->type == NL80211_IFTYPE_STATION) { - hif_set_uapsd_info(wvif, wvif->edca.uapsd_mask); + hif_set_uapsd_info(wvif, wvif->uapsd_mask); if (wvif->setbssparams_done && wvif->state == WFX_STATE_STA) wfx_update_pm(wvif); } @@ -1426,7 +1426,7 @@ int wfx_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) }, }; - BUILD_BUG_ON(ARRAY_SIZE(default_edca_params) != ARRAY_SIZE(wvif->edca.params)); + BUILD_BUG_ON(ARRAY_SIZE(default_edca_params) != ARRAY_SIZE(wvif->edca_params)); if (wfx_api_older_than(wdev, 2, 0)) { default_edca_params[IEEE80211_AC_BE].queue_id = HIF_QUEUE_ID_BACKGROUND; default_edca_params[IEEE80211_AC_BK].queue_id = HIF_QUEUE_ID_BESTEFFORT; @@ -1502,12 +1502,12 @@ int wfx_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) hif_set_macaddr(wvif, vif->addr); for (i = 0; i < IEEE80211_NUM_ACS; i++) { - memcpy(>edca.params[i], _edca_params[i], + memcpy(>edca_params[i], _edca_params[i], sizeof(default_edca_params[i])); - hif_set_edca_queue_params(wvif, >edca.params[i]); + hif_set_edca_queue_params(wvif, >edca_params[i]); } - wvif->edca.uapsd_mask = 0; - hif_set_uapsd_info(wvif, wvif->edca.uapsd_mask); + wvif->uapsd_mask = 0; + hif_set_uapsd_info(wvif, wvif->uapsd_mask); wfx_tx_policy_init(wvif); wvif = NULL; diff --git a/drivers/staging/wfx/sta.h b/drivers/staging/wfx/sta.h index 74755f6fa030..9595e1fc60db 100644 --- a/drivers/staging/wfx/sta.h +++ b/drivers/staging/wfx/sta.h @@ -34,12 +34,6 @@ struct wfx_hif_event { struct hif_ind_event evt; }; -struct wfx_edca_params { - /* NOTE: index is a linux queue id. */ - struct hif_req_edca_queue_params params[IEEE80211_NUM_ACS]; - unsigned long uapsd_mask; -}; - struct wfx_grp_addr_table { bool enable; int num_addresses; diff --git a/drivers/staging/wfx/wfx.h b/drivers/staging/wfx/wfx.h index ff29163436b6..5a2f8af17eb7 100644 --- a/drivers/staging/wfx/wfx.h +++ b/drivers/staging/wfx/wfx.h @@ -113,7 +113,8 @@ struct wfx_vif { int
[PATCH 06/55] staging: wfx: fix rate control handling
From: Jérôme Pouiller A tx_retry_policy (the equivalent of a list of ieee80211_tx_rate in hardware API) is not able to include a rate multiple time. So currently, the driver merges the identical rates from the policy provided by minstrel (and it try to do the best choice it can in the associated flags) before to sent it to firmware. Until now, when rates are merged, field "count" is set to max(count1, count2). But, it means that the sum of retries for all rates could be far less than initial number of retries. So, this patch changes the value of field "count" to count1 + count2. Thus, sum of all retries for all rates stay the same. 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 b726dd5e59f3..46ad83b95f52 100644 --- a/drivers/staging/wfx/data_tx.c +++ b/drivers/staging/wfx/data_tx.c @@ -524,9 +524,9 @@ static void wfx_tx_fixup_rates(struct ieee80211_tx_rate *rates) for (i = 0; i < IEEE80211_TX_MAX_RATES - 1; i++) { if (rates[i + 1].idx == rates[i].idx && rates[i].idx != -1) { - rates[i].count = - max_t(int, rates[i].count, - rates[i + 1].count); + rates[i].count += rates[i + 1].count; + if (rates[i].count > 15) + rates[i].count = 15; rates[i + 1].idx = -1; rates[i + 1].count = 0; -- 2.20.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 27/55] staging: wfx: better naming for hif_req_join->short_preamble
From: Jérôme Pouiller HIF_PREAMBLE_SHORT_LONG12 is never used. So it is possible to change "preamble_type" into a boolean and drop "enum hif_preamble". Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/hif_api_cmd.h | 16 ++-- drivers/staging/wfx/hif_api_mib.h | 5 +++-- drivers/staging/wfx/sta.c | 6 +++--- 3 files changed, 12 insertions(+), 15 deletions(-) diff --git a/drivers/staging/wfx/hif_api_cmd.h b/drivers/staging/wfx/hif_api_cmd.h index e848bd3073a2..fc078d54bfbf 100644 --- a/drivers/staging/wfx/hif_api_cmd.h +++ b/drivers/staging/wfx/hif_api_cmd.h @@ -377,12 +377,6 @@ struct hif_cnf_edca_queue_params { u32 status; } __packed; -enum hif_preamble { - HIF_PREAMBLE_LONG = 0x0, - HIF_PREAMBLE_SHORT = 0x1, - HIF_PREAMBLE_SHORT_LONG12 = 0x2 -}; - struct hif_join_flags { u8reserved1:2; u8force_no_beacon:1; @@ -397,9 +391,10 @@ struct hif_req_join { u16 channel_number; u8bssid[ETH_ALEN]; u16 atim_window; - u8preamble_type; + u8short_preamble:1; + u8reserved2:7; u8probe_for_join; - u8reserved; + u8reserved3; struct hif_join_flags join_flags; u32 ssid_length; u8ssid[HIF_API_SSID_SIZE]; @@ -462,8 +457,9 @@ struct hif_req_start { u32 reserved1; u32 beacon_interval; u8dtim_period; - u8preamble_type; - u8reserved2; + u8short_preamble:1; + u8reserved2:7; + u8reserved3; u8ssid_length; u8ssid[HIF_API_SSID_SIZE]; u32 basic_rate_set; diff --git a/drivers/staging/wfx/hif_api_mib.h b/drivers/staging/wfx/hif_api_mib.h index 94b789ceb4ff..34e4310ad71f 100644 --- a/drivers/staging/wfx/hif_api_mib.h +++ b/drivers/staging/wfx/hif_api_mib.h @@ -471,8 +471,9 @@ struct hif_mib_set_association_mode { u8mode:1; u8rateset:1; u8spacing:1; - u8reserved:4; - u8preamble_type; + u8reserved1:4; + u8short_preamble:1; + u8reserved2:7; u8mixed_or_greenfield_type; u8mpdu_start_spacing; u32 basic_rate_set; diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c index 23ec7a4a926b..e5c933678c47 100644 --- a/drivers/staging/wfx/sta.c +++ b/drivers/staging/wfx/sta.c @@ -652,7 +652,7 @@ static void wfx_do_join(struct wfx_vif *wvif) struct cfg80211_bss *bss = NULL; struct hif_req_join join = { .infrastructure_bss_mode = !conf->ibss_joined, - .preamble_type = conf->use_short_preamble ? HIF_PREAMBLE_SHORT : HIF_PREAMBLE_LONG, + .short_preamble = conf->use_short_preamble, .probe_for_join = 1, .atim_window = 0, .basic_rate_set = wfx_rate_mask_to_hw(wvif->wdev, @@ -843,7 +843,7 @@ static int wfx_start_ap(struct wfx_vif *wvif) .channel_number = wvif->channel->hw_value, .beacon_interval = conf->beacon_int, .dtim_period = conf->dtim_period, - .preamble_type = conf->use_short_preamble ? HIF_PREAMBLE_SHORT : HIF_PREAMBLE_LONG, + .short_preamble = conf->use_short_preamble, .basic_rate_set = wfx_rate_mask_to_hw(wvif->wdev, conf->basic_rates), }; @@ -994,7 +994,7 @@ static void wfx_join_finalize(struct wfx_vif *wvif, association_mode.mode = 1; association_mode.rateset = 1; association_mode.spacing = 1; - association_mode.preamble_type = info->use_short_preamble ? HIF_PREAMBLE_SHORT : HIF_PREAMBLE_LONG; + association_mode.short_preamble = info->use_short_preamble; association_mode.basic_rate_set = cpu_to_le32(wfx_rate_mask_to_hw(wvif->wdev, info->basic_rates)); association_mode.mixed_or_greenfield_type = wfx_ht_greenfield(>ht_info); association_mode.mpdu_start_spacing = wfx_ht_ampdu_density(>ht_info); -- 2.20.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 53/55] staging: wfx: delayed_link_loss cannot happen
From: Jérôme Pouiller Original code allows to detect an BSS loss during a scan and delaying the handling of BSS loss. However, there it is no real problem to just make these two events mutually exclusive (there is just a performance penalty). Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/scan.c | 4 drivers/staging/wfx/sta.c | 18 +++--- drivers/staging/wfx/wfx.h | 1 - 3 files changed, 3 insertions(+), 20 deletions(-) diff --git a/drivers/staging/wfx/scan.c b/drivers/staging/wfx/scan.c index bdbce6926e91..dde2f8868147 100644 --- a/drivers/staging/wfx/scan.c +++ b/drivers/staging/wfx/scan.c @@ -95,10 +95,6 @@ void wfx_hw_scan_work(struct work_struct *work) mutex_unlock(>wdev->conf_mutex); mutex_unlock(>scan_lock); __ieee80211_scan_completed_compat(wvif->wdev->hw, ret < 0); - if (wvif->delayed_link_loss) { - wvif->delayed_link_loss = false; - wfx_cqm_bssloss_sm(wvif, 1, 0, 0); - } } int wfx_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c index 7ae763e96455..3296bc3521d5 100644 --- a/drivers/staging/wfx/sta.c +++ b/drivers/staging/wfx/sta.c @@ -63,7 +63,6 @@ void wfx_cqm_bssloss_sm(struct wfx_vif *wvif, int init, int good, int bad) int tx = 0; mutex_lock(>bss_loss_lock); - wvif->delayed_link_loss = 0; cancel_work_sync(>bss_params_work); if (init) { @@ -429,18 +428,9 @@ static void wfx_event_handler_work(struct work_struct *work) switch (event->evt.event_id) { case HIF_EVENT_IND_BSSLOST: cancel_work_sync(>unjoin_work); - if (mutex_trylock(>scan_lock)) { - wfx_cqm_bssloss_sm(wvif, 1, 0, 0); - mutex_unlock(>scan_lock); - } else { - /* Scan is in progress. Delay reporting. -* Scan complete will trigger bss_loss_work -*/ - wvif->delayed_link_loss = 1; - /* Also start a watchdog. */ - schedule_delayed_work(>bss_loss_work, - 5 * HZ); - } + mutex_lock(>scan_lock); + wfx_cqm_bssloss_sm(wvif, 1, 0, 0); + mutex_unlock(>scan_lock); break; case HIF_EVENT_IND_BSSREGAINED: wfx_cqm_bssloss_sm(wvif, 0, 0, 0); @@ -497,8 +487,6 @@ static void wfx_do_unjoin(struct wfx_vif *wvif) { mutex_lock(>wdev->conf_mutex); - wvif->delayed_link_loss = false; - if (!wvif->state) goto done; diff --git a/drivers/staging/wfx/wfx.h b/drivers/staging/wfx/wfx.h index 5e7c911db024..db433bee87af 100644 --- a/drivers/staging/wfx/wfx.h +++ b/drivers/staging/wfx/wfx.h @@ -70,7 +70,6 @@ struct wfx_vif { int id; enum wfx_state state; - int delayed_link_loss; int bss_loss_state; u32 bss_loss_confirm_id; struct mutexbss_loss_lock; -- 2.20.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 30/55] staging: wfx: firmware already handle powersave mode during scan
From: Jérôme Pouiller When user try to launch scan while connected, it is necessary to notify the AP that we cannot receive data (using power save mode). Firmware already handles this automatically so the code in the driver is redundant and can be dropped. By edge effect, hack of scan status in wfx_set_pm() is now useless. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/scan.c | 14 -- drivers/staging/wfx/sta.c | 7 +-- 2 files changed, 1 insertion(+), 20 deletions(-) diff --git a/drivers/staging/wfx/scan.c b/drivers/staging/wfx/scan.c index cb7a1fdd0001..4b95e6a97df7 100644 --- a/drivers/staging/wfx/scan.c +++ b/drivers/staging/wfx/scan.c @@ -141,22 +141,11 @@ void wfx_scan_work(struct work_struct *work) .scan_req.scan_type.type = 0,/* Foreground */ }; struct ieee80211_channel *first; - bool first_run = (wvif->scan.begin == wvif->scan.curr && - wvif->scan.begin != wvif->scan.end); int i; down(>scan.lock); mutex_lock(>wdev->conf_mutex); - if (first_run) { - if (wvif->state == WFX_STATE_STA && - !(wvif->powersave_mode.pm_mode.enter_psm)) { - struct hif_req_set_pm_mode pm = wvif->powersave_mode; - - pm.pm_mode.enter_psm = 1; - wfx_set_pm(wvif, ); - } - } if (!wvif->scan.req || wvif->scan.curr == wvif->scan.end) { if (wvif->scan.output_power != wvif->wdev->output_power) @@ -177,9 +166,6 @@ void wfx_scan_work(struct work_struct *work) __ieee80211_scan_completed_compat(wvif->wdev->hw, wvif->scan.status ? 1 : 0); up(>scan.lock); - if (wvif->state == WFX_STATE_STA && - !(wvif->powersave_mode.pm_mode.enter_psm)) - wfx_set_pm(wvif, >powersave_mode); return; } first = *wvif->scan.curr; diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c index 62e65493a4fe..fb45aa66fc56 100644 --- a/drivers/staging/wfx/sta.c +++ b/drivers/staging/wfx/sta.c @@ -375,7 +375,6 @@ int wfx_set_pm(struct wfx_vif *wvif, const struct hif_req_set_pm_mode *arg) { struct hif_req_set_pm_mode pm = *arg; u16 uapsd_flags; - int ret; if (wvif->state != WFX_STATE_STA || !wvif->bss_params.aid) return 0; @@ -396,11 +395,7 @@ int wfx_set_pm(struct wfx_vif *wvif, const struct hif_req_set_pm_mode *arg) msecs_to_jiffies(300))) dev_warn(wvif->wdev->dev, "timeout while waiting of set_pm_mode_complete\n"); - ret = hif_set_pm(wvif, ); - // FIXME: why ? - if (-ETIMEDOUT == wvif->scan.status) - wvif->scan.status = 1; - return ret; + return hif_set_pm(wvif, ); } int wfx_set_rts_threshold(struct ieee80211_hw *hw, u32 value) -- 2.20.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 29/55] staging: wfx: simplify handling of tx_lock in wfx_do_join()
From: Jérôme Pouiller In the old days, wfx_do_join() could be called from different contexts. Now that wfx_do_join() is called only from one place, it is cleaner to keep lock and unlock of data inside the function. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/sta.c | 9 - 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c index 939c64f108ed..62e65493a4fe 100644 --- a/drivers/staging/wfx/sta.c +++ b/drivers/staging/wfx/sta.c @@ -644,7 +644,6 @@ static void wfx_set_mfp(struct wfx_vif *wvif, hif_set_mfp(wvif, mfpc, mfpr); } -/* MUST be called with tx_lock held! It will be unlocked for us. */ static void wfx_do_join(struct wfx_vif *wvif) { const u8 *bssid; @@ -659,6 +658,8 @@ static void wfx_do_join(struct wfx_vif *wvif) conf->basic_rates), }; + wfx_tx_lock_flush(wvif->wdev); + if (wvif->channel->flags & IEEE80211_CHAN_NO_IR) join.probe_for_join = 0; @@ -1180,10 +1181,8 @@ void wfx_bss_info_changed(struct ieee80211_hw *hw, } mutex_unlock(>conf_mutex); - if (do_join) { - wfx_tx_lock_flush(wdev); - wfx_do_join(wvif); /* Will unlock it for us */ - } + if (do_join) + wfx_do_join(wvif); } static void wfx_ps_notify(struct wfx_vif *wvif, enum sta_notify_cmd notify_cmd, -- 2.20.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 28/55] staging: wfx: better naming for hif_mib_set_association_mode->greenfield
From: Jérôme Pouiller Current name "mixed_or_greenfield_type" does not allow to know if "true" means "mixed" of "greenfield". It is possible to use a better name and drop "enum hif_tx_mode". Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/hif_api_mib.h | 8 ++-- drivers/staging/wfx/sta.c | 2 +- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/drivers/staging/wfx/hif_api_mib.h b/drivers/staging/wfx/hif_api_mib.h index 34e4310ad71f..1603b3074bf7 100644 --- a/drivers/staging/wfx/hif_api_mib.h +++ b/drivers/staging/wfx/hif_api_mib.h @@ -395,11 +395,6 @@ struct hif_mib_non_erp_protection { u8 reserved2[3]; } __packed; -enum hif_tx_mode { - HIF_TX_MODE_MIXED= 0x0, - HIF_TX_MODE_GREENFIELD = 0x1 -}; - enum hif_tmplt { HIF_TMPLT_PRBREQ = 0x0, HIF_TMPLT_BCN = 0x1, @@ -474,7 +469,8 @@ struct hif_mib_set_association_mode { u8reserved1:4; u8short_preamble:1; u8reserved2:7; - u8mixed_or_greenfield_type; + u8greenfield:1; + u8reserved3:7; u8mpdu_start_spacing; u32 basic_rate_set; } __packed; diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c index e5c933678c47..939c64f108ed 100644 --- a/drivers/staging/wfx/sta.c +++ b/drivers/staging/wfx/sta.c @@ -996,7 +996,7 @@ static void wfx_join_finalize(struct wfx_vif *wvif, association_mode.spacing = 1; association_mode.short_preamble = info->use_short_preamble; association_mode.basic_rate_set = cpu_to_le32(wfx_rate_mask_to_hw(wvif->wdev, info->basic_rates)); - association_mode.mixed_or_greenfield_type = wfx_ht_greenfield(>ht_info); + association_mode.greenfield = wfx_ht_greenfield(>ht_info); association_mode.mpdu_start_spacing = wfx_ht_ampdu_density(>ht_info); wfx_cqm_bssloss_sm(wvif, 0, 0, 0); -- 2.20.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 32/55] staging: wfx: drop useless argument from wfx_set_pm()
From: Jérôme Pouiller Argument to wfx_set_pm() is always wvif->powersave_mode. So, we can simplify it. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/sta.c | 16 +++- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c index eb087b9c8097..ee1b15950389 100644 --- a/drivers/staging/wfx/sta.c +++ b/drivers/staging/wfx/sta.c @@ -326,12 +326,10 @@ void wfx_configure_filter(struct ieee80211_hw *hw, } } -static int wfx_set_pm(struct wfx_vif *wvif, - const struct hif_req_set_pm_mode *arg) +static int wfx_update_pm(struct wfx_vif *wvif) { - struct hif_req_set_pm_mode pm = *arg; + struct hif_req_set_pm_mode pm = wvif->powersave_mode; u16 uapsd_flags; - int ret; if (wvif->state != WFX_STATE_STA || !wvif->bss_params.aid) return 0; @@ -390,7 +388,7 @@ int wfx_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, if (!ret && wvif->setbssparams_done && wvif->state == WFX_STATE_STA && old_uapsd_flags != new_uapsd_flags) - ret = wfx_set_pm(wvif, >powersave_mode); + ret = wfx_update_pm(wvif); } } else { ret = -EINVAL; @@ -1014,7 +1012,7 @@ static void wfx_join_finalize(struct wfx_vif *wvif, hif_set_bss_params(wvif, >bss_params); wvif->setbssparams_done = true; wfx_set_beacon_wakeup_period_work(>set_beacon_wakeup_period_work); - wfx_set_pm(wvif, >powersave_mode); + wfx_update_pm(wvif); } } @@ -1451,7 +1449,7 @@ int wfx_config(struct ieee80211_hw *hw, u32 changed) } } if (wvif->state == WFX_STATE_STA && wvif->bss_params.aid) - wfx_set_pm(wvif, >powersave_mode); + wfx_update_pm(wvif); } wvif = wdev_to_wvif(wdev, 0); } @@ -1591,7 +1589,7 @@ int wfx_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) else hif_set_block_ack_policy(wvif, 0x00, 0x00); // Combo force powersave mode. We can re-enable it now - wfx_set_pm(wvif, >powersave_mode); + wfx_update_pm(wvif); } return 0; } @@ -1666,7 +1664,7 @@ void wfx_remove_interface(struct ieee80211_hw *hw, else hif_set_block_ack_policy(wvif, 0x00, 0x00); // Combo force powersave mode. We can re-enable it now - wfx_set_pm(wvif, >powersave_mode); + wfx_update_pm(wvif); } } -- 2.20.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 11/55] staging: wfx: increase SPI bus frequency limit
From: Jérôme Pouiller The chip has now proven that it can run at 50MHz on any boards without any problem. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/bus_spi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/wfx/bus_spi.c b/drivers/staging/wfx/bus_spi.c index ab0cda1e124f..44fc42bb43a0 100644 --- a/drivers/staging/wfx/bus_spi.c +++ b/drivers/staging/wfx/bus_spi.c @@ -183,7 +183,7 @@ static int wfx_spi_probe(struct spi_device *func) if (func->bits_per_word != 16 && func->bits_per_word != 8) dev_warn(>dev, "unusual bits/word value: %d\n", func->bits_per_word); - if (func->max_speed_hz > 4900) + if (func->max_speed_hz > 5000) dev_warn(>dev, "%dHz is a very high speed\n", func->max_speed_hz); -- 2.20.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 34/55] staging: wfx: drop unnecessary wvif->powersave_mode
From: Jérôme Pouiller Power save status is already available in bss_conf. So there is no reason to keep information duplicated in wvif->powersave_mode. In add, type of wvif->powersave_mode is low level struct made to communicate with device. We would like to limit usage of this kind of struct in upper layers of the driver. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/sta.c | 31 +-- drivers/staging/wfx/wfx.h | 1 - 2 files changed, 13 insertions(+), 19 deletions(-) diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c index 91fa4d8aa37d..c57135f77572 100644 --- a/drivers/staging/wfx/sta.c +++ b/drivers/staging/wfx/sta.c @@ -328,12 +328,23 @@ void wfx_configure_filter(struct ieee80211_hw *hw, static int wfx_update_pm(struct wfx_vif *wvif) { - struct hif_req_set_pm_mode pm = wvif->powersave_mode; + struct ieee80211_conf *conf = >wdev->hw->conf; + struct hif_req_set_pm_mode pm; u16 uapsd_flags; if (wvif->state != WFX_STATE_STA || !wvif->bss_params.aid) return 0; + memset(, 0, sizeof(pm)); + if (conf->flags & IEEE80211_CONF_PS) { + pm.pm_mode.enter_psm = 1; + // Firmware does not support more than 128ms + pm.fast_psm_idle_period = + min(conf->dynamic_ps_timeout * 2, 255); + if (pm.fast_psm_idle_period) + pm.pm_mode.fast_psm = 1; + } + memcpy(_flags, >uapsd_info, sizeof(uapsd_flags)); if (uapsd_flags != 0) @@ -1432,24 +1443,8 @@ int wfx_config(struct ieee80211_hw *hw, u32 changed) if (changed & IEEE80211_CONF_CHANGE_PS) { wvif = NULL; - while ((wvif = wvif_iterate(wdev, wvif)) != NULL) { - memset(>powersave_mode, 0, - sizeof(wvif->powersave_mode)); - if (conf->flags & IEEE80211_CONF_PS) { - wvif->powersave_mode.pm_mode.enter_psm = 1; - if (conf->dynamic_ps_timeout > 0) { - wvif->powersave_mode.pm_mode.fast_psm = 1; - /* -* Firmware does not support more than -* 128ms -*/ - wvif->powersave_mode.fast_psm_idle_period = - min(conf->dynamic_ps_timeout * - 2, 255); - } - } + while ((wvif = wvif_iterate(wdev, wvif)) != NULL) wfx_update_pm(wvif); - } wvif = wdev_to_wvif(wdev, 0); } diff --git a/drivers/staging/wfx/wfx.h b/drivers/staging/wfx/wfx.h index 781a8c8ba982..c82d29764d66 100644 --- a/drivers/staging/wfx/wfx.h +++ b/drivers/staging/wfx/wfx.h @@ -125,7 +125,6 @@ struct wfx_vif { struct wfx_scan scan; - struct hif_req_set_pm_mode powersave_mode; struct completion set_pm_mode_complete; struct list_headevent_queue; -- 2.20.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 52/55] staging: wfx: delayed_unjoin cannot happen
From: Jérôme Pouiller Original code allows to detect an unjoin request during a scan and delaying the unjoin request. However, it is far easier to just block the unjoin request until the end of the scan request. In fact, it is already the case since scan and unjoin are protected by conf_mutex. So, currently, the handling of delayed_unjoin is just dead code. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/scan.c | 7 +-- drivers/staging/wfx/sta.c | 14 -- drivers/staging/wfx/wfx.h | 1 - 3 files changed, 1 insertion(+), 21 deletions(-) diff --git a/drivers/staging/wfx/scan.c b/drivers/staging/wfx/scan.c index 540009b72240..bdbce6926e91 100644 --- a/drivers/staging/wfx/scan.c +++ b/drivers/staging/wfx/scan.c @@ -95,12 +95,7 @@ void wfx_hw_scan_work(struct work_struct *work) mutex_unlock(>wdev->conf_mutex); mutex_unlock(>scan_lock); __ieee80211_scan_completed_compat(wvif->wdev->hw, ret < 0); - if (wvif->delayed_unjoin) { - wvif->delayed_unjoin = false; - wfx_tx_lock(wvif->wdev); - if (!schedule_work(>unjoin_work)) - wfx_tx_unlock(wvif->wdev); - } else if (wvif->delayed_link_loss) { + if (wvif->delayed_link_loss) { wvif->delayed_link_loss = false; wfx_cqm_bssloss_sm(wvif, 1, 0, 0); } diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c index 4354bb8081c5..7ae763e96455 100644 --- a/drivers/staging/wfx/sta.c +++ b/drivers/staging/wfx/sta.c @@ -66,10 +66,6 @@ void wfx_cqm_bssloss_sm(struct wfx_vif *wvif, int init, int good, int bad) wvif->delayed_link_loss = 0; cancel_work_sync(>bss_params_work); - /* If we have a pending unjoin */ - if (wvif->delayed_unjoin) - goto end; - if (init) { schedule_delayed_work(>bss_loss_work, HZ); wvif->bss_loss_state = 0; @@ -501,16 +497,6 @@ static void wfx_do_unjoin(struct wfx_vif *wvif) { mutex_lock(>wdev->conf_mutex); - if (!mutex_trylock(>scan_lock)) { - if (wvif->delayed_unjoin) - dev_dbg(wvif->wdev->dev, - "delayed unjoin is already scheduled\n"); - else - wvif->delayed_unjoin = true; - goto done; - } - mutex_unlock(>scan_lock); - wvif->delayed_link_loss = false; if (!wvif->state) diff --git a/drivers/staging/wfx/wfx.h b/drivers/staging/wfx/wfx.h index b5f763c3fac7..5e7c911db024 100644 --- a/drivers/staging/wfx/wfx.h +++ b/drivers/staging/wfx/wfx.h @@ -122,7 +122,6 @@ struct wfx_vif { struct work_struct set_cts_work; int join_complete_status; - booldelayed_unjoin; struct work_struct unjoin_work; /* avoid some operations in parallel with scan */ -- 2.20.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 35/55] staging: wfx: do not try to save call to hif_set_pm()
From: Jérôme Pouiller Current code try to not exchange data with device if it is not necessary. However, it seems that the additional code does not provide any gain. So, we prefer to keep a simpler code. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/sta.c | 7 +-- 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c index c57135f77572..dcb4693ec980 100644 --- a/drivers/staging/wfx/sta.c +++ b/drivers/staging/wfx/sta.c @@ -371,14 +371,11 @@ int wfx_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct wfx_dev *wdev = hw->priv; struct wfx_vif *wvif = (struct wfx_vif *) vif->drv_priv; int ret = 0; - /* To prevent re-applying PM request OID again and again*/ - u16 old_uapsd_flags, new_uapsd_flags; struct hif_req_edca_queue_params *edca; mutex_lock(>conf_mutex); if (queue < hw->queues) { - old_uapsd_flags = *((u16 *) >uapsd_info); edca = >edca.params[queue]; wvif->edca.uapsd_enable[queue] = params->uapsd; @@ -395,10 +392,8 @@ int wfx_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, if (wvif->vif->type == NL80211_IFTYPE_STATION) { ret = wfx_set_uapsd_param(wvif, >edca); - new_uapsd_flags = *((u16 *) >uapsd_info); if (!ret && wvif->setbssparams_done && - wvif->state == WFX_STATE_STA && - old_uapsd_flags != new_uapsd_flags) + wvif->state == WFX_STATE_STA) ret = wfx_update_pm(wvif); } } else { -- 2.20.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 54/55] staging: wfx: implement cancel_hw_scan()
From: Jérôme Pouiller The device provides an API to abort a scan request. Expose this feature to mac80211. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/main.c | 1 + drivers/staging/wfx/scan.c | 13 + drivers/staging/wfx/scan.h | 1 + drivers/staging/wfx/wfx.h | 1 + 4 files changed, 16 insertions(+) diff --git a/drivers/staging/wfx/main.c b/drivers/staging/wfx/main.c index cf4bcb14a12d..45c9939b7e62 100644 --- a/drivers/staging/wfx/main.c +++ b/drivers/staging/wfx/main.c @@ -135,6 +135,7 @@ static const struct ieee80211_ops wfx_ops = { .tx = wfx_tx, .conf_tx= wfx_conf_tx, .hw_scan= wfx_hw_scan, + .cancel_hw_scan = wfx_cancel_hw_scan, .sta_add= wfx_sta_add, .sta_remove = wfx_sta_remove, .sta_notify = wfx_sta_notify, diff --git a/drivers/staging/wfx/scan.c b/drivers/staging/wfx/scan.c index dde2f8868147..24061d09c404 100644 --- a/drivers/staging/wfx/scan.c +++ b/drivers/staging/wfx/scan.c @@ -54,6 +54,7 @@ static int send_scan_req(struct wfx_vif *wvif, break; } wfx_tx_lock_flush(wvif->wdev); + wvif->scan_abort = false; reinit_completion(>scan_complete); ret = hif_scan(wvif, req, start_idx, i - start_idx); if (ret < 0) @@ -68,6 +69,10 @@ static int send_scan_req(struct wfx_vif *wvif, hif_stop_scan(wvif); return -ETIMEDOUT; } + if (wvif->scan_abort) { + dev_notice(wvif->wdev->dev, "scan abort\n"); + return -ECONNABORTED; + } return i - start_idx; } @@ -115,6 +120,14 @@ int wfx_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, return 0; } +void wfx_cancel_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif) +{ + struct wfx_vif *wvif = (struct wfx_vif *)vif->drv_priv; + + wvif->scan_abort = true; + hif_stop_scan(wvif); +} + void wfx_scan_complete(struct wfx_vif *wvif, const struct hif_ind_scan_cmpl *arg) { diff --git a/drivers/staging/wfx/scan.h b/drivers/staging/wfx/scan.h index b547f1927d72..bba9f15a9ff5 100644 --- a/drivers/staging/wfx/scan.h +++ b/drivers/staging/wfx/scan.h @@ -18,6 +18,7 @@ struct wfx_vif; void wfx_hw_scan_work(struct work_struct *work); int wfx_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_scan_request *req); +void wfx_cancel_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif); void wfx_scan_complete(struct wfx_vif *wvif, const struct hif_ind_scan_cmpl *ind); diff --git a/drivers/staging/wfx/wfx.h b/drivers/staging/wfx/wfx.h index db433bee87af..0a3df382af03 100644 --- a/drivers/staging/wfx/wfx.h +++ b/drivers/staging/wfx/wfx.h @@ -127,6 +127,7 @@ struct wfx_vif { struct mutexscan_lock; struct work_struct scan_work; struct completion scan_complete; + boolscan_abort; struct ieee80211_scan_request *scan_req; struct completion set_pm_mode_complete; -- 2.20.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 51/55] staging: wfx: workaround bug with "iw scan"
From: Jérôme Pouiller mac80211 specification does not forbid hw_scan() to call ieee80211_scan_completed(). However, from userspace point of view, not all applications support this behavior. In particular, the code of iw contains a big fat warning: /* * This code has a bug, which requires creating a separate * nl80211 socket to fix: * It is possible for a NL80211_CMD_NEW_SCAN_RESULTS or * NL80211_CMD_SCAN_ABORTED message to be sent by the kernel * before (!) we listen to it, because we only start listening * after we send our scan request. [...] * Alas, the kernel doesn't do that (yet). */ So, we have to avoid to call ieee80211_scan_completed() from hw_scan() (it's a kind of unwritten rule). This patch relocates the hw_scan() process to a work_struct to fix the problem. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/scan.c | 47 -- drivers/staging/wfx/scan.h | 1 + drivers/staging/wfx/sta.c | 1 + drivers/staging/wfx/wfx.h | 2 ++ 4 files changed, 34 insertions(+), 17 deletions(-) diff --git a/drivers/staging/wfx/scan.c b/drivers/staging/wfx/scan.c index b73e61e8da46..540009b72240 100644 --- a/drivers/staging/wfx/scan.c +++ b/drivers/staging/wfx/scan.c @@ -71,23 +71,19 @@ static int send_scan_req(struct wfx_vif *wvif, return i - start_idx; } -int wfx_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - struct ieee80211_scan_request *hw_req) +/* + * 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 + */ +void wfx_hw_scan_work(struct work_struct *work) { - struct wfx_dev *wdev = hw->priv; - struct wfx_vif *wvif = (struct wfx_vif *) vif->drv_priv; + 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; - WARN_ON(hw_req->req.n_channels > HIF_API_MAX_NB_CHANNELS); - - if (vif->type == NL80211_IFTYPE_AP) - return -EOPNOTSUPP; - - if (wvif->state == WFX_STATE_PRE_STA) - return -EBUSY; - mutex_lock(>scan_lock); - mutex_lock(>conf_mutex); + mutex_lock(>wdev->conf_mutex); update_probe_tmpl(wvif, _req->req); wfx_fwd_probe_req(wvif, true); chan_cur = 0; @@ -96,18 +92,35 @@ int wfx_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, if (ret > 0) chan_cur += ret; } while (ret > 0 && chan_cur < hw_req->req.n_channels); - __ieee80211_scan_completed_compat(hw, ret < 0); - mutex_unlock(>conf_mutex); + mutex_unlock(>wdev->conf_mutex); mutex_unlock(>scan_lock); + __ieee80211_scan_completed_compat(wvif->wdev->hw, ret < 0); if (wvif->delayed_unjoin) { wvif->delayed_unjoin = false; - wfx_tx_lock(wdev); + wfx_tx_lock(wvif->wdev); if (!schedule_work(>unjoin_work)) - wfx_tx_unlock(wdev); + wfx_tx_unlock(wvif->wdev); } else if (wvif->delayed_link_loss) { wvif->delayed_link_loss = false; wfx_cqm_bssloss_sm(wvif, 1, 0, 0); } +} + +int wfx_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_scan_request *hw_req) +{ + struct wfx_vif *wvif = (struct wfx_vif *)vif->drv_priv; + + WARN_ON(hw_req->req.n_channels > HIF_API_MAX_NB_CHANNELS); + + if (vif->type == NL80211_IFTYPE_AP) + return -EOPNOTSUPP; + + if (wvif->state == WFX_STATE_PRE_STA) + return -EBUSY; + + wvif->scan_req = hw_req; + schedule_work(>scan_work); return 0; } diff --git a/drivers/staging/wfx/scan.h b/drivers/staging/wfx/scan.h index 03bc6c7e562d..b547f1927d72 100644 --- a/drivers/staging/wfx/scan.h +++ b/drivers/staging/wfx/scan.h @@ -15,6 +15,7 @@ struct wfx_dev; struct wfx_vif; +void wfx_hw_scan_work(struct work_struct *work); int wfx_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_scan_request *req); void wfx_scan_complete(struct wfx_vif *wvif, diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c index 16f5db873275..4354bb8081c5 100644 --- a/drivers/staging/wfx/sta.c +++ b/drivers/staging/wfx/sta.c @@ -1427,6 +1427,7 @@ int wfx_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) mutex_init(>scan_lock); init_completion(>scan_complete); + INIT_WORK(>scan_work, wfx_hw_scan_work); mutex_unlock(>conf_mutex); diff --git a/drivers/staging/wfx/wfx.h b/drivers/staging/wfx/wfx.h index 3356d0cbf7af..
[PATCH 09/55] staging: wfx: fix hif_set_mfp() with big endian hosts
From: Jérôme Pouiller struct hif_mib_protected_mgmt_policy is an array of u8. There is no reason to swap its bytes. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/hif_tx_mib.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/wfx/hif_tx_mib.h b/drivers/staging/wfx/hif_tx_mib.h index bb091e395ff5..9be74881c56c 100644 --- a/drivers/staging/wfx/hif_tx_mib.h +++ b/drivers/staging/wfx/hif_tx_mib.h @@ -147,7 +147,6 @@ static inline int hif_set_mfp(struct wfx_vif *wvif, bool capable, bool required) } if (!required) val.unpmf_allowed = 1; - cpu_to_le32s((u32 *) ); return hif_write_mib(wvif->wdev, wvif->id, HIF_MIB_ID_PROTECTED_MGMT_POLICY, , sizeof(val)); -- 2.20.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 04/55] staging: wfx: use boolean appropriately
From: Jérôme Pouiller The field 'uploaded' is used as a boolean, so call it a boolean. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/data_tx.c | 4 ++-- drivers/staging/wfx/data_tx.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/wfx/data_tx.c b/drivers/staging/wfx/data_tx.c index df3aca03b50b..b726dd5e59f3 100644 --- a/drivers/staging/wfx/data_tx.c +++ b/drivers/staging/wfx/data_tx.c @@ -184,7 +184,7 @@ static int wfx_tx_policy_get(struct wfx_vif *wvif, */ entry = list_entry(cache->free.prev, struct tx_policy, link); memcpy(entry->rates, wanted.rates, sizeof(entry->rates)); - entry->uploaded = 0; + entry->uploaded = false; entry->usage_count = 0; idx = entry - cache->cache; } @@ -241,7 +241,7 @@ static int wfx_tx_policy_upload(struct wfx_vif *wvif) dst->terminate = 1; dst->count_init = 1; memcpy(>rates, src->rates, sizeof(src->rates)); - src->uploaded = 1; + src->uploaded = true; arg->num_tx_rate_policies++; } } diff --git a/drivers/staging/wfx/data_tx.h b/drivers/staging/wfx/data_tx.h index f63e5d8cf929..0fc388db62e0 100644 --- a/drivers/staging/wfx/data_tx.h +++ b/drivers/staging/wfx/data_tx.h @@ -41,7 +41,7 @@ struct tx_policy { struct list_head link; int usage_count; u8 rates[12]; - u8 uploaded; + bool uploaded; }; struct tx_policy_cache { -- 2.20.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 22/55] staging: wfx: ensure that received hif messages are never modified
From: Jérôme Pouiller There are no real reason to modify the data received from device. So, let's mark the arguments constant. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/data_rx.c | 8 ++- drivers/staging/wfx/data_rx.h | 4 +- drivers/staging/wfx/data_tx.c | 2 +- drivers/staging/wfx/data_tx.h | 2 +- drivers/staging/wfx/hif_rx.c | 94 +-- drivers/staging/wfx/scan.c| 3 +- drivers/staging/wfx/scan.h| 3 +- drivers/staging/wfx/secure_link.h | 8 ++- drivers/staging/wfx/sta.c | 2 +- drivers/staging/wfx/sta.h | 2 +- 10 files changed, 72 insertions(+), 56 deletions(-) diff --git a/drivers/staging/wfx/data_rx.c b/drivers/staging/wfx/data_rx.c index e7fcce8d0cc4..d460c0ffca1f 100644 --- a/drivers/staging/wfx/data_rx.c +++ b/drivers/staging/wfx/data_rx.c @@ -48,7 +48,9 @@ static int wfx_handle_pspoll(struct wfx_vif *wvif, struct sk_buff *skb) return 0; } -static int wfx_drop_encrypt_data(struct wfx_dev *wdev, struct hif_ind_rx *arg, struct sk_buff *skb) +static int wfx_drop_encrypt_data(struct wfx_dev *wdev, +const struct hif_ind_rx *arg, +struct sk_buff *skb) { struct ieee80211_hdr *frame = (struct ieee80211_hdr *) skb->data; size_t hdrlen = ieee80211_hdrlen(frame->frame_control); @@ -98,8 +100,8 @@ static int wfx_drop_encrypt_data(struct wfx_dev *wdev, struct hif_ind_rx *arg, s } -void wfx_rx_cb(struct wfx_vif *wvif, struct hif_ind_rx *arg, - struct sk_buff *skb) +void wfx_rx_cb(struct wfx_vif *wvif, + const struct hif_ind_rx *arg, struct sk_buff *skb) { int link_id = arg->rx_flags.peer_sta_id; struct ieee80211_rx_status *hdr = IEEE80211_SKB_RXCB(skb); diff --git a/drivers/staging/wfx/data_rx.h b/drivers/staging/wfx/data_rx.h index a50ce352bc5e..61c28bfd2a37 100644 --- a/drivers/staging/wfx/data_rx.h +++ b/drivers/staging/wfx/data_rx.h @@ -13,7 +13,7 @@ struct wfx_vif; struct sk_buff; -void wfx_rx_cb(struct wfx_vif *wvif, struct hif_ind_rx *arg, - struct sk_buff *skb); +void wfx_rx_cb(struct wfx_vif *wvif, + const struct hif_ind_rx *arg, struct sk_buff *skb); #endif /* WFX_DATA_RX_H */ diff --git a/drivers/staging/wfx/data_tx.c b/drivers/staging/wfx/data_tx.c index c9dea627661f..a45243a7f15f 100644 --- a/drivers/staging/wfx/data_tx.c +++ b/drivers/staging/wfx/data_tx.c @@ -720,7 +720,7 @@ void wfx_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, ieee80211_tx_status_irqsafe(wdev->hw, skb); } -void wfx_tx_confirm_cb(struct wfx_vif *wvif, struct hif_cnf_tx *arg) +void wfx_tx_confirm_cb(struct wfx_vif *wvif, const struct hif_cnf_tx *arg) { int i; int tx_count; diff --git a/drivers/staging/wfx/data_tx.h b/drivers/staging/wfx/data_tx.h index 0fc388db62e0..078d0cfc521a 100644 --- a/drivers/staging/wfx/data_tx.h +++ b/drivers/staging/wfx/data_tx.h @@ -65,7 +65,7 @@ void wfx_tx_policy_upload_work(struct work_struct *work); void wfx_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, struct sk_buff *skb); -void wfx_tx_confirm_cb(struct wfx_vif *wvif, struct hif_cnf_tx *arg); +void wfx_tx_confirm_cb(struct wfx_vif *wvif, const struct hif_cnf_tx *arg); void wfx_skb_dtor(struct wfx_dev *wdev, struct sk_buff *skb); int wfx_unmap_link(struct wfx_vif *wvif, int link_id); diff --git a/drivers/staging/wfx/hif_rx.c b/drivers/staging/wfx/hif_rx.c index 1494ad5a507b..8a3ccdc60b7d 100644 --- a/drivers/staging/wfx/hif_rx.c +++ b/drivers/staging/wfx/hif_rx.c @@ -18,8 +18,8 @@ #include "secure_link.h" #include "hif_api_cmd.h" -static int hif_generic_confirm(struct wfx_dev *wdev, struct hif_msg *hif, - void *buf) +static int hif_generic_confirm(struct wfx_dev *wdev, + const struct hif_msg *hif, const void *buf) { // All confirm messages start with status int status = le32_to_cpu(*((__le32 *) buf)); @@ -59,9 +59,10 @@ static int hif_generic_confirm(struct wfx_dev *wdev, struct hif_msg *hif, return status; } -static int hif_tx_confirm(struct wfx_dev *wdev, struct hif_msg *hif, void *buf) +static int hif_tx_confirm(struct wfx_dev *wdev, + const struct hif_msg *hif, const void *buf) { - struct hif_cnf_tx *body = buf; + const struct hif_cnf_tx *body = buf; struct wfx_vif *wvif = wdev_to_wvif(wdev, hif->interface); WARN_ON(!wvif); @@ -72,11 +73,12 @@ static int hif_tx_confirm(struct wfx_dev *wdev, struct hif_msg *hif, void *buf) return 0; } -static int hif_multi_tx_confirm(struct wfx_dev *wdev, struct hif_msg *hif, - void *buf) +static int hif_multi_tx_confirm(struct wfx_dev *wdev, + const struct hif_msg *hif, const void *buf) { -
[PATCH 26/55] staging: wfx: improve API of hif_req_join->infrastructure_bss_mode
From: Jérôme Pouiller In fact "mode" is a boolean that indicates if IBSS mode is used. This patch fixes the name and uses a more adapted memory representation. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/hif_api_cmd.h | 8 ++-- drivers/staging/wfx/sta.c | 2 +- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/drivers/staging/wfx/hif_api_cmd.h b/drivers/staging/wfx/hif_api_cmd.h index 4ce3bb51cf04..e848bd3073a2 100644 --- a/drivers/staging/wfx/hif_api_cmd.h +++ b/drivers/staging/wfx/hif_api_cmd.h @@ -377,11 +377,6 @@ struct hif_cnf_edca_queue_params { u32 status; } __packed; -enum hif_ap_mode { - HIF_MODE_IBSS = 0x0, - HIF_MODE_BSS = 0x1 -}; - enum hif_preamble { HIF_PREAMBLE_LONG = 0x0, HIF_PREAMBLE_SHORT = 0x1, @@ -396,7 +391,8 @@ struct hif_join_flags { } __packed; struct hif_req_join { - u8mode; + u8infrastructure_bss_mode:1; + u8reserved1:7; u8band; u16 channel_number; u8bssid[ETH_ALEN]; diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c index b4bb5b653e64..23ec7a4a926b 100644 --- a/drivers/staging/wfx/sta.c +++ b/drivers/staging/wfx/sta.c @@ -651,7 +651,7 @@ static void wfx_do_join(struct wfx_vif *wvif) struct ieee80211_bss_conf *conf = >vif->bss_conf; struct cfg80211_bss *bss = NULL; struct hif_req_join join = { - .mode = conf->ibss_joined ? HIF_MODE_IBSS : HIF_MODE_BSS, + .infrastructure_bss_mode = !conf->ibss_joined, .preamble_type = conf->use_short_preamble ? HIF_PREAMBLE_SHORT : HIF_PREAMBLE_LONG, .probe_for_join = 1, .atim_window = 0, -- 2.20.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 24/55] staging: wfx: fix typo in "num_i_es"
From: Jérôme Pouiller The script that has imported API header has made a mistake "num_i_es". Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/hif_api_cmd.h | 2 +- drivers/staging/wfx/hif_tx.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/wfx/hif_api_cmd.h b/drivers/staging/wfx/hif_api_cmd.h index 90ba6e9b82ea..3e77fbe3d5ff 100644 --- a/drivers/staging/wfx/hif_api_cmd.h +++ b/drivers/staging/wfx/hif_api_cmd.h @@ -137,7 +137,7 @@ struct hif_ie_tlv { struct hif_req_update_ie { struct hif_ie_flags ie_flags; - u16 num_i_es; + u16 num_ies; struct hif_ie_tlv ie[]; } __packed; diff --git a/drivers/staging/wfx/hif_tx.c b/drivers/staging/wfx/hif_tx.c index 2f74abca2b60..6fb98ddbc0e2 100644 --- a/drivers/staging/wfx/hif_tx.c +++ b/drivers/staging/wfx/hif_tx.c @@ -429,7 +429,7 @@ int hif_update_ie(struct wfx_vif *wvif, const struct hif_ie_flags *target_frame, struct hif_req_update_ie *body = wfx_alloc_hif(buf_len, ); memcpy(>ie_flags, target_frame, sizeof(struct hif_ie_flags)); - body->num_i_es = cpu_to_le16(1); + body->num_ies = cpu_to_le16(1); memcpy(body->ie, ies, ies_len); wfx_fill_header(hif, wvif->id, HIF_REQ_ID_UPDATE_IE, buf_len); ret = wfx_cmd_send(wvif->wdev, hif, NULL, 0, false); -- 2.20.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 12/55] staging: wfx: don't print useless error messages
From: Jérôme Pouiller During chip probing, if error does not come from secure boot (for exemple when firmware has been found), others errors probably appears. It is not necessary to say to user that the error does not come from secure boot. So, drop the message saying "no error reported by secure boot". BTW, we take the opportunity to simplify print_boot_status(). Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/fwio.c | 26 ++ 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/drivers/staging/wfx/fwio.c b/drivers/staging/wfx/fwio.c index dbf8bda71ff7..47e627bf0f8e 100644 --- a/drivers/staging/wfx/fwio.c +++ b/drivers/staging/wfx/fwio.c @@ -61,7 +61,7 @@ #define DCA_TIMEOUT 50 // milliseconds #define WAKEUP_TIMEOUT 200 // milliseconds -static const char * const fwio_error_strings[] = { +static const char * const fwio_errors[] = { [ERR_INVALID_SEC_TYPE] = "Invalid section type or wrong encryption", [ERR_SIG_VERIF_FAILED] = "Signature verification failed", [ERR_AES_CTRL_KEY] = "AES control key not initialized", @@ -220,22 +220,16 @@ static int upload_firmware(struct wfx_dev *wdev, const u8 *data, size_t len) static void print_boot_status(struct wfx_dev *wdev) { - u32 val32; + u32 reg; - sram_reg_read(wdev, WFX_STATUS_INFO, ); - if (val32 == 0x12345678) { - dev_info(wdev->dev, "no error reported by secure boot\n"); - } else { - sram_reg_read(wdev, WFX_ERR_INFO, ); - if (val32 < ARRAY_SIZE(fwio_error_strings) && - fwio_error_strings[val32]) - dev_info(wdev->dev, "secure boot error: %s\n", -fwio_error_strings[val32]); - else - dev_info(wdev->dev, -"secure boot error: Unknown (0x%02x)\n", -val32); - } + sram_reg_read(wdev, WFX_STATUS_INFO, ); + if (reg == 0x12345678) + return; + sram_reg_read(wdev, WFX_ERR_INFO, ); + if (reg < ARRAY_SIZE(fwio_errors) && fwio_errors[reg]) + dev_info(wdev->dev, "secure boot: %s\n", fwio_errors[reg]); + else + dev_info(wdev->dev, "secure boot: Error %#02x\n", reg); } static int load_firmware_secure(struct wfx_dev *wdev) -- 2.20.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 20/55] staging: wfx: make conditions easier to read
From: Jérôme Pouiller We prefer series of simple boolean conditions than computing bitmasks. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/sta.c | 27 +++ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c index 471dd15b227f..7f4eaa8e6d84 100644 --- a/drivers/staging/wfx/sta.c +++ b/drivers/staging/wfx/sta.c @@ -1055,9 +1055,11 @@ void wfx_bss_info_changed(struct ieee80211_hw *hw, } } - if (changed & - (BSS_CHANGED_BEACON | BSS_CHANGED_AP_PROBE_RESP | -BSS_CHANGED_BSSID | BSS_CHANGED_SSID | BSS_CHANGED_IBSS)) { + if (changed & BSS_CHANGED_BEACON || + changed & BSS_CHANGED_AP_PROBE_RESP || + changed & BSS_CHANGED_BSSID || + changed & BSS_CHANGED_SSID || + changed & BSS_CHANGED_IBSS) { wvif->beacon_int = info->beacon_int; wfx_update_beaconing(wvif); wfx_upload_beacon(wvif); @@ -1095,10 +1097,11 @@ void wfx_bss_info_changed(struct ieee80211_hw *hw, if (changed & BSS_CHANGED_BSSID) do_join = true; - if (changed & - (BSS_CHANGED_ASSOC | BSS_CHANGED_BSSID | -BSS_CHANGED_IBSS | BSS_CHANGED_BASIC_RATES | -BSS_CHANGED_HT)) { + if (changed & BSS_CHANGED_ASSOC || + changed & BSS_CHANGED_BSSID || + changed & BSS_CHANGED_IBSS || + changed & BSS_CHANGED_BASIC_RATES || + changed & BSS_CHANGED_HT) { if (info->assoc) { if (wvif->state < WFX_STATE_PRE_STA) { ieee80211_connection_loss(vif); @@ -1120,9 +1123,9 @@ void wfx_bss_info_changed(struct ieee80211_hw *hw, } /* ERP Protection */ - if (changed & (BSS_CHANGED_ASSOC | - BSS_CHANGED_ERP_CTS_PROT | - BSS_CHANGED_ERP_PREAMBLE)) { + if (changed & BSS_CHANGED_ASSOC || + changed & BSS_CHANGED_ERP_CTS_PROT || + changed & BSS_CHANGED_ERP_PREAMBLE) { u32 prev_erp_info = wvif->erp_info; if (info->use_cts_prot) @@ -1139,10 +1142,10 @@ void wfx_bss_info_changed(struct ieee80211_hw *hw, schedule_work(>set_cts_work); } - if (changed & (BSS_CHANGED_ASSOC | BSS_CHANGED_ERP_SLOT)) + if (changed & BSS_CHANGED_ASSOC || changed & BSS_CHANGED_ERP_SLOT) hif_slot_time(wvif, info->use_short_slot ? 9 : 20); - if (changed & (BSS_CHANGED_ASSOC | BSS_CHANGED_CQM)) { + if (changed & BSS_CHANGED_ASSOC || changed & BSS_CHANGED_CQM) { struct hif_mib_rcpi_rssi_threshold th = { .rolling_average_count = 8, .detection = 1, -- 2.20.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 18/55] staging: wfx: remove useless include
From: Jérôme Pouiller hif_tx.c does not use any struct skb. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/hif_tx.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/wfx/hif_tx.c b/drivers/staging/wfx/hif_tx.c index cb7cddcb9815..e8c2bd1efbac 100644 --- a/drivers/staging/wfx/hif_tx.c +++ b/drivers/staging/wfx/hif_tx.c @@ -6,7 +6,6 @@ * Copyright (c) 2017-2019, Silicon Laboratories, Inc. * Copyright (c) 2010, ST-Ericsson */ -#include #include #include "hif_tx.h" -- 2.20.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 23/55] staging: wfx: fix typo in "num_of_ssi_ds"
From: Jérôme Pouiller The script that has imported API headers has made a mistake in "num_of_ssi_ds". Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/hif_api_cmd.h | 4 ++-- drivers/staging/wfx/hif_tx.c | 10 +- drivers/staging/wfx/scan.c| 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/staging/wfx/hif_api_cmd.h b/drivers/staging/wfx/hif_api_cmd.h index c15831de4ff4..90ba6e9b82ea 100644 --- a/drivers/staging/wfx/hif_api_cmd.h +++ b/drivers/staging/wfx/hif_api_cmd.h @@ -180,7 +180,7 @@ struct hif_req_start_scan { struct hif_auto_scan_param auto_scan_param; u8num_of_probe_requests; u8probe_delay; - u8num_of_ssi_ds; + u8num_of_ssids; u8num_of_channels; u32 min_channel_time; u32 max_channel_time; @@ -196,7 +196,7 @@ struct hif_start_scan_req_cstnbssid_body { struct hif_auto_scan_param auto_scan_param; u8num_of_probe_requests; u8probe_delay; - u8num_of_ssi_ds; + u8num_of_ssids; u8num_of_channels; u32 min_channel_time; u32 max_channel_time; diff --git a/drivers/staging/wfx/hif_tx.c b/drivers/staging/wfx/hif_tx.c index e8c2bd1efbac..2f74abca2b60 100644 --- a/drivers/staging/wfx/hif_tx.c +++ b/drivers/staging/wfx/hif_tx.c @@ -227,12 +227,12 @@ int hif_scan(struct wfx_vif *wvif, const struct wfx_scan_params *arg) struct hif_ssid_def *ssids; size_t buf_len = sizeof(struct hif_req_start_scan) + arg->scan_req.num_of_channels * sizeof(u8) + - arg->scan_req.num_of_ssi_ds * sizeof(struct hif_ssid_def); + arg->scan_req.num_of_ssids * sizeof(struct hif_ssid_def); struct hif_req_start_scan *body = wfx_alloc_hif(buf_len, ); u8 *ptr = (u8 *) body + sizeof(*body); WARN(arg->scan_req.num_of_channels > HIF_API_MAX_NB_CHANNELS, "invalid params"); - WARN(arg->scan_req.num_of_ssi_ds > 2, "invalid params"); + WARN(arg->scan_req.num_of_ssids > 2, "invalid params"); WARN(arg->scan_req.band > 1, "invalid params"); // FIXME: This API is unnecessary complex, fixing NumOfChannels and @@ -243,11 +243,11 @@ int hif_scan(struct wfx_vif *wvif, const struct wfx_scan_params *arg) cpu_to_le32s(>max_channel_time); cpu_to_le32s(>tx_power_level); memcpy(ptr, arg->ssids, - arg->scan_req.num_of_ssi_ds * sizeof(struct hif_ssid_def)); + arg->scan_req.num_of_ssids * sizeof(struct hif_ssid_def)); ssids = (struct hif_ssid_def *) ptr; - for (i = 0; i < body->num_of_ssi_ds; ++i) + for (i = 0; i < body->num_of_ssids; ++i) cpu_to_le32s([i].ssid_length); - ptr += arg->scan_req.num_of_ssi_ds * sizeof(struct hif_ssid_def); + ptr += arg->scan_req.num_of_ssids * sizeof(struct hif_ssid_def); memcpy(ptr, arg->ch, arg->scan_req.num_of_channels * sizeof(u8)); ptr += arg->scan_req.num_of_channels * sizeof(u8); WARN(buf_len != ptr - (u8 *) body, "allocation size mismatch"); diff --git a/drivers/staging/wfx/scan.c b/drivers/staging/wfx/scan.c index 45e78c5722ff..cb7a1fdd0001 100644 --- a/drivers/staging/wfx/scan.c +++ b/drivers/staging/wfx/scan.c @@ -204,7 +204,7 @@ void wfx_scan_work(struct work_struct *work) scan.scan_req.max_transmit_rate = API_RATE_INDEX_B_1MBPS; scan.scan_req.num_of_probe_requests = (first->flags & IEEE80211_CHAN_NO_IR) ? 0 : 2; - scan.scan_req.num_of_ssi_ds = wvif->scan.n_ssids; + scan.scan_req.num_of_ssids = wvif->scan.n_ssids; scan.ssids = >scan.ssids[0]; scan.scan_req.num_of_channels = it - wvif->scan.curr; scan.scan_req.probe_delay = 100; -- 2.20.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 21/55] staging: wfx: ensure that traces never modify arguments
From: Jérôme Pouiller There is no reason for a trace to change any bit of the argument. So, let's make sure that is the case by declaring the arguments constant. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/traces.h | 14 -- 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/staging/wfx/traces.h b/drivers/staging/wfx/traces.h index 3f6198ab2235..30c6a13f0e22 100644 --- a/drivers/staging/wfx/traces.h +++ b/drivers/staging/wfx/traces.h @@ -153,7 +153,7 @@ hif_mib_list_enum #define hif_mib_list hif_mib_list_enum { -1, NULL } DECLARE_EVENT_CLASS(hif_data, - TP_PROTO(struct hif_msg *hif, int tx_fill_level, bool is_recv), + TP_PROTO(const struct hif_msg *hif, int tx_fill_level, bool is_recv), TP_ARGS(hif, tx_fill_level, is_recv), TP_STRUCT__entry( __field(int, tx_fill_level) @@ -203,12 +203,12 @@ DECLARE_EVENT_CLASS(hif_data, ) ); DEFINE_EVENT(hif_data, hif_send, - TP_PROTO(struct hif_msg *hif, int tx_fill_level, bool is_recv), + TP_PROTO(const struct hif_msg *hif, int tx_fill_level, bool is_recv), TP_ARGS(hif, tx_fill_level, is_recv)); #define _trace_hif_send(hif, tx_fill_level)\ trace_hif_send(hif, tx_fill_level, false) DEFINE_EVENT(hif_data, hif_recv, - TP_PROTO(struct hif_msg *hif, int tx_fill_level, bool is_recv), + TP_PROTO(const struct hif_msg *hif, int tx_fill_level, bool is_recv), TP_ARGS(hif, tx_fill_level, is_recv)); #define _trace_hif_recv(hif, tx_fill_level)\ trace_hif_recv(hif, tx_fill_level, true) @@ -359,7 +359,8 @@ TRACE_EVENT(bh_stats, trace_bh_stats(ind, req, cnf, busy, release) TRACE_EVENT(tx_stats, - TP_PROTO(struct hif_cnf_tx *tx_cnf, struct sk_buff *skb, int delay), + TP_PROTO(const struct hif_cnf_tx *tx_cnf, const struct sk_buff *skb, +int delay), TP_ARGS(tx_cnf, skb, delay), TP_STRUCT__entry( __field(int, pkt_id) @@ -375,8 +376,9 @@ TRACE_EVENT(tx_stats, // Keep sync with wfx_rates definition in main.c static const int hw_rate[] = { 0, 1, 2, 3, 6, 7, 8, 9, 10, 11, 12, 13 }; - struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); - struct ieee80211_tx_rate *rates = tx_info->driver_rates; + const struct ieee80211_tx_info *tx_info = + (const struct ieee80211_tx_info *)skb->cb; + const struct ieee80211_tx_rate *rates = tx_info->driver_rates; int i; __entry->pkt_id = tx_cnf->packet_id; -- 2.20.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 13/55] staging: wfx: avoid double warning when no more tx policy are available
From: Jérôme Pouiller Currently, number of available tx retry policies is checked two times. Only one is sufficient. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/data_tx.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/wfx/data_tx.c b/drivers/staging/wfx/data_tx.c index 32e269becd75..c9dea627661f 100644 --- a/drivers/staging/wfx/data_tx.c +++ b/drivers/staging/wfx/data_tx.c @@ -169,7 +169,8 @@ static int wfx_tx_policy_get(struct wfx_vif *wvif, wfx_tx_policy_build(wvif, , rates); spin_lock_bh(>lock); - if (WARN_ON(list_empty(>free))) { + if (list_empty(>free)) { + WARN(1, "unable to get a valid Tx policy"); spin_unlock_bh(>lock); return WFX_INVALID_RATE_ID; } -- 2.20.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 15/55] staging: wfx: take advantage of IS_ERR_OR_NULL()
From: Jérôme Pouiller Obviously, current code can be replaced by IS_ERR_OR_NULL(). Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/wfx/main.c b/drivers/staging/wfx/main.c index 3b47b6c21ea1..cf4bcb14a12d 100644 --- a/drivers/staging/wfx/main.c +++ b/drivers/staging/wfx/main.c @@ -182,7 +182,7 @@ struct gpio_desc *wfx_get_gpio(struct device *dev, int override, } else { ret = devm_gpiod_get(dev, label, GPIOD_OUT_LOW); } - if (IS_ERR(ret) || !ret) { + if (IS_ERR_OR_NULL(ret)) { if (!ret || PTR_ERR(ret) == -ENOENT) dev_warn(dev, "gpio %s is not defined\n", label); else -- 2.20.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 17/55] staging: wfx: use meaningful names for CFG_BYTE_ORDER_*
From: Jérôme Pouiller This new naming allows to save a comment. Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/bus_spi.c | 2 ++ drivers/staging/wfx/fwio.c| 2 +- drivers/staging/wfx/hwio.h| 15 +-- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/drivers/staging/wfx/bus_spi.c b/drivers/staging/wfx/bus_spi.c index 0a055c4041af..40bc33035de2 100644 --- a/drivers/staging/wfx/bus_spi.c +++ b/drivers/staging/wfx/bus_spi.c @@ -107,6 +107,8 @@ static int wfx_spi_copy_to_io(void *priv, unsigned int addr, cpu_to_le16s(); + // Register address and CONFIG content always use 16bit big endian + // ("BADC" order) if (bus->need_swab) swab16s(); if (bus->need_swab && addr == WFX_REG_CONFIG) diff --git a/drivers/staging/wfx/fwio.c b/drivers/staging/wfx/fwio.c index 47e627bf0f8e..9d61082c1e6c 100644 --- a/drivers/staging/wfx/fwio.c +++ b/drivers/staging/wfx/fwio.c @@ -339,7 +339,7 @@ int wfx_init_device(struct wfx_dev *wdev) ktime_t now, start; u32 reg; - reg = CFG_DIRECT_ACCESS_MODE | CFG_CPU_RESET | CFG_WORD_MODE2; + reg = CFG_DIRECT_ACCESS_MODE | CFG_CPU_RESET | CFG_BYTE_ORDER_ABCD; if (wdev->pdata.use_rising_clk) reg |= CFG_CLK_RISE_EDGE; ret = config_reg_write(wdev, reg); diff --git a/drivers/staging/wfx/hwio.h b/drivers/staging/wfx/hwio.h index b2c1a66de963..4b6ef061b40b 100644 --- a/drivers/staging/wfx/hwio.h +++ b/drivers/staging/wfx/hwio.h @@ -37,16 +37,11 @@ int ahb_reg_write(struct wfx_dev *wdev, u32 addr, u32 val); #define CFG_ERR_HOST_NO_IN_QUEUE 0x0040 #define CFG_ERR_HOST_CRC_MISS 0x0080 // only with SDIO #define CFG_SPI_IGNORE_CS 0x0080 // only with SPI -/* Bytes ordering (only writable in SPI): */ -#define CFG_WORD_MODE_MASK 0x0300 -/* - * B1,B0,B3,B2 (In SPI, register address and - * CONFIG data always use this mode) - */ -#define CFG_WORD_MODE0 0x -#define CFG_WORD_MODE1 0x0100 // B3,B2,B1,B0 -#define CFG_WORD_MODE2 0x0200 // B0,B1,B2,B3 (SDIO) -#define CFG_DIRECT_ACCESS_MODE 0x0400 // Direct or queue access mode +#define CFG_BYTE_ORDER_MASK0x0300 // only writable with SPI +#define CFG_BYTE_ORDER_BADC0x +#define CFG_BYTE_ORDER_DCBA0x0100 +#define CFG_BYTE_ORDER_ABCD0x0200 // SDIO always use this value +#define CFG_DIRECT_ACCESS_MODE 0x0400 #define CFG_PREFETCH_AHB 0x0800 #define CFG_DISABLE_CPU_CLK0x1000 #define CFG_PREFETCH_SRAM 0x2000 -- 2.20.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel