2016-07-11 14:55:19

by Amitkumar Karwar

[permalink] [raw]
Subject: [PATCH 0/9] mwifiex patches

This patch series includes couple of fixes and enhancements.

Amitkumar Karwar (3):
mwifiex: fix failed to reconnect after interface disabled/enabled
mwifiex: cfg80211 set_default_mgmt_key handler
mwifiex: remove misleading disconnect message

Ganapathi Bhat (2):
mwifiex: support random MAC address for scanning
mwifiex: fix radar detection issue

Karthik D A (2):
mwifiex: Fixed endianness problem for big endian platform
mwifiex: add region code information in debugfs

Xinming Hu (2):
mwifiex: process rxba_sync event
mwifiex: add HT aggregation support for adhoc mode

drivers/net/wireless/marvell/mwifiex/11h.c | 27 ++--
drivers/net/wireless/marvell/mwifiex/11n.h | 7 +-
.../net/wireless/marvell/mwifiex/11n_rxreorder.c | 79 ++++++++++-
.../net/wireless/marvell/mwifiex/11n_rxreorder.h | 6 +-
drivers/net/wireless/marvell/mwifiex/cfg80211.c | 32 ++++-
drivers/net/wireless/marvell/mwifiex/cmdevt.c | 18 ++-
drivers/net/wireless/marvell/mwifiex/debugfs.c | 2 +
drivers/net/wireless/marvell/mwifiex/fw.h | 58 ++++++---
drivers/net/wireless/marvell/mwifiex/main.h | 1 +
drivers/net/wireless/marvell/mwifiex/scan.c | 16 +++
drivers/net/wireless/marvell/mwifiex/sta_cmd.c | 27 ++--
drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c | 2 +-
drivers/net/wireless/marvell/mwifiex/sta_event.c | 144 ++++++++++++++++++++-
drivers/net/wireless/marvell/mwifiex/uap_event.c | 7 +-
14 files changed, 367 insertions(+), 59 deletions(-)

--
1.9.1



2016-07-11 15:02:52

by Amitkumar Karwar

[permalink] [raw]
Subject: [PATCH 6/9] mwifiex: process rxba_sync event

From: Xinming Hu <[email protected]>

Firmware may filter and drop packets under certain condition, for
example, ARP SA=DA packet. this event will be used to synchronize
the Rx Block Acknowledgment (BA) window bitmap and to fill any holes
in driver side.

