diff mbox series

[v10,1/2] wifi: mwifiex: add host mlme for client mode

Message ID 20240418060626.431202-2-yu-hao.lin@nxp.com (mailing list archive)
State Changes Requested
Delegated to: Kalle Valo
Headers show
Series wifi: mwifiex: add code to support host mlme | expand

Commit Message

David Lin April 18, 2024, 6:06 a.m. UTC
Add host based MLME to enable WPA3 functionalities in client mode.
This feature required a firmware with the corresponding V2 Key API
support. The feature (WPA3) is currently enabled and verified only
on IW416. Also, verified no regression with change when host MLME
is disabled.

Signed-off-by: David Lin <yu-hao.lin@nxp.com>
Reviewed-by: Francesco Dolcini <francesco.dolcini@toradex.com>
---

v10:
   - use eth_broadcast_addr() to set the broadcast address.
   - add comment for constant used for the length of FW special 4 address
     management header.
   - check host_mlme_enabled to decide if creating host_mlme_workqueue
     or not.
   - use cpu_to_le16 instead of casting via (__force __le16).
   - change the abbreviation "disasso" to "disassoc" of the printout message. 

v9:
   - remove redundent code.

v8:
   - first full and complete patch to support host based MLME for client
     mode.

---
 .../net/wireless/marvell/mwifiex/cfg80211.c   | 314 ++++++++++++++++++
 drivers/net/wireless/marvell/mwifiex/cmdevt.c |  25 ++
 drivers/net/wireless/marvell/mwifiex/decl.h   |  23 ++
 drivers/net/wireless/marvell/mwifiex/fw.h     |  33 ++
 drivers/net/wireless/marvell/mwifiex/init.c   |   6 +
 drivers/net/wireless/marvell/mwifiex/join.c   |  66 +++-
 drivers/net/wireless/marvell/mwifiex/main.c   |  62 ++++
 drivers/net/wireless/marvell/mwifiex/main.h   |  16 +
 drivers/net/wireless/marvell/mwifiex/scan.c   |   6 +
 drivers/net/wireless/marvell/mwifiex/sdio.c   |  13 +
 drivers/net/wireless/marvell/mwifiex/sdio.h   |   2 +
 .../net/wireless/marvell/mwifiex/sta_event.c  |  36 +-
 .../net/wireless/marvell/mwifiex/sta_ioctl.c  |   2 +-
 drivers/net/wireless/marvell/mwifiex/sta_tx.c |   9 +-
 drivers/net/wireless/marvell/mwifiex/util.c   |  80 +++++
 15 files changed, 679 insertions(+), 14 deletions(-)

Comments

Francesco Dolcini April 18, 2024, 6:37 a.m. UTC | #1
On Thu, Apr 18, 2024 at 02:06:25PM +0800, David Lin wrote:
> Add host based MLME to enable WPA3 functionalities in client mode.
> This feature required a firmware with the corresponding V2 Key API
> support. The feature (WPA3) is currently enabled and verified only
> on IW416. Also, verified no regression with change when host MLME
> is disabled.
> 
> Signed-off-by: David Lin <yu-hao.lin@nxp.com>
> Reviewed-by: Francesco Dolcini <francesco.dolcini@toradex.com>

...

> diff --git a/drivers/net/wireless/marvell/mwifiex/util.c b/drivers/net/wireless/marvell/mwifiex/util.c
> index 745b1d925b21..3817c08a1507 100644
> --- a/drivers/net/wireless/marvell/mwifiex/util.c
> +++ b/drivers/net/wireless/marvell/mwifiex/util.c
> @@ -417,6 +456,47 @@ mwifiex_process_mgmt_packet(struct mwifiex_private *priv,

...

> +				mwifiex_dbg
> +				(priv->adapter, MSG,
> +				 "assoc: receive disassoc from %pM\n",
> +				 ieee_hdr->addr3);

The way you indented this does not seems kernel coding style compliant ...
however checkpatch does not complain ... so maybe I am just wrong.

In case you need to send a new version, please keep the open parenthesis together with the function name

				mwifiex_dbg(priv->adapter, MSG,
					    "assoc: receive disassoc from %pM\n",
					    ieee_hdr->addr3);

(yes, it's 81 column - and it's fine).

Again, IMHO, do not send a v11 just for this trivial change.

Francesco
David Lin April 18, 2024, 8:24 a.m. UTC | #2
> From: Francesco Dolcini <francesco@dolcini.it>
> Sent: Thursday, April 18, 2024 2:38 PM
> To: David Lin <yu-hao.lin@nxp.com>
> Cc: linux-wireless@vger.kernel.org; linux-kernel@vger.kernel.org;
> briannorris@chromium.org; kvalo@kernel.org; francesco@dolcini.it; Pete
> Hsieh <tsung-hsien.hsieh@nxp.com>; Francesco Dolcini
> <francesco.dolcini@toradex.com>
> Subject: [EXT] Re: [PATCH v10 1/2] wifi: mwifiex: add host mlme for client
> mode
> 
> Caution: This is an external email. Please take care when clicking links or
> opening attachments. When in doubt, report the message using the 'Report
> this email' button
> 
> 
> On Thu, Apr 18, 2024 at 02:06:25PM +0800, David Lin wrote:
> > Add host based MLME to enable WPA3 functionalities in client mode.
> > This feature required a firmware with the corresponding V2 Key API
> > support. The feature (WPA3) is currently enabled and verified only on
> > IW416. Also, verified no regression with change when host MLME is
> > disabled.
> >
> > Signed-off-by: David Lin <yu-hao.lin@nxp.com>
> > Reviewed-by: Francesco Dolcini <francesco.dolcini@toradex.com>
> 
> ...
> 
> > diff --git a/drivers/net/wireless/marvell/mwifiex/util.c
> > b/drivers/net/wireless/marvell/mwifiex/util.c
> > index 745b1d925b21..3817c08a1507 100644
> > --- a/drivers/net/wireless/marvell/mwifiex/util.c
> > +++ b/drivers/net/wireless/marvell/mwifiex/util.c
> > @@ -417,6 +456,47 @@ mwifiex_process_mgmt_packet(struct
> > mwifiex_private *priv,
> 
> ...
> 
> > +                             mwifiex_dbg
> > +                             (priv->adapter, MSG,
> > +                              "assoc: receive disassoc from %pM\n",
> > +                              ieee_hdr->addr3);
> 
> The way you indented this does not seems kernel coding style compliant ...
> however checkpatch does not complain ... so maybe I am just wrong.
> 
> In case you need to send a new version, please keep the open parenthesis
> together with the function name
> 
>                                 mwifiex_dbg(priv->adapter, MSG,
>                                             "assoc: receive disassoc
> from %pM\n",
>                                             ieee_hdr->addr3);
> 
> (yes, it's 81 column - and it's fine).
> 
> Again, IMHO, do not send a v11 just for this trivial change.
> 
> Francesco
>

Because checkpatch.pl doesn't complain about this kind of coding, I use this way to let code less and equal 80.
I will correct it if new version of code is needed.

David
Brian Norris May 23, 2024, 12:53 a.m. UTC | #3
On Thu, Apr 18, 2024 at 02:06:25PM +0800, David Lin wrote:
> +static int
> +mwifiex_cfg80211_probe_client(struct wiphy *wiphy,
> +			      struct net_device *dev, const u8 *peer,
> +			      u64 *cookie)
> +{
> +	return -EOPNOTSUPP;
> +}
> +

> +		mwifiex_cfg80211_ops.probe_client =
> +			mwifiex_cfg80211_probe_client;

For the record, I feel like this question was not adequately handled
from v8. That thread is:

https://lore.kernel.org/all/CA+ASDXM1PEMRyxRpBryJ7G6e7yzG8Ku+g2_qpHN3g5djFpAWkw@mail.gmail.com/
Re: [EXT] Re: [PATCH v8 1/2] wifi: mwifiex: add host mlme for client mode

Brian
David Lin May 24, 2024, 9:46 a.m. UTC | #4
Hi Brian,

> From: Brian Norris <briannorris@chromium.org>
> Sent: Thursday, May 23, 2024 8:54 AM
> To: David Lin <yu-hao.lin@nxp.com>
> Cc: linux-wireless@vger.kernel.org; linux-kernel@vger.kernel.org;
> kvalo@kernel.org; francesco@dolcini.it; Pete Hsieh
> <tsung-hsien.hsieh@nxp.com>; Francesco Dolcini
> <francesco.dolcini@toradex.com>
> Subject: [EXT] Re: [PATCH v10 1/2] wifi: mwifiex: add host mlme for client
> mode
>
> On Thu, Apr 18, 2024 at 02:06:25PM +0800, David Lin wrote:
> > +static int
> > +mwifiex_cfg80211_probe_client(struct wiphy *wiphy,
> > +                           struct net_device *dev, const u8 *peer,
> > +                           u64 *cookie) {
> > +     return -EOPNOTSUPP;
> > +}
> > +
>
> > +             mwifiex_cfg80211_ops.probe_client =
> > +                     mwifiex_cfg80211_probe_client;
>
> For the record, I feel like this question was not adequately handled from v8.
> That thread is:
>
> https://lore.kern/
> el.org%2Fall%2FCA%2BASDXM1PEMRyxRpBryJ7G6e7yzG8Ku%2Bg2_qpHN3g5d
> jFpAWkw%40mail.gmail.com%2F&data=05%7C02%7Cyu-hao.lin%40nxp.com%
> 7C0b65f7e4a5fc46c8bdbc08dc7ac2c9ff%7C686ea1d3bc2b4c6fa92cd99c5c301
> 635%7C0%7C0%7C638520224227876720%7CUnknown%7CTWFpbGZsb3d8eyJ
> WIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7
> C0%7C%7C%7C&sdata=MpqW1U4yTgDcM0g20DRSAxEnHkNNkd2hwsZrVAxg8p
> w%3D&reserved=0
> Re: [EXT] Re: [PATCH v8 1/2] wifi: mwifiex: add host mlme for client mode
>
> Brian

The difference with and without hooking probe_client() is that "poll_command_supported" of hostapd will be set or not.
If "poll_command_supported" is not set (won't hook probe_client), it will let hostapd to set "use_monitor" and client can't
connect to AP.

Maybe I can put following comments:

Hook probe_client to avoid hostapd to set "poll_command_supported" as 0 and set "use_monitor" to 1.

David
Brian Norris May 24, 2024, 5:02 p.m. UTC | #5
On Fri, May 24, 2024 at 2:46 AM David Lin <yu-hao.lin@nxp.com> wrote:
> > From: Brian Norris <briannorris@chromium.org>
> >
> > On Thu, Apr 18, 2024 at 02:06:25PM +0800, David Lin wrote:
> > > +static int
> > > +mwifiex_cfg80211_probe_client(struct wiphy *wiphy,
> > > +                           struct net_device *dev, const u8 *peer,
> > > +                           u64 *cookie) {
> > > +     return -EOPNOTSUPP;
> > > +}
> > > +
> >
> > > +             mwifiex_cfg80211_ops.probe_client =
> > > +                     mwifiex_cfg80211_probe_client;
> >
> > For the record, I feel like this question was not adequately handled from v8.
> > That thread is:
> >
> > https://lore.kern/
> > el.org%2Fall%2FCA%2BASDXM1PEMRyxRpBryJ7G6e7yzG8Ku%2Bg2_qpHN3g5d
> > jFpAWkw%40mail.gmail.com%2F&data=05%7C02%7Cyu-hao.lin%40nxp.com%
> > 7C0b65f7e4a5fc46c8bdbc08dc7ac2c9ff%7C686ea1d3bc2b4c6fa92cd99c5c301
> > 635%7C0%7C0%7C638520224227876720%7CUnknown%7CTWFpbGZsb3d8eyJ
> > WIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7
> > C0%7C%7C%7C&sdata=MpqW1U4yTgDcM0g20DRSAxEnHkNNkd2hwsZrVAxg8p
> > w%3D&reserved=0
> > Re: [EXT] Re: [PATCH v8 1/2] wifi: mwifiex: add host mlme for client mode
>
> The difference with and without hooking probe_client() is that "poll_command_supported" of hostapd will be set or not.
> If "poll_command_supported" is not set (won't hook probe_client), it will let hostapd to set "use_monitor" and client can't
> connect to AP.

Yes, I already said that in the above reply.

If you read my v8 reply, my suggestion was that you need to fix
hostapd, rather than advertise lies in the kernel. You don't support
probe_client, so you shouldn't advertise it.

I think you should dig into the reasoning from this commit to figure
out what to do:
https://w1.fi/cgit/hostap/commit/?id=a11241fa114923b47892ad3279966839e9c2741d

Personally, I'm not sure what hostapd is doing with
NL80211_CMD_PROBE_CLIENT ... but you're the one submitting the code,
not me.

> Maybe I can put following comments:
>
> Hook probe_client to avoid hostapd to set "poll_command_supported" as 0 and set "use_monitor" to 1.

If we really can't fix hostapd, I'd avoid using such literal
descriptions of implementation details like variable names. Maybe
better:

"hostapd looks for NL80211_CMD_PROBE_CLIENT support; otherwise, it
requires monitor-mode support (which mwifiex doesn't support). Provide
fake probe_client support to work around this."

But again, please actually explore the reason hostapd is doing this
first, and see if you can fix it.

Brian
David Lin May 24, 2024, 10 p.m. UTC | #6
> From: Brian Norris <briannorris@chromium.org>
> Sent: Saturday, May 25, 2024 1:02 AM
> To: David Lin <yu-hao.lin@nxp.com>
> Cc: linux-wireless@vger.kernel.org; linux-kernel@vger.kernel.org;
> kvalo@kernel.org; francesco@dolcini.it; Pete Hsieh
> <tsung-hsien.hsieh@nxp.com>; Francesco Dolcini
> <francesco.dolcini@toradex.com>
> Subject: Re: [EXT] Re: [PATCH v10 1/2] wifi: mwifiex: add host mlme for client
> mode
> 
> On Fri, May 24, 2024 at 2:46 AM David Lin <yu-hao.lin@nxp.com> wrote:
> > > From: Brian Norris <briannorris@chromium.org>
> > >
> > > On Thu, Apr 18, 2024 at 02:06:25PM +0800, David Lin wrote:
> > > > +static int
> > > > +mwifiex_cfg80211_probe_client(struct wiphy *wiphy,
> > > > +                           struct net_device *dev, const u8
> *peer,
> > > > +                           u64 *cookie) {
> > > > +     return -EOPNOTSUPP;
> > > > +}
> > > > +
> > >
> > > > +             mwifiex_cfg80211_ops.probe_client =
> > > > +                     mwifiex_cfg80211_probe_client;
> > >
> > > For the record, I feel like this question was not adequately handled from
> v8.
> > > That thread is:
> > >
> > > https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Flo
> > >
> re.kern%2F&data=05%7C02%7Cyu-hao.lin%40nxp.com%7C2816a3135edd445
> d3a4
> > >
> 508dc7c13485e%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C6385
> 21669
> > >
> 455363246%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoi
> V2luMz
> > >
> IiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C0%7C%7C%7C&sdata=SsB%2FD1dUX
> %2FZD
> > > jU4MWursrFn3WRfSM6f3h%2Fnd0FZMYm0%3D&reserved=0
> > >
> el.org%2Fall%2FCA%2BASDXM1PEMRyxRpBryJ7G6e7yzG8Ku%2Bg2_qpHN3g5
> d
> > >
> jFpAWkw%40mail.gmail.com%2F&data=05%7C02%7Cyu-hao.lin%40nxp.com
> %
> > >
> 7C0b65f7e4a5fc46c8bdbc08dc7ac2c9ff%7C686ea1d3bc2b4c6fa92cd99c5c301
> > >
> 635%7C0%7C0%7C638520224227876720%7CUnknown%7CTWFpbGZsb3d8eyJ
> > >
> WIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7
> > >
> C0%7C%7C%7C&sdata=MpqW1U4yTgDcM0g20DRSAxEnHkNNkd2hwsZrVAxg8
> p
> > > w%3D&reserved=0
> > > Re: [EXT] Re: [PATCH v8 1/2] wifi: mwifiex: add host mlme for client
> > > mode
> >
> > The difference with and without hooking probe_client() is that
> "poll_command_supported" of hostapd will be set or not.
> > If "poll_command_supported" is not set (won't hook probe_client), it
> > will let hostapd to set "use_monitor" and client can't connect to AP.
> 
> Yes, I already said that in the above reply.
> 
> If you read my v8 reply, my suggestion was that you need to fix hostapd,
> rather than advertise lies in the kernel. You don't support probe_client, so
> you shouldn't advertise it.
> 
> I think you should dig into the reasoning from this commit to figure out
> what to do:
> https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fw1.fi%
> 2Fcgit%2Fhostap%2Fcommit%2F%3Fid%3Da11241fa114923b47892ad3279966
> 839e9c2741d&data=05%7C02%7Cyu-hao.lin%40nxp.com%7C2816a3135edd4
> 45d3a4508dc7c13485e%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%
> 7C638521669455374712%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAw
> MDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C0%7C%7C%7C&
> sdata=QXFrzLUM2CgSgWR0COo1vrmi5VlhpCzGCmEbxlyySS0%3D&reserved=0
> 
> Personally, I'm not sure what hostapd is doing with
> NL80211_CMD_PROBE_CLIENT ... but you're the one submitting the code,
> not me.
> 
> > Maybe I can put following comments:
> >
> > Hook probe_client to avoid hostapd to set "poll_command_supported" as
> 0 and set "use_monitor" to 1.
> 
> If we really can't fix hostapd, I'd avoid using such literal descriptions of
> implementation details like variable names. Maybe
> better:
> 
> "hostapd looks for NL80211_CMD_PROBE_CLIENT support; otherwise, it
> requires monitor-mode support (which mwifiex doesn't support). Provide
> fake probe_client support to work around this."
> 
> But again, please actually explore the reason hostapd is doing this first, and
> see if you can fix it.
> 
> Brian

I think it needs time to support probe client. Can we put your suggested comments to the code
used to hook probe_client() and add

"TODO: support probe client" to mwifiex_cfg80211_probe_client().

David
Brian Norris May 24, 2024, 10:54 p.m. UTC | #7
On Fri, May 24, 2024 at 3:01 PM David Lin <yu-hao.lin@nxp.com> wrote:
> I think it needs time to support probe client. Can we put your suggested comments to the code
> used to hook probe_client() and add
>
> "TODO: support probe client" to mwifiex_cfg80211_probe_client().

Are you suggesting that you plan to actually implement proper
probe_client support? Did you already do what I suggested, and
understand why hostapd needs probe_client support? This seems to be a
common pattern -- that reviewers are asking for you to do your
research, and it takes several requests before you actually do it.

Now that I've tried to do that research for you ... it looks like
hostapd uses probe_client to augment TX MGMT acks, as a proxy for
station presence / inactivity. If a station is inactive and
non-responsive, we disconnect it eventually. So that looks to me like
probe_client support should actually be optional, if your driver
reports TX status? And in that case, I'd still recommend you try to
fix hostapd.

But if you're really planning to implement proper probe_client
support, then I suppose the TODO approach is also OK.

I'd also request that you please actually do your research when
reviewers ask questions. I'm frankly not sure why I'm spending my time
on the above research, when the onus should be on the submitter to
explain why they're doing what they're doing.

Brian
David Lin May 25, 2024, 12:50 a.m. UTC | #8
Hi Brian,

> From: Brian Norris <briannorris@chromium.org>
> Sent: Saturday, May 25, 2024 6:55 AM
> To: David Lin <yu-hao.lin@nxp.com>
> Cc: linux-wireless@vger.kernel.org; linux-kernel@vger.kernel.org;
> kvalo@kernel.org; francesco@dolcini.it; Pete Hsieh
> <tsung-hsien.hsieh@nxp.com>; Francesco Dolcini
> <francesco.dolcini@toradex.com>
> Subject: Re: [EXT] Re: [PATCH v10 1/2] wifi: mwifiex: add host mlme for client
> mode
> 
> Caution: This is an external email. Please take care when clicking links or
> opening attachments. When in doubt, report the message using the 'Report
> this email' button
> 
> 
> On Fri, May 24, 2024 at 3:01 PM David Lin <yu-hao.lin@nxp.com> wrote:
> > I think it needs time to support probe client. Can we put your
> > suggested comments to the code used to hook probe_client() and add
> >
> > "TODO: support probe client" to mwifiex_cfg80211_probe_client().
> 
> Are you suggesting that you plan to actually implement proper probe_client
> support? Did you already do what I suggested, and understand why hostapd
> needs probe_client support? This seems to be a common pattern -- that
> reviewers are asking for you to do your research, and it takes several
> requests before you actually do it.
> 
> Now that I've tried to do that research for you ... it looks like hostapd uses
> probe_client to augment TX MGMT acks, as a proxy for station presence /
> inactivity. If a station is inactive and non-responsive, we disconnect it
> eventually. So that looks to me like probe_client support should actually be
> optional, if your driver reports TX status? And in that case, I'd still
> recommend you try to fix hostapd.
> 
> But if you're really planning to implement proper probe_client support, then
> I suppose the TODO approach is also OK.
> 
> I'd also request that you please actually do your research when reviewers
> ask questions. I'm frankly not sure why I'm spending my time on the above
> research, when the onus should be on the submitter to explain why they're
> doing what they're doing.
> 
> Brian

Yes. I know when aging time of station is out, hostapd will use probe_client to check if station is still there before really disconnect it.

Without this feature, it won't really affect mayor function of hostapd.

That is the reason that I suggest that we put comments and TODO to the code.

David
David Lin May 25, 2024, 11:24 a.m. UTC | #9
> From: David Lin <yu-hao.lin@nxp.com>
> Sent: Saturday, May 25, 2024 8:51 AM
> To: Brian Norris <briannorris@chromium.org>
> Cc: linux-wireless@vger.kernel.org; linux-kernel@vger.kernel.org;
> kvalo@kernel.org; francesco@dolcini.it; Pete Hsieh
> <tsung-hsien.hsieh@nxp.com>; Francesco Dolcini
> <francesco.dolcini@toradex.com>
> Subject: RE: [EXT] Re: [PATCH v10 1/2] wifi: mwifiex: add host mlme for client
> mode
> 
> Hi Brian,
> 
> > From: Brian Norris <briannorris@chromium.org>
> > Sent: Saturday, May 25, 2024 6:55 AM
> > To: David Lin <yu-hao.lin@nxp.com>
> > Cc: linux-wireless@vger.kernel.org; linux-kernel@vger.kernel.org;
> > kvalo@kernel.org; francesco@dolcini.it; Pete Hsieh
> > <tsung-hsien.hsieh@nxp.com>; Francesco Dolcini
> > <francesco.dolcini@toradex.com>
> > Subject: Re: [EXT] Re: [PATCH v10 1/2] wifi: mwifiex: add host mlme
> > for client mode
> >
> > Caution: This is an external email. Please take care when clicking
> > links or opening attachments. When in doubt, report the message using
> > the 'Report this email' button
> >
> >
> > On Fri, May 24, 2024 at 3:01 PM David Lin <yu-hao.lin@nxp.com> wrote:
> > > I think it needs time to support probe client. Can we put your
> > > suggested comments to the code used to hook probe_client() and add
> > >
> > > "TODO: support probe client" to mwifiex_cfg80211_probe_client().
> >
> > Are you suggesting that you plan to actually implement proper
> > probe_client support? Did you already do what I suggested, and
> > understand why hostapd needs probe_client support? This seems to be a
> > common pattern -- that reviewers are asking for you to do your
> > research, and it takes several requests before you actually do it.
> >
> > Now that I've tried to do that research for you ... it looks like
> > hostapd uses probe_client to augment TX MGMT acks, as a proxy for
> > station presence / inactivity. If a station is inactive and
> > non-responsive, we disconnect it eventually. So that looks to me like
> > probe_client support should actually be optional, if your driver
> > reports TX status? And in that case, I'd still recommend you try to fix
> hostapd.
> >
> > But if you're really planning to implement proper probe_client
> > support, then I suppose the TODO approach is also OK.
> >
> > I'd also request that you please actually do your research when
> > reviewers ask questions. I'm frankly not sure why I'm spending my time
> > on the above research, when the onus should be on the submitter to
> > explain why they're doing what they're doing.
> >
> > Brian
> 
> Yes. I know when aging time of station is out, hostapd will use probe_client
> to check if station is still there before really disconnect it.
> 
> Without this feature, it won't really affect mayor function of hostapd.
> 
> That is the reason that I suggest that we put comments and TODO to the
> code.
> 
> David

If you agree that this extra check can be optional, maybe I can just put your suggested comments to the code.

David
David Lin June 14, 2024, 2:18 a.m. UTC | #10
Hi Brian,

> From: David Lin <yu-hao.lin@nxp.com>
> Sent: Saturday, May 25, 2024 8:51 AM
> To: Brian Norris <briannorris@chromium.org>
> Cc: linux-wireless@vger.kernel.org; linux-kernel@vger.kernel.org;
> kvalo@kernel.org; francesco@dolcini.it; Pete Hsieh
> <tsung-hsien.hsieh@nxp.com>; Francesco Dolcini
> <francesco.dolcini@toradex.com>
> Subject: RE: [EXT] Re: [PATCH v10 1/2] wifi: mwifiex: add host mlme for client
> mode
> 
> Hi Brian,
> 
> > From: Brian Norris <briannorris@chromium.org>
> > Sent: Saturday, May 25, 2024 6:55 AM
> > To: David Lin <yu-hao.lin@nxp.com>
> > Cc: linux-wireless@vger.kernel.org; linux-kernel@vger.kernel.org;
> > kvalo@kernel.org; francesco@dolcini.it; Pete Hsieh
> > <tsung-hsien.hsieh@nxp.com>; Francesco Dolcini
> > <francesco.dolcini@toradex.com>
> > Subject: Re: [EXT] Re: [PATCH v10 1/2] wifi: mwifiex: add host mlme
> > for client mode
> >
> > Caution: This is an external email. Please take care when clicking
> > links or opening attachments. When in doubt, report the message using
> > the 'Report this email' button
> >
> >
> > On Fri, May 24, 2024 at 3:01 PM David Lin <yu-hao.lin@nxp.com> wrote:
> > > I think it needs time to support probe client. Can we put your
> > > suggested comments to the code used to hook probe_client() and add
> > >
> > > "TODO: support probe client" to mwifiex_cfg80211_probe_client().
> >
> > Are you suggesting that you plan to actually implement proper
> > probe_client support? Did you already do what I suggested, and
> > understand why hostapd needs probe_client support? This seems to be a
> > common pattern -- that reviewers are asking for you to do your
> > research, and it takes several requests before you actually do it.
> >
> > Now that I've tried to do that research for you ... it looks like
> > hostapd uses probe_client to augment TX MGMT acks, as a proxy for
> > station presence / inactivity. If a station is inactive and
> > non-responsive, we disconnect it eventually. So that looks to me like
> > probe_client support should actually be optional, if your driver
> > reports TX status? And in that case, I'd still recommend you try to fix hostapd.
> >
> > But if you're really planning to implement proper probe_client
> > support, then I suppose the TODO approach is also OK.
> >
> > I'd also request that you please actually do your research when
> > reviewers ask questions. I'm frankly not sure why I'm spending my time
> > on the above research, when the onus should be on the submitter to
> > explain why they're doing what they're doing.
> >
> > Brian
> 
> Yes. I know when aging time of station is out, hostapd will use probe_client to
> check if station is still there before really disconnect it.
> 
> Without this feature, it won't really affect mayor function of hostapd.
> 
> That is the reason that I suggest that we put comments and TODO to the code.
> 
> David

> If you agree that this extra check can be optional, maybe I can just put your suggested comments to the code.

> David

Please let me know what else should I do to let this patch be ACKed by you.

Thanks,
David
Brian Norris June 20, 2024, 5:53 p.m. UTC | #11
Hi David,

On Sat, May 25, 2024 at 12:50:59AM +0000, David Lin wrote:
> 
> > From: Brian Norris <briannorris@chromium.org>
> > Sent: Saturday, May 25, 2024 6:55 AM
> > 
> > On Fri, May 24, 2024 at 3:01 PM David Lin <yu-hao.lin@nxp.com> wrote:
> > > I think it needs time to support probe client. Can we put your
> > > suggested comments to the code used to hook probe_client() and add
> > >
> > > "TODO: support probe client" to mwifiex_cfg80211_probe_client().
> > 
> > Are you suggesting that you plan to actually implement proper probe_client
> > support? Did you already do what I suggested, and understand why hostapd
> > needs probe_client support? This seems to be a common pattern -- that
> > reviewers are asking for you to do your research, and it takes several
> > requests before you actually do it.
> > 
> > Now that I've tried to do that research for you ... it looks like hostapd uses
> > probe_client to augment TX MGMT acks, as a proxy for station presence /
> > inactivity. If a station is inactive and non-responsive, we disconnect it
> > eventually. So that looks to me like probe_client support should actually be
> > optional, if your driver reports TX status? And in that case, I'd still
> > recommend you try to fix hostapd.
> > 
> > But if you're really planning to implement proper probe_client support, then
> > I suppose the TODO approach is also OK.
> > 
> > I'd also request that you please actually do your research when reviewers
> > ask questions. I'm frankly not sure why I'm spending my time on the above
> > research, when the onus should be on the submitter to explain why they're
> > doing what they're doing.
> 
> Yes. I know when aging time of station is out, hostapd will use probe_client to check if station is still there before really disconnect it.
> 
> Without this feature, it won't really affect mayor function of hostapd.

I'm glad *you* know all about the above behavior, but *I* didn't know
about it until I went and researched what this API does, and how hostapd
is using it. But that isn't my job -- it's your job, as the code
submitter, to explain your reasoning and reduce the amount of work that
readers/reviewers/maintainers have to do to understand your code and
agree that it is the right thing to do.

It's not clear to me that you've really learned the above lesson, and
it's really affecting the rate at which I review your code. This is by
far not the first time that you've placed the burden on the reader. And
if you're going to make the job difficult, then I'll prioritize enjoying
my free time, or stuff that actually pays me at $DAY_JOB, or ...

> That is the reason that I suggest that we put comments and TODO to the code.

OK, I suppose that works for me.

Brian
David Lin June 21, 2024, 4:36 a.m. UTC | #12
Hi Brian,

> From: Brian Norris <briannorris@chromium.org>
> Sent: Friday, June 21, 2024 1:53 AM
> To: David Lin <yu-hao.lin@nxp.com>
> Cc: linux-wireless@vger.kernel.org; linux-kernel@vger.kernel.org;
> kvalo@kernel.org; francesco@dolcini.it; Pete Hsieh
> <tsung-hsien.hsieh@nxp.com>; Francesco Dolcini
> <francesco.dolcini@toradex.com>
> Subject: Re: [EXT] Re: [PATCH v10 1/2] wifi: mwifiex: add host mlme for client
> mode
> 
> Caution: This is an external email. Please take care when clicking links or
> opening attachments. When in doubt, report the message using the 'Report
> this email' button
> 
> 
> Hi David,
> 
> On Sat, May 25, 2024 at 12:50:59AM +0000, David Lin wrote:
> >
> > > From: Brian Norris <briannorris@chromium.org>
> > > Sent: Saturday, May 25, 2024 6:55 AM
> > >
> > > On Fri, May 24, 2024 at 3:01 PM David Lin <yu-hao.lin@nxp.com> wrote:
> > > > I think it needs time to support probe client. Can we put your
> > > > suggested comments to the code used to hook probe_client() and add
> > > >
> > > > "TODO: support probe client" to mwifiex_cfg80211_probe_client().
> > >
> > > Are you suggesting that you plan to actually implement proper
> > > probe_client support? Did you already do what I suggested, and
> > > understand why hostapd needs probe_client support? This seems to be
> > > a common pattern -- that reviewers are asking for you to do your
> > > research, and it takes several requests before you actually do it.
> > >
> > > Now that I've tried to do that research for you ... it looks like
> > > hostapd uses probe_client to augment TX MGMT acks, as a proxy for
> > > station presence / inactivity. If a station is inactive and
> > > non-responsive, we disconnect it eventually. So that looks to me
> > > like probe_client support should actually be optional, if your
> > > driver reports TX status? And in that case, I'd still recommend you try to fix
> hostapd.
> > >
> > > But if you're really planning to implement proper probe_client
> > > support, then I suppose the TODO approach is also OK.
> > >
> > > I'd also request that you please actually do your research when
> > > reviewers ask questions. I'm frankly not sure why I'm spending my
> > > time on the above research, when the onus should be on the submitter
> > > to explain why they're doing what they're doing.
> >
> > Yes. I know when aging time of station is out, hostapd will use probe_client
> to check if station is still there before really disconnect it.
> >
> > Without this feature, it won't really affect mayor function of hostapd.
> 
> I'm glad *you* know all about the above behavior, but *I* didn't know about it
> until I went and researched what this API does, and how hostapd is using it. But
> that isn't my job -- it's your job, as the code submitter, to explain your
> reasoning and reduce the amount of work that readers/reviewers/maintainers
> have to do to understand your code and agree that it is the right thing to do.
> 
> It's not clear to me that you've really learned the above lesson, and it's really
> affecting the rate at which I review your code. This is by far not the first time
> that you've placed the burden on the reader. And if you're going to make the
> job difficult, then I'll prioritize enjoying my free time, or stuff that actually pays
> me at $DAY_JOB, or ...

I will keep this in mind.

> 
> > That is the reason that I suggest that we put comments and TODO to the
> code.
> 
> OK, I suppose that works for me.
> 
> Brian

I suggest that we just put your comments and prepare patch v11.

Thanks,
David
David Lin July 1, 2024, 1:12 a.m. UTC | #13
Hi Brian,

> -----Original Message-----
> From: David Lin <yu-hao.lin@nxp.com>
> Sent: Friday, June 21, 2024 12:36 PM
> To: Brian Norris <briannorris@chromium.org>
> Cc: linux-wireless@vger.kernel.org; linux-kernel@vger.kernel.org;
> kvalo@kernel.org; francesco@dolcini.it; Pete Hsieh
> <tsung-hsien.hsieh@nxp.com>; Francesco Dolcini
> <francesco.dolcini@toradex.com>
> Subject: RE: [EXT] Re: [PATCH v10 1/2] wifi: mwifiex: add host mlme for client
> mode
> 
> Caution: This is an external email. Please take care when clicking links or
> opening attachments. When in doubt, report the message using the 'Report
> this email' button
> 
> 
> Hi Brian,
> 
> > From: Brian Norris <briannorris@chromium.org>
> > Sent: Friday, June 21, 2024 1:53 AM
> > To: David Lin <yu-hao.lin@nxp.com>
> > Cc: linux-wireless@vger.kernel.org; linux-kernel@vger.kernel.org;
> > kvalo@kernel.org; francesco@dolcini.it; Pete Hsieh
> > <tsung-hsien.hsieh@nxp.com>; Francesco Dolcini
> > <francesco.dolcini@toradex.com>
> > Subject: Re: [EXT] Re: [PATCH v10 1/2] wifi: mwifiex: add host mlme
> > for client mode
> >
> > Caution: This is an external email. Please take care when clicking
> > links or opening attachments. When in doubt, report the message using
> > the 'Report this email' button
> >
> >
> > Hi David,
> >
> > On Sat, May 25, 2024 at 12:50:59AM +0000, David Lin wrote:
> > >
> > > > From: Brian Norris <briannorris@chromium.org>
> > > > Sent: Saturday, May 25, 2024 6:55 AM
> > > >
> > > > On Fri, May 24, 2024 at 3:01 PM David Lin <yu-hao.lin@nxp.com>
> wrote:
> > > > > I think it needs time to support probe client. Can we put your
> > > > > suggested comments to the code used to hook probe_client() and
> > > > > add
> > > > >
> > > > > "TODO: support probe client" to mwifiex_cfg80211_probe_client().
> > > >
> > > > Are you suggesting that you plan to actually implement proper
> > > > probe_client support? Did you already do what I suggested, and
> > > > understand why hostapd needs probe_client support? This seems to
> > > > be a common pattern -- that reviewers are asking for you to do
> > > > your research, and it takes several requests before you actually do it.
> > > >
> > > > Now that I've tried to do that research for you ... it looks like
> > > > hostapd uses probe_client to augment TX MGMT acks, as a proxy for
> > > > station presence / inactivity. If a station is inactive and
> > > > non-responsive, we disconnect it eventually. So that looks to me
> > > > like probe_client support should actually be optional, if your
> > > > driver reports TX status? And in that case, I'd still recommend
> > > > you try to fix
> > hostapd.
> > > >
> > > > But if you're really planning to implement proper probe_client
> > > > support, then I suppose the TODO approach is also OK.
> > > >
> > > > I'd also request that you please actually do your research when
> > > > reviewers ask questions. I'm frankly not sure why I'm spending my
> > > > time on the above research, when the onus should be on the
> > > > submitter to explain why they're doing what they're doing.
> > >
> > > Yes. I know when aging time of station is out, hostapd will use
> > > probe_client
> > to check if station is still there before really disconnect it.
> > >
> > > Without this feature, it won't really affect mayor function of hostapd.
> >
> > I'm glad *you* know all about the above behavior, but *I* didn't know
> > about it until I went and researched what this API does, and how
> > hostapd is using it. But that isn't my job -- it's your job, as the
> > code submitter, to explain your reasoning and reduce the amount of
> > work that readers/reviewers/maintainers have to do to understand your
> code and agree that it is the right thing to do.
> >
> > It's not clear to me that you've really learned the above lesson, and
> > it's really affecting the rate at which I review your code. This is by
> > far not the first time that you've placed the burden on the reader.
> > And if you're going to make the job difficult, then I'll prioritize
> > enjoying my free time, or stuff that actually pays me at $DAY_JOB, or ...
> 
> I will keep this in mind.
> 
> >
> > > That is the reason that I suggest that we put comments and TODO to
> > > the
> > code.
> >
> > OK, I suppose that works for me.
> >
> > Brian
> 
> I suggest that we just put your comments and prepare patch v11.
> 
> Thanks,
> David

I think WPA3 is more robust and updated security method. Please help to let this patch be accepted.
Please let me know what else should be done to let this patch be ACKed by you. Another is already
ACKed by you with minor modification.

Thanks for your efforts and helps.

David
Brian Norris July 1, 2024, 8:47 p.m. UTC | #14
Hi David,

On Sun, Jun 30, 2024 at 6:12 PM David Lin <yu-hao.lin@nxp.com> wrote:
> > -----Original Message-----
> > From: David Lin <yu-hao.lin@nxp.com>
> > Sent: Friday, June 21, 2024 12:36 PM
> >
> > > From: Brian Norris <briannorris@chromium.org>
> > > Sent: Friday, June 21, 2024 1:53 AM
> > >
> > > On Sat, May 25, 2024 at 12:50:59AM +0000, David Lin wrote:
> > > > That is the reason that I suggest that we put comments and TODO to
> > > > the
> > > code.
> > >
> > > OK, I suppose that works for me.

^^^
I don't have anything to add to this. This means "go ahead with the
quoted suggestion."

If you factor in the latest comments (which, I think is only the above
at the moment) then v11 likely will be good to merge from my
perspective.

> > I suggest that we just put your comments and prepare patch v11.
>
> I think WPA3 is more robust and updated security method. Please help to let this patch be accepted.
> Please let me know what else should be done to let this patch be ACKed by you. Another is already
> ACKed by you with minor modification.

See above.

Brian
David Lin July 2, 2024, 11:23 a.m. UTC | #15
Hi Brian,

> From: Brian Norris <briannorris@chromium.org>
> Sent: Tuesday, July 2, 2024 4:47 AM
> To: David Lin <yu-hao.lin@nxp.com>
> Cc: linux-wireless@vger.kernel.org; linux-kernel@vger.kernel.org;
> kvalo@kernel.org; francesco@dolcini.it; Pete Hsieh
> <tsung-hsien.hsieh@nxp.com>; Francesco Dolcini
> <francesco.dolcini@toradex.com>
> Subject: Re: [EXT] Re: [PATCH v10 1/2] wifi: mwifiex: add host mlme for client
> mode
> 
> 
> Hi David,
> 
> On Sun, Jun 30, 2024 at 6:12 PM David Lin <yu-hao.lin@nxp.com> wrote:
> > > -----Original Message-----
> > > From: David Lin <yu-hao.lin@nxp.com>
> > > Sent: Friday, June 21, 2024 12:36 PM
> > >
> > > > From: Brian Norris <briannorris@chromium.org>
> > > > Sent: Friday, June 21, 2024 1:53 AM
> > > >
> > > > On Sat, May 25, 2024 at 12:50:59AM +0000, David Lin wrote:
> > > > > That is the reason that I suggest that we put comments and TODO
> > > > > to the
> > > > code.
> > > >
> > > > OK, I suppose that works for me.
> 
> ^^^
> I don't have anything to add to this. This means "go ahead with the quoted
> suggestion."
> 
> If you factor in the latest comments (which, I think is only the above at the
> moment) then v11 likely will be good to merge from my perspective.
> 
> > > I suggest that we just put your comments and prepare patch v11.
> >
> > I think WPA3 is more robust and updated security method. Please help to let
> this patch be accepted.
> > Please let me know what else should be done to let this patch be ACKed
> > by you. Another is already ACKed by you with minor modification.
> 
> See above.
> 
> Brian

I want to confirm with you:
For patch v11:

[1/2]: Carry your "Acked-by" tag with following comment put to the code
used to hook probe_client().

"hostapd looks for NL80211_CMD_PROBE_CLIENT support; otherwise, it
requires monitor-mode support (which mwifiex doesn't support). Provide
fake probe_client support to work around this."

[2/2]: Carry your "Acked-by" tag with the modification of mwifiex_mgmt_stypes.

Thanks,
David
Brian Norris July 2, 2024, 6:21 p.m. UTC | #16
On Tue, Jul 2, 2024 at 4:23 AM David Lin <yu-hao.lin@nxp.com> wrote:
> I want to confirm with you:
> For patch v11:
>
> [1/2]: Carry your "Acked-by" tag with following comment put to the code
> used to hook probe_client().
>
> "hostapd looks for NL80211_CMD_PROBE_CLIENT support; otherwise, it
> requires monitor-mode support (which mwifiex doesn't support). Provide
> fake probe_client support to work around this."

Sure. I never actually acked this patch, but you can have my preemptive:

Acked-by: Brian Norris <briannorris@chromium.org>

> [2/2]: Carry your "Acked-by" tag with the modification of mwifiex_mgmt_stypes.

Yes.

Brian
diff mbox series

Patch

diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
index b909a7665e9c..53eeda388802 100644
--- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
@@ -268,6 +268,8 @@  mwifiex_cfg80211_update_mgmt_frame_registrations(struct wiphy *wiphy,
 
 	if (mask != priv->mgmt_frame_mask) {
 		priv->mgmt_frame_mask = mask;
+		if (priv->host_mlme_reg)
+			priv->mgmt_frame_mask |= HOST_MLME_MGMT_MASK;
 		mwifiex_send_cmd(priv, HostCmd_CMD_MGMT_FRAME_REG,
 				 HostCmd_ACT_GEN_SET, 0,
 				 &priv->mgmt_frame_mask, false);
@@ -848,6 +850,7 @@  static int mwifiex_deinit_priv_params(struct mwifiex_private *priv)
 	struct mwifiex_adapter *adapter = priv->adapter;
 	unsigned long flags;
 
+	priv->host_mlme_reg = false;
 	priv->mgmt_frame_mask = 0;
 	if (mwifiex_send_cmd(priv, HostCmd_CMD_MGMT_FRAME_REG,
 			     HostCmd_ACT_GEN_SET, 0,
@@ -3631,6 +3634,9 @@  static int mwifiex_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
 	if (!ISSUPP_FIRMWARE_SUPPLICANT(priv->adapter->fw_cap_info))
 		return -EOPNOTSUPP;
 
+	if (priv->adapter->host_mlme_enabled)
+		return 0;
+
 	return mwifiex_send_cmd(priv, HostCmd_CMD_GTK_REKEY_OFFLOAD_CFG,
 				HostCmd_ACT_GEN_SET, 0, data, true);
 }
@@ -4204,6 +4210,301 @@  mwifiex_cfg80211_change_station(struct wiphy *wiphy, struct net_device *dev,
 	return ret;
 }
 
+static int
+mwifiex_cfg80211_authenticate(struct wiphy *wiphy,
+			      struct net_device *dev,
+			      struct cfg80211_auth_request *req)
+{
+	struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
+	struct mwifiex_adapter *adapter = priv->adapter;
+	struct sk_buff *skb;
+	u16 pkt_len, auth_alg;
+	int ret;
+	struct mwifiex_ieee80211_mgmt *mgmt;
+	struct mwifiex_txinfo *tx_info;
+	u32 tx_control = 0, pkt_type = PKT_TYPE_MGMT;
+	u8 trans = 1, status_code = 0;
+	u8 *varptr;
+
+	if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP) {
+		mwifiex_dbg(priv->adapter, ERROR, "Interface role is AP\n");
+		return -EFAULT;
+	}
+
+	if (priv->wdev.iftype != NL80211_IFTYPE_STATION) {
+		mwifiex_dbg(priv->adapter, ERROR,
+			    "Interface type is not correct (type %d)\n",
+			    priv->wdev.iftype);
+		return -EINVAL;
+	}
+
+	if (priv->auth_alg != WLAN_AUTH_SAE &&
+	    (priv->auth_flag & HOST_MLME_AUTH_PENDING)) {
+		mwifiex_dbg(priv->adapter, ERROR, "Pending auth on going\n");
+		return -EBUSY;
+	}
+
+	if (!priv->host_mlme_reg) {
+		priv->host_mlme_reg = true;
+		priv->mgmt_frame_mask |= HOST_MLME_MGMT_MASK;
+		mwifiex_send_cmd(priv, HostCmd_CMD_MGMT_FRAME_REG,
+				 HostCmd_ACT_GEN_SET, 0,
+				 &priv->mgmt_frame_mask, false);
+	}
+
+	switch (req->auth_type) {
+	case NL80211_AUTHTYPE_OPEN_SYSTEM:
+		auth_alg = WLAN_AUTH_OPEN;
+		break;
+	case NL80211_AUTHTYPE_SHARED_KEY:
+		auth_alg = WLAN_AUTH_SHARED_KEY;
+		break;
+	case NL80211_AUTHTYPE_FT:
+		auth_alg = WLAN_AUTH_FT;
+		break;
+	case NL80211_AUTHTYPE_NETWORK_EAP:
+		auth_alg = WLAN_AUTH_LEAP;
+		break;
+	case NL80211_AUTHTYPE_SAE:
+		auth_alg = WLAN_AUTH_SAE;
+		break;
+	default:
+		mwifiex_dbg(priv->adapter, ERROR,
+			    "unsupported auth type=%d\n", req->auth_type);
+		return -EOPNOTSUPP;
+	}
+
+	if (!priv->auth_flag) {
+		ret = mwifiex_remain_on_chan_cfg(priv, HostCmd_ACT_GEN_SET,
+						 req->bss->channel,
+						 AUTH_TX_DEFAULT_WAIT_TIME);
+
+		if (!ret) {
+			priv->roc_cfg.cookie = get_random_u32() | 1;
+			priv->roc_cfg.chan = *req->bss->channel;
+		} else {
+			return -EFAULT;
+		}
+	}
+
+	priv->sec_info.authentication_mode = auth_alg;
+
+	mwifiex_cancel_scan(adapter);
+
+	pkt_len = (u16)req->ie_len + req->auth_data_len +
+		MWIFIEX_MGMT_HEADER_LEN + MWIFIEX_AUTH_BODY_LEN;
+	if (req->auth_data_len >= 4)
+		pkt_len -= 4;
+
+	skb = dev_alloc_skb(MWIFIEX_MIN_DATA_HEADER_LEN +
+			    MWIFIEX_MGMT_FRAME_HEADER_SIZE +
+			    pkt_len + sizeof(pkt_len));
+	if (!skb) {
+		mwifiex_dbg(priv->adapter, ERROR,
+			    "allocate skb failed for management frame\n");
+		return -ENOMEM;
+	}
+
+	tx_info = MWIFIEX_SKB_TXCB(skb);
+	memset(tx_info, 0, sizeof(*tx_info));
+	tx_info->bss_num = priv->bss_num;
+	tx_info->bss_type = priv->bss_type;
+	tx_info->pkt_len = pkt_len;
+
+	skb_reserve(skb, MWIFIEX_MIN_DATA_HEADER_LEN +
+		    MWIFIEX_MGMT_FRAME_HEADER_SIZE + sizeof(pkt_len));
+	memcpy(skb_push(skb, sizeof(pkt_len)), &pkt_len, sizeof(pkt_len));
+	memcpy(skb_push(skb, sizeof(tx_control)),
+	       &tx_control, sizeof(tx_control));
+	memcpy(skb_push(skb, sizeof(pkt_type)), &pkt_type, sizeof(pkt_type));
+
+	mgmt = (struct mwifiex_ieee80211_mgmt *)skb_put(skb, pkt_len);
+	memset(mgmt, 0, pkt_len);
+	mgmt->frame_control =
+		cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH);
+	memcpy(mgmt->da, req->bss->bssid, ETH_ALEN);
+	memcpy(mgmt->sa, priv->curr_addr, ETH_ALEN);
+	memcpy(mgmt->bssid, req->bss->bssid, ETH_ALEN);
+	eth_broadcast_addr(mgmt->addr4);
+
+	if (req->auth_data_len >= 4) {
+		if (req->auth_type == NL80211_AUTHTYPE_SAE) {
+			__le16 *pos = (__le16 *)req->auth_data;
+
+			trans = le16_to_cpu(pos[0]);
+			status_code = le16_to_cpu(pos[1]);
+		}
+		memcpy((u8 *)(&mgmt->auth.variable), req->auth_data + 4,
+		       req->auth_data_len - 4);
+		varptr = (u8 *)&mgmt->auth.variable +
+			 (req->auth_data_len - 4);
+	}
+
+	mgmt->auth.auth_alg = cpu_to_le16(auth_alg);
+	mgmt->auth.auth_transaction = cpu_to_le16(trans);
+	mgmt->auth.status_code = cpu_to_le16(status_code);
+
+	if (req->ie && req->ie_len) {
+		if (!varptr)
+			varptr = (u8 *)&mgmt->auth.variable;
+		memcpy((u8 *)varptr, req->ie, req->ie_len);
+	}
+
+	priv->auth_flag = HOST_MLME_AUTH_PENDING;
+	priv->auth_alg = auth_alg;
+
+	skb->priority = WMM_HIGHEST_PRIORITY;
+	__net_timestamp(skb);
+
+	mwifiex_dbg(priv->adapter, MSG,
+		    "auth: send authentication to %pM\n", req->bss->bssid);
+
+	mwifiex_queue_tx_pkt(priv, skb);
+
+	return 0;
+}
+
+static int
+mwifiex_cfg80211_associate(struct wiphy *wiphy, struct net_device *dev,
+			   struct cfg80211_assoc_request *req)
+{
+	struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
+	struct mwifiex_adapter *adapter = priv->adapter;
+	int ret;
+	struct cfg80211_ssid req_ssid;
+	const u8 *ssid_ie;
+
+	if (GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_STA) {
+		mwifiex_dbg(adapter, ERROR,
+			    "%s: reject infra assoc request in non-STA role\n",
+			    dev->name);
+		return -EINVAL;
+	}
+
+	if (test_bit(MWIFIEX_SURPRISE_REMOVED, &adapter->work_flags) ||
+	    test_bit(MWIFIEX_IS_CMD_TIMEDOUT, &adapter->work_flags)) {
+		mwifiex_dbg(adapter, ERROR,
+			    "%s: Ignore association.\t"
+			    "Card removed or FW in bad state\n",
+			    dev->name);
+		return -EFAULT;
+	}
+
+	if (priv->auth_alg == WLAN_AUTH_SAE)
+		priv->auth_flag = HOST_MLME_AUTH_DONE;
+
+	if (priv->auth_flag && !(priv->auth_flag & HOST_MLME_AUTH_DONE))
+		return -EBUSY;
+
+	if (priv->roc_cfg.cookie) {
+		ret = mwifiex_remain_on_chan_cfg(priv, HostCmd_ACT_GEN_REMOVE,
+						 &priv->roc_cfg.chan, 0);
+		if (!ret)
+			memset(&priv->roc_cfg, 0,
+			       sizeof(struct mwifiex_roc_cfg));
+		else
+			return -EFAULT;
+	}
+
+	if (!mwifiex_stop_bg_scan(priv))
+		cfg80211_sched_scan_stopped_locked(priv->wdev.wiphy, 0);
+
+	memset(&req_ssid, 0, sizeof(struct cfg80211_ssid));
+	rcu_read_lock();
+	ssid_ie = ieee80211_bss_get_ie(req->bss, WLAN_EID_SSID);
+
+	if (!ssid_ie)
+		goto ssid_err;
+
+	req_ssid.ssid_len = ssid_ie[1];
+	if (req_ssid.ssid_len > IEEE80211_MAX_SSID_LEN) {
+		mwifiex_dbg(adapter, ERROR, "invalid SSID - aborting\n");
+		goto ssid_err;
+	}
+
+	memcpy(req_ssid.ssid, ssid_ie + 2, req_ssid.ssid_len);
+	if (!req_ssid.ssid_len || req_ssid.ssid[0] < 0x20) {
+		mwifiex_dbg(adapter, ERROR, "invalid SSID - aborting\n");
+		goto ssid_err;
+	}
+	rcu_read_unlock();
+
+	/* As this is new association, clear locally stored
+	 * keys and security related flags
+	 */
+	priv->sec_info.wpa_enabled = false;
+	priv->sec_info.wpa2_enabled = false;
+	priv->wep_key_curr_index = 0;
+	priv->sec_info.encryption_mode = 0;
+	priv->sec_info.is_authtype_auto = 0;
+	if (mwifiex_set_encode(priv, NULL, NULL, 0, 0, NULL, 1)) {
+		mwifiex_dbg(priv->adapter, ERROR, "deleting the crypto keys\n");
+		return -EFAULT;
+	}
+
+	if (req->crypto.n_ciphers_pairwise)
+		priv->sec_info.encryption_mode =
+			req->crypto.ciphers_pairwise[0];
+
+	if (req->crypto.cipher_group)
+		priv->sec_info.encryption_mode = req->crypto.cipher_group;
+
+	if (req->ie)
+		mwifiex_set_gen_ie(priv, req->ie, req->ie_len);
+
+	memcpy(priv->cfg_bssid, req->bss->bssid, ETH_ALEN);
+
+	mwifiex_dbg(adapter, MSG,
+		    "assoc: send association to %pM\n", req->bss->bssid);
+
+	cfg80211_ref_bss(adapter->wiphy, req->bss);
+	ret = mwifiex_bss_start(priv, req->bss, &req_ssid);
+	if (ret) {
+		priv->auth_flag = 0;
+		priv->auth_alg = WLAN_AUTH_NONE;
+		eth_zero_addr(priv->cfg_bssid);
+	}
+
+	if (priv->assoc_rsp_size) {
+		priv->req_bss = req->bss;
+		adapter->assoc_resp_received = true;
+		queue_work(adapter->host_mlme_workqueue,
+			   &adapter->host_mlme_work);
+	}
+
+	cfg80211_put_bss(priv->adapter->wiphy, req->bss);
+
+	return 0;
+
+ssid_err:
+	rcu_read_unlock();
+	return -EFAULT;
+}
+
+static int
+mwifiex_cfg80211_deauthenticate(struct wiphy *wiphy,
+				struct net_device *dev,
+				struct cfg80211_deauth_request *req)
+{
+	return mwifiex_cfg80211_disconnect(wiphy, dev, req->reason_code);
+}
+
+static int
+mwifiex_cfg80211_disassociate(struct wiphy *wiphy,
+			      struct net_device *dev,
+			      struct cfg80211_disassoc_request *req)
+{
+	return mwifiex_cfg80211_disconnect(wiphy, dev, req->reason_code);
+}
+
+static int
+mwifiex_cfg80211_probe_client(struct wiphy *wiphy,
+			      struct net_device *dev, const u8 *peer,
+			      u64 *cookie)
+{
+	return -EOPNOTSUPP;
+}
+
 /* station cfg80211 operations */
 static struct cfg80211_ops mwifiex_cfg80211_ops = {
 	.add_virtual_intf = mwifiex_add_virtual_intf,
@@ -4349,6 +4650,16 @@  int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
 			    "%s: creating new wiphy\n", __func__);
 		return -ENOMEM;
 	}
+	if (adapter->host_mlme_enabled) {
+		mwifiex_cfg80211_ops.auth = mwifiex_cfg80211_authenticate;
+		mwifiex_cfg80211_ops.assoc = mwifiex_cfg80211_associate;
+		mwifiex_cfg80211_ops.deauth = mwifiex_cfg80211_deauthenticate;
+		mwifiex_cfg80211_ops.disassoc = mwifiex_cfg80211_disassociate;
+		mwifiex_cfg80211_ops.disconnect = NULL;
+		mwifiex_cfg80211_ops.connect = NULL;
+		mwifiex_cfg80211_ops.probe_client =
+			mwifiex_cfg80211_probe_client;
+	}
 	wiphy->max_scan_ssids = MWIFIEX_MAX_SSID_LIST_LENGTH;
 	wiphy->max_scan_ie_len = MWIFIEX_MAX_VSIE_LEN;
 	wiphy->mgmt_stypes = mwifiex_mgmt_stypes;
@@ -4430,6 +4741,9 @@  int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
 			   NL80211_FEATURE_LOW_PRIORITY_SCAN |
 			   NL80211_FEATURE_NEED_OBSS_SCAN;
 
+	if (adapter->host_mlme_enabled)
+		wiphy->features |= NL80211_FEATURE_SAE;
+
 	if (ISSUPP_ADHOC_ENABLED(adapter->fw_cap_info))
 		wiphy->features |= NL80211_FEATURE_HT_IBSS;
 
diff --git a/drivers/net/wireless/marvell/mwifiex/cmdevt.c b/drivers/net/wireless/marvell/mwifiex/cmdevt.c
index 9eff29a25544..da983e27023c 100644
--- a/drivers/net/wireless/marvell/mwifiex/cmdevt.c
+++ b/drivers/net/wireless/marvell/mwifiex/cmdevt.c
@@ -924,6 +924,24 @@  int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter)
 	return ret;
 }
 
+void mwifiex_process_assoc_resp(struct mwifiex_adapter *adapter)
+{
+	struct cfg80211_rx_assoc_resp_data assoc_resp = {
+		.uapsd_queues = -1,
+	};
+	struct mwifiex_private *priv =
+		mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA);
+
+	if (priv->assoc_rsp_size) {
+		assoc_resp.links[0].bss = priv->req_bss;
+		assoc_resp.buf = priv->assoc_rsp_buf;
+		assoc_resp.len = priv->assoc_rsp_size;
+		cfg80211_rx_assoc_resp(priv->netdev,
+				       &assoc_resp);
+		priv->assoc_rsp_size = 0;
+	}
+}
+
 /*
  * This function handles the timeout of command sending.
  *
@@ -1672,6 +1690,13 @@  int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv,
 	if (adapter->fw_api_ver == MWIFIEX_FW_V15)
 		adapter->scan_chan_gap_enabled = true;
 
+	if (adapter->key_api_major_ver != KEY_API_VER_MAJOR_V2)
+		adapter->host_mlme_enabled = false;
+
+	mwifiex_dbg(adapter, MSG, "host_mlme: %s, key_api: %d\n",
+		    adapter->host_mlme_enabled ? "enable" : "disable",
+		    adapter->key_api_major_ver);
+
 	return 0;
 }
 
diff --git a/drivers/net/wireless/marvell/mwifiex/decl.h b/drivers/net/wireless/marvell/mwifiex/decl.h
index 326ffb05d791..84603f1e7f6e 100644
--- a/drivers/net/wireless/marvell/mwifiex/decl.h
+++ b/drivers/net/wireless/marvell/mwifiex/decl.h
@@ -31,6 +31,29 @@ 
 						 *   + sizeof(tx_control)
 						 */
 
+#define FRMCTL_LEN                2
+#define DURATION_LEN              2
+#define SEQCTL_LEN                2
+/* special FW 4 address management header */
+#define MWIFIEX_MGMT_HEADER_LEN   (FRMCTL_LEN + DURATION_LEN + ETH_ALEN + \
+				   ETH_ALEN + ETH_ALEN + SEQCTL_LEN + ETH_ALEN)
+
+#define AUTH_ALG_LEN              2
+#define AUTH_TRANSACTION_LEN      2
+#define AUTH_STATUS_LEN           2
+#define MWIFIEX_AUTH_BODY_LEN     (AUTH_ALG_LEN + AUTH_TRANSACTION_LEN + \
+				   AUTH_STATUS_LEN)
+
+#define HOST_MLME_AUTH_PENDING    BIT(0)
+#define HOST_MLME_AUTH_DONE       BIT(1)
+
+#define HOST_MLME_MGMT_MASK       (BIT(IEEE80211_STYPE_AUTH >> 4) | \
+				   BIT(IEEE80211_STYPE_DEAUTH >> 4) | \
+				   BIT(IEEE80211_STYPE_DISASSOC >> 4))
+#define AUTH_TX_DEFAULT_WAIT_TIME 2400
+
+#define WLAN_AUTH_NONE            0xFFFF
+
 #define MWIFIEX_MAX_TX_BASTREAM_SUPPORTED	2
 #define MWIFIEX_MAX_RX_BASTREAM_SUPPORTED	16
 #define MWIFIEX_MAX_TDLS_PEER_SUPPORTED 8
diff --git a/drivers/net/wireless/marvell/mwifiex/fw.h b/drivers/net/wireless/marvell/mwifiex/fw.h
index 3adc447b715f..0f89b86aa527 100644
--- a/drivers/net/wireless/marvell/mwifiex/fw.h
+++ b/drivers/net/wireless/marvell/mwifiex/fw.h
@@ -210,6 +210,8 @@  enum MWIFIEX_802_11_PRIVACY_FILTER {
 #define TLV_TYPE_RANDOM_MAC         (PROPRIETARY_TLV_BASE_ID + 236)
 #define TLV_TYPE_CHAN_ATTR_CFG      (PROPRIETARY_TLV_BASE_ID + 237)
 #define TLV_TYPE_MAX_CONN           (PROPRIETARY_TLV_BASE_ID + 279)
+#define TLV_TYPE_HOST_MLME          (PROPRIETARY_TLV_BASE_ID + 307)
+#define TLV_TYPE_SAE_PWE_MODE       (PROPRIETARY_TLV_BASE_ID + 339)
 
 #define MWIFIEX_TX_DATA_BUF_SIZE_2K        2048
 
@@ -744,6 +746,25 @@  struct uap_rxpd {
 	u8 flags;
 } __packed;
 
+struct mwifiex_auth {
+	__le16 auth_alg;
+	__le16 auth_transaction;
+	__le16 status_code;
+	/* possibly followed by Challenge text */
+	u8 variable[];
+} __packed;
+
+struct mwifiex_ieee80211_mgmt {
+	__le16 frame_control;
+	__le16 duration;
+	u8 da[ETH_ALEN];
+	u8 sa[ETH_ALEN];
+	u8 bssid[ETH_ALEN];
+	__le16 seq_ctrl;
+	u8 addr4[ETH_ALEN];
+	struct mwifiex_auth auth;
+} __packed;
+
 struct mwifiex_fw_chan_stats {
 	u8 chan_num;
 	u8 bandcfg;
@@ -803,6 +824,11 @@  struct mwifiex_ie_types_ssid_param_set {
 	u8 ssid[];
 } __packed;
 
+struct mwifiex_ie_types_host_mlme {
+	struct mwifiex_ie_types_header header;
+	u8 host_mlme;
+} __packed;
+
 struct mwifiex_ie_types_num_probes {
 	struct mwifiex_ie_types_header header;
 	__le16 num_probes;
@@ -906,6 +932,13 @@  struct mwifiex_ie_types_tdls_idle_timeout {
 	__le16 value;
 } __packed;
 
+#define MWIFIEX_AUTHTYPE_SAE 6
+
+struct mwifiex_ie_types_sae_pwe_mode {
+	struct mwifiex_ie_types_header header;
+	u8 pwe[];
+} __packed;
+
 struct mwifiex_ie_types_rsn_param_set {
 	struct mwifiex_ie_types_header header;
 	u8 rsn_ie[];
diff --git a/drivers/net/wireless/marvell/mwifiex/init.c b/drivers/net/wireless/marvell/mwifiex/init.c
index c9c58419c37b..a336d45b9677 100644
--- a/drivers/net/wireless/marvell/mwifiex/init.c
+++ b/drivers/net/wireless/marvell/mwifiex/init.c
@@ -81,6 +81,9 @@  int mwifiex_init_priv(struct mwifiex_private *priv)
 	priv->bcn_avg_factor = DEFAULT_BCN_AVG_FACTOR;
 	priv->data_avg_factor = DEFAULT_DATA_AVG_FACTOR;
 
+	priv->auth_flag = 0;
+	priv->auth_alg = WLAN_AUTH_NONE;
+
 	priv->sec_info.wep_enabled = 0;
 	priv->sec_info.authentication_mode = NL80211_AUTHTYPE_OPEN_SYSTEM;
 	priv->sec_info.encryption_mode = 0;
@@ -220,6 +223,9 @@  static void mwifiex_init_adapter(struct mwifiex_adapter *adapter)
 	adapter->cmd_resp_received = false;
 	adapter->event_received = false;
 	adapter->data_received = false;
+	adapter->assoc_resp_received = false;
+	adapter->priv_link_lost = NULL;
+	adapter->host_mlme_link_lost = false;
 
 	clear_bit(MWIFIEX_SURPRISE_REMOVED, &adapter->work_flags);
 
diff --git a/drivers/net/wireless/marvell/mwifiex/join.c b/drivers/net/wireless/marvell/mwifiex/join.c
index 9d98a1908dd6..249210fb2e75 100644
--- a/drivers/net/wireless/marvell/mwifiex/join.c
+++ b/drivers/net/wireless/marvell/mwifiex/join.c
@@ -382,7 +382,9 @@  int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv,
 	struct mwifiex_ie_types_ss_param_set *ss_tlv;
 	struct mwifiex_ie_types_rates_param_set *rates_tlv;
 	struct mwifiex_ie_types_auth_type *auth_tlv;
+	struct mwifiex_ie_types_sae_pwe_mode *sae_pwe_tlv;
 	struct mwifiex_ie_types_chan_list_param_set *chan_tlv;
+	struct mwifiex_ie_types_host_mlme *host_mlme_tlv;
 	u8 rates[MWIFIEX_SUPPORTED_RATES];
 	u32 rates_size;
 	u16 tmp_cap;
@@ -460,6 +462,24 @@  int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv,
 
 	pos += sizeof(auth_tlv->header) + le16_to_cpu(auth_tlv->header.len);
 
+	if (priv->sec_info.authentication_mode == WLAN_AUTH_SAE) {
+		auth_tlv->auth_type = cpu_to_le16(MWIFIEX_AUTHTYPE_SAE);
+		if (bss_desc->bcn_rsnx_ie &&
+		    bss_desc->bcn_rsnx_ie->ieee_hdr.len &&
+		    (bss_desc->bcn_rsnx_ie->data[0] &
+		    WLAN_RSNX_CAPA_SAE_H2E)) {
+			sae_pwe_tlv =
+				(struct mwifiex_ie_types_sae_pwe_mode *)pos;
+			sae_pwe_tlv->header.type =
+				cpu_to_le16(TLV_TYPE_SAE_PWE_MODE);
+			sae_pwe_tlv->header.len =
+				cpu_to_le16(sizeof(sae_pwe_tlv->pwe[0]));
+			sae_pwe_tlv->pwe[0] = bss_desc->bcn_rsnx_ie->data[0];
+			pos += sizeof(sae_pwe_tlv->header) +
+				sizeof(sae_pwe_tlv->pwe[0]);
+		}
+	}
+
 	if (IS_SUPPORT_MULTI_BANDS(priv->adapter) &&
 	    !(ISSUPP_11NENABLED(priv->adapter->fw_cap_info) &&
 	    (!bss_desc->disable_11n) &&
@@ -491,6 +511,16 @@  int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv,
 			sizeof(struct mwifiex_chan_scan_param_set);
 	}
 
+	if (priv->adapter->host_mlme_enabled) {
+		host_mlme_tlv = (struct mwifiex_ie_types_host_mlme *)pos;
+		host_mlme_tlv->header.type = cpu_to_le16(TLV_TYPE_HOST_MLME);
+		host_mlme_tlv->header.len =
+			cpu_to_le16(sizeof(host_mlme_tlv->host_mlme));
+		host_mlme_tlv->host_mlme = 1;
+		pos += sizeof(host_mlme_tlv->header) +
+			sizeof(host_mlme_tlv->host_mlme);
+	}
+
 	if (!priv->wps.session_enable) {
 		if (priv->sec_info.wpa_enabled || priv->sec_info.wpa2_enabled)
 			rsn_ie_len = mwifiex_append_rsn_ie_wpa_wpa2(priv, &pos);
@@ -641,7 +671,21 @@  int mwifiex_ret_802_11_associate(struct mwifiex_private *priv,
 		goto done;
 	}
 
-	assoc_rsp = (struct ieee_types_assoc_rsp *) &resp->params;
+	if (adapter->host_mlme_enabled) {
+		struct ieee80211_mgmt *hdr;
+
+		hdr = (struct ieee80211_mgmt *)&resp->params;
+		if (!memcmp(hdr->bssid,
+			    priv->attempted_bss_desc->mac_address,
+			    ETH_ALEN))
+			assoc_rsp = (struct ieee_types_assoc_rsp *)
+				&hdr->u.assoc_resp;
+		else
+			assoc_rsp =
+				(struct ieee_types_assoc_rsp *)&resp->params;
+	} else {
+		assoc_rsp = (struct ieee_types_assoc_rsp *)&resp->params;
+	}
 
 	cap_info = le16_to_cpu(assoc_rsp->cap_info_bitmap);
 	status_code = le16_to_cpu(assoc_rsp->status_code);
@@ -680,6 +724,9 @@  int mwifiex_ret_802_11_associate(struct mwifiex_private *priv,
 				mwifiex_dbg(priv->adapter, ERROR,
 					    "ASSOC_RESP: UNSPECIFIED failure\n");
 			}
+
+			if (priv->adapter->host_mlme_enabled)
+				priv->assoc_rsp_size = 0;
 		} else {
 			ret = status_code;
 		}
@@ -778,7 +825,8 @@  int mwifiex_ret_802_11_associate(struct mwifiex_private *priv,
 
 	priv->adapter->dbg.num_cmd_assoc_success++;
 
-	mwifiex_dbg(priv->adapter, INFO, "info: ASSOC_RESP: associated\n");
+	mwifiex_dbg(priv->adapter, MSG, "assoc: associated with %pM\n",
+		    priv->attempted_bss_desc->mac_address);
 
 	/* Add the ra_list here for infra mode as there will be only 1 ra
 	   always */
@@ -1491,6 +1539,20 @@  int mwifiex_deauthenticate(struct mwifiex_private *priv, u8 *mac)
 	if (!priv->media_connected)
 		return 0;
 
+	if (priv->adapter->host_mlme_enabled) {
+		priv->auth_flag = 0;
+		priv->auth_alg = WLAN_AUTH_NONE;
+		priv->host_mlme_reg = false;
+		priv->mgmt_frame_mask = 0;
+		if (mwifiex_send_cmd(priv, HostCmd_CMD_MGMT_FRAME_REG,
+				     HostCmd_ACT_GEN_SET, 0,
+				     &priv->mgmt_frame_mask, false)) {
+			mwifiex_dbg(priv->adapter, ERROR,
+				    "could not unregister mgmt frame rx\n");
+			return -1;
+		}
+	}
+
 	switch (priv->bss_mode) {
 	case NL80211_IFTYPE_STATION:
 	case NL80211_IFTYPE_P2P_CLIENT:
diff --git a/drivers/net/wireless/marvell/mwifiex/main.c b/drivers/net/wireless/marvell/mwifiex/main.c
index d99127dc466e..88cd2d6a1dcb 100644
--- a/drivers/net/wireless/marvell/mwifiex/main.c
+++ b/drivers/net/wireless/marvell/mwifiex/main.c
@@ -530,6 +530,11 @@  static void mwifiex_terminate_workqueue(struct mwifiex_adapter *adapter)
 		destroy_workqueue(adapter->rx_workqueue);
 		adapter->rx_workqueue = NULL;
 	}
+
+	if (adapter->host_mlme_workqueue) {
+		destroy_workqueue(adapter->host_mlme_workqueue);
+		adapter->host_mlme_workqueue = NULL;
+	}
 }
 
 /*
@@ -802,6 +807,10 @@  mwifiex_bypass_tx_queue(struct mwifiex_private *priv,
 			    "bypass txqueue; eth type %#x, mgmt %d\n",
 			     ntohs(eth_hdr->h_proto),
 			     mwifiex_is_skb_mgmt_frame(skb));
+		if (eth_hdr->h_proto == htons(ETH_P_PAE))
+			mwifiex_dbg(priv->adapter, MSG,
+				    "key: send EAPOL to %pM\n",
+				    eth_hdr->h_dest);
 		return true;
 	}
 
@@ -1384,6 +1393,35 @@  int is_command_pending(struct mwifiex_adapter *adapter)
 	return !is_cmd_pend_q_empty;
 }
 
+/* This is the host mlme work queue function.
+ * It handles the host mlme operations.
+ */
+static void mwifiex_host_mlme_work_queue(struct work_struct *work)
+{
+	struct mwifiex_adapter *adapter =
+		container_of(work, struct mwifiex_adapter, host_mlme_work);
+
+	if (test_bit(MWIFIEX_SURPRISE_REMOVED, &adapter->work_flags))
+		return;
+
+	/* Check for host mlme disconnection */
+	if (adapter->host_mlme_link_lost) {
+		if (adapter->priv_link_lost) {
+			mwifiex_reset_connect_state(adapter->priv_link_lost,
+						    WLAN_REASON_DEAUTH_LEAVING,
+						    true);
+			adapter->priv_link_lost = NULL;
+		}
+		adapter->host_mlme_link_lost = false;
+	}
+
+	/* Check for host mlme Assoc Resp */
+	if (adapter->assoc_resp_received) {
+		mwifiex_process_assoc_resp(adapter);
+		adapter->assoc_resp_received = false;
+	}
+}
+
 /*
  * This is the RX work queue function.
  *
@@ -1558,6 +1596,18 @@  mwifiex_reinit_sw(struct mwifiex_adapter *adapter)
 		INIT_WORK(&adapter->rx_work, mwifiex_rx_work_queue);
 	}
 
+	if (adapter->host_mlme_enabled) {
+		adapter->host_mlme_workqueue =
+			alloc_workqueue("MWIFIEX_HOST_MLME_WORK_QUEUE",
+					WQ_HIGHPRI |
+					WQ_MEM_RECLAIM |
+					WQ_UNBOUND, 0);
+		if (!adapter->host_mlme_workqueue)
+			goto err_kmalloc;
+		INIT_WORK(&adapter->host_mlme_work,
+			  mwifiex_host_mlme_work_queue);
+	}
+
 	/* Register the device. Fill up the private data structure with
 	 * relevant information from the card. Some code extracted from
 	 * mwifiex_register_dev()
@@ -1721,6 +1771,18 @@  mwifiex_add_card(void *card, struct completion *fw_done,
 		goto err_registerdev;
 	}
 
+	if (adapter->host_mlme_enabled) {
+		adapter->host_mlme_workqueue =
+			alloc_workqueue("MWIFIEX_HOST_MLME_WORK_QUEUE",
+					WQ_HIGHPRI |
+					WQ_MEM_RECLAIM |
+					WQ_UNBOUND, 0);
+		if (!adapter->host_mlme_workqueue)
+			goto err_kmalloc;
+		INIT_WORK(&adapter->host_mlme_work,
+			  mwifiex_host_mlme_work_queue);
+	}
+
 	if (mwifiex_init_hw_fw(adapter, true)) {
 		pr_err("%s: firmware init failed\n", __func__);
 		goto err_init_fw;
diff --git a/drivers/net/wireless/marvell/mwifiex/main.h b/drivers/net/wireless/marvell/mwifiex/main.h
index 175882485a19..a0fdabc43fff 100644
--- a/drivers/net/wireless/marvell/mwifiex/main.h
+++ b/drivers/net/wireless/marvell/mwifiex/main.h
@@ -424,6 +424,8 @@  struct mwifiex_bssdescriptor {
 	u16 wpa_offset;
 	struct ieee_types_generic *bcn_rsn_ie;
 	u16 rsn_offset;
+	struct ieee_types_generic *bcn_rsnx_ie;
+	u16 rsnx_offset;
 	struct ieee_types_generic *bcn_wapi_ie;
 	u16 wapi_offset;
 	u8 *beacon_buf;
@@ -525,6 +527,8 @@  struct mwifiex_private {
 	u8 bss_priority;
 	u8 bss_num;
 	u8 bss_started;
+	u8 auth_flag;
+	u16 auth_alg;
 	u8 frame_type;
 	u8 curr_addr[ETH_ALEN];
 	u8 media_connected;
@@ -608,6 +612,7 @@  struct mwifiex_private {
 #define MWIFIEX_ASSOC_RSP_BUF_SIZE  500
 	u8 assoc_rsp_buf[MWIFIEX_ASSOC_RSP_BUF_SIZE];
 	u32 assoc_rsp_size;
+	struct cfg80211_bss *req_bss;
 
 #define MWIFIEX_GENIE_BUF_SIZE      256
 	u8 gen_ie_buf[MWIFIEX_GENIE_BUF_SIZE];
@@ -647,6 +652,7 @@  struct mwifiex_private {
 	u16 gen_idx;
 	u8 ap_11n_enabled;
 	u8 ap_11ac_enabled;
+	bool host_mlme_reg;
 	u32 mgmt_frame_mask;
 	struct mwifiex_roc_cfg roc_cfg;
 	bool scan_aborting;
@@ -876,6 +882,8 @@  struct mwifiex_adapter {
 	struct work_struct main_work;
 	struct workqueue_struct *rx_workqueue;
 	struct work_struct rx_work;
+	struct workqueue_struct *host_mlme_workqueue;
+	struct work_struct host_mlme_work;
 	bool rx_work_enabled;
 	bool rx_processing;
 	bool delay_main_work;
@@ -907,6 +915,9 @@  struct mwifiex_adapter {
 	u8 cmd_resp_received;
 	u8 event_received;
 	u8 data_received;
+	u8 assoc_resp_received;
+	struct mwifiex_private *priv_link_lost;
+	u8 host_mlme_link_lost;
 	u16 seq_num;
 	struct cmd_ctrl_node *cmd_pool;
 	struct cmd_ctrl_node *curr_cmd;
@@ -996,6 +1007,7 @@  struct mwifiex_adapter {
 	bool is_up;
 
 	bool ext_scan;
+	bool host_mlme_enabled;
 	u8 fw_api_ver;
 	u8 key_api_major_ver, key_api_minor_ver;
 	u8 max_p2p_conn, max_sta_conn;
@@ -1061,6 +1073,9 @@  int mwifiex_recv_packet(struct mwifiex_private *priv, struct sk_buff *skb);
 int mwifiex_uap_recv_packet(struct mwifiex_private *priv,
 			    struct sk_buff *skb);
 
+void mwifiex_host_mlme_disconnect(struct mwifiex_private *priv,
+				  u16 reason_code, u8 *sa);
+
 int mwifiex_process_mgmt_packet(struct mwifiex_private *priv,
 				struct sk_buff *skb);
 
@@ -1092,6 +1107,7 @@  void mwifiex_insert_cmd_to_pending_q(struct mwifiex_adapter *adapter,
 
 int mwifiex_exec_next_cmd(struct mwifiex_adapter *adapter);
 int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter);
+void mwifiex_process_assoc_resp(struct mwifiex_adapter *adapter);
 int mwifiex_handle_rx_packet(struct mwifiex_adapter *adapter,
 			     struct sk_buff *skb);
 int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb,
diff --git a/drivers/net/wireless/marvell/mwifiex/scan.c b/drivers/net/wireless/marvell/mwifiex/scan.c
index 0326b121747c..e782d652cb93 100644
--- a/drivers/net/wireless/marvell/mwifiex/scan.c
+++ b/drivers/net/wireless/marvell/mwifiex/scan.c
@@ -1371,6 +1371,12 @@  int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter,
 			bss_entry->rsn_offset = (u16) (current_ptr -
 							bss_entry->beacon_buf);
 			break;
+		case WLAN_EID_RSNX:
+			bss_entry->bcn_rsnx_ie =
+				(struct ieee_types_generic *)current_ptr;
+			bss_entry->rsnx_offset =
+				(u16)(current_ptr - bss_entry->beacon_buf);
+			break;
 		case WLAN_EID_BSS_AC_ACCESS_DELAY:
 			bss_entry->bcn_wapi_ie =
 				(struct ieee_types_generic *) current_ptr;
diff --git a/drivers/net/wireless/marvell/mwifiex/sdio.c b/drivers/net/wireless/marvell/mwifiex/sdio.c
index f41048b5cd3c..f5c3267a23a2 100644
--- a/drivers/net/wireless/marvell/mwifiex/sdio.c
+++ b/drivers/net/wireless/marvell/mwifiex/sdio.c
@@ -332,6 +332,7 @@  static const struct mwifiex_sdio_device mwifiex_sdio_sd8786 = {
 	.can_auto_tdls = false,
 	.can_ext_scan = false,
 	.fw_ready_extra_delay = false,
+	.host_mlme = false,
 };
 
 static const struct mwifiex_sdio_device mwifiex_sdio_sd8787 = {
@@ -348,6 +349,7 @@  static const struct mwifiex_sdio_device mwifiex_sdio_sd8787 = {
 	.can_auto_tdls = false,
 	.can_ext_scan = true,
 	.fw_ready_extra_delay = false,
+	.host_mlme = false,
 };
 
 static const struct mwifiex_sdio_device mwifiex_sdio_sd8797 = {
@@ -364,6 +366,7 @@  static const struct mwifiex_sdio_device mwifiex_sdio_sd8797 = {
 	.can_auto_tdls = false,
 	.can_ext_scan = true,
 	.fw_ready_extra_delay = false,
+	.host_mlme = false,
 };
 
 static const struct mwifiex_sdio_device mwifiex_sdio_sd8897 = {
@@ -380,6 +383,7 @@  static const struct mwifiex_sdio_device mwifiex_sdio_sd8897 = {
 	.can_auto_tdls = false,
 	.can_ext_scan = true,
 	.fw_ready_extra_delay = false,
+	.host_mlme = false,
 };
 
 static const struct mwifiex_sdio_device mwifiex_sdio_sd8977 = {
@@ -397,6 +401,7 @@  static const struct mwifiex_sdio_device mwifiex_sdio_sd8977 = {
 	.can_auto_tdls = false,
 	.can_ext_scan = true,
 	.fw_ready_extra_delay = false,
+	.host_mlme = false,
 };
 
 static const struct mwifiex_sdio_device mwifiex_sdio_sd8978 = {
@@ -414,6 +419,7 @@  static const struct mwifiex_sdio_device mwifiex_sdio_sd8978 = {
 	.can_auto_tdls = false,
 	.can_ext_scan = true,
 	.fw_ready_extra_delay = true,
+	.host_mlme = true,
 };
 
 static const struct mwifiex_sdio_device mwifiex_sdio_sd8997 = {
@@ -432,6 +438,7 @@  static const struct mwifiex_sdio_device mwifiex_sdio_sd8997 = {
 	.can_auto_tdls = false,
 	.can_ext_scan = true,
 	.fw_ready_extra_delay = false,
+	.host_mlme = false,
 };
 
 static const struct mwifiex_sdio_device mwifiex_sdio_sd8887 = {
@@ -448,6 +455,7 @@  static const struct mwifiex_sdio_device mwifiex_sdio_sd8887 = {
 	.can_auto_tdls = true,
 	.can_ext_scan = true,
 	.fw_ready_extra_delay = false,
+	.host_mlme = false,
 };
 
 static const struct mwifiex_sdio_device mwifiex_sdio_sd8987 = {
@@ -465,6 +473,7 @@  static const struct mwifiex_sdio_device mwifiex_sdio_sd8987 = {
 	.can_auto_tdls = true,
 	.can_ext_scan = true,
 	.fw_ready_extra_delay = false,
+	.host_mlme = false,
 };
 
 static const struct mwifiex_sdio_device mwifiex_sdio_sd8801 = {
@@ -481,6 +490,7 @@  static const struct mwifiex_sdio_device mwifiex_sdio_sd8801 = {
 	.can_auto_tdls = false,
 	.can_ext_scan = true,
 	.fw_ready_extra_delay = false,
+	.host_mlme = false,
 };
 
 static struct memory_type_mapping generic_mem_type_map[] = {
@@ -574,6 +584,7 @@  mwifiex_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id)
 		card->can_auto_tdls = data->can_auto_tdls;
 		card->can_ext_scan = data->can_ext_scan;
 		card->fw_ready_extra_delay = data->fw_ready_extra_delay;
+		card->host_mlme = data->host_mlme;
 		INIT_WORK(&card->work, mwifiex_sdio_work);
 	}
 
@@ -2512,6 +2523,8 @@  static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
 		adapter->num_mem_types = ARRAY_SIZE(mem_type_mapping_tbl);
 	}
 
+	adapter->host_mlme_enabled = card->host_mlme;
+
 	return 0;
 }
 
diff --git a/drivers/net/wireless/marvell/mwifiex/sdio.h b/drivers/net/wireless/marvell/mwifiex/sdio.h
index cb63ad55d675..65d142286c46 100644
--- a/drivers/net/wireless/marvell/mwifiex/sdio.h
+++ b/drivers/net/wireless/marvell/mwifiex/sdio.h
@@ -256,6 +256,7 @@  struct sdio_mmc_card {
 	bool can_auto_tdls;
 	bool can_ext_scan;
 	bool fw_ready_extra_delay;
+	bool host_mlme;
 
 	struct mwifiex_sdio_mpa_tx mpa_tx;
 	struct mwifiex_sdio_mpa_rx mpa_rx;
@@ -280,6 +281,7 @@  struct mwifiex_sdio_device {
 	bool can_auto_tdls;
 	bool can_ext_scan;
 	bool fw_ready_extra_delay;
+	bool host_mlme;
 };
 
 /*
diff --git a/drivers/net/wireless/marvell/mwifiex/sta_event.c b/drivers/net/wireless/marvell/mwifiex/sta_event.c
index df9cdd10a494..b5f3821a6a8f 100644
--- a/drivers/net/wireless/marvell/mwifiex/sta_event.c
+++ b/drivers/net/wireless/marvell/mwifiex/sta_event.c
@@ -135,6 +135,9 @@  void mwifiex_reset_connect_state(struct mwifiex_private *priv, u16 reason_code,
 
 	priv->media_connected = false;
 
+	priv->auth_flag = 0;
+	priv->auth_alg = WLAN_AUTH_NONE;
+
 	priv->scan_block = false;
 	priv->port_open = false;
 
@@ -222,8 +225,12 @@  void mwifiex_reset_connect_state(struct mwifiex_private *priv, u16 reason_code,
 		    priv->cfg_bssid, reason_code);
 	if (priv->bss_mode == NL80211_IFTYPE_STATION ||
 	    priv->bss_mode == NL80211_IFTYPE_P2P_CLIENT) {
-		cfg80211_disconnected(priv->netdev, reason_code, NULL, 0,
-				      !from_ap, GFP_KERNEL);
+		if (adapter->host_mlme_enabled && adapter->host_mlme_link_lost)
+			mwifiex_host_mlme_disconnect(adapter->priv_link_lost,
+						     reason_code, NULL);
+		else
+			cfg80211_disconnected(priv->netdev, reason_code, NULL,
+					      0, !from_ap, GFP_KERNEL);
 	}
 	eth_zero_addr(priv->cfg_bssid);
 
@@ -746,7 +753,15 @@  int mwifiex_process_sta_event(struct mwifiex_private *priv)
 		if (priv->media_connected) {
 			reason_code =
 				get_unaligned_le16(adapter->event_body);
-			mwifiex_reset_connect_state(priv, reason_code, true);
+			if (adapter->host_mlme_enabled) {
+				adapter->priv_link_lost = priv;
+				adapter->host_mlme_link_lost = true;
+				queue_work(adapter->host_mlme_workqueue,
+					   &adapter->host_mlme_work);
+			} else {
+				mwifiex_reset_connect_state(priv, reason_code,
+							    true);
+			}
 		}
 		break;
 
@@ -999,10 +1014,17 @@  int mwifiex_process_sta_event(struct mwifiex_private *priv)
 	case EVENT_REMAIN_ON_CHAN_EXPIRED:
 		mwifiex_dbg(adapter, EVENT,
 			    "event: Remain on channel expired\n");
-		cfg80211_remain_on_channel_expired(&priv->wdev,
-						   priv->roc_cfg.cookie,
-						   &priv->roc_cfg.chan,
-						   GFP_ATOMIC);
+
+		if (adapter->host_mlme_enabled &&
+		    (priv->auth_flag & HOST_MLME_AUTH_PENDING)) {
+			priv->auth_flag = 0;
+			priv->auth_alg = WLAN_AUTH_NONE;
+		} else {
+			cfg80211_remain_on_channel_expired(&priv->wdev,
+							   priv->roc_cfg.cookie,
+							   &priv->roc_cfg.chan,
+							   GFP_ATOMIC);
+		}
 
 		memset(&priv->roc_cfg, 0x00, sizeof(struct mwifiex_roc_cfg));
 
diff --git a/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c b/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c
index 32a27fad7b79..a94659988a4c 100644
--- a/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c
+++ b/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c
@@ -339,7 +339,7 @@  int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
 			ret = mwifiex_associate(priv, bss_desc);
 		}
 
-		if (bss)
+		if (bss && !priv->adapter->host_mlme_enabled)
 			cfg80211_put_bss(priv->adapter->wiphy, bss);
 	} else {
 		/* Adhoc mode */
diff --git a/drivers/net/wireless/marvell/mwifiex/sta_tx.c b/drivers/net/wireless/marvell/mwifiex/sta_tx.c
index 70c2790b8e35..9d0ef04ebe02 100644
--- a/drivers/net/wireless/marvell/mwifiex/sta_tx.c
+++ b/drivers/net/wireless/marvell/mwifiex/sta_tx.c
@@ -36,7 +36,7 @@  void mwifiex_process_sta_txpd(struct mwifiex_private *priv,
 	struct txpd *local_tx_pd;
 	struct mwifiex_txinfo *tx_info = MWIFIEX_SKB_TXCB(skb);
 	unsigned int pad;
-	u16 pkt_type, pkt_offset;
+	u16 pkt_type, pkt_length, pkt_offset;
 	int hroom = adapter->intf_hdr_len;
 
 	pkt_type = mwifiex_is_skb_mgmt_frame(skb) ? PKT_TYPE_MGMT : 0;
@@ -49,9 +49,10 @@  void mwifiex_process_sta_txpd(struct mwifiex_private *priv,
 	memset(local_tx_pd, 0, sizeof(struct txpd));
 	local_tx_pd->bss_num = priv->bss_num;
 	local_tx_pd->bss_type = priv->bss_type;
-	local_tx_pd->tx_pkt_length = cpu_to_le16((u16)(skb->len -
-						       (sizeof(struct txpd) +
-							pad)));
+	pkt_length = (u16)(skb->len - (sizeof(struct txpd) + pad));
+	if (pkt_type == PKT_TYPE_MGMT)
+		pkt_length -= MWIFIEX_MGMT_FRAME_HEADER_SIZE;
+	local_tx_pd->tx_pkt_length = cpu_to_le16(pkt_length);
 
 	local_tx_pd->priority = (u8) skb->priority;
 	local_tx_pd->pkt_delay_2ms =
diff --git a/drivers/net/wireless/marvell/mwifiex/util.c b/drivers/net/wireless/marvell/mwifiex/util.c
index 745b1d925b21..3817c08a1507 100644
--- a/drivers/net/wireless/marvell/mwifiex/util.c
+++ b/drivers/net/wireless/marvell/mwifiex/util.c
@@ -370,6 +370,45 @@  mwifiex_parse_mgmt_packet(struct mwifiex_private *priv, u8 *payload, u16 len,
 
 	return 0;
 }
+
+/* This function sends deauth packet to the kernel. */
+void mwifiex_host_mlme_disconnect(struct mwifiex_private *priv,
+				  u16 reason_code, u8 *sa)
+{
+	u8 frame_buf[100];
+	struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)frame_buf;
+
+	memset(frame_buf, 0, sizeof(frame_buf));
+	mgmt->frame_control = cpu_to_le16(IEEE80211_STYPE_DEAUTH);
+	mgmt->duration = 0;
+	mgmt->seq_ctrl = 0;
+	mgmt->u.deauth.reason_code = cpu_to_le16(reason_code);
+
+	if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) {
+		eth_broadcast_addr(mgmt->da);
+		memcpy(mgmt->sa,
+		       priv->curr_bss_params.bss_descriptor.mac_address,
+		       ETH_ALEN);
+		memcpy(mgmt->bssid, priv->cfg_bssid, ETH_ALEN);
+		priv->auth_flag = 0;
+		priv->auth_alg = WLAN_AUTH_NONE;
+	} else {
+		memcpy(mgmt->da, priv->curr_addr, ETH_ALEN);
+		memcpy(mgmt->sa, sa, ETH_ALEN);
+		memcpy(mgmt->bssid, priv->curr_addr, ETH_ALEN);
+	}
+
+	if (GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_UAP) {
+		wiphy_lock(priv->wdev.wiphy);
+		cfg80211_rx_mlme_mgmt(priv->netdev, frame_buf, 26);
+		wiphy_unlock(priv->wdev.wiphy);
+	} else {
+		cfg80211_rx_mgmt(&priv->wdev,
+				 priv->bss_chandef.chan->center_freq,
+				 0, frame_buf, 26, 0);
+	}
+}
+
 /*
  * This function processes the received management packet and send it
  * to the kernel.
@@ -417,6 +456,47 @@  mwifiex_process_mgmt_packet(struct mwifiex_private *priv,
 	pkt_len -= ETH_ALEN;
 	rx_pd->rx_pkt_length = cpu_to_le16(pkt_len);
 
+	if (priv->host_mlme_reg &&
+	    (GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_UAP) &&
+	    (ieee80211_is_auth(ieee_hdr->frame_control) ||
+	     ieee80211_is_deauth(ieee_hdr->frame_control) ||
+	     ieee80211_is_disassoc(ieee_hdr->frame_control))) {
+		if (ieee80211_is_auth(ieee_hdr->frame_control)) {
+			if (priv->auth_flag & HOST_MLME_AUTH_PENDING) {
+				if (priv->auth_alg != WLAN_AUTH_SAE) {
+					priv->auth_flag &=
+						~HOST_MLME_AUTH_PENDING;
+					priv->auth_flag |=
+						HOST_MLME_AUTH_DONE;
+				}
+			} else {
+				return 0;
+			}
+
+			mwifiex_dbg(priv->adapter, MSG,
+				    "auth: receive authentication from %pM\n",
+				    ieee_hdr->addr3);
+		} else {
+			if (!priv->wdev.connected)
+				return 0;
+
+			if (ieee80211_is_deauth(ieee_hdr->frame_control)) {
+				mwifiex_dbg(priv->adapter, MSG,
+					    "auth: receive deauth from %pM\n",
+					    ieee_hdr->addr3);
+				priv->auth_flag = 0;
+				priv->auth_alg = WLAN_AUTH_NONE;
+			} else {
+				mwifiex_dbg
+				(priv->adapter, MSG,
+				 "assoc: receive disassoc from %pM\n",
+				 ieee_hdr->addr3);
+			}
+		}
+
+		cfg80211_rx_mlme_mgmt(priv->netdev, skb->data, pkt_len);
+	}
+
 	cfg80211_rx_mgmt(&priv->wdev, priv->roc_cfg.chan.center_freq,
 			 CAL_RSSI(rx_pd->snr, rx_pd->nf), skb->data, pkt_len,
 			 0);