2014-09-01 07:30:09

by Avinash Patil

[permalink] [raw]
Subject: [PATCH 00/17] mwifiex updates for 3.17

This patch series brings in scan enhancement including scan channel gap,
support for parsing FW API version from HW_SPEC command response,
support for processing RX in work queue and few trivial fixes for
SDIO multiport aggregation.

Amitkumar Karwar (7):
mwifiex: fix a bug in Tx multiport aggregation
mwifiex: minor cleanup in multiport aggregation
mwifiex: fix left_len calculation issue
mwifiex: rename macro and variables related to API revision
mwifiex: use firmware API revision from GET_HW_SPEC response
mwifiex: remove redundant variable report_scan_result
mwifiex: remove low priority scan handling

Avinash Patil (9):
mwifiex: fix probable memory corruption while processing TDLS frame
mwifiex: avoid processing RX packets with invalid length
mwifiex: rework internal scan for association
mwifiex: support for event done interrupt
mwifiex: set passive scan type for scan requests with no ssid
mwifiex: bring in scan channel gap feature
mwifiex: remove restriction of single channel scan when connected
mwifiex: process TX even when scan is ongoing
mwifiex: add rx workqueue support

Xinming Hu (1):
mwifiex: fix 5G association failure after leaving 2.4G IBSS

drivers/net/wireless/mwifiex/11n_rxreorder.c | 14 ++
drivers/net/wireless/mwifiex/cfg80211.c | 13 +-
drivers/net/wireless/mwifiex/cmdevt.c | 28 ++--
drivers/net/wireless/mwifiex/fw.h | 17 ++-
drivers/net/wireless/mwifiex/init.c | 25 +++-
drivers/net/wireless/mwifiex/main.c | 194 +++++++++++++--------------
drivers/net/wireless/mwifiex/main.h | 49 +++++--
drivers/net/wireless/mwifiex/pcie.c | 37 ++++-
drivers/net/wireless/mwifiex/pcie.h | 5 +-
drivers/net/wireless/mwifiex/scan.c | 112 ++++++++++------
drivers/net/wireless/mwifiex/sdio.c | 28 ++--
drivers/net/wireless/mwifiex/sta_cmd.c | 2 +-
drivers/net/wireless/mwifiex/sta_cmdresp.c | 4 +-
drivers/net/wireless/mwifiex/sta_ioctl.c | 13 +-
drivers/net/wireless/mwifiex/tdls.c | 4 +-
15 files changed, 339 insertions(+), 206 deletions(-)

--
1.8.1.4



2014-09-09 18:30:12

by John W. Linville

[permalink] [raw]
Subject: Re: [PATCH 00/17] mwifiex updates for 3.17

OK.

On Tue, Sep 09, 2014 at 10:10:01AM -0700, Avinash Patil wrote:
> Hi John,
>
> Please drop this series. I will send v2.
>
> Thanks,
> Avinash.
>
> -----Original Message-----
> From: Avinash Patil [mailto:[email protected]]
> Sent: Monday, September 01, 2014 6:29 PM
> To: [email protected]
> Cc: [email protected]; Amitkumar Karwar; Xinming Hu; Marc Yang; Cathy Luo; Maithili Hinge; Avinash Patil
> Subject: [PATCH 00/17] mwifiex updates for 3.17
>
> This patch series brings in scan enhancement including scan channel gap, support for parsing FW API version from HW_SPEC command response, support for processing RX in work queue and few trivial fixes for SDIO multiport aggregation.
>
> Amitkumar Karwar (7):
> mwifiex: fix a bug in Tx multiport aggregation
> mwifiex: minor cleanup in multiport aggregation
> mwifiex: fix left_len calculation issue
> mwifiex: rename macro and variables related to API revision
> mwifiex: use firmware API revision from GET_HW_SPEC response
> mwifiex: remove redundant variable report_scan_result
> mwifiex: remove low priority scan handling
>
> Avinash Patil (9):
> mwifiex: fix probable memory corruption while processing TDLS frame
> mwifiex: avoid processing RX packets with invalid length
> mwifiex: rework internal scan for association
> mwifiex: support for event done interrupt
> mwifiex: set passive scan type for scan requests with no ssid
> mwifiex: bring in scan channel gap feature
> mwifiex: remove restriction of single channel scan when connected
> mwifiex: process TX even when scan is ongoing
> mwifiex: add rx workqueue support
>
> Xinming Hu (1):
> mwifiex: fix 5G association failure after leaving 2.4G IBSS
>
> drivers/net/wireless/mwifiex/11n_rxreorder.c | 14 ++
> drivers/net/wireless/mwifiex/cfg80211.c | 13 +-
> drivers/net/wireless/mwifiex/cmdevt.c | 28 ++--
> drivers/net/wireless/mwifiex/fw.h | 17 ++-
> drivers/net/wireless/mwifiex/init.c | 25 +++-
> drivers/net/wireless/mwifiex/main.c | 194 +++++++++++++--------------
> drivers/net/wireless/mwifiex/main.h | 49 +++++--
> drivers/net/wireless/mwifiex/pcie.c | 37 ++++-
> drivers/net/wireless/mwifiex/pcie.h | 5 +-
> drivers/net/wireless/mwifiex/scan.c | 112 ++++++++++------
> drivers/net/wireless/mwifiex/sdio.c | 28 ++--
> drivers/net/wireless/mwifiex/sta_cmd.c | 2 +-
> drivers/net/wireless/mwifiex/sta_cmdresp.c | 4 +-
> drivers/net/wireless/mwifiex/sta_ioctl.c | 13 +-
> drivers/net/wireless/mwifiex/tdls.c | 4 +-
> 15 files changed, 339 insertions(+), 206 deletions(-)
>
> --
> 1.8.1.4
>
>

--
John W. Linville Someday the world will need a hero, and you
[email protected] might be all we have. Be ready.

2014-09-01 07:31:20

by Avinash Patil

[permalink] [raw]
Subject: [PATCH 06/17] mwifiex: fix a bug in Tx multiport aggregation

From: Amitkumar Karwar <[email protected]>

When aggregation port limit is reached, we stop aggregation and
the data is sent to firmware. It is observed that one less packet
than the port limit is aggregated in this case. ex. 15 instead of
16.
The reason is we have redundant port limit checks before current
packet is added to aggregation buffer.

The issue is fixed by removing these checks. We already have
necessary check in precopy current buffer handling.

Signed-off-by: Amitkumar Karwar <[email protected]>
Signed-off-by: Avinash Patil <[email protected]>
Signed-off-by: Bing Zhao <[email protected]>
---
drivers/net/wireless/mwifiex/sdio.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c
index 1770fa3..993841e 100644
--- a/drivers/net/wireless/mwifiex/sdio.c
+++ b/drivers/net/wireless/mwifiex/sdio.c
@@ -1527,8 +1527,7 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter,
__func__);

if (MP_TX_AGGR_IN_PROGRESS(card)) {
- if (!mp_tx_aggr_port_limit_reached(card) &&
- MP_TX_AGGR_BUF_HAS_ROOM(card, pkt_len)) {
+ if (MP_TX_AGGR_BUF_HAS_ROOM(card, pkt_len)) {
f_precopy_cur_buf = 1;

if (!(card->mp_wr_bitmap &
@@ -1540,8 +1539,7 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter,
/* No room in Aggr buf, send it */
f_send_aggr_buf = 1;

- if (mp_tx_aggr_port_limit_reached(card) ||
- !(card->mp_wr_bitmap &
+ if (!(card->mp_wr_bitmap &
(1 << card->curr_wr_port)))
f_send_cur_buf = 1;
else
--
1.8.1.4


2014-09-01 07:32:01

by Avinash Patil

[permalink] [raw]
Subject: [PATCH 14/17] mwifiex: process TX even when scan is ongoing

With channel scan gap, FW comes back to connected channel after each
single channel scan. So we can safely transfer data to FW during scan.
FW would send this data once on connected channel.

Signed-off-by: Avinash Patil <[email protected]>
Signed-off-by: Amitkumar Karwar <[email protected]>
Signed-off-by: Marc Yang <[email protected]>
Signed-off-by: Cathy Luo <[email protected]>
---
drivers/net/wireless/mwifiex/main.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index dfa37ea..1f1b7d7 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -284,8 +284,7 @@ process_start:
adapter->tx_lock_flag)
break;

- if ((adapter->scan_processing &&
- !adapter->scan_delay_cnt) || adapter->data_sent ||
+ if (adapter->data_sent ||
mwifiex_wmm_lists_empty(adapter)) {
if (adapter->cmd_sent || adapter->curr_cmd ||
(!is_command_pending(adapter)))
@@ -339,8 +338,7 @@ process_start:
}
}

- if ((!adapter->scan_processing || adapter->scan_delay_cnt) &&
- !adapter->data_sent && !mwifiex_wmm_lists_empty(adapter)) {
+ if (!adapter->data_sent && !mwifiex_wmm_lists_empty(adapter)) {
mwifiex_wmm_process_tx(adapter);
if (adapter->hs_activated) {
adapter->is_hs_configured = false;
--
1.8.1.4


2014-09-05 08:10:32

by Avinash Patil

[permalink] [raw]
Subject: RE: [PATCH 17/17] mwifiex: add rx workqueue support

Hi James,

Thanks for pointing out.

John,

Do you want me to send a follow up patch for this? Else I will fix this and send v2.

Thanks,
Avinash
________________________________________
From: [email protected] [[email protected]]
Sent: Thursday, September 04, 2014 9:17 AM
To: Avinash Patil
Cc: [email protected]; [email protected]; Amitkumar Karwar; Xinming Hu; Marc Yang; Cathy Luo; Maithili Hinge
Subject: Re: [PATCH 17/17] mwifiex: add rx workqueue support

On Mon, Sep 01, 2014 at 06:29:05PM +0530, Avinash Patil wrote:
> This patch adds RX work queue support to mwifiex.
> Packets received are queued to internal queue which are then
> processed by scheduling a work item for RX process.
>
> RX work is enabled only on SMP systems.
>
> Signed-off-by: Avinash Patil <[email protected]>
> Signed-off-by: Marc Yang <[email protected]>
> Signed-off-by: Cathy Luo <[email protected]>
> ---
> drivers/net/wireless/mwifiex/11n_rxreorder.c | 14 ++++
> drivers/net/wireless/mwifiex/init.c | 19 ++++++
> drivers/net/wireless/mwifiex/main.c | 95 ++++++++++++++++++++++++++++
> drivers/net/wireless/mwifiex/main.h | 14 ++++
> drivers/net/wireless/mwifiex/pcie.c | 12 +++-
> drivers/net/wireless/mwifiex/sdio.c | 11 +++-
> 6 files changed, 163 insertions(+), 2 deletions(-)
>
> [...]
> diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
> index fb38d81..2ed59a0 100644
> --- a/drivers/net/wireless/mwifiex/main.c
> +++ b/drivers/net/wireless/mwifiex/main.c
> [...]
> @@ -784,6 +858,15 @@ mwifiex_add_card(void *card, struct semaphore *sem,
> adapter->cmd_wait_q.status = 0;
> adapter->scan_wait_q_woken = false;
>
> + if (num_possible_cpus() > 1) {
> + adapter->rx_work_enabled = true;
> + pr_debug("info: %s rx work enabled, cpus %d :\n", __func__,
> + num_possible_cpus());
> + /*to ensure this is seen in dmesg logs*/
> + pr_err("info: %s rx work enabled, cpus %d :\n", __func__,
> + num_possible_cpus());

Either pr_debug or pr_err, but not both.

(Would love to test, but stuck on 3.5, and don't know how to
backport mwifiex.)

--
James Cameron
http://quozl.linux.org.au/

2014-09-04 17:15:13

by John W. Linville

[permalink] [raw]
Subject: Re: [PATCH 00/17] mwifiex updates for 3.17

These don't all seem to be fixes. Do you want me to take them for
3.18? Or do you want to divide this list between fixes and features
and post them as different series for 3.17 and 3.18?

John

On Mon, Sep 01, 2014 at 06:28:48PM +0530, Avinash Patil wrote:
> This patch series brings in scan enhancement including scan channel gap,
> support for parsing FW API version from HW_SPEC command response,
> support for processing RX in work queue and few trivial fixes for
> SDIO multiport aggregation.
>
> Amitkumar Karwar (7):
> mwifiex: fix a bug in Tx multiport aggregation
> mwifiex: minor cleanup in multiport aggregation
> mwifiex: fix left_len calculation issue
> mwifiex: rename macro and variables related to API revision
> mwifiex: use firmware API revision from GET_HW_SPEC response
> mwifiex: remove redundant variable report_scan_result
> mwifiex: remove low priority scan handling
>
> Avinash Patil (9):
> mwifiex: fix probable memory corruption while processing TDLS frame
> mwifiex: avoid processing RX packets with invalid length
> mwifiex: rework internal scan for association
> mwifiex: support for event done interrupt
> mwifiex: set passive scan type for scan requests with no ssid
> mwifiex: bring in scan channel gap feature
> mwifiex: remove restriction of single channel scan when connected
> mwifiex: process TX even when scan is ongoing
> mwifiex: add rx workqueue support
>
> Xinming Hu (1):
> mwifiex: fix 5G association failure after leaving 2.4G IBSS
>
> drivers/net/wireless/mwifiex/11n_rxreorder.c | 14 ++
> drivers/net/wireless/mwifiex/cfg80211.c | 13 +-
> drivers/net/wireless/mwifiex/cmdevt.c | 28 ++--
> drivers/net/wireless/mwifiex/fw.h | 17 ++-
> drivers/net/wireless/mwifiex/init.c | 25 +++-
> drivers/net/wireless/mwifiex/main.c | 194 +++++++++++++--------------
> drivers/net/wireless/mwifiex/main.h | 49 +++++--
> drivers/net/wireless/mwifiex/pcie.c | 37 ++++-
> drivers/net/wireless/mwifiex/pcie.h | 5 +-
> drivers/net/wireless/mwifiex/scan.c | 112 ++++++++++------
> drivers/net/wireless/mwifiex/sdio.c | 28 ++--
> drivers/net/wireless/mwifiex/sta_cmd.c | 2 +-
> drivers/net/wireless/mwifiex/sta_cmdresp.c | 4 +-
> drivers/net/wireless/mwifiex/sta_ioctl.c | 13 +-
> drivers/net/wireless/mwifiex/tdls.c | 4 +-
> 15 files changed, 339 insertions(+), 206 deletions(-)
>
> --
> 1.8.1.4
>
>

--
John W. Linville Someday the world will need a hero, and you
[email protected] might be all we have. Be ready.

2014-09-01 07:30:40

by Avinash Patil

[permalink] [raw]
Subject: [PATCH 01/17] mwifiex: fix probable memory corruption while processing TDLS frame

Size of RSN IE buffer in driver is 254 while maximum size of received buffer
to be copied to RSN IE buffer can be 255. Add boundary check to copy maximum
of 254 bytes into RSN IE buffer.

Reported-by: Dan Carpenter <[email protected]>
Signed-off-by: Avinash Patil <[email protected]>
---
drivers/net/wireless/mwifiex/tdls.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/mwifiex/tdls.c b/drivers/net/wireless/mwifiex/tdls.c
index 4c5fd95..e294907 100644
--- a/drivers/net/wireless/mwifiex/tdls.c
+++ b/drivers/net/wireless/mwifiex/tdls.c
@@ -871,7 +871,9 @@ void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv,
break;
case WLAN_EID_RSN:
memcpy((u8 *)&sta_ptr->tdls_cap.rsn_ie, pos,
- sizeof(struct ieee_types_header) + pos[1]);
+ sizeof(struct ieee_types_header) +
+ min_t(u8, pos[1], IEEE_MAX_IE_SIZE -
+ sizeof(struct ieee_types_header)));
break;
case WLAN_EID_QOS_CAPA:
sta_ptr->tdls_cap.qos_info = pos[2];
--
1.8.1.4


2014-09-01 07:31:27

by Avinash Patil

[permalink] [raw]
Subject: [PATCH 07/17] mwifiex: minor cleanup in multiport aggregation

From: Amitkumar Karwar <[email protected]>

'mp_data_port_mask' and 'mp_end_port' gives correct information
even for the chipsets supporting SDIO new mode (32 ports).
We will get rid of this chip specific handling.

Signed-off-by: Amitkumar Karwar <[email protected]>
Signed-off-by: Avinash Patil <[email protected]>
Signed-off-by: Bing Zhao <[email protected]>
---
drivers/net/wireless/mwifiex/sdio.c | 11 ++---------
1 file changed, 2 insertions(+), 9 deletions(-)

diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c
index 993841e..bdab122 100644
--- a/drivers/net/wireless/mwifiex/sdio.c
+++ b/drivers/net/wireless/mwifiex/sdio.c
@@ -622,22 +622,15 @@ static int mwifiex_get_wr_port_data(struct mwifiex_adapter *adapter, u32 *port)

dev_dbg(adapter->dev, "data: mp_wr_bitmap=0x%08x\n", wr_bitmap);

- if (card->supports_sdio_new_mode &&
- !(wr_bitmap & reg->data_port_mask)) {
+ if (!(wr_bitmap & card->mp_data_port_mask)) {
adapter->data_sent = true;
return -EBUSY;
- } else if (!card->supports_sdio_new_mode &&
- !(wr_bitmap & card->mp_data_port_mask)) {
- return -1;
}

if (card->mp_wr_bitmap & (1 << card->curr_wr_port)) {
card->mp_wr_bitmap &= (u32) (~(1 << card->curr_wr_port));
*port = card->curr_wr_port;
- if (((card->supports_sdio_new_mode) &&
- (++card->curr_wr_port == card->max_ports)) ||
- ((!card->supports_sdio_new_mode) &&
- (++card->curr_wr_port == card->mp_end_port)))
+ if (++card->curr_wr_port == card->mp_end_port)
card->curr_wr_port = reg->start_wr_port;
} else {
adapter->data_sent = true;
--
1.8.1.4


2014-09-09 17:10:10

by Avinash Patil

[permalink] [raw]
Subject: RE: [PATCH 00/17] mwifiex updates for 3.17

Hi John,

Please drop this series. I will send v2.

Thanks,
Avinash.

-----Original Message-----
From: Avinash Patil [mailto:[email protected]]
Sent: Monday, September 01, 2014 6:29 PM
To: [email protected]
Cc: [email protected]; Amitkumar Karwar; Xinming Hu; Marc Yang; Cathy Luo; Maithili Hinge; Avinash Patil
Subject: [PATCH 00/17] mwifiex updates for 3.17

This patch series brings in scan enhancement including scan channel gap, support for parsing FW API version from HW_SPEC command response, support for processing RX in work queue and few trivial fixes for SDIO multiport aggregation.

Amitkumar Karwar (7):
mwifiex: fix a bug in Tx multiport aggregation
mwifiex: minor cleanup in multiport aggregation
mwifiex: fix left_len calculation issue
mwifiex: rename macro and variables related to API revision
mwifiex: use firmware API revision from GET_HW_SPEC response
mwifiex: remove redundant variable report_scan_result
mwifiex: remove low priority scan handling

Avinash Patil (9):
mwifiex: fix probable memory corruption while processing TDLS frame
mwifiex: avoid processing RX packets with invalid length
mwifiex: rework internal scan for association
mwifiex: support for event done interrupt
mwifiex: set passive scan type for scan requests with no ssid
mwifiex: bring in scan channel gap feature
mwifiex: remove restriction of single channel scan when connected
mwifiex: process TX even when scan is ongoing
mwifiex: add rx workqueue support

Xinming Hu (1):
mwifiex: fix 5G association failure after leaving 2.4G IBSS

drivers/net/wireless/mwifiex/11n_rxreorder.c | 14 ++
drivers/net/wireless/mwifiex/cfg80211.c | 13 +-
drivers/net/wireless/mwifiex/cmdevt.c | 28 ++--
drivers/net/wireless/mwifiex/fw.h | 17 ++-
drivers/net/wireless/mwifiex/init.c | 25 +++-
drivers/net/wireless/mwifiex/main.c | 194 +++++++++++++--------------
drivers/net/wireless/mwifiex/main.h | 49 +++++--
drivers/net/wireless/mwifiex/pcie.c | 37 ++++-
drivers/net/wireless/mwifiex/pcie.h | 5 +-
drivers/net/wireless/mwifiex/scan.c | 112 ++++++++++------
drivers/net/wireless/mwifiex/sdio.c | 28 ++--
drivers/net/wireless/mwifiex/sta_cmd.c | 2 +-
drivers/net/wireless/mwifiex/sta_cmdresp.c | 4 +-
drivers/net/wireless/mwifiex/sta_ioctl.c | 13 +-
drivers/net/wireless/mwifiex/tdls.c | 4 +-
15 files changed, 339 insertions(+), 206 deletions(-)

--
1.8.1.4


2014-09-01 07:31:53

by Avinash Patil

[permalink] [raw]
Subject: [PATCH 13/17] mwifiex: remove restriction of single channel scan when connected

With scan channel gap in place, FW comes back to connected channel
after each scan; so we dont need to restrict FW to scan
single channel while connected.

Signed-off-by: Avinash Patil <[email protected]>
Signed-off-by: Amitkumar Karwar <[email protected]>
Signed-off-by: Marc Yang <[email protected]>
Signed-off-by: Cathy Luo <[email protected]>
---
drivers/net/wireless/mwifiex/scan.c | 6 ------
1 file changed, 6 deletions(-)

diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c
index 6fd69af..7c85f61 100644
--- a/drivers/net/wireless/mwifiex/scan.c
+++ b/drivers/net/wireless/mwifiex/scan.c
@@ -1067,12 +1067,6 @@ mwifiex_config_scan(struct mwifiex_private *priv,
*filtered_scan);
}

- /*
- * In associated state we will reduce the number of channels scanned per
- * scan command to 1 to avoid any traffic delay/loss.
- */
- if (priv->media_connected)
- *max_chan_per_scan = 1;
}

/*
--
1.8.1.4


2014-09-01 07:31:15

by Avinash Patil

[permalink] [raw]
Subject: [PATCH 05/17] mwifiex: fix 5G association failure after leaving 2.4G IBSS

From: Xinming Hu <[email protected]>

When assocaiting to an AP , mwifiex set supported data rates
based on target AP's capability. For 5G AP(11a mode), a/n/ac mode
would possibly be set.
However, for some chips which dont support 11AC mode current config_bands
will be used instead.

For example, if we join an IBSS in 11b mode ,adapter->config_bands
will be set to 1(11b mode). Then we leave IBSS ,and try to connect
5G a/n mode AP. At this time , only 11b mode data rates will be
supported in assoc request , which result in assoc failure with
reason code 18: Association denied due to requesting station not
supporting all rates.

This patch fix such a cornel case, by adding additional check for
current chip's 11ac capability.

Reported-by: Andreas Fenkart <[email protected]>
Signed-off-by: Xinming Hu <[email protected]>
Signed-off-by: Avinash Patil <[email protected]>
Signed-off-by: Amitkumar Karwar <[email protected]>
Signed-off-by: Marc Yang <[email protected]>
Signed-off-by: Cathy Luo <[email protected]>
---
drivers/net/wireless/mwifiex/sta_ioctl.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c
index caae973..0b998fd 100644
--- a/drivers/net/wireless/mwifiex/sta_ioctl.c
+++ b/drivers/net/wireless/mwifiex/sta_ioctl.c
@@ -287,10 +287,13 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
return -1;

if (mwifiex_band_to_radio_type(bss_desc->bss_band) ==
- HostCmd_SCAN_RADIO_TYPE_BG)
+ HostCmd_SCAN_RADIO_TYPE_BG) {
config_bands = BAND_B | BAND_G | BAND_GN;
- else
- config_bands = BAND_A | BAND_AN | BAND_AAC;
+ } else {
+ config_bands = BAND_A | BAND_AN;
+ if (adapter->fw_bands & BAND_AAC)
+ config_bands |= BAND_AAC;
+ }

if (!((config_bands | adapter->fw_bands) & ~adapter->fw_bands))
adapter->config_bands = config_bands;
--
1.8.1.4


2014-09-01 07:31:55

by Avinash Patil

[permalink] [raw]
Subject: [PATCH 09/17] mwifiex: rename macro and variables related to API revision

From: Amitkumar Karwar <[email protected]>

We will remove 'fw' prefix from these variable and macro
names and make them generic.

Signed-off-by: Amitkumar Karwar <[email protected]>
Signed-off-by: Avinash Patil <[email protected]>
Signed-off-by: Cathy Luo <[email protected]>
---
drivers/net/wireless/mwifiex/cmdevt.c | 18 +++++++++---------
drivers/net/wireless/mwifiex/fw.h | 8 ++++----
drivers/net/wireless/mwifiex/init.c | 4 ++--
drivers/net/wireless/mwifiex/main.h | 2 +-
drivers/net/wireless/mwifiex/sta_cmd.c | 2 +-
drivers/net/wireless/mwifiex/sta_cmdresp.c | 2 +-
drivers/net/wireless/mwifiex/sta_ioctl.c | 4 ++--
7 files changed, 20 insertions(+), 20 deletions(-)

diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c
index 0c21239..720e519 100644
--- a/drivers/net/wireless/mwifiex/cmdevt.c
+++ b/drivers/net/wireless/mwifiex/cmdevt.c
@@ -1470,7 +1470,7 @@ int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv,
struct host_cmd_ds_get_hw_spec *hw_spec = &resp->params.hw_spec;
struct mwifiex_adapter *adapter = priv->adapter;
struct mwifiex_ie_types_header *tlv;
- struct hw_spec_fw_api_rev *api_rev;
+ struct hw_spec_api_rev *api_rev;
u16 resp_size, api_id;
int i, left_len, parsed_len = 0;

@@ -1538,23 +1538,23 @@ int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv,
while (left_len > sizeof(struct mwifiex_ie_types_header)) {
tlv = (void *)&hw_spec->tlvs + parsed_len;
switch (le16_to_cpu(tlv->type)) {
- case TLV_TYPE_FW_API_REV:
- api_rev = (struct hw_spec_fw_api_rev *)tlv;
+ case TLV_TYPE_API_REV:
+ api_rev = (struct hw_spec_api_rev *)tlv;
api_id = le16_to_cpu(api_rev->api_id);
switch (api_id) {
case KEY_API_VER_ID:
- adapter->fw_key_api_major_ver =
+ adapter->key_api_major_ver =
api_rev->major_ver;
- adapter->fw_key_api_minor_ver =
+ adapter->key_api_minor_ver =
api_rev->minor_ver;
dev_dbg(adapter->dev,
- "fw_key_api v%d.%d\n",
- adapter->fw_key_api_major_ver,
- adapter->fw_key_api_minor_ver);
+ "key_api v%d.%d\n",
+ adapter->key_api_major_ver,
+ adapter->key_api_minor_ver);
break;
default:
dev_warn(adapter->dev,
- "Unknown FW api_id: %d\n",
+ "Unknown api_id: %d\n",
api_id);
break;
}
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h
index 49da2d5..adc47f3 100644
--- a/drivers/net/wireless/mwifiex/fw.h
+++ b/drivers/net/wireless/mwifiex/fw.h
@@ -83,7 +83,7 @@ enum KEY_TYPE_ID {
#define WPA_PN_SIZE 8
#define KEY_PARAMS_FIXED_LEN 10
#define KEY_INDEX_MASK 0xf
-#define FW_KEY_API_VER_MAJOR_V2 2
+#define KEY_API_VER_MAJOR_V2 2

#define KEY_MCAST BIT(0)
#define KEY_UNICAST BIT(1)
@@ -170,7 +170,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
#define TLV_TYPE_COALESCE_RULE (PROPRIETARY_TLV_BASE_ID + 154)
#define TLV_TYPE_KEY_PARAM_V2 (PROPRIETARY_TLV_BASE_ID + 156)
#define TLV_TYPE_TDLS_IDLE_TIMEOUT (PROPRIETARY_TLV_BASE_ID + 194)
-#define TLV_TYPE_FW_API_REV (PROPRIETARY_TLV_BASE_ID + 199)
+#define TLV_TYPE_API_REV (PROPRIETARY_TLV_BASE_ID + 199)

#define MWIFIEX_TX_DATA_BUF_SIZE_2K 2048

@@ -844,11 +844,11 @@ struct host_cmd_ds_802_11_ps_mode_enh {
} params;
} __packed;

-enum FW_API_VER_ID {
+enum API_VER_ID {
KEY_API_VER_ID = 1,
};

-struct hw_spec_fw_api_rev {
+struct hw_spec_api_rev {
struct mwifiex_ie_types_header header;
__le16 api_id;
u8 major_ver;
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c
index 269a277..80bda80 100644
--- a/drivers/net/wireless/mwifiex/init.c
+++ b/drivers/net/wireless/mwifiex/init.c
@@ -282,8 +282,8 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter)
adapter->max_mgmt_ie_index = MAX_MGMT_IE_INDEX;
adapter->empty_tx_q_cnt = 0;
adapter->ext_scan = true;
- adapter->fw_key_api_major_ver = 0;
- adapter->fw_key_api_minor_ver = 0;
+ adapter->key_api_major_ver = 0;
+ adapter->key_api_minor_ver = 0;
}

/*
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index a2733b1..5439963 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -833,7 +833,7 @@ struct mwifiex_adapter {
struct semaphore *card_sem;
bool ext_scan;
u8 fw_api_ver;
- u8 fw_key_api_major_ver, fw_key_api_minor_ver;
+ u8 key_api_major_ver, key_api_minor_ver;
struct work_struct iface_work;
unsigned long iface_work_flags;
struct memory_type_mapping *mem_type_mapping_tbl;
diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c
index 733de92..225f749 100644
--- a/drivers/net/wireless/mwifiex/sta_cmd.c
+++ b/drivers/net/wireless/mwifiex/sta_cmd.c
@@ -965,7 +965,7 @@ mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv,
u16 cmd_action, u32 cmd_oid,
struct mwifiex_ds_encrypt_key *enc_key)
{
- if (priv->adapter->fw_key_api_major_ver == FW_KEY_API_VER_MAJOR_V2)
+ if (priv->adapter->key_api_major_ver == KEY_API_VER_MAJOR_V2)
return mwifiex_cmd_802_11_key_material_v2(priv, cmd,
cmd_action, cmd_oid,
enc_key);
diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c
index 08b78ba..62866b0 100644
--- a/drivers/net/wireless/mwifiex/sta_cmdresp.c
+++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c
@@ -637,7 +637,7 @@ static int mwifiex_ret_802_11_key_material_v2(struct mwifiex_private *priv,
static int mwifiex_ret_802_11_key_material(struct mwifiex_private *priv,
struct host_cmd_ds_command *resp)
{
- if (priv->adapter->fw_key_api_major_ver == FW_KEY_API_VER_MAJOR_V2)
+ if (priv->adapter->key_api_major_ver == KEY_API_VER_MAJOR_V2)
return mwifiex_ret_802_11_key_material_v2(priv, resp);
else
return mwifiex_ret_802_11_key_material_v1(priv, resp);
diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c
index 0b998fd..92f3eb8 100644
--- a/drivers/net/wireless/mwifiex/sta_ioctl.c
+++ b/drivers/net/wireless/mwifiex/sta_ioctl.c
@@ -880,7 +880,7 @@ static int mwifiex_sec_ioctl_set_wep_key(struct mwifiex_private *priv,
return -1;
}

- if (adapter->fw_key_api_major_ver == FW_KEY_API_VER_MAJOR_V2) {
+ if (adapter->key_api_major_ver == KEY_API_VER_MAJOR_V2) {
memcpy(encrypt_key->key_material,
wep_key->key_material, wep_key->key_length);
encrypt_key->key_len = wep_key->key_length;
@@ -906,7 +906,7 @@ static int mwifiex_sec_ioctl_set_wep_key(struct mwifiex_private *priv,
memset(&priv->wep_key[index], 0,
sizeof(struct mwifiex_wep_key));

- if (adapter->fw_key_api_major_ver == FW_KEY_API_VER_MAJOR_V2)
+ if (adapter->key_api_major_ver == KEY_API_VER_MAJOR_V2)
enc_key = encrypt_key;
else
enc_key = NULL;
--
1.8.1.4


2014-09-01 07:32:15

by Avinash Patil

[permalink] [raw]
Subject: [PATCH 16/17] mwifiex: remove low priority scan handling

From: Amitkumar Karwar <[email protected]>

We have a logic in driver to delay or abort low priority scan
to serve Tx traffic effectively. With scan channel
gap support added, firmware now allows driver to send Tx data while
scan operation is in progress. Hence low priority scan handling
in driver is not required now. This patch removes related code.

Signed-off-by: Amitkumar Karwar <[email protected]>
Signed-off-by: Avinash Patil <[email protected]>
Signed-off-by: Cathy Luo <[email protected]>
---
drivers/net/wireless/mwifiex/cfg80211.c | 7 ---
drivers/net/wireless/mwifiex/init.c | 1 -
drivers/net/wireless/mwifiex/main.c | 93 ---------------------------------
drivers/net/wireless/mwifiex/main.h | 10 ----
drivers/net/wireless/mwifiex/scan.c | 59 ++++++++++-----------
5 files changed, 29 insertions(+), 141 deletions(-)

diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index 654fc27..22badc7 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -1935,13 +1935,6 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy,

wiphy_dbg(wiphy, "info: received scan request on %s\n", dev->name);

- if ((request->flags & NL80211_SCAN_FLAG_LOW_PRIORITY) &&
- atomic_read(&priv->wmm.tx_pkts_queued) >=
- MWIFIEX_MIN_TX_PENDING_TO_CANCEL_SCAN) {
- dev_dbg(priv->adapter->dev, "scan rejected due to traffic\n");
- return -EBUSY;
- }
-
/* Block scan request if scan operation or scan cleanup when interface
* is disabled is in process
*/
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c
index d99c6f6..cd9baad 100644
--- a/drivers/net/wireless/mwifiex/init.c
+++ b/drivers/net/wireless/mwifiex/init.c
@@ -281,7 +281,6 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter)
memset(&adapter->arp_filter, 0, sizeof(adapter->arp_filter));
adapter->arp_filter_size = 0;
adapter->max_mgmt_ie_index = MAX_MGMT_IE_INDEX;
- adapter->empty_tx_q_cnt = 0;
adapter->ext_scan = true;
adapter->key_api_major_ver = 0;
adapter->key_api_minor_ver = 0;
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index 1f1b7d7..fb38d81 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -28,91 +28,6 @@ const char driver_version[] = "mwifiex " VERSION " (%s) ";
static char *cal_data_cfg;
module_param(cal_data_cfg, charp, 0);

-static void scan_delay_timer_fn(unsigned long data)
-{
- struct mwifiex_private *priv = (struct mwifiex_private *)data;
- struct mwifiex_adapter *adapter = priv->adapter;
- struct cmd_ctrl_node *cmd_node, *tmp_node;
- spinlock_t *scan_q_lock = &adapter->scan_pending_q_lock;
- unsigned long flags;
-
- if (adapter->surprise_removed)
- return;
-
- if (adapter->scan_delay_cnt == MWIFIEX_MAX_SCAN_DELAY_CNT ||
- !adapter->scan_processing) {
- /*
- * Abort scan operation by cancelling all pending scan
- * commands
- */
- spin_lock_irqsave(scan_q_lock, flags);
- list_for_each_entry_safe(cmd_node, tmp_node,
- &adapter->scan_pending_q, list) {
- list_del(&cmd_node->list);
- mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
- }
- spin_unlock_irqrestore(scan_q_lock, flags);
-
- spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
- adapter->scan_processing = false;
- adapter->scan_delay_cnt = 0;
- adapter->empty_tx_q_cnt = 0;
- spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
-
- if (priv->scan_request) {
- dev_dbg(adapter->dev, "info: aborting scan\n");
- cfg80211_scan_done(priv->scan_request, 1);
- priv->scan_request = NULL;
- } else {
- priv->scan_aborting = false;
- dev_dbg(adapter->dev, "info: scan already aborted\n");
- }
- goto done;
- }
-
- if (!atomic_read(&priv->adapter->is_tx_received)) {
- adapter->empty_tx_q_cnt++;
- if (adapter->empty_tx_q_cnt == MWIFIEX_MAX_EMPTY_TX_Q_CNT) {
- /*
- * No Tx traffic for 200msec. Get scan command from
- * scan pending queue and put to cmd pending queue to
- * resume scan operation
- */
- adapter->scan_delay_cnt = 0;
- adapter->empty_tx_q_cnt = 0;
- spin_lock_irqsave(scan_q_lock, flags);
-
- if (list_empty(&adapter->scan_pending_q)) {
- spin_unlock_irqrestore(scan_q_lock, flags);
- goto done;
- }
-
- cmd_node = list_first_entry(&adapter->scan_pending_q,
- struct cmd_ctrl_node, list);
- list_del(&cmd_node->list);
- spin_unlock_irqrestore(scan_q_lock, flags);
-
- mwifiex_insert_cmd_to_pending_q(adapter, cmd_node,
- true);
- queue_work(adapter->workqueue, &adapter->main_work);
- goto done;
- }
- } else {
- adapter->empty_tx_q_cnt = 0;
- }
-
- /* Delay scan operation further by 20msec */
- mod_timer(&priv->scan_delay_timer, jiffies +
- msecs_to_jiffies(MWIFIEX_SCAN_DELAY_MSEC));
- adapter->scan_delay_cnt++;
-
-done:
- if (atomic_read(&priv->adapter->is_tx_received))
- atomic_set(&priv->adapter->is_tx_received, false);
-
- return;
-}
-
/*
* This function registers the device and performs all the necessary
* initializations.
@@ -160,10 +75,6 @@ static int mwifiex_register(void *card, struct mwifiex_if_ops *if_ops,

adapter->priv[i]->adapter = adapter;
adapter->priv_num++;
-
- setup_timer(&adapter->priv[i]->scan_delay_timer,
- scan_delay_timer_fn,
- (unsigned long)adapter->priv[i]);
}
mwifiex_init_lock_list(adapter);

@@ -207,7 +118,6 @@ static int mwifiex_unregister(struct mwifiex_adapter *adapter)
for (i = 0; i < adapter->priv_num; i++) {
if (adapter->priv[i]) {
mwifiex_free_curr_bcn(adapter->priv[i]);
- del_timer_sync(&adapter->priv[i]->scan_delay_timer);
kfree(adapter->priv[i]);
}
}
@@ -596,9 +506,6 @@ int mwifiex_queue_tx_pkt(struct mwifiex_private *priv, struct sk_buff *skb)
atomic_inc(&priv->adapter->tx_pending);
mwifiex_wmm_add_buf_txqueue(priv, skb);

- if (priv->adapter->scan_delay_cnt)
- atomic_set(&priv->adapter->is_tx_received, true);
-
queue_work(priv->adapter->workqueue, &priv->adapter->main_work);

return 0;
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index 4e8e881..064612d 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -90,12 +90,6 @@ enum {

#define MWIFIEX_MAX_TOTAL_SCAN_TIME (MWIFIEX_TIMER_10S - MWIFIEX_TIMER_1S)

-#define MWIFIEX_MAX_SCAN_DELAY_CNT 50
-#define MWIFIEX_MAX_EMPTY_TX_Q_CNT 10
-#define MWIFIEX_SCAN_DELAY_MSEC 20
-
-#define MWIFIEX_MIN_TX_PENDING_TO_CANCEL_SCAN 2
-
#define RSN_GTK_OUI_OFFSET 2

#define MWIFIEX_OUI_NOT_PRESENT 0
@@ -561,7 +555,6 @@ struct mwifiex_private {
u16 proberesp_idx;
u16 assocresp_idx;
u16 rsn_idx;
- struct timer_list scan_delay_timer;
u8 ap_11n_enabled;
u8 ap_11ac_enabled;
u32 mgmt_frame_mask;
@@ -816,8 +809,6 @@ struct mwifiex_adapter {
spinlock_t queue_lock; /* lock for tx queues */
u8 country_code[IEEE80211_COUNTRY_STRING_LEN];
u16 max_mgmt_ie_index;
- u8 scan_delay_cnt;
- u8 empty_tx_q_cnt;
const struct firmware *cal_data;
struct device_node *dt_node;

@@ -829,7 +820,6 @@ struct mwifiex_adapter {
u32 usr_dot_11ac_dev_cap_a;
u32 usr_dot_11ac_mcs_support;

- atomic_t is_tx_received;
atomic_t pending_bridged_pkts;
struct semaphore *card_sem;
bool ext_scan;
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c
index 7b07da2..67f9cdb 100644
--- a/drivers/net/wireless/mwifiex/scan.c
+++ b/drivers/net/wireless/mwifiex/scan.c
@@ -1765,7 +1765,7 @@ static void mwifiex_complete_scan(struct mwifiex_private *priv)
static void mwifiex_check_next_scan_command(struct mwifiex_private *priv)
{
struct mwifiex_adapter *adapter = priv->adapter;
- struct cmd_ctrl_node *cmd_node;
+ struct cmd_ctrl_node *cmd_node, *tmp_node;
unsigned long flags;

spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
@@ -1786,37 +1786,36 @@ static void mwifiex_check_next_scan_command(struct mwifiex_private *priv)
priv->scan_aborting = false;
dev_dbg(adapter->dev, "info: scan already aborted\n");
}
- } else {
- if ((priv->scan_aborting && !priv->scan_request) ||
- priv->scan_block) {
- spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
- flags);
- adapter->scan_delay_cnt = MWIFIEX_MAX_SCAN_DELAY_CNT;
- mod_timer(&priv->scan_delay_timer, jiffies);
- dev_dbg(priv->adapter->dev,
- "info: %s: triggerring scan abort\n", __func__);
- } else if (!mwifiex_wmm_lists_empty(adapter) &&
- (priv->scan_request && (priv->scan_request->flags &
- NL80211_SCAN_FLAG_LOW_PRIORITY))) {
- spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
- flags);
- adapter->scan_delay_cnt = 1;
- mod_timer(&priv->scan_delay_timer, jiffies +
- msecs_to_jiffies(MWIFIEX_SCAN_DELAY_MSEC));
- dev_dbg(priv->adapter->dev,
- "info: %s: deferring scan\n", __func__);
- } else {
- /* Get scan command from scan_pending_q and put to
- * cmd_pending_q
- */
- cmd_node = list_first_entry(&adapter->scan_pending_q,
- struct cmd_ctrl_node, list);
+ } else if ((priv->scan_aborting && !priv->scan_request) ||
+ priv->scan_block) {
+ list_for_each_entry_safe(cmd_node, tmp_node,
+ &adapter->scan_pending_q, list) {
list_del(&cmd_node->list);
- spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
- flags);
- mwifiex_insert_cmd_to_pending_q(adapter, cmd_node,
- true);
+ mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
+ }
+ spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
+
+ spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
+ adapter->scan_processing = false;
+ spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
+
+ if (priv->scan_request) {
+ dev_dbg(adapter->dev, "info: aborting scan\n");
+ cfg80211_scan_done(priv->scan_request, 1);
+ priv->scan_request = NULL;
+ } else {
+ priv->scan_aborting = false;
+ dev_dbg(adapter->dev, "info: scan already aborted\n");
}
+ } else {
+ /* Get scan command from scan_pending_q and put to
+ * cmd_pending_q
+ */
+ cmd_node = list_first_entry(&adapter->scan_pending_q,
+ struct cmd_ctrl_node, list);
+ list_del(&cmd_node->list);
+ spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
+ mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, true);
}

return;
--
1.8.1.4


2014-09-04 03:56:24

by James Cameron

[permalink] [raw]
Subject: Re: [PATCH 17/17] mwifiex: add rx workqueue support

On Mon, Sep 01, 2014 at 06:29:05PM +0530, Avinash Patil wrote:
> This patch adds RX work queue support to mwifiex.
> Packets received are queued to internal queue which are then
> processed by scheduling a work item for RX process.
>
> RX work is enabled only on SMP systems.
>
> Signed-off-by: Avinash Patil <[email protected]>
> Signed-off-by: Marc Yang <[email protected]>
> Signed-off-by: Cathy Luo <[email protected]>
> ---
> drivers/net/wireless/mwifiex/11n_rxreorder.c | 14 ++++
> drivers/net/wireless/mwifiex/init.c | 19 ++++++
> drivers/net/wireless/mwifiex/main.c | 95 ++++++++++++++++++++++++++++
> drivers/net/wireless/mwifiex/main.h | 14 ++++
> drivers/net/wireless/mwifiex/pcie.c | 12 +++-
> drivers/net/wireless/mwifiex/sdio.c | 11 +++-
> 6 files changed, 163 insertions(+), 2 deletions(-)
>
> [...]
> diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
> index fb38d81..2ed59a0 100644
> --- a/drivers/net/wireless/mwifiex/main.c
> +++ b/drivers/net/wireless/mwifiex/main.c
> [...]
> @@ -784,6 +858,15 @@ mwifiex_add_card(void *card, struct semaphore *sem,
> adapter->cmd_wait_q.status = 0;
> adapter->scan_wait_q_woken = false;
>
> + if (num_possible_cpus() > 1) {
> + adapter->rx_work_enabled = true;
> + pr_debug("info: %s rx work enabled, cpus %d :\n", __func__,
> + num_possible_cpus());
> + /*to ensure this is seen in dmesg logs*/
> + pr_err("info: %s rx work enabled, cpus %d :\n", __func__,
> + num_possible_cpus());

Either pr_debug or pr_err, but not both.

(Would love to test, but stuck on 3.5, and don't know how to
backport mwifiex.)

--
James Cameron
http://quozl.linux.org.au/

2014-09-01 07:32:10

by Avinash Patil

[permalink] [raw]
Subject: [PATCH 15/17] mwifiex: remove redundant variable report_scan_result

From: Amitkumar Karwar <[email protected]>

This variable is never used, get rid of it.

Signed-off-by: Amitkumar Karwar <[email protected]>
Signed-off-by: Avinash Patil <[email protected]>
---
drivers/net/wireless/mwifiex/main.h | 1 -
drivers/net/wireless/mwifiex/scan.c | 3 ---
drivers/net/wireless/mwifiex/sta_cmdresp.c | 2 --
3 files changed, 6 deletions(-)

diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index 18c327c..4e8e881 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -548,7 +548,6 @@ struct mwifiex_private {
u8 nick_name[16];
u16 current_key_index;
struct semaphore async_sem;
- u8 report_scan_result;
struct cfg80211_scan_request *scan_request;
u8 cfg_bssid[6];
struct wps wps;
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c
index 7c85f61..7b07da2 100644
--- a/drivers/net/wireless/mwifiex/scan.c
+++ b/drivers/net/wireless/mwifiex/scan.c
@@ -1778,9 +1778,6 @@ static void mwifiex_check_next_scan_command(struct mwifiex_private *priv)
if (!adapter->ext_scan)
mwifiex_complete_scan(priv);

- if (priv->report_scan_result)
- priv->report_scan_result = false;
-
if (priv->scan_request) {
dev_dbg(adapter->dev, "info: notifying scan done\n");
cfg80211_scan_done(priv->scan_request, 0);
diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c
index 62866b0..4aad446 100644
--- a/drivers/net/wireless/mwifiex/sta_cmdresp.c
+++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c
@@ -85,8 +85,6 @@ mwifiex_process_cmdresp_error(struct mwifiex_private *priv,
spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
adapter->scan_processing = false;
spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
- if (priv->report_scan_result)
- priv->report_scan_result = false;
break;

case HostCmd_CMD_MAC_CONTROL:
--
1.8.1.4


2014-09-01 07:32:21

by Avinash Patil

[permalink] [raw]
Subject: [PATCH 17/17] mwifiex: add rx workqueue support

This patch adds RX work queue support to mwifiex.
Packets received are queued to internal queue which are then
processed by scheduling a work item for RX process.

RX work is enabled only on SMP systems.

Signed-off-by: Avinash Patil <[email protected]>
Signed-off-by: Marc Yang <[email protected]>
Signed-off-by: Cathy Luo <[email protected]>
---
drivers/net/wireless/mwifiex/11n_rxreorder.c | 14 ++++
drivers/net/wireless/mwifiex/init.c | 19 ++++++
drivers/net/wireless/mwifiex/main.c | 95 ++++++++++++++++++++++++++++
drivers/net/wireless/mwifiex/main.h | 14 ++++
drivers/net/wireless/mwifiex/pcie.c | 12 +++-
drivers/net/wireless/mwifiex/sdio.c | 11 +++-
6 files changed, 163 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.c b/drivers/net/wireless/mwifiex/11n_rxreorder.c
index 06a2c21..4005707 100644
--- a/drivers/net/wireless/mwifiex/11n_rxreorder.c
+++ b/drivers/net/wireless/mwifiex/11n_rxreorder.c
@@ -183,6 +183,15 @@ mwifiex_del_rx_reorder_entry(struct mwifiex_private *priv,
if (!tbl)
return;

+ spin_lock_irqsave(&priv->adapter->rx_proc_lock, flags);
+ priv->adapter->rx_locked = true;
+ if (priv->adapter->rx_processing) {
+ spin_unlock_irqrestore(&priv->adapter->rx_proc_lock, flags);
+ flush_workqueue(priv->adapter->rx_workqueue);
+ } else {
+ spin_unlock_irqrestore(&priv->adapter->rx_proc_lock, flags);
+ }
+
start_win = (tbl->start_win + tbl->win_size) & (MAX_TID_VALUE - 1);
mwifiex_11n_dispatch_pkt_until_start_win(priv, tbl, start_win);

@@ -194,6 +203,11 @@ mwifiex_del_rx_reorder_entry(struct mwifiex_private *priv,

kfree(tbl->rx_reorder_ptr);
kfree(tbl);
+
+ spin_lock_irqsave(&priv->adapter->rx_proc_lock, flags);
+ priv->adapter->rx_locked = false;
+ spin_unlock_irqrestore(&priv->adapter->rx_proc_lock, flags);
+
}

/*
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c
index cd9baad..f7c97cf 100644
--- a/drivers/net/wireless/mwifiex/init.c
+++ b/drivers/net/wireless/mwifiex/init.c
@@ -447,8 +447,11 @@ int mwifiex_init_lock_list(struct mwifiex_adapter *adapter)
spin_lock_init(&adapter->cmd_free_q_lock);
spin_lock_init(&adapter->cmd_pending_q_lock);
spin_lock_init(&adapter->scan_pending_q_lock);
+ spin_lock_init(&adapter->rx_q_lock);
+ spin_lock_init(&adapter->rx_proc_lock);

skb_queue_head_init(&adapter->usb_rx_data_q);
+ skb_queue_head_init(&adapter->rx_data_q);

for (i = 0; i < adapter->priv_num; ++i) {
INIT_LIST_HEAD(&adapter->bss_prio_tbl[i].bss_prio_head);
@@ -614,6 +617,7 @@ mwifiex_shutdown_drv(struct mwifiex_adapter *adapter)
int ret = -EINPROGRESS;
struct mwifiex_private *priv;
s32 i;
+ unsigned long flags;
struct sk_buff *skb;

/* mwifiex already shutdown */
@@ -648,6 +652,21 @@ mwifiex_shutdown_drv(struct mwifiex_adapter *adapter)
}
}

+ spin_lock_irqsave(&adapter->rx_proc_lock, flags);
+
+ while ((skb = skb_dequeue(&adapter->rx_data_q))) {
+ struct mwifiex_rxinfo *rx_info = MWIFIEX_SKB_RXCB(skb);
+
+ atomic_dec(&adapter->rx_pending);
+ priv = adapter->priv[rx_info->bss_num];
+ if (priv)
+ priv->stats.rx_dropped++;
+
+ dev_kfree_skb_any(skb);
+ }
+
+ spin_unlock_irqrestore(&adapter->rx_proc_lock, flags);
+
spin_lock(&adapter->mwifiex_lock);

if (adapter->if_ops.data_complete) {
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index fb38d81..2ed59a0 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -126,6 +126,42 @@ static int mwifiex_unregister(struct mwifiex_adapter *adapter)
return 0;
}

+static int mwifiex_process_rx(struct mwifiex_adapter *adapter)
+{
+ unsigned long flags;
+ struct sk_buff *skb;
+ bool delay_main_work = adapter->delay_main_work;
+
+ spin_lock_irqsave(&adapter->rx_proc_lock, flags);
+ if (adapter->rx_processing || adapter->rx_locked) {
+ spin_unlock_irqrestore(&adapter->rx_proc_lock, flags);
+ goto exit_rx_proc;
+ } else {
+ adapter->rx_processing = true;
+ spin_unlock_irqrestore(&adapter->rx_proc_lock, flags);
+ }
+
+ /* Check for Rx data */
+ while ((skb = skb_dequeue(&adapter->rx_data_q))) {
+ atomic_dec(&adapter->rx_pending);
+ if (adapter->delay_main_work &&
+ (atomic_dec_return(&adapter->rx_pending) <
+ LOW_RX_PENDING)) {
+ adapter->delay_main_work = false;
+ queue_work(adapter->rx_workqueue, &adapter->rx_work);
+ }
+ mwifiex_handle_rx_packet(adapter, skb);
+ }
+ spin_lock_irqsave(&adapter->rx_proc_lock, flags);
+ adapter->rx_processing = false;
+ spin_unlock_irqrestore(&adapter->rx_proc_lock, flags);
+
+ if (delay_main_work)
+ queue_work(adapter->workqueue, &adapter->main_work);
+exit_rx_proc:
+ return 0;
+}
+
/*
* The main process.
*
@@ -163,6 +199,19 @@ process_start:
(adapter->hw_status == MWIFIEX_HW_STATUS_NOT_READY))
break;

+ /* If we process interrupts first, it would increase RX pending
+ * even further. Avoid this by checking if rx_pending has
+ * crossed high threshold and schedule rx work queue
+ * and then process interrupts
+ */
+ if (atomic_read(&adapter->rx_pending) >= HIGH_RX_PENDING) {
+ adapter->delay_main_work = true;
+ if (!adapter->rx_processing)
+ queue_work(adapter->rx_workqueue,
+ &adapter->rx_work);
+ break;
+ }
+
/* Handle pending interrupt if any */
if (adapter->int_status) {
if (adapter->hs_activated)
@@ -171,6 +220,9 @@ process_start:
adapter->if_ops.process_int_status(adapter);
}

+ if (adapter->rx_work_enabled && adapter->data_received)
+ queue_work(adapter->rx_workqueue, &adapter->rx_work);
+
/* Need to wake up the card ? */
if ((adapter->ps_state == PS_STATE_SLEEP) &&
(adapter->pm_wakeup_card_req &&
@@ -183,6 +235,7 @@ process_start:
}

if (IS_CARD_RX_RCVD(adapter)) {
+ adapter->data_received = false;
adapter->pm_wakeup_fw_try = false;
if (adapter->ps_state == PS_STATE_SLEEP)
adapter->ps_state = PS_STATE_AWAKE;
@@ -315,6 +368,12 @@ static void mwifiex_terminate_workqueue(struct mwifiex_adapter *adapter)
flush_workqueue(adapter->workqueue);
destroy_workqueue(adapter->workqueue);
adapter->workqueue = NULL;
+
+ if (adapter->rx_workqueue) {
+ flush_workqueue(adapter->rx_workqueue);
+ destroy_workqueue(adapter->rx_workqueue);
+ adapter->rx_workqueue = NULL;
+ }
}

/*
@@ -729,6 +788,21 @@ int is_command_pending(struct mwifiex_adapter *adapter)
}

/*
+ * This is the RX work queue function.
+ *
+ * It handles the RX operations.
+ */
+static void mwifiex_rx_work_queue(struct work_struct *work)
+{
+ struct mwifiex_adapter *adapter =
+ container_of(work, struct mwifiex_adapter, rx_work);
+
+ if (adapter->surprise_removed)
+ return;
+ mwifiex_process_rx(adapter);
+}
+
+/*
* This is the main work queue function.
*
* It handles the main process, which in turn handles the complete
@@ -784,6 +858,15 @@ mwifiex_add_card(void *card, struct semaphore *sem,
adapter->cmd_wait_q.status = 0;
adapter->scan_wait_q_woken = false;

+ if (num_possible_cpus() > 1) {
+ adapter->rx_work_enabled = true;
+ pr_debug("info: %s rx work enabled, cpus %d :\n", __func__,
+ num_possible_cpus());
+ /*to ensure this is seen in dmesg logs*/
+ pr_err("info: %s rx work enabled, cpus %d :\n", __func__,
+ num_possible_cpus());
+ }
+
adapter->workqueue =
alloc_workqueue("MWIFIEX_WORK_QUEUE",
WQ_HIGHPRI | WQ_MEM_RECLAIM | WQ_UNBOUND, 1);
@@ -791,6 +874,18 @@ mwifiex_add_card(void *card, struct semaphore *sem,
goto err_kmalloc;

INIT_WORK(&adapter->main_work, mwifiex_main_work_queue);
+
+ if (adapter->rx_work_enabled) {
+ adapter->rx_workqueue = alloc_workqueue("MWIFIEX_RX_WORK_QUEUE",
+ WQ_HIGHPRI |
+ WQ_MEM_RECLAIM |
+ WQ_UNBOUND, 1);
+ if (!adapter->rx_workqueue)
+ goto err_kmalloc;
+
+ INIT_WORK(&adapter->rx_work, mwifiex_rx_work_queue);
+ }
+
if (adapter->if_ops.iface_work)
INIT_WORK(&adapter->iface_work, adapter->if_ops.iface_work);

diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index 064612d..c6c229e 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -58,6 +58,9 @@ enum {
#define MAX_TX_PENDING 100
#define LOW_TX_PENDING 80

+#define HIGH_RX_PENDING 50
+#define LOW_RX_PENDING 20
+
#define MWIFIEX_UPLD_SIZE (2312)

#define MAX_EVENT_SIZE 2048
@@ -714,6 +717,12 @@ struct mwifiex_adapter {
atomic_t cmd_pending;
struct workqueue_struct *workqueue;
struct work_struct main_work;
+ struct workqueue_struct *rx_workqueue;
+ struct work_struct rx_work;
+ bool rx_work_enabled;
+ bool rx_processing;
+ bool delay_main_work;
+ bool rx_locked;
struct mwifiex_bss_prio_tbl bss_prio_tbl[MWIFIEX_MAX_BSS_NUM];
/* spin lock for init/shutdown */
spinlock_t mwifiex_lock;
@@ -754,6 +763,10 @@ struct mwifiex_adapter {
struct list_head scan_pending_q;
/* spin lock for scan_pending_q */
spinlock_t scan_pending_q_lock;
+ /* spin lock for RX queue */
+ spinlock_t rx_q_lock;
+ /* spin lock for RX processing routine */
+ spinlock_t rx_proc_lock;
struct sk_buff_head usb_rx_data_q;
u32 scan_processing;
u16 region_code;
@@ -830,6 +843,7 @@ struct mwifiex_adapter {
struct memory_type_mapping *mem_type_mapping_tbl;
u8 num_mem_types;
u8 curr_mem_idx;
+ struct sk_buff_head rx_data_q;
};

int mwifiex_init_lock_list(struct mwifiex_adapter *adapter);
diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c
index 2ada1b7..1504b16 100644
--- a/drivers/net/wireless/mwifiex/pcie.c
+++ b/drivers/net/wireless/mwifiex/pcie.c
@@ -1233,6 +1233,7 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter)
struct sk_buff *skb_tmp = NULL;
struct mwifiex_pcie_buf_desc *desc;
struct mwifiex_pfu_buf_desc *desc2;
+ unsigned long flags;

if (!mwifiex_pcie_ok_to_access_hw(adapter))
mwifiex_pm_wakeup_card(adapter);
@@ -1283,7 +1284,16 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter)
"info: RECV DATA: Rd=%#x, Wr=%#x, Len=%d\n",
card->rxbd_rdptr, wrptr, rx_len);
skb_pull(skb_data, INTF_HEADER_LEN);
- mwifiex_handle_rx_packet(adapter, skb_data);
+ if (adapter->rx_work_enabled) {
+ spin_lock_irqsave(&adapter->rx_q_lock, flags);
+ skb_queue_tail(&adapter->rx_data_q, skb_data);
+ spin_unlock_irqrestore(&adapter->rx_q_lock,
+ flags);
+ adapter->data_received = true;
+ atomic_inc(&adapter->rx_pending);
+ } else {
+ mwifiex_handle_rx_packet(adapter, skb_data);
+ }
}

skb_tmp = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE);
diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c
index bdab122..ea8fc58 100644
--- a/drivers/net/wireless/mwifiex/sdio.c
+++ b/drivers/net/wireless/mwifiex/sdio.c
@@ -1039,6 +1039,7 @@ static int mwifiex_decode_rx_packet(struct mwifiex_adapter *adapter,
struct sk_buff *skb, u32 upld_typ)
{
u8 *cmd_buf;
+ unsigned long flags;
__le16 *curr_ptr = (__le16 *)skb->data;
u16 pkt_len = le16_to_cpu(*curr_ptr);

@@ -1048,7 +1049,15 @@ static int mwifiex_decode_rx_packet(struct mwifiex_adapter *adapter,
switch (upld_typ) {
case MWIFIEX_TYPE_DATA:
dev_dbg(adapter->dev, "info: --- Rx: Data packet ---\n");
- mwifiex_handle_rx_packet(adapter, skb);
+ if (adapter->rx_work_enabled) {
+ spin_lock_irqsave(&adapter->rx_q_lock, flags);
+ skb_queue_tail(&adapter->rx_data_q, skb);
+ spin_unlock_irqrestore(&adapter->rx_q_lock, flags);
+ adapter->data_received = true;
+ atomic_inc(&adapter->rx_pending);
+ } else {
+ mwifiex_handle_rx_packet(adapter, skb);
+ }
break;

case MWIFIEX_TYPE_CMD:
--
1.8.1.4


2014-09-01 07:31:04

by Avinash Patil

[permalink] [raw]
Subject: [PATCH 02/17] mwifiex: avoid processing RX packets with invalid length

If rx_len received in interface header from FW is more than
RX buffer size, skb_put for such length results into skb_panic.
Avoid this by not processing such packets. We just print a warning
for such packets and free skb.

Reviewed-by: Paul Stewart <[email protected]>
Signed-off-by: Avinash Patil <[email protected]>
Signed-off-by: Amitkumar Karwar <[email protected]>
Signed-off-by: Bing Zhao <[email protected]>
Signed-off-by: Marc Yang <[email protected]>
---
drivers/net/wireless/mwifiex/pcie.c | 20 ++++++++++++++------
1 file changed, 14 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c
index ff05458..27c2bf8 100644
--- a/drivers/net/wireless/mwifiex/pcie.c
+++ b/drivers/net/wireless/mwifiex/pcie.c
@@ -1271,12 +1271,20 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter)
*/
pkt_len = *((__le16 *)skb_data->data);
rx_len = le16_to_cpu(pkt_len);
- skb_put(skb_data, rx_len);
- dev_dbg(adapter->dev,
- "info: RECV DATA: Rd=%#x, Wr=%#x, Len=%d\n",
- card->rxbd_rdptr, wrptr, rx_len);
- skb_pull(skb_data, INTF_HEADER_LEN);
- mwifiex_handle_rx_packet(adapter, skb_data);
+ if (WARN_ON(rx_len <= INTF_HEADER_LEN ||
+ rx_len > MWIFIEX_RX_DATA_BUF_SIZE)) {
+ dev_err(adapter->dev,
+ "Invalid RX len %d, Rd=%#x, Wr=%#x\n",
+ rx_len, card->rxbd_rdptr, wrptr);
+ dev_kfree_skb_any(skb_data);
+ } else {
+ skb_put(skb_data, rx_len);
+ dev_dbg(adapter->dev,
+ "info: RECV DATA: Rd=%#x, Wr=%#x, Len=%d\n",
+ card->rxbd_rdptr, wrptr, rx_len);
+ skb_pull(skb_data, INTF_HEADER_LEN);
+ mwifiex_handle_rx_packet(adapter, skb_data);
+ }

skb_tmp = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE);
if (!skb_tmp) {
--
1.8.1.4


2014-09-01 07:31:11

by Avinash Patil

[permalink] [raw]
Subject: [PATCH 04/17] mwifiex: support for event done interrupt

This patch adds support for writing CPU event interrupt done back
to device.
Patch also increases interrupt buffer ring size from 4 to 8.

Signed-off-by: Avinash Patil <[email protected]>
Signed-off-by: Cathy Luo <[email protected]>
---
drivers/net/wireless/mwifiex/pcie.c | 7 +++++++
drivers/net/wireless/mwifiex/pcie.h | 5 +++--
2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c
index 27c2bf8..2ada1b7 100644
--- a/drivers/net/wireless/mwifiex/pcie.c
+++ b/drivers/net/wireless/mwifiex/pcie.c
@@ -1726,6 +1726,13 @@ static int mwifiex_pcie_process_event_ready(struct mwifiex_adapter *adapter)
buffer is released. This is just to make things simpler,
we need to find a better method of managing these buffers.
*/
+ } else {
+ if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
+ CPU_INTR_EVENT_DONE)) {
+ dev_warn(adapter->dev,
+ "Write register failed\n");
+ return -1;
+ }
}

return 0;
diff --git a/drivers/net/wireless/mwifiex/pcie.h b/drivers/net/wireless/mwifiex/pcie.h
index a1a8fd3..200e8b0 100644
--- a/drivers/net/wireless/mwifiex/pcie.h
+++ b/drivers/net/wireless/mwifiex/pcie.h
@@ -40,8 +40,8 @@
#define MWIFIEX_TXBD_MASK 0x3F
#define MWIFIEX_RXBD_MASK 0x3F

-#define MWIFIEX_MAX_EVT_BD 0x04
-#define MWIFIEX_EVTBD_MASK 0x07
+#define MWIFIEX_MAX_EVT_BD 0x08
+#define MWIFIEX_EVTBD_MASK 0x0f

/* PCIE INTERNAL REGISTERS */
#define PCIE_SCRATCH_0_REG 0xC10
@@ -69,6 +69,7 @@
#define CPU_INTR_DOOR_BELL BIT(1)
#define CPU_INTR_SLEEP_CFM_DONE BIT(2)
#define CPU_INTR_RESET BIT(3)
+#define CPU_INTR_EVENT_DONE BIT(5)

#define HOST_INTR_DNLD_DONE BIT(0)
#define HOST_INTR_UPLD_RDY BIT(1)
--
1.8.1.4


2014-09-01 07:31:04

by Avinash Patil

[permalink] [raw]
Subject: [PATCH 03/17] mwifiex: rework internal scan for association

There was an issue with internal scan during association wherein
we would complete internal scan on first scan command response.
This would cause association failure if AP is not found in first scan
response e.g. APs from A band.
This patch fixes this issue by completing internal scan only when all
scan commands from scan pending queue and command pending queue are
sent to FW and response to last scan command is received.

Tested-by: Xinmin Hu <[email protected]>
Signed-off-by: Avinash Patil <[email protected]>
Signed-off-by: Amitkumar Karwar <[email protected]>
Signed-off-by: Marc Yang <[email protected]>
Signed-off-by: Cathy Luo <[email protected]>
---
drivers/net/wireless/mwifiex/scan.c | 27 ++++++++++++++++++++++++++-
1 file changed, 26 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c
index dee717a..bec48cc 100644
--- a/drivers/net/wireless/mwifiex/scan.c
+++ b/drivers/net/wireless/mwifiex/scan.c
@@ -1970,9 +1970,34 @@ int mwifiex_cmd_802_11_scan_ext(struct mwifiex_private *priv,
/* This function handles the command response of extended scan */
int mwifiex_ret_802_11_scan_ext(struct mwifiex_private *priv)
{
+ struct mwifiex_adapter *adapter = priv->adapter;
+ struct host_cmd_ds_command *cmd_ptr;
+ struct cmd_ctrl_node *cmd_node;
+ unsigned long cmd_flags, scan_flags;
+ bool complete_scan = false;
+
dev_dbg(priv->adapter->dev, "info: EXT scan returns successfully\n");

- mwifiex_complete_scan(priv);
+ spin_lock_irqsave(&adapter->cmd_pending_q_lock, cmd_flags);
+ spin_lock_irqsave(&adapter->scan_pending_q_lock, scan_flags);
+ if (list_empty(&adapter->scan_pending_q)) {
+ complete_scan = true;
+ list_for_each_entry(cmd_node, &adapter->cmd_pending_q, list) {
+ cmd_ptr = (void *)cmd_node->cmd_skb->data;
+ if (le16_to_cpu(cmd_ptr->command) ==
+ HostCmd_CMD_802_11_SCAN_EXT) {
+ dev_dbg(priv->adapter->dev,
+ "Scan pending in command pending list");
+ complete_scan = false;
+ break;
+ }
+ }
+ }
+ spin_unlock_irqrestore(&adapter->scan_pending_q_lock, scan_flags);
+ spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, cmd_flags);
+
+ if (complete_scan)
+ mwifiex_complete_scan(priv);

return 0;
}
--
1.8.1.4


2014-09-01 07:31:42

by Avinash Patil

[permalink] [raw]
Subject: [PATCH 08/17] mwifiex: fix left_len calculation issue

From: Amitkumar Karwar <[email protected]>

While updating 'left_len' in each iteration, we should subtract
last TLV length not the accumulated length of TLVs parsed till
now.
This bug in parsing logic is exposed by newer firmware which adds
two TLVs in GET_HW_SPEC command response. Earlier firmwares used to
add only one TLV.

Signed-off-by: Amitkumar Karwar <[email protected]>
Signed-off-by: Avinash Patil <[email protected]>
Signed-off-by: Cathy Luo <[email protected]>
---
drivers/net/wireless/mwifiex/cmdevt.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c
index baf0aab..0c21239 100644
--- a/drivers/net/wireless/mwifiex/cmdevt.c
+++ b/drivers/net/wireless/mwifiex/cmdevt.c
@@ -1567,7 +1567,8 @@ int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv,
}
parsed_len += le16_to_cpu(tlv->len) +
sizeof(struct mwifiex_ie_types_header);
- left_len -= parsed_len;
+ left_len -= le16_to_cpu(tlv->len) +
+ sizeof(struct mwifiex_ie_types_header);
}
}

--
1.8.1.4


2014-09-01 07:31:40

by Avinash Patil

[permalink] [raw]
Subject: [PATCH 11/17] mwifiex: set passive scan type for scan requests with no ssid

It was observed that station would sent probe request even when
scan type has been set as passive during iw scan.
This was happening because driver sets passive scan type only
when channel has IEEE80211_CHAN_NO_IR flag set.
Along with this, add condition to check if no ssids are specified in
scan request so as to mark such scan request passive.

Signed-off-by: Avinash Patil <[email protected]>
---
drivers/net/wireless/mwifiex/cfg80211.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index e2e6bf1..320512f 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -1980,7 +1980,7 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy,
user_scan_cfg->chan_list[i].chan_number = chan->hw_value;
user_scan_cfg->chan_list[i].radio_type = chan->band;

- if (chan->flags & IEEE80211_CHAN_NO_IR)
+ if ((chan->flags & IEEE80211_CHAN_NO_IR) || !request->n_ssids)
user_scan_cfg->chan_list[i].scan_type =
MWIFIEX_SCAN_TYPE_PASSIVE;
else
--
1.8.1.4


2014-09-01 07:31:47

by Avinash Patil

[permalink] [raw]
Subject: [PATCH 12/17] mwifiex: bring in scan channel gap feature

With scan channel gap when any station/AP is active, FW comes back
to connected channel for any pending data transfter after scanning each
channel.
We set scan channel gap TLV to FW in scan command when any of the
interface is active. This enables scan channel gap in FW.
Also when scan channel gap is enabled, we would scan maximum channels
allowed by FW.

Signed-off-by: Avinash Patil <[email protected]>
Signed-off-by: Amitkumar Karwar <[email protected]>
Signed-off-by: Marc Yang <[email protected]>
Signed-off-by: Cathy Luo <[email protected]>
---
drivers/net/wireless/mwifiex/cfg80211.c | 4 ++++
drivers/net/wireless/mwifiex/fw.h | 10 +++++++++-
drivers/net/wireless/mwifiex/init.c | 1 +
drivers/net/wireless/mwifiex/main.h | 22 ++++++++++++++++++++++
drivers/net/wireless/mwifiex/scan.c | 17 +++++++++++++++++
5 files changed, 53 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index 320512f..654fc27 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -1990,6 +1990,10 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy,
user_scan_cfg->chan_list[i].scan_time = 0;
}

+ if (mwifiex_is_any_intf_active(priv))
+ user_scan_cfg->scan_chan_gap =
+ priv->adapter->scan_chan_gap_time;
+
ret = mwifiex_scan_networks(priv, user_scan_cfg);
kfree(user_scan_cfg);
if (ret) {
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h
index 6a703ea..1eb6173 100644
--- a/drivers/net/wireless/mwifiex/fw.h
+++ b/drivers/net/wireless/mwifiex/fw.h
@@ -170,7 +170,8 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
#define TLV_TYPE_COALESCE_RULE (PROPRIETARY_TLV_BASE_ID + 154)
#define TLV_TYPE_KEY_PARAM_V2 (PROPRIETARY_TLV_BASE_ID + 156)
#define TLV_TYPE_TDLS_IDLE_TIMEOUT (PROPRIETARY_TLV_BASE_ID + 194)
-#define TLV_TYPE_API_REV (PROPRIETARY_TLV_BASE_ID + 199)
+#define TLV_TYPE_SCAN_CHANNEL_GAP (PROPRIETARY_TLV_BASE_ID + 197)
+#define TLV_TYPE_API_REV (PROPRIETARY_TLV_BASE_ID + 199)

#define MWIFIEX_TX_DATA_BUF_SIZE_2K 2048

@@ -653,6 +654,12 @@ struct mwifiex_ie_types_num_probes {
__le16 num_probes;
} __packed;

+struct mwifiex_ie_types_scan_chan_gap {
+ struct mwifiex_ie_types_header header;
+ /* time gap in TUs to be used between two consecutive channels scan */
+ __le16 chan_gap;
+} __packed;
+
struct mwifiex_ie_types_wildcard_ssid_params {
struct mwifiex_ie_types_header header;
u8 max_ssid_length;
@@ -1249,6 +1256,7 @@ struct mwifiex_user_scan_cfg {
u8 num_ssids;
/* Variable number (fixed maximum) of channels to scan up */
struct mwifiex_user_scan_chan chan_list[MWIFIEX_USER_SCAN_CHAN_MAX];
+ u16 scan_chan_gap;
} __packed;

struct ie_body {
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c
index 80bda80..d99c6f6 100644
--- a/drivers/net/wireless/mwifiex/init.c
+++ b/drivers/net/wireless/mwifiex/init.c
@@ -212,6 +212,7 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter)
adapter->specific_scan_time = MWIFIEX_SPECIFIC_SCAN_CHAN_TIME;
adapter->active_scan_time = MWIFIEX_ACTIVE_SCAN_CHAN_TIME;
adapter->passive_scan_time = MWIFIEX_PASSIVE_SCAN_CHAN_TIME;
+ adapter->scan_chan_gap_time = MWIFIEX_DEF_SCAN_CHAN_GAP_TIME;

adapter->scan_probes = 1;

diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index 5439963..18c327c 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -84,6 +84,7 @@ enum {
#define MWIFIEX_PASSIVE_SCAN_CHAN_TIME 110
#define MWIFIEX_ACTIVE_SCAN_CHAN_TIME 30
#define MWIFIEX_SPECIFIC_SCAN_CHAN_TIME 30
+#define MWIFIEX_DEF_SCAN_CHAN_GAP_TIME 50

#define SCAN_RSSI(RSSI) (0x100 - ((u8)(RSSI)))

@@ -770,6 +771,7 @@ struct mwifiex_adapter {
u16 specific_scan_time;
u16 active_scan_time;
u16 passive_scan_time;
+ u16 scan_chan_gap_time;
u8 fw_bands;
u8 adhoc_start_band;
u8 config_bands;
@@ -1139,6 +1141,25 @@ mwifiex_11h_get_csa_closed_channel(struct mwifiex_private *priv)
return priv->csa_chan;
}

+static inline u8 mwifiex_is_any_intf_active(struct mwifiex_private *priv)
+{
+ struct mwifiex_private *priv_num;
+ int i;
+
+ for (i = 0; i < priv->adapter->priv_num; i++) {
+ priv_num = priv->adapter->priv[i];
+ if (priv_num) {
+ if ((GET_BSS_ROLE(priv_num) == MWIFIEX_BSS_ROLE_UAP &&
+ priv_num->bss_started) ||
+ (GET_BSS_ROLE(priv_num) == MWIFIEX_BSS_ROLE_STA &&
+ priv_num->media_connected))
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
int mwifiex_init_shutdown_fw(struct mwifiex_private *priv,
u32 func_init_shutdown);
int mwifiex_add_card(void *, struct semaphore *, struct mwifiex_if_ops *, u8);
@@ -1274,6 +1295,7 @@ void mwifiex_disable_all_tdls_links(struct mwifiex_private *priv);
bool mwifiex_is_bss_in_11ac_mode(struct mwifiex_private *priv);
u8 mwifiex_get_center_freq_index(struct mwifiex_private *priv, u8 band,
u32 pri_chan, u8 chan_bw);
+int mwifiex_init_channel_scan_gap(struct mwifiex_adapter *adapter);

#ifdef CONFIG_DEBUG_FS
void mwifiex_debugfs_init(void);
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c
index bec48cc..6fd69af 100644
--- a/drivers/net/wireless/mwifiex/scan.c
+++ b/drivers/net/wireless/mwifiex/scan.c
@@ -799,6 +799,7 @@ mwifiex_config_scan(struct mwifiex_private *priv,
{
struct mwifiex_adapter *adapter = priv->adapter;
struct mwifiex_ie_types_num_probes *num_probes_tlv;
+ struct mwifiex_ie_types_scan_chan_gap *chan_gap_tlv;
struct mwifiex_ie_types_wildcard_ssid_params *wildcard_ssid_tlv;
struct mwifiex_ie_types_bssid_list *bssid_tlv;
u8 *tlv_pos;
@@ -939,6 +940,22 @@ mwifiex_config_scan(struct mwifiex_private *priv,
else
*max_chan_per_scan = MWIFIEX_DEF_CHANNELS_PER_SCAN_CMD;

+ if (user_scan_in->scan_chan_gap) {
+ *max_chan_per_scan = MWIFIEX_MAX_CHANNELS_PER_SPECIFIC_SCAN;
+ dev_dbg(adapter->dev, "info: scan: channel gap = %d\n",
+ user_scan_in->scan_chan_gap);
+
+ chan_gap_tlv = (void *)tlv_pos;
+ chan_gap_tlv->header.type =
+ cpu_to_le16(TLV_TYPE_SCAN_CHANNEL_GAP);
+ chan_gap_tlv->header.len =
+ cpu_to_le16(sizeof(chan_gap_tlv->chan_gap));
+ chan_gap_tlv->chan_gap =
+ cpu_to_le16((user_scan_in->scan_chan_gap));
+
+ tlv_pos += sizeof(struct mwifiex_ie_types_scan_chan_gap);
+ }
+
/* If the input config or adapter has the number of Probes set,
add tlv */
if (num_probes) {
--
1.8.1.4


2014-09-01 07:31:58

by Avinash Patil

[permalink] [raw]
Subject: [PATCH 10/17] mwifiex: use firmware API revision from GET_HW_SPEC response

From: Amitkumar Karwar <[email protected]>

Newer firmware returns API revision in GET_HW_SPEC command
response. We will make use of it instead of parsing this
information from FW release number.

Signed-off-by: Amitkumar Karwar <[email protected]>
Signed-off-by: Avinash Patil <[email protected]>
Signed-off-by: Cathy Luo <[email protected]>
---
drivers/net/wireless/mwifiex/cmdevt.c | 7 +++++++
drivers/net/wireless/mwifiex/fw.h | 1 +
2 files changed, 8 insertions(+)

diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c
index 720e519..fcc70ae 100644
--- a/drivers/net/wireless/mwifiex/cmdevt.c
+++ b/drivers/net/wireless/mwifiex/cmdevt.c
@@ -1552,6 +1552,13 @@ int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv,
adapter->key_api_major_ver,
adapter->key_api_minor_ver);
break;
+ case FW_API_VER_ID:
+ adapter->fw_api_ver =
+ api_rev->major_ver;
+ dev_dbg(adapter->dev,
+ "Firmware api version %d\n",
+ adapter->fw_api_ver);
+ break;
default:
dev_warn(adapter->dev,
"Unknown api_id: %d\n",
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h
index adc47f3..6a703ea 100644
--- a/drivers/net/wireless/mwifiex/fw.h
+++ b/drivers/net/wireless/mwifiex/fw.h
@@ -846,6 +846,7 @@ struct host_cmd_ds_802_11_ps_mode_enh {

enum API_VER_ID {
KEY_API_VER_ID = 1,
+ FW_API_VER_ID = 2,
};

struct hw_spec_api_rev {
--
1.8.1.4


2014-09-04 17:23:16

by Avinash Patil

[permalink] [raw]
Subject: RE: [PATCH 00/17] mwifiex updates for 3.17

Hi John,

Please take them for 3.18.
Patch1 and Patch8 are critical fixes. Could you please add them to stable?

Thanks,
Avinash

-----Original Message-----
From: John W. Linville [mailto:[email protected]]
Sent: Thursday, September 04, 2014 10:45 PM
To: Avinash Patil
Cc: [email protected]; Amitkumar Karwar; Xinming Hu; Marc Yang; Cathy Luo; Maithili Hinge
Subject: Re: [PATCH 00/17] mwifiex updates for 3.17

These don't all seem to be fixes. Do you want me to take them for 3.18? Or do you want to divide this list between fixes and features and post them as different series for 3.17 and 3.18?

John

On Mon, Sep 01, 2014 at 06:28:48PM +0530, Avinash Patil wrote:
> This patch series brings in scan enhancement including scan channel
> gap, support for parsing FW API version from HW_SPEC command response,
> support for processing RX in work queue and few trivial fixes for SDIO
> multiport aggregation.
>
> Amitkumar Karwar (7):
> mwifiex: fix a bug in Tx multiport aggregation
> mwifiex: minor cleanup in multiport aggregation
> mwifiex: fix left_len calculation issue
> mwifiex: rename macro and variables related to API revision
> mwifiex: use firmware API revision from GET_HW_SPEC response
> mwifiex: remove redundant variable report_scan_result
> mwifiex: remove low priority scan handling
>
> Avinash Patil (9):
> mwifiex: fix probable memory corruption while processing TDLS frame
> mwifiex: avoid processing RX packets with invalid length
> mwifiex: rework internal scan for association
> mwifiex: support for event done interrupt
> mwifiex: set passive scan type for scan requests with no ssid
> mwifiex: bring in scan channel gap feature
> mwifiex: remove restriction of single channel scan when connected
> mwifiex: process TX even when scan is ongoing
> mwifiex: add rx workqueue support
>
> Xinming Hu (1):
> mwifiex: fix 5G association failure after leaving 2.4G IBSS
>
> drivers/net/wireless/mwifiex/11n_rxreorder.c | 14 ++
> drivers/net/wireless/mwifiex/cfg80211.c | 13 +-
> drivers/net/wireless/mwifiex/cmdevt.c | 28 ++--
> drivers/net/wireless/mwifiex/fw.h | 17 ++-
> drivers/net/wireless/mwifiex/init.c | 25 +++-
> drivers/net/wireless/mwifiex/main.c | 194 +++++++++++++--------------
> drivers/net/wireless/mwifiex/main.h | 49 +++++--
> drivers/net/wireless/mwifiex/pcie.c | 37 ++++-
> drivers/net/wireless/mwifiex/pcie.h | 5 +-
> drivers/net/wireless/mwifiex/scan.c | 112 ++++++++++------
> drivers/net/wireless/mwifiex/sdio.c | 28 ++--
> drivers/net/wireless/mwifiex/sta_cmd.c | 2 +-
> drivers/net/wireless/mwifiex/sta_cmdresp.c | 4 +-
> drivers/net/wireless/mwifiex/sta_ioctl.c | 13 +-
> drivers/net/wireless/mwifiex/tdls.c | 4 +-
> 15 files changed, 339 insertions(+), 206 deletions(-)
>
> --
> 1.8.1.4
>
>

--
John W. Linville Someday the world will need a hero, and you
[email protected] might be all we have. Be ready.