Signed-off-by: Xinming Hu <[email protected]>
Signed-off-by: Amitkumar Karwar <[email protected]>
---
.../net/wireless/marvell/mwifiex/11n_rxreorder.c | 79 +++++++++++++++++++++-
.../net/wireless/marvell/mwifiex/11n_rxreorder.h | 6 +-
drivers/net/wireless/marvell/mwifiex/fw.h | 12 ++++
drivers/net/wireless/marvell/mwifiex/sta_event.c | 6 ++
drivers/net/wireless/marvell/mwifiex/uap_event.c | 7 +-
5 files changed, 107 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c b/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c
index a74cc43..96b411e 100644
--- a/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c
+++ b/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c
@@ -78,8 +78,15 @@ static int mwifiex_11n_dispatch_amsdu_pkt(struct mwifiex_private *priv,
*/
static int mwifiex_11n_dispatch_pkt(struct mwifiex_private *priv, void *payload)
{
- int ret = mwifiex_11n_dispatch_amsdu_pkt(priv, payload);

+ int ret;
+
+ if (payload == (void *)MWIFIEX_RX_PKT_DROPPED_IN_FW) {
+ mwifiex_dbg(priv->adapter, INFO, "info: fw drop data\n");
+ return 0;
+ }
+
+ ret = mwifiex_11n_dispatch_amsdu_pkt(priv, payload);
if (!ret)
return 0;

@@ -921,3 +928,73 @@ void mwifiex_coex_ampdu_rxwinsize(struct mwifiex_adapter *adapter)
else
mwifiex_update_ampdu_rxwinsize(adapter, false);
}
+
+/* This function handles rxba_sync event
+ */
+void mwifiex_11n_rxba_sync_event(struct mwifiex_private *priv,
+ u8 *event_buf, u16 len)
+{
+ struct mwifiex_ie_types_rxba_sync *tlv_rxba = (void *)event_buf;
+ u16 tlv_type, tlv_len;
+ struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr;
+ u8 i, j;
+ u16 seq_num, tlv_seq_num, tlv_bitmap_len;
+ int tlv_buf_left = len;
+ int ret;
+ u8 *tmp;
+
+ mwifiex_dbg_dump(priv->adapter, EVT_D, "RXBA_SYNC event:",
+ event_buf, len);
+ while (tlv_buf_left >= sizeof(*tlv_rxba)) {
+ tlv_type = le16_to_cpu(tlv_rxba->header.type);
+ tlv_len = le16_to_cpu(tlv_rxba->header.len);
+ if (tlv_type != TLV_TYPE_RXBA_SYNC) {
+ mwifiex_dbg(priv->adapter, ERROR,
+ "Wrong TLV id=0x%x\n", tlv_type);
+ return;
+ }
+
+ tlv_seq_num = le16_to_cpu(tlv_rxba->seq_num);
+ tlv_bitmap_len = le16_to_cpu(tlv_rxba->bitmap_len);
+ mwifiex_dbg(priv->adapter, INFO,
+ "%pM tid=%d seq_num=%d bitmap_len=%d\n",
+ tlv_rxba->mac, tlv_rxba->tid, tlv_seq_num,
+ tlv_bitmap_len);
+
+ rx_reor_tbl_ptr =
+ mwifiex_11n_get_rx_reorder_tbl(priv, tlv_rxba->tid,
+ tlv_rxba->mac);
+ if (!rx_reor_tbl_ptr) {
+ mwifiex_dbg(priv->adapter, ERROR,
+ "Can not find rx_reorder_tbl!");
+ return;
+ }
+
+ for (i = 0; i < tlv_bitmap_len; i++) {
+ for (j = 0 ; j < 8; j++) {
+ if (tlv_rxba->bitmap[i] & (1 << j)) {
+ seq_num = (MAX_TID_VALUE - 1) &
+ (tlv_seq_num + i * 8 + j);
+
+ mwifiex_dbg(priv->adapter, ERROR,
+ "drop packet,seq=%d\n",
+ seq_num);
+
+ ret = mwifiex_11n_rx_reorder_pkt
+ (priv, seq_num, tlv_rxba->tid,
+ tlv_rxba->mac, 0,
+ (void *)MWIFIEX_RX_PKT_DROPPED_IN_FW);
+
+ if (ret)
+ mwifiex_dbg(priv->adapter,
+ ERROR,
+ "Fail to drop packet");
+ }
+ }
+ }
+
+ tlv_buf_left -= (sizeof(*tlv_rxba) + tlv_len);
+ tmp = (u8 *)tlv_rxba + tlv_len + sizeof(*tlv_rxba);
+ tlv_rxba = (struct mwifiex_ie_types_rxba_sync *)tmp;
+ }
+}
diff --git a/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.h b/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.h
index 63ecea8..05c2243 100644
--- a/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.h
+++ b/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.h
@@ -43,6 +43,9 @@
#define BA_SETUP_MAX_PACKET_THRESHOLD 16
#define BA_SETUP_PACKET_OFFSET 16

+/* Indicate packet has been dropped in FW */
+#define MWIFIEX_RX_PKT_DROPPED_IN_FW 0xffffffff
+
enum mwifiex_rxreor_flags {
RXREOR_FORCE_NO_DROP = 1<<0,
RXREOR_INIT_WINDOW_SHIFT = 1<<1,
@@ -81,5 +84,6 @@ struct mwifiex_rx_reorder_tbl *
mwifiex_11n_get_rx_reorder_tbl(struct mwifiex_private *priv, int tid, u8 *ta);
void mwifiex_11n_del_rx_reorder_tbl_by_ta(struct mwifiex_private *priv, u8 *ta);
void mwifiex_update_rxreor_flags(struct mwifiex_adapter *adapter, u8 flags);
-
+void mwifiex_11n_rxba_sync_event(struct mwifiex_private *priv,
+ u8 *event_buf, u16 len);
#endif /* _MWIFIEX_11N_RXREORDER_H_ */
diff --git a/drivers/net/wireless/marvell/mwifiex/fw.h b/drivers/net/wireless/marvell/mwifiex/fw.h
index 3797ef4..3b40e0d 100644
--- a/drivers/net/wireless/marvell/mwifiex/fw.h
+++ b/drivers/net/wireless/marvell/mwifiex/fw.h
@@ -176,6 +176,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
#define TLV_TYPE_PWK_CIPHER (PROPRIETARY_TLV_BASE_ID + 145)
#define TLV_TYPE_GWK_CIPHER (PROPRIETARY_TLV_BASE_ID + 146)
#define TLV_TYPE_TX_PAUSE (PROPRIETARY_TLV_BASE_ID + 148)
+#define TLV_TYPE_RXBA_SYNC (PROPRIETARY_TLV_BASE_ID + 153)
#define TLV_TYPE_COALESCE_RULE (PROPRIETARY_TLV_BASE_ID + 154)
#define TLV_TYPE_KEY_PARAM_V2 (PROPRIETARY_TLV_BASE_ID + 156)
#define TLV_TYPE_REPEAT_COUNT (PROPRIETARY_TLV_BASE_ID + 176)
@@ -532,6 +533,7 @@ enum P2P_MODES {
#define EVENT_CHANNEL_REPORT_RDY 0x00000054
#define EVENT_TX_DATA_PAUSE 0x00000055
#define EVENT_EXT_SCAN_REPORT 0x00000058
+#define EVENT_RXBA_SYNC 0x00000059
#define EVENT_BG_SCAN_STOPPED 0x00000065
#define EVENT_REMAIN_ON_CHAN_EXPIRED 0x0000005f
#define EVENT_MULTI_CHAN_INFO 0x0000006a
@@ -735,6 +737,16 @@ struct mwifiex_ie_types_chan_list_param_set {
struct mwifiex_chan_scan_param_set chan_scan_param[1];
} __packed;

+struct mwifiex_ie_types_rxba_sync {
+ struct mwifiex_ie_types_header header;
+ u8 mac[ETH_ALEN];
+ u8 tid;
+ u8 reserved;
+ __le16 seq_num;
+ __le16 bitmap_len;
+ u8 bitmap[1];
+} __packed;
+
struct chan_band_param_set {
u8 radio_type;
u8 chan_number;
diff --git a/drivers/net/wireless/marvell/mwifiex/sta_event.c b/drivers/net/wireless/marvell/mwifiex/sta_event.c
index 7e394d4..b973ee8 100644
--- a/drivers/net/wireless/marvell/mwifiex/sta_event.c
+++ b/drivers/net/wireless/marvell/mwifiex/sta_event.c
@@ -873,6 +873,12 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
mwifiex_bt_coex_wlan_param_update_event(priv,
adapter->event_skb);
break;
+ case EVENT_RXBA_SYNC:
+ dev_dbg(adapter->dev, "EVENT: RXBA_SYNC\n");
+ mwifiex_11n_rxba_sync_event(priv, adapter->event_body,
+ adapter->event_skb->len -
+ sizeof(eventcause));
+ break;
default:
mwifiex_dbg(adapter, ERROR, "event: unknown event id: %#x\n",
eventcause);
diff --git a/drivers/net/wireless/marvell/mwifiex/uap_event.c b/drivers/net/wireless/marvell/mwifiex/uap_event.c
index 86ff542..d24eca3 100644
--- a/drivers/net/wireless/marvell/mwifiex/uap_event.c
+++ b/drivers/net/wireless/marvell/mwifiex/uap_event.c
@@ -306,7 +306,12 @@ int mwifiex_process_uap_event(struct mwifiex_private *priv)
mwifiex_dbg(adapter, EVENT, "event: multi-chan info\n");
mwifiex_process_multi_chan_event(priv, adapter->event_skb);
break;
-
+ case EVENT_RXBA_SYNC:
+ dev_dbg(adapter->dev, "EVENT: RXBA_SYNC\n");
+ mwifiex_11n_rxba_sync_event(priv, adapter->event_body,
+ adapter->event_skb->len -
+ sizeof(eventcause));
+ break;
default:
mwifiex_dbg(adapter, EVENT,
"event: unknown event id: %#x\n", eventcause);
--
1.9.1


2016-07-21 15:51:35

by Jouni Malinen

[permalink] [raw]
Subject: Re: [PATCH 5/9] mwifiex: cfg80211 set_default_mgmt_key handler

On Thu, Jul 21, 2016 at 09:18:11AM +0000, Amitkumar Karwar wrote:
> > From: Kalle Valo [mailto:[email protected]]
> > Is it correct to ignore the key index? I see that brcmfmac ignores it as
> > well but I want to still confirm this.
> >
> > Does this mean that with this patcfh mwifiex properly supports MFP?
>
> Yes. We do pass MFP tests with this patch.

Did you test IGTK rekeying? This patch looks exactly as broken as it did
the last time it was proposed more than a year ago and after the same
concern not receiving any reaction.. hostapd will configure two
different IGTKs with different Key IDs and change the TX key on the AP
once all associated STAs have the new key. If the driver does not
support updating the TX key index, either the old or the new STAs
associated after rekeying will not have the correct key.

--
Jouni Malinen PGP id EFC895FA

2016-07-26 15:12:23

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH 5/9] mwifiex: cfg80211 set_default_mgmt_key handler

Jouni Malinen <[email protected]> writes:

> On Thu, Jul 21, 2016 at 09:18:11AM +0000, Amitkumar Karwar wrote:
>> > From: Kalle Valo [mailto:[email protected]]
>> > Is it correct to ignore the key index? I see that brcmfmac ignores it as
>> > well but I want to still confirm this.
>> >
>> > Does this mean that with this patcfh mwifiex properly supports MFP?
>>
>> Yes. We do pass MFP tests with this patch.
>
> Did you test IGTK rekeying? This patch looks exactly as broken as it did
> the last time it was proposed more than a year ago and after the same
> concern not receiving any reaction..

Indeed, I had already forgetten that this patch was submitted February
2015:

https://patchwork.kernel.org/patch/5819421/

Please don't do like this and repost patches without earlier comments
addressed (or at least document the history).

--
Kalle Valo

2016-07-11 15:06:43

by Amitkumar Karwar

[permalink] [raw]
Subject: [PATCH 9/9] mwifiex: fix radar detection issue

From: Ganapathi Bhat <[email protected]>

It's been observed that firmware sends RADAR detected event without
specifying bss_num/bss_type. Also, the event body is empty.
Currently the event is being ignored by driver.

This patch checks on which interface 11H is active, accordingly fills
bss_num/bss_type and handles the event. Condition
"if (le32_to_cpu(rdr_event->passed))" which always fails is also removed.

Signed-off-by: Ganapathi Bhat <[email protected]>
Signed-off-by: Amitkumar Karwar <[email protected]>
---
drivers/net/wireless/marvell/mwifiex/11h.c | 27 +++++++++++----------------
drivers/net/wireless/marvell/mwifiex/cmdevt.c | 18 ++++++++++++++++--
2 files changed, 27 insertions(+), 18 deletions(-)

diff --git a/drivers/net/wireless/marvell/mwifiex/11h.c b/drivers/net/wireless/marvell/mwifiex/11h.c
index 81c60d0..43dccd5 100644
--- a/drivers/net/wireless/marvell/mwifiex/11h.c
+++ b/drivers/net/wireless/marvell/mwifiex/11h.c
@@ -260,22 +260,17 @@ int mwifiex_11h_handle_radar_detected(struct mwifiex_private *priv,

rdr_event = (void *)(skb->data + sizeof(u32));

- if (le32_to_cpu(rdr_event->passed)) {
- mwifiex_dbg(priv->adapter, MSG,
- "radar detected; indicating kernel\n");
- if (mwifiex_stop_radar_detection(priv, &priv->dfs_chandef))
- mwifiex_dbg(priv->adapter, ERROR,
- "Failed to stop CAC in FW\n");
- cfg80211_radar_event(priv->adapter->wiphy, &priv->dfs_chandef,
- GFP_KERNEL);
- mwifiex_dbg(priv->adapter, MSG, "regdomain: %d\n",
- rdr_event->reg_domain);
- mwifiex_dbg(priv->adapter, MSG, "radar detection type: %d\n",
- rdr_event->det_type);
- } else {
- mwifiex_dbg(priv->adapter, MSG,
- "false radar detection event!\n");
- }
+ mwifiex_dbg(priv->adapter, MSG,
+ "radar detected; indicating kernel\n");
+ if (mwifiex_stop_radar_detection(priv, &priv->dfs_chandef))
+ mwifiex_dbg(priv->adapter, ERROR,
+ "Failed to stop CAC in FW\n");
+ cfg80211_radar_event(priv->adapter->wiphy, &priv->dfs_chandef,
+ GFP_KERNEL);
+ mwifiex_dbg(priv->adapter, MSG, "regdomain: %d\n",
+ rdr_event->reg_domain);
+ mwifiex_dbg(priv->adapter, MSG, "radar detection type: %d\n",
+ rdr_event->det_type);

return 0;
}
diff --git a/drivers/net/wireless/marvell/mwifiex/cmdevt.c b/drivers/net/wireless/marvell/mwifiex/cmdevt.c
index c29f26d..d433aa0 100644
--- a/drivers/net/wireless/marvell/mwifiex/cmdevt.c
+++ b/drivers/net/wireless/marvell/mwifiex/cmdevt.c
@@ -480,13 +480,27 @@ int mwifiex_free_cmd_buffer(struct mwifiex_adapter *adapter)
*/
int mwifiex_process_event(struct mwifiex_adapter *adapter)
{
- int ret;
+ int ret, i;
struct mwifiex_private *priv =
mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
struct sk_buff *skb = adapter->event_skb;
- u32 eventcause = adapter->event_cause;
+ u32 eventcause;
struct mwifiex_rxinfo *rx_info;

+ if ((adapter->event_cause & EVENT_ID_MASK) == EVENT_RADAR_DETECTED) {
+ for (i = 0; i < adapter->priv_num; i++) {
+ priv = adapter->priv[i];
+ if (priv && mwifiex_is_11h_active(priv)) {
+ adapter->event_cause |=
+ ((priv->bss_num & 0xff) << 16) |
+ ((priv->bss_type & 0xff) << 24);
+ break;
+ }
+ }
+ }
+
+ eventcause = adapter->event_cause;
+
/* Save the last event to debug log */
adapter->dbg.last_event_index =
(adapter->dbg.last_event_index + 1) % DBG_CMD_NUM;
--
1.9.1


2016-07-21 09:48:30

by Amitkumar Karwar

[permalink] [raw]
Subject: RE: [PATCH 6/9] mwifiex: process rxba_sync event

Hi Kalle,

> From: Kalle Valo [mailto:[email protected]]
> Sent: Monday, July 18, 2016 10:54 PM
> To: Amitkumar Karwar
> Cc: [email protected]; Cathy Luo; Nishant Sarmukadam;
> Xinming Hu
> Subject: Re: [PATCH 6/9] mwifiex: process rxba_sync event
>
> Amitkumar Karwar <[email protected]> writes:
>
> > From: Xinming Hu <[email protected]>
> >
> > Firmware may filter and drop packets under certain condition, for
> > example, ARP SA=DA packet. this event will be used to synchronize the
> > Rx Block Acknowledgment (BA) window bitmap and to fill any holes in
> > driver side.
> >
> > Signed-off-by: Xinming Hu <[email protected]>
> > Signed-off-by: Amitkumar Karwar <[email protected]>
>
> [...]
>
> > --- a/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c
> > +++ b/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c
> > @@ -78,8 +78,15 @@ static int mwifiex_11n_dispatch_amsdu_pkt(struct
> mwifiex_private *priv,
> > */
> > static int mwifiex_11n_dispatch_pkt(struct mwifiex_private *priv,
> > void *payload) {
> > - int ret = mwifiex_11n_dispatch_amsdu_pkt(priv, payload);
> >
> > + int ret;
> > +
> > + if (payload == (void *)MWIFIEX_RX_PKT_DROPPED_IN_FW) {
> > + mwifiex_dbg(priv->adapter, INFO, "info: fw drop data\n");
> > + return 0;
> > + }
>
> [...]
>
> > + mwifiex_dbg(priv->adapter, ERROR,
> > + "drop packet,seq=%d\n",
> > + seq_num);
> > +
> > + ret = mwifiex_11n_rx_reorder_pkt
> > + (priv, seq_num, tlv_rxba->tid,
> > + tlv_rxba->mac, 0,
> > + (void *)MWIFIEX_RX_PKT_DROPPED_IN_FW);
>
> [...]
>
> > +/* Indicate packet has been dropped in FW */
> > +#define MWIFIEX_RX_PKT_DROPPED_IN_FW 0xffffffff
>
> That pointer magic is rather ugly, why not use a proper boolean?
>

Thanks for review. I will get rid of this macro and submit updated version.

Regards,
Amitkumar

2016-07-22 16:55:21

by Jouni Malinen

[permalink] [raw]
Subject: Re: [PATCH 5/9] mwifiex: cfg80211 set_default_mgmt_key handler

On Fri, Jul 22, 2016 at 03:59:47PM +0000, Amitkumar Karwar wrote:
> I am trying to understand the problem you mentioned during IGTK rekeying. Today I ran tests with two stations connecting an AP. MFP is enabled on all of them.
>
> On hostapd side, my observation is add_key() is always called followed by set_default_mgmt_key(). set_default_mgmt_key() sets the key added by add_key() as default key.
>
> We are ignoring set_default_mgmt_key() and updating Tx key index during add_key() itself.
>
> Your concerns is we should not update Tx key index during add_key(). Reason is IGTK rekeying is not yet completed with all stations. Right?

Correct. set_default_mgmt_key() does not have much effect for the very
first IGTK configuration, but whenever doing IGTK rekeying, hostapd
behaves just like it does with GTK rekeying. In other words, a different
Key ID is selected (alternating between 4 and 5), a random new IGTK is
generated, the new IGTK is configured to the local driver (but the old
IGTK is still supposed to be used for TX), each associated STA is
notified of the new IGTK, the new IGTK is taken into use once the group
key handshake has completed with each associated STA. It is that last
operation that needs set_default_mgmt_key() to allow this rekeying to
work correctly. If you update the TX Key ID on add_key(), you'll risk
sending out frames that some of the associated STAs do not yet have a
key to validate.

--
Jouni Malinen PGP id EFC895FA

2016-07-11 14:56:36

by Amitkumar Karwar

[permalink] [raw]
Subject: [PATCH 1/9] mwifiex: Fixed endianness problem for big endian platform

From: Karthik D A <[email protected]>

The driver sends and recives information to and from the firmware.
Correct endianness should be ensured as firmware follows little
endian format and host can be little/big endian.

Signed-off-by: Karthik D A <[email protected]>
Signed-off-by: Amitkumar Karwar <[email protected]>
---
drivers/net/wireless/marvell/mwifiex/fw.h | 30 +++++++++++-----------
drivers/net/wireless/marvell/mwifiex/sta_cmd.c | 27 ++++++++++---------
drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c | 2 +-
3 files changed, 31 insertions(+), 28 deletions(-)

diff --git a/drivers/net/wireless/marvell/mwifiex/fw.h b/drivers/net/wireless/marvell/mwifiex/fw.h
index 5596b6b..c46267b 100644
--- a/drivers/net/wireless/marvell/mwifiex/fw.h
+++ b/drivers/net/wireless/marvell/mwifiex/fw.h
@@ -1646,7 +1646,7 @@ struct mwifiex_ie_types_sta_info {
};

struct host_cmd_ds_sta_list {
- u16 sta_count;
+ __le16 sta_count;
u8 tlv[0];
} __packed;

@@ -2034,26 +2034,26 @@ struct host_cmd_ds_set_bss_mode {

struct host_cmd_ds_pcie_details {
/* TX buffer descriptor ring address */
- u32 txbd_addr_lo;
- u32 txbd_addr_hi;
+ __le32 txbd_addr_lo;
+ __le32 txbd_addr_hi;
/* TX buffer descriptor ring count */
- u32 txbd_count;
+ __le32 txbd_count;

/* RX buffer descriptor ring address */
- u32 rxbd_addr_lo;
- u32 rxbd_addr_hi;
+ __le32 rxbd_addr_lo;
+ __le32 rxbd_addr_hi;
/* RX buffer descriptor ring count */
- u32 rxbd_count;
+ __le32 rxbd_count;

/* Event buffer descriptor ring address */
- u32 evtbd_addr_lo;
- u32 evtbd_addr_hi;
+ __le32 evtbd_addr_lo;
+ __le32 evtbd_addr_hi;
/* Event buffer descriptor ring count */
- u32 evtbd_count;
+ __le32 evtbd_count;

/* Sleep cookie buffer physical address */
- u32 sleep_cookie_addr_lo;
- u32 sleep_cookie_addr_hi;
+ __le32 sleep_cookie_addr_lo;
+ __le32 sleep_cookie_addr_hi;
} __packed;

struct mwifiex_ie_types_rssi_threshold {
@@ -2093,8 +2093,8 @@ struct mwifiex_ie_types_mc_group_info {
u8 chan_buf_weight;
u8 band_config;
u8 chan_num;
- u32 chan_time;
- u32 reserved;
+ __le32 chan_time;
+ __le32 reserved;
union {
u8 sdio_func_num;
u8 usb_ep_num;
@@ -2185,7 +2185,7 @@ struct host_cmd_ds_robust_coex {
} __packed;

struct host_cmd_ds_wakeup_reason {
- u16 wakeup_reason;
+ __le16 wakeup_reason;
} __packed;

struct host_cmd_ds_gtk_rekey_params {
diff --git a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
index 8c65849..fd0bc96 100644
--- a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
+++ b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
@@ -1248,20 +1248,23 @@ mwifiex_cmd_pcie_host_spec(struct mwifiex_private *priv,
return 0;

/* Send the ring base addresses and count to firmware */
- host_spec->txbd_addr_lo = (u32)(card->txbd_ring_pbase);
- host_spec->txbd_addr_hi = (u32)(((u64)card->txbd_ring_pbase)>>32);
- host_spec->txbd_count = MWIFIEX_MAX_TXRX_BD;
- host_spec->rxbd_addr_lo = (u32)(card->rxbd_ring_pbase);
- host_spec->rxbd_addr_hi = (u32)(((u64)card->rxbd_ring_pbase)>>32);
- host_spec->rxbd_count = MWIFIEX_MAX_TXRX_BD;
- host_spec->evtbd_addr_lo = (u32)(card->evtbd_ring_pbase);
- host_spec->evtbd_addr_hi = (u32)(((u64)card->evtbd_ring_pbase)>>32);
- host_spec->evtbd_count = MWIFIEX_MAX_EVT_BD;
+ host_spec->txbd_addr_lo = cpu_to_le32((u32)(card->txbd_ring_pbase));
+ host_spec->txbd_addr_hi =
+ cpu_to_le32((u32)(((u64)card->txbd_ring_pbase) >> 32));
+ host_spec->txbd_count = cpu_to_le32(MWIFIEX_MAX_TXRX_BD);
+ host_spec->rxbd_addr_lo = cpu_to_le32((u32)(card->rxbd_ring_pbase));
+ host_spec->rxbd_addr_hi =
+ cpu_to_le32((u32)(((u64)card->rxbd_ring_pbase) >> 32));
+ host_spec->rxbd_count = cpu_to_le32(MWIFIEX_MAX_TXRX_BD);
+ host_spec->evtbd_addr_lo = cpu_to_le32((u32)(card->evtbd_ring_pbase));
+ host_spec->evtbd_addr_hi =
+ cpu_to_le32((u32)(((u64)card->evtbd_ring_pbase) >> 32));
+ host_spec->evtbd_count = cpu_to_le32(MWIFIEX_MAX_EVT_BD);
if (card->sleep_cookie_vbase) {
host_spec->sleep_cookie_addr_lo =
- (u32)(card->sleep_cookie_pbase);
- host_spec->sleep_cookie_addr_hi =
- (u32)(((u64)(card->sleep_cookie_pbase)) >> 32);
+ cpu_to_le32((u32)(card->sleep_cookie_pbase));
+ host_spec->sleep_cookie_addr_hi = cpu_to_le32((u32)(((u64)
+ (card->sleep_cookie_pbase)) >> 32));
mwifiex_dbg(priv->adapter, INFO,
"sleep_cook_lo phy addr: 0x%x\n",
host_spec->sleep_cookie_addr_lo);
diff --git a/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c b/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c
index 9050d06..a1810c2 100644
--- a/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c
+++ b/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c
@@ -963,7 +963,7 @@ static int mwifiex_ret_uap_sta_list(struct mwifiex_private *priv,
int i;
struct mwifiex_sta_node *sta_node;

- for (i = 0; i < sta_list->sta_count; i++) {
+ for (i = 0; i < (le16_to_cpu(sta_list->sta_count)); i++) {
sta_node = mwifiex_get_sta_entry(priv, sta_info->mac);
if (unlikely(!sta_node))
continue;
--
1.9.1


2016-07-18 17:24:24

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH 6/9] mwifiex: process rxba_sync event

Amitkumar Karwar <[email protected]> writes:

> From: Xinming Hu <[email protected]>
>
> Firmware may filter and drop packets under certain condition, for
> example, ARP SA=DA packet. this event will be used to synchronize
> the Rx Block Acknowledgment (BA) window bitmap and to fill any holes
> in driver side.
>
> Signed-off-by: Xinming Hu <[email protected]>
> Signed-off-by: Amitkumar Karwar <[email protected]>

[...]

> --- a/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c
> +++ b/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c
> @@ -78,8 +78,15 @@ static int mwifiex_11n_dispatch_amsdu_pkt(struct mwifiex_private *priv,
> */
> static int mwifiex_11n_dispatch_pkt(struct mwifiex_private *priv, void *payload)
> {
> - int ret = mwifiex_11n_dispatch_amsdu_pkt(priv, payload);
>
> + int ret;
> +
> + if (payload == (void *)MWIFIEX_RX_PKT_DROPPED_IN_FW) {
> + mwifiex_dbg(priv->adapter, INFO, "info: fw drop data\n");
> + return 0;
> + }

[...]

> + mwifiex_dbg(priv->adapter, ERROR,
> + "drop packet,seq=%d\n",
> + seq_num);
> +
> + ret = mwifiex_11n_rx_reorder_pkt
> + (priv, seq_num, tlv_rxba->tid,
> + tlv_rxba->mac, 0,
> + (void *)MWIFIEX_RX_PKT_DROPPED_IN_FW);

[...]

> +/* Indicate packet has been dropped in FW */
> +#define MWIFIEX_RX_PKT_DROPPED_IN_FW 0xffffffff

That pointer magic is rather ugly, why not use a proper boolean?

--
Kalle Valo

2016-07-18 17:19:08

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH 5/9] mwifiex: cfg80211 set_default_mgmt_key handler

Amitkumar Karwar <[email protected]> writes:

> It is observed that hostapd fails to setup with management frame
> protection mode enabled when using mwifiex. This patch adds
> cfg80211_set_default_mgmt_key handler to resolve the problem.
>
> Signed-off-by: Amitkumar Karwar <[email protected]>
> ---
> drivers/net/wireless/marvell/mwifiex/cfg80211.c | 13 +++++++++++++
> 1 file changed, 13 insertions(+)
>
> diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
> index 8955f8c..bf95cca 100644
> --- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c
> +++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
> @@ -484,6 +484,18 @@ mwifiex_cfg80211_add_key(struct wiphy *wiphy, struct net_device *netdev,
> }
>
> /*
> + * CFG802.11 operation handler to set default mgmt key.
> + */
> +static int
> +mwifiex_cfg80211_set_default_mgmt_key(struct wiphy *wiphy,
> + struct net_device *netdev,
> + u8 key_index)
> +{
> + wiphy_dbg(wiphy, "set default mgmt key, key index=%d\n", key_index);
> + return 0;
> +}
> +
> +/*
> * This function sends domain information to the firmware.
> *
> * The following information are passed to the firmware -
> @@ -4002,6 +4014,7 @@ static struct cfg80211_ops mwifiex_cfg80211_ops = {
> .leave_ibss = mwifiex_cfg80211_leave_ibss,
> .add_key = mwifiex_cfg80211_add_key,
> .del_key = mwifiex_cfg80211_del_key,
> + .set_default_mgmt_key = mwifiex_cfg80211_set_default_mgmt_key,
> .mgmt_tx = mwifiex_cfg80211_mgmt_tx,
> .mgmt_frame_register = mwifiex_cfg80211_mgmt_frame_register,
> .remain_on_channel = mwifiex_cfg80211_remain_on_channel,

Is it correct to ignore the key index? I see that brcmfmac ignores it as
well but I want to still confirm this.

Does this mean that with this patcfh mwifiex properly supports MFP?

--
Kalle Valo

2016-07-21 09:18:16

by Amitkumar Karwar

[permalink] [raw]
Subject: RE: [PATCH 5/9] mwifiex: cfg80211 set_default_mgmt_key handler

Hi Kalle,

> From: Kalle Valo [mailto:[email protected]]
> Sent: Monday, July 18, 2016 10:49 PM
> To: Amitkumar Karwar
> Cc: [email protected]; Cathy Luo; Nishant Sarmukadam
> Subject: Re: [PATCH 5/9] mwifiex: cfg80211 set_default_mgmt_key handler
>
> Amitkumar Karwar <[email protected]> writes:
>
> > It is observed that hostapd fails to setup with management frame
> > protection mode enabled when using mwifiex. This patch adds
> > cfg80211_set_default_mgmt_key handler to resolve the problem.
> >
> > Signed-off-by: Amitkumar Karwar <[email protected]>
> > ---
> > drivers/net/wireless/marvell/mwifiex/cfg80211.c | 13 +++++++++++++
> > 1 file changed, 13 insertions(+)
> >
> > diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c
> > b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
> > index 8955f8c..bf95cca 100644
> > --- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c
> > +++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
> > @@ -484,6 +484,18 @@ mwifiex_cfg80211_add_key(struct wiphy *wiphy,
> > struct net_device *netdev, }
> >
> > /*
> > + * CFG802.11 operation handler to set default mgmt key.
> > + */
> > +static int
> > +mwifiex_cfg80211_set_default_mgmt_key(struct wiphy *wiphy,
> > + struct net_device *netdev,
> > + u8 key_index)
> > +{
> > + wiphy_dbg(wiphy, "set default mgmt key, key index=%d\n",
> key_index);
> > + return 0;
> > +}
> > +
> > +/*
> > * This function sends domain information to the firmware.
> > *
> > * The following information are passed to the firmware - @@ -4002,6
> > +4014,7 @@ static struct cfg80211_ops mwifiex_cfg80211_ops = {
> > .leave_ibss = mwifiex_cfg80211_leave_ibss,
> > .add_key = mwifiex_cfg80211_add_key,
> > .del_key = mwifiex_cfg80211_del_key,
> > + .set_default_mgmt_key = mwifiex_cfg80211_set_default_mgmt_key,
> > .mgmt_tx = mwifiex_cfg80211_mgmt_tx,
> > .mgmt_frame_register = mwifiex_cfg80211_mgmt_frame_register,
> > .remain_on_channel = mwifiex_cfg80211_remain_on_channel,
>
> Is it correct to ignore the key index? I see that brcmfmac ignores it as
> well but I want to still confirm this.
>
> Does this mean that with this patcfh mwifiex properly supports MFP?
>

Yes. We do pass MFP tests with this patch.

Regards,
Amitkumar

2016-07-11 15:03:58

by Amitkumar Karwar

[permalink] [raw]
Subject: [PATCH 7/9] mwifiex: remove misleading disconnect message

Disconnect message in mwifiex_reset_connect_state() would displays
necessary information. We unnecessarily have exactly same message in
cfg80211_disconnect(). As priv->cfg_bssid is cleared at this point of
time, it prints incorrect(all zero) MAC.

This message is removed here.

Signed-off-by: Amitkumar Karwar <[email protected]>
---
drivers/net/wireless/marvell/mwifiex/cfg80211.c | 4 ----
1 file changed, 4 deletions(-)

diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
index bf95cca..73dd39d 100644
--- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
@@ -2022,10 +2022,6 @@ mwifiex_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
if (mwifiex_deauthenticate(priv, NULL))
return -EFAULT;

- mwifiex_dbg(priv->adapter, MSG,
- "info: successfully disconnected from %pM:\t"
- "reason code %d\n", priv->cfg_bssid, reason_code);
-
eth_zero_addr(priv->cfg_bssid);
priv->hs2_enabled = false;

--
1.9.1


2016-07-11 15:05:02

by Amitkumar Karwar

[permalink] [raw]
Subject: [PATCH 8/9] mwifiex: add HT aggregation support for adhoc mode

From: Xinming Hu <[email protected]>

This patch adds HT support for adhoc station. Firmware will upload
ibss sta connect event with beacon data, whenever new station joins
the adhoc network. Driver will check the HT IE and decide whether to
support HT aggreagation or not.

Signed-off-by: Xinming Hu <[email protected]>
Signed-off-by: Cathy Luo <[email protected]>
Signed-off-by: Amitkumar Karwar <[email protected]>
---
drivers/net/wireless/marvell/mwifiex/11n.h | 7 +-
drivers/net/wireless/marvell/mwifiex/fw.h | 9 ++
drivers/net/wireless/marvell/mwifiex/sta_event.c | 132 ++++++++++++++++++++++-
3 files changed, 144 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/marvell/mwifiex/11n.h b/drivers/net/wireless/marvell/mwifiex/11n.h
index afdd58a..ea0fa68 100644
--- a/drivers/net/wireless/marvell/mwifiex/11n.h
+++ b/drivers/net/wireless/marvell/mwifiex/11n.h
@@ -171,9 +171,10 @@ mwifiex_find_stream_to_delete(struct mwifiex_private *priv, int ptr_tid,
static inline int mwifiex_is_sta_11n_enabled(struct mwifiex_private *priv,
struct mwifiex_sta_node *node)
{
-
- if (!node || (priv->bss_role != MWIFIEX_BSS_ROLE_UAP) ||
- !priv->ap_11n_enabled)
+ if (!node || ((priv->bss_role == MWIFIEX_BSS_ROLE_UAP) &&
+ !priv->ap_11n_enabled) ||
+ ((priv->bss_mode == NL80211_IFTYPE_ADHOC) &&
+ !priv->adapter->adhoc_11n_enabled))
return 0;

return node->is_11n_enabled;
diff --git a/drivers/net/wireless/marvell/mwifiex/fw.h b/drivers/net/wireless/marvell/mwifiex/fw.h
index 3b40e0d..a88030a 100644
--- a/drivers/net/wireless/marvell/mwifiex/fw.h
+++ b/drivers/net/wireless/marvell/mwifiex/fw.h
@@ -210,6 +210,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {

#define MWIFIEX_TX_DATA_BUF_SIZE_4K 4096
#define MWIFIEX_TX_DATA_BUF_SIZE_8K 8192
+#define MWIFIEX_TX_DATA_BUF_SIZE_12K 12288

#define ISSUPP_11NENABLED(FwCapInfo) (FwCapInfo & BIT(11))
#define ISSUPP_TDLS_ENABLED(FwCapInfo) (FwCapInfo & BIT(14))
@@ -506,6 +507,8 @@ enum P2P_MODES {
#define EVENT_RSSI_HIGH 0x0000001c
#define EVENT_SNR_HIGH 0x0000001d
#define EVENT_IBSS_COALESCED 0x0000001e
+#define EVENT_IBSS_STA_CONNECT 0x00000020
+#define EVENT_IBSS_STA_DISCONNECT 0x00000021
#define EVENT_DATA_RSSI_LOW 0x00000024
#define EVENT_DATA_SNR_LOW 0x00000025
#define EVENT_DATA_RSSI_HIGH 0x00000026
@@ -1686,6 +1689,12 @@ struct mwifiex_ie_types_wmm_param_set {
u8 wmm_ie[1];
};

+struct mwifiex_ie_types_mgmt_frame {
+ struct mwifiex_ie_types_header header;
+ __le16 frame_control;
+ u8 frame_contents[0];
+};
+
struct mwifiex_ie_types_wmm_queue_status {
struct mwifiex_ie_types_header header;
u8 queue_index;
diff --git a/drivers/net/wireless/marvell/mwifiex/sta_event.c b/drivers/net/wireless/marvell/mwifiex/sta_event.c
index b973ee8..9df0c4d 100644
--- a/drivers/net/wireless/marvell/mwifiex/sta_event.c
+++ b/drivers/net/wireless/marvell/mwifiex/sta_event.c
@@ -25,6 +25,99 @@
#include "wmm.h"
#include "11n.h"

+#define MWIFIEX_IBSS_CONNECT_EVT_FIX_SIZE 12
+
+static int mwifiex_check_ibss_peer_capabilties(struct mwifiex_private *priv,
+ struct mwifiex_sta_node *sta_ptr,
+ struct sk_buff *event)
+{
+ int evt_len, ele_len;
+ u8 *curr;
+ struct ieee_types_header *ele_hdr;
+ struct mwifiex_ie_types_mgmt_frame *tlv_mgmt_frame;
+ const struct ieee80211_ht_cap *ht_cap;
+ const struct ieee80211_vht_cap *vht_cap;
+
+ skb_pull(event, MWIFIEX_IBSS_CONNECT_EVT_FIX_SIZE);
+ evt_len = event->len;
+ curr = event->data;
+
+ mwifiex_dbg_dump(priv->adapter, EVT_D, "ibss peer capabilties:",
+ event->data, event->len);
+
+ skb_push(event, MWIFIEX_IBSS_CONNECT_EVT_FIX_SIZE);
+
+ tlv_mgmt_frame = (void *)curr;
+ if (evt_len >= sizeof(*tlv_mgmt_frame) &&
+ le16_to_cpu(tlv_mgmt_frame->header.type) ==
+ TLV_TYPE_UAP_MGMT_FRAME) {
+ /* Locate curr pointer to the start of beacon tlv,
+ * timestamp 8 bytes, beacon intervel 2 bytes,
+ * capability info 2 bytes, totally 12 byte beacon header
+ */
+ evt_len = le16_to_cpu(tlv_mgmt_frame->header.len);
+ curr += (sizeof(*tlv_mgmt_frame) + 12);
+ } else {
+ mwifiex_dbg(priv->adapter, MSG,
+ "management frame tlv not found!\n");
+ return 0;
+ }
+
+ while (evt_len >= sizeof(*ele_hdr)) {
+ ele_hdr = (struct ieee_types_header *)curr;
+ ele_len = ele_hdr->len;
+
+ if (evt_len < ele_len + sizeof(*ele_hdr))
+ break;
+
+ switch (ele_hdr->element_id) {
+ case WLAN_EID_HT_CAPABILITY:
+ sta_ptr->is_11n_enabled = true;
+ ht_cap = (void *)(ele_hdr + 2);
+ sta_ptr->max_amsdu = le16_to_cpu(ht_cap->cap_info) &
+ IEEE80211_HT_CAP_MAX_AMSDU ?
+ MWIFIEX_TX_DATA_BUF_SIZE_8K :
+ MWIFIEX_TX_DATA_BUF_SIZE_4K;
+ mwifiex_dbg(priv->adapter, INFO,
+ "11n enabled!, max_amsdu : %d\n",
+ sta_ptr->max_amsdu);
+ break;
+
+ case WLAN_EID_VHT_CAPABILITY:
+ sta_ptr->is_11ac_enabled = true;
+ vht_cap = (void *)(ele_hdr + 2);
+ /* check VHT MAXMPDU capability */
+ switch (le32_to_cpu(vht_cap->vht_cap_info) & 0x3) {
+ case IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454:
+ sta_ptr->max_amsdu =
+ MWIFIEX_TX_DATA_BUF_SIZE_12K;
+ break;
+ case IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991:
+ sta_ptr->max_amsdu =
+ MWIFIEX_TX_DATA_BUF_SIZE_8K;
+ break;
+ case IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895:
+ sta_ptr->max_amsdu =
+ MWIFIEX_TX_DATA_BUF_SIZE_4K;
+ default:
+ break;
+ }
+
+ mwifiex_dbg(priv->adapter, INFO,
+ "11ac enabled!, max_amsdu : %d\n",
+ sta_ptr->max_amsdu);
+ break;
+ default:
+ break;
+ }
+
+ curr += (ele_len + sizeof(*ele_hdr));
+ evt_len -= (ele_len + sizeof(*ele_hdr));
+ }
+
+ return 0;
+}
+
/*
* This function resets the connection state.
*
@@ -519,6 +612,8 @@ void mwifiex_bt_coex_wlan_param_update_event(struct mwifiex_private *priv,
* - EVENT_LINK_QUALITY
* - EVENT_PRE_BEACON_LOST
* - EVENT_IBSS_COALESCED
+ * - EVENT_IBSS_STA_CONNECT
+ * - EVENT_IBSS_STA_DISCONNECT
* - EVENT_WEP_ICV_ERR
* - EVENT_BW_CHANGE
* - EVENT_HOSTWAKE_STAIE
@@ -547,9 +642,11 @@ void mwifiex_bt_coex_wlan_param_update_event(struct mwifiex_private *priv,
int mwifiex_process_sta_event(struct mwifiex_private *priv)
{
struct mwifiex_adapter *adapter = priv->adapter;
- int ret = 0;
+ int ret = 0, i;
u32 eventcause = adapter->event_cause;
u16 ctrl, reason_code;
+ u8 ibss_sta_addr[ETH_ALEN];
+ struct mwifiex_sta_node *sta_ptr;

switch (eventcause) {
case EVENT_DUMMY_HOST_WAKEUP_SIGNAL:
@@ -775,6 +872,39 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
HostCmd_CMD_802_11_IBSS_COALESCING_STATUS,
HostCmd_ACT_GEN_GET, 0, NULL, false);
break;
+ case EVENT_IBSS_STA_CONNECT:
+ ether_addr_copy(ibss_sta_addr, adapter->event_body + 2);
+ mwifiex_dbg(adapter, EVENT, "event: IBSS_STA_CONNECT %pM\n",
+ ibss_sta_addr);
+ sta_ptr = mwifiex_add_sta_entry(priv, ibss_sta_addr);
+ if (sta_ptr && adapter->adhoc_11n_enabled) {
+ mwifiex_check_ibss_peer_capabilties(priv, sta_ptr,
+ adapter->event_skb);
+ if (sta_ptr->is_11n_enabled)
+ for (i = 0; i < MAX_NUM_TID; i++)
+ sta_ptr->ampdu_sta[i] =
+ priv->aggr_prio_tbl[i].ampdu_user;
+ else
+ for (i = 0; i < MAX_NUM_TID; i++)
+ sta_ptr->ampdu_sta[i] =
+ BA_STREAM_NOT_ALLOWED;
+ memset(sta_ptr->rx_seq, 0xff, sizeof(sta_ptr->rx_seq));
+ }
+
+ break;
+ case EVENT_IBSS_STA_DISCONNECT:
+ ether_addr_copy(ibss_sta_addr, adapter->event_body + 2);
+ mwifiex_dbg(adapter, EVENT, "event: IBSS_STA_DISCONNECT %pM\n",
+ ibss_sta_addr);
+ sta_ptr = mwifiex_get_sta_entry(priv, ibss_sta_addr);
+ if (sta_ptr && sta_ptr->is_11n_enabled) {
+ mwifiex_11n_del_rx_reorder_tbl_by_ta(priv,
+ ibss_sta_addr);
+ mwifiex_del_tx_ba_stream_tbl_by_ra(priv, ibss_sta_addr);
+ }
+ mwifiex_wmm_del_peer_ra_list(priv, ibss_sta_addr);
+ mwifiex_del_sta_entry(priv, ibss_sta_addr);
+ break;
case EVENT_ADDBA:
mwifiex_dbg(adapter, EVENT, "event: ADDBA Request\n");
mwifiex_send_cmd(priv, HostCmd_CMD_11N_ADDBA_RSP,
--
1.9.1


2016-07-11 15:03:12

by Amitkumar Karwar

[permalink] [raw]
Subject: [PATCH 5/9] mwifiex: cfg80211 set_default_mgmt_key handler

It is observed that hostapd fails to setup with management frame
protection mode enabled when using mwifiex. This patch adds
cfg80211_set_default_mgmt_key handler to resolve the problem.

Signed-off-by: Amitkumar Karwar <[email protected]>
---
drivers/net/wireless/marvell/mwifiex/cfg80211.c | 13 +++++++++++++
1 file changed, 13 insertions(+)

diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
index 8955f8c..bf95cca 100644
--- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
@@ -484,6 +484,18 @@ mwifiex_cfg80211_add_key(struct wiphy *wiphy, struct net_device *netdev,
}

/*
+ * CFG802.11 operation handler to set default mgmt key.
+ */
+static int
+mwifiex_cfg80211_set_default_mgmt_key(struct wiphy *wiphy,
+ struct net_device *netdev,
+ u8 key_index)
+{
+ wiphy_dbg(wiphy, "set default mgmt key, key index=%d\n", key_index);
+ return 0;
+}
+
+/*
* This function sends domain information to the firmware.
*
* The following information are passed to the firmware -
@@ -4002,6 +4014,7 @@ static struct cfg80211_ops mwifiex_cfg80211_ops = {
.leave_ibss = mwifiex_cfg80211_leave_ibss,
.add_key = mwifiex_cfg80211_add_key,
.del_key = mwifiex_cfg80211_del_key,
+ .set_default_mgmt_key = mwifiex_cfg80211_set_default_mgmt_key,
.mgmt_tx = mwifiex_cfg80211_mgmt_tx,
.mgmt_frame_register = mwifiex_cfg80211_mgmt_frame_register,
.remain_on_channel = mwifiex_cfg80211_remain_on_channel,
--
1.9.1


2016-07-11 14:57:40

by Amitkumar Karwar

[permalink] [raw]
Subject: [PATCH 2/9] mwifiex: add region code information in debugfs

From: Karthik D A <[email protected]>

region code is an EEPROM setting received from firmware. Let's display
this in debugfs along with other information.

Signed-off-by: Karthik D A <[email protected]>
Signed-off-by: Amitkumar Karwar <[email protected]>
---
drivers/net/wireless/marvell/mwifiex/debugfs.c | 2 ++
1 file changed, 2 insertions(+)

diff --git a/drivers/net/wireless/marvell/mwifiex/debugfs.c b/drivers/net/wireless/marvell/mwifiex/debugfs.c
index bccf17a..b9284b5 100644
--- a/drivers/net/wireless/marvell/mwifiex/debugfs.c
+++ b/drivers/net/wireless/marvell/mwifiex/debugfs.c
@@ -118,6 +118,8 @@ mwifiex_info_read(struct file *file, char __user *ubuf,
p += sprintf(p, "bssid=\"%pM\"\n", info.bssid);
p += sprintf(p, "channel=\"%d\"\n", (int) info.bss_chan);
p += sprintf(p, "country_code = \"%s\"\n", info.country_code);
+ p += sprintf(p, "region_code=\"0x%x\"\n",
+ priv->adapter->region_code);

netdev_for_each_mc_addr(ha, netdev)
p += sprintf(p, "multicast_address[%d]=\"%pM\"\n",
--
1.9.1


2016-07-25 09:33:25

by Amitkumar Karwar

[permalink] [raw]
Subject: RE: [PATCH 5/9] mwifiex: cfg80211 set_default_mgmt_key handler

Hi Jouni,

> From: Jouni Malinen [mailto:[email protected]]
> Sent: Friday, July 22, 2016 10:25 PM
> To: Amitkumar Karwar
> Cc: Kalle Valo; [email protected]; Cathy Luo; Nishant
> Sarmukadam
> Subject: Re: [PATCH 5/9] mwifiex: cfg80211 set_default_mgmt_key handler
>
> On Fri, Jul 22, 2016 at 03:59:47PM +0000, Amitkumar Karwar wrote:
> > I am trying to understand the problem you mentioned during IGTK
> rekeying. Today I ran tests with two stations connecting an AP. MFP is
> enabled on all of them.
> >
> > On hostapd side, my observation is add_key() is always called followed
> by set_default_mgmt_key(). set_default_mgmt_key() sets the key added by
> add_key() as default key.
> >
> > We are ignoring set_default_mgmt_key() and updating Tx key index
> during add_key() itself.
> >
> > Your concerns is we should not update Tx key index during add_key().
> Reason is IGTK rekeying is not yet completed with all stations. Right?
>
> Correct. set_default_mgmt_key() does not have much effect for the very
> first IGTK configuration, but whenever doing IGTK rekeying, hostapd
> behaves just like it does with GTK rekeying. In other words, a different
> Key ID is selected (alternating between 4 and 5), a random new IGTK is
> generated, the new IGTK is configured to the local driver (but the old
> IGTK is still supposed to be used for TX), each associated STA is
> notified of the new IGTK, the new IGTK is taken into use once the group
> key handshake has completed with each associated STA. It is that last
> operation that needs set_default_mgmt_key() to allow this rekeying to
> work correctly. If you update the TX Key ID on add_key(), you'll risk
> sending out frames that some of the associated STAs do not yet have a
> key to validate.
>

Got it. We will implement set_default_mgmt_key() and check if any firmware changes required.

Regards,
Amitkumar

2016-07-11 15:01:38

by Amitkumar Karwar

[permalink] [raw]
Subject: [PATCH 4/9] mwifiex: support random MAC address for scanning

From: Ganapathi Bhat <[email protected]>

This patch advertises RANDOM_MAC_ADDR feature to cfg80211. It allow the
application to issue scan with a MAC address and mask. Random MACs are
generated and used in probe requests sent for scanning until it is changed
by the application or device is restarted.

Signed-off-by: Ganapathi Bhat <[email protected]>
Signed-off-by: Amitkumar Karwar <[email protected]>
---
drivers/net/wireless/marvell/mwifiex/cfg80211.c | 15 ++++++++++++++-
drivers/net/wireless/marvell/mwifiex/fw.h | 7 +++++++
drivers/net/wireless/marvell/mwifiex/main.h | 1 +
drivers/net/wireless/marvell/mwifiex/scan.c | 16 ++++++++++++++++
4 files changed, 38 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
index 867ab81..8955f8c 100644
--- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
@@ -2483,6 +2483,16 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy,

priv->scan_request = request;

+ if (request->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
+ ether_addr_copy(priv->random_mac, request->mac_addr);
+ for (i = 0; i < ETH_ALEN; i++) {
+ priv->random_mac[i] &= request->mac_addr_mask[i];
+ priv->random_mac[i] |= get_random_int() &
+ ~(request->mac_addr_mask[i]);
+ }
+ }
+
+ ether_addr_copy(user_scan_cfg->random_mac, priv->random_mac);
user_scan_cfg->num_ssids = request->n_ssids;
user_scan_cfg->ssid_list = request->ssids;

@@ -4171,7 +4181,10 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
wiphy->features |= NL80211_FEATURE_HT_IBSS |
NL80211_FEATURE_INACTIVITY_TIMER |
NL80211_FEATURE_LOW_PRIORITY_SCAN |
- NL80211_FEATURE_NEED_OBSS_SCAN;
+ NL80211_FEATURE_NEED_OBSS_SCAN |
+ NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR |
+ NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR |
+ NL80211_FEATURE_ND_RANDOM_MAC_ADDR;

if (ISSUPP_TDLS_ENABLED(adapter->fw_cap_info))
wiphy->features |= NL80211_FEATURE_TDLS_CHANNEL_SWITCH;
diff --git a/drivers/net/wireless/marvell/mwifiex/fw.h b/drivers/net/wireless/marvell/mwifiex/fw.h
index c46267b..3797ef4 100644
--- a/drivers/net/wireless/marvell/mwifiex/fw.h
+++ b/drivers/net/wireless/marvell/mwifiex/fw.h
@@ -188,6 +188,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
#define TLV_BTCOEX_WL_AGGR_WINSIZE (PROPRIETARY_TLV_BASE_ID + 202)
#define TLV_BTCOEX_WL_SCANTIME (PROPRIETARY_TLV_BASE_ID + 203)
#define TLV_TYPE_BSS_MODE (PROPRIETARY_TLV_BASE_ID + 206)
+#define TLV_TYPE_RANDOM_MAC (PROPRIETARY_TLV_BASE_ID + 236)

#define MWIFIEX_TX_DATA_BUF_SIZE_2K 2048

@@ -780,6 +781,11 @@ struct mwifiex_ie_types_scan_chan_gap {
__le16 chan_gap;
} __packed;

+struct mwifiex_ie_types_random_mac {
+ struct mwifiex_ie_types_header header;
+ u8 mac[ETH_ALEN];
+} __packed;
+
struct mwifiex_ietypes_chanstats {
struct mwifiex_ie_types_header header;
struct mwifiex_fw_chan_stats chanstats[0];
@@ -1464,6 +1470,7 @@ struct mwifiex_user_scan_cfg {
/* 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;
+ u8 random_mac[ETH_ALEN];
} __packed;

#define MWIFIEX_BG_SCAN_CHAN_MAX 38
diff --git a/drivers/net/wireless/marvell/mwifiex/main.h b/drivers/net/wireless/marvell/mwifiex/main.h
index 9f6bb40..5902600 100644
--- a/drivers/net/wireless/marvell/mwifiex/main.h
+++ b/drivers/net/wireless/marvell/mwifiex/main.h
@@ -675,6 +675,7 @@ struct mwifiex_private {
struct mwifiex_user_scan_chan hidden_chan[MWIFIEX_USER_SCAN_CHAN_MAX];
u8 assoc_resp_ht_param;
bool ht_param_present;
+ u8 random_mac[ETH_ALEN];
};


diff --git a/drivers/net/wireless/marvell/mwifiex/scan.c b/drivers/net/wireless/marvell/mwifiex/scan.c
index 87e7000..ed252d8 100644
--- a/drivers/net/wireless/marvell/mwifiex/scan.c
+++ b/drivers/net/wireless/marvell/mwifiex/scan.c
@@ -820,6 +820,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_random_mac *random_mac_tlv;
struct mwifiex_ie_types_wildcard_ssid_params *wildcard_ssid_tlv;
struct mwifiex_ie_types_bssid_list *bssid_tlv;
u8 *tlv_pos;
@@ -835,6 +836,7 @@ mwifiex_config_scan(struct mwifiex_private *priv,
u8 ssid_filter;
struct mwifiex_ie_types_htcap *ht_cap;
struct mwifiex_ie_types_bss_mode *bss_mode;
+ const u8 zero_mac[6] = {0, 0, 0, 0, 0, 0};

/* The tlv_buf_len is calculated for each scan command. The TLVs added
in this routine will be preserved since the routine that sends the
@@ -967,6 +969,18 @@ mwifiex_config_scan(struct mwifiex_private *priv,
tlv_pos +=
sizeof(struct mwifiex_ie_types_scan_chan_gap);
}
+
+ if (!ether_addr_equal(user_scan_in->random_mac, zero_mac)) {
+ random_mac_tlv = (void *)tlv_pos;
+ random_mac_tlv->header.type =
+ cpu_to_le16(TLV_TYPE_RANDOM_MAC);
+ random_mac_tlv->header.len =
+ cpu_to_le16(sizeof(random_mac_tlv->mac));
+ ether_addr_copy(random_mac_tlv->mac,
+ user_scan_in->random_mac);
+ tlv_pos +=
+ sizeof(struct mwifiex_ie_types_random_mac);
+ }
} else {
scan_cfg_out->bss_mode = (u8) adapter->scan_mode;
num_probes = adapter->scan_probes;
@@ -1922,6 +1936,7 @@ mwifiex_active_scan_req_for_passive_chan(struct mwifiex_private *priv)
}

adapter->active_scan_triggered = true;
+ ether_addr_copy(user_scan_cfg->random_mac, priv->random_mac);
user_scan_cfg->num_ssids = priv->scan_request->n_ssids;
user_scan_cfg->ssid_list = priv->scan_request->ssids;

@@ -2749,6 +2764,7 @@ static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv,
if (!scan_cfg)
return -ENOMEM;

+ ether_addr_copy(scan_cfg->random_mac, priv->random_mac);
scan_cfg->ssid_list = req_ssid;
scan_cfg->num_ssids = 1;

--
1.9.1


2016-07-11 14:59:23

by Amitkumar Karwar

[permalink] [raw]
Subject: [PATCH 3/9] mwifiex: fix failed to reconnect after interface disabled/enabled

Recent patch "mwifiex: fix NULL pointer" skips extended scan event
handling when suspend is in progress. It created a problem for scan
after interface disabled/enabled case.

This patch solves the problem by checking netif_running() status.

Fixes:16d25da94f3d654 ("mwifiex: fix NULL pointer dereference during suspend")
Signed-off-by: Amitkumar Karwar <[email protected]>
---
drivers/net/wireless/marvell/mwifiex/sta_event.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/marvell/mwifiex/sta_event.c b/drivers/net/wireless/marvell/mwifiex/sta_event.c
index a422f33..7e394d4 100644
--- a/drivers/net/wireless/marvell/mwifiex/sta_event.c
+++ b/drivers/net/wireless/marvell/mwifiex/sta_event.c
@@ -708,7 +708,11 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)

case EVENT_EXT_SCAN_REPORT:
mwifiex_dbg(adapter, EVENT, "event: EXT_SCAN Report\n");
- if (adapter->ext_scan && !priv->scan_aborting)
+ /* We intend to skip this event during suspend, but handle
+ * it in interface disabled case
+ */
+ if (adapter->ext_scan && (!priv->scan_aborting ||
+ !netif_running(priv->netdev)))
ret = mwifiex_handle_event_ext_scan_report(priv,
adapter->event_skb->data);

--
1.9.1


2016-07-22 15:59:53

by Amitkumar Karwar

[permalink] [raw]
Subject: RE: [PATCH 5/9] mwifiex: cfg80211 set_default_mgmt_key handler

Hi Jouni,

> From: Jouni Malinen [mailto:[email protected]]
> Sent: Thursday, July 21, 2016 9:22 PM
> To: Amitkumar Karwar
> Cc: Kalle Valo; [email protected]; Cathy Luo; Nishant
> Sarmukadam
> Subject: Re: [PATCH 5/9] mwifiex: cfg80211 set_default_mgmt_key handler
>
> On Thu, Jul 21, 2016 at 09:18:11AM +0000, Amitkumar Karwar wrote:
> > > From: Kalle Valo [mailto:[email protected]] Is it correct to
> > > ignore the key index? I see that brcmfmac ignores it as well but I
> > > want to still confirm this.
> > >
> > > Does this mean that with this patcfh mwifiex properly supports MFP?
> >
> > Yes. We do pass MFP tests with this patch.
>
> Did you test IGTK rekeying? This patch looks exactly as broken as it did
> the last time it was proposed more than a year ago and after the same
> concern not receiving any reaction.. hostapd will configure two
> different IGTKs with different Key IDs and change the TX key on the AP
> once all associated STAs have the new key. If the driver does not
> support updating the TX key index, either the old or the new STAs
> associated after rekeying will not have the correct key.
>

Thanks for your feedback and guidance on this.

I am trying to understand the problem you mentioned during IGTK rekeying. Today I ran tests with two stations connecting an AP. MFP is enabled on all of them.

On hostapd side, my observation is add_key() is always called followed by set_default_mgmt_key(). set_default_mgmt_key() sets the key added by add_key() as default key.

We are ignoring set_default_mgmt_key() and updating Tx key index during add_key() itself.

Your concerns is we should not update Tx key index during add_key(). Reason is IGTK rekeying is not yet completed with all stations. Right?

Regards,
Amitkumar