Re: [PATCH] staging: wfx: fix reset GPIO polarity

2019-12-05 Thread Jérôme Pouiller
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

2019-12-05 Thread Jérôme Pouiller
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

2019-12-17 Thread Jérôme Pouiller
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

2019-12-17 Thread Jérôme Pouiller
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()

2019-12-17 Thread Jérôme Pouiller
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

2019-12-17 Thread Jérôme Pouiller
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

2019-12-17 Thread Jérôme Pouiller
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()

2019-12-17 Thread Jérôme Pouiller
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()

2019-12-17 Thread Jérôme Pouiller
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

2019-12-17 Thread Jérôme Pouiller
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

2019-12-17 Thread Jérôme Pouiller
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

2019-12-17 Thread Jérôme Pouiller
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

2019-12-17 Thread Jérôme Pouiller
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()

2019-12-17 Thread Jérôme Pouiller
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

2019-12-17 Thread Jérôme Pouiller
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

2019-12-17 Thread Jérôme Pouiller
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

2019-12-17 Thread Jérôme Pouiller
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

2019-12-17 Thread Jérôme Pouiller
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()

2019-12-17 Thread Jérôme Pouiller
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()

2019-12-17 Thread Jérôme Pouiller
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

2019-12-17 Thread Jérôme Pouiller
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()

2019-12-17 Thread Jérôme Pouiller
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

2019-12-17 Thread Jérôme Pouiller
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()

2019-12-17 Thread Jérôme Pouiller
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()

2019-12-17 Thread Jérôme Pouiller
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

2019-12-17 Thread Jérôme Pouiller
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

2019-12-17 Thread Jérôme Pouiller
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

2019-12-17 Thread Jérôme Pouiller
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

2019-12-17 Thread Jérôme Pouiller
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"

2019-12-17 Thread Jérôme Pouiller
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

2019-12-17 Thread Jérôme Pouiller
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

2019-12-17 Thread Jérôme Pouiller
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

2019-12-17 Thread Jérôme Pouiller
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

2019-12-17 Thread Jérôme Pouiller
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"

2019-12-17 Thread Jérôme Pouiller
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

2019-12-17 Thread Jérôme Pouiller
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

2019-12-17 Thread Jérôme Pouiller
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

2019-12-17 Thread Jérôme Pouiller
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

2019-12-17 Thread Jérôme Pouiller
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

2019-12-17 Thread Jérôme Pouiller
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

2019-12-17 Thread Jérôme Pouiller
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

2019-12-17 Thread Jérôme Pouiller
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

2019-12-17 Thread Jérôme Pouiller
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

2019-12-17 Thread Jérôme Pouiller
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

2019-12-17 Thread Jérôme Pouiller
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

2019-12-17 Thread Jérôme Pouiller
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"

2019-12-17 Thread Jérôme Pouiller
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

2019-12-17 Thread Jérôme Pouiller
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

2019-12-17 Thread Jérôme Pouiller
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

2019-12-17 Thread Jérôme Pouiller
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

2019-12-17 Thread Jérôme Pouiller
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()

2019-12-17 Thread Jérôme Pouiller
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

2019-12-17 Thread Jérôme Pouiller
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

2019-12-17 Thread Jérôme Pouiller
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

2019-12-17 Thread Jérôme Pouiller
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

2019-12-17 Thread Jérôme Pouiller
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_*

2019-12-17 Thread Jérôme Pouiller
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

2019-12-17 Thread Jérôme Pouiller
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

2019-12-17 Thread Jérôme Pouiller
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

2019-12-17 Thread Jérôme Pouiller
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

2019-12-17 Thread Jérôme Pouiller
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

2019-12-16 Thread Jérôme Pouiller
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

2019-12-16 Thread Jérôme Pouiller
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

2019-12-16 Thread Jérôme Pouiller
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()

2019-12-16 Thread Jérôme Pouiller
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

2019-12-16 Thread Jérôme Pouiller
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

2019-12-16 Thread Jérôme Pouiller
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

2019-12-16 Thread Jérôme Pouiller
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()

2019-12-16 Thread Jérôme Pouiller
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

2019-12-16 Thread Jérôme Pouiller
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()

2019-12-16 Thread Jérôme Pouiller
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

2019-12-16 Thread Jérôme Pouiller
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

2019-12-16 Thread Jérôme Pouiller
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

2019-12-16 Thread Jérôme Pouiller
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

2019-12-16 Thread Jérôme Pouiller
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

2019-12-16 Thread Jérôme Pouiller
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

2019-12-16 Thread Jérôme Pouiller
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

2019-12-16 Thread Jérôme Pouiller
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()

2019-12-16 Thread Jérôme Pouiller
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

2019-12-16 Thread Jérôme Pouiller
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()

2019-12-16 Thread Jérôme Pouiller
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

2019-12-16 Thread Jérôme Pouiller
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

2019-12-16 Thread Jérôme Pouiller
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

2019-12-16 Thread Jérôme Pouiller
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()

2019-12-16 Thread Jérôme Pouiller
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()

2019-12-16 Thread Jérôme Pouiller
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"

2019-12-16 Thread Jérôme Pouiller
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

2019-12-16 Thread Jérôme Pouiller
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

2019-12-16 Thread Jérôme Pouiller
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

2019-12-16 Thread Jérôme Pouiller
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

2019-12-16 Thread Jérôme Pouiller
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"

2019-12-16 Thread Jérôme Pouiller
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

2019-12-16 Thread Jérôme Pouiller
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

2019-12-16 Thread Jérôme Pouiller
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

2019-12-16 Thread Jérôme Pouiller
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"

2019-12-16 Thread Jérôme Pouiller
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

2019-12-16 Thread Jérôme Pouiller
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

2019-12-16 Thread Jérôme Pouiller
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()

2019-12-16 Thread Jérôme Pouiller
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_*

2019-12-16 Thread Jérôme Pouiller
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


  1   2   3   4   >