RE: [EXT] Re: [PATCH v4 1/1] wifi: mwifiex: added code to support host mlme.

From: David Lin
Date: Tue Oct 24 2023 - 03:46:55 EST


> From: Francesco Dolcini <francesco@xxxxxxxxxx>
> Sent: Tuesday, September 26, 2023 10:40 PM
> To: David Lin <yu-hao.lin@xxxxxxx>
> Cc: linux-wireless@xxxxxxxxxxxxxxx; linux-kernel@xxxxxxxxxxxxxxx; Sharvari
> Harisangam <sharvari.harisangam@xxxxxxx>; Pete Hsieh
> <tsung-hsien.hsieh@xxxxxxx>; kvalo@xxxxxxxxxx; amitkarwar@xxxxxxxxx;
> ganapathi017@xxxxxxxxx; huxinming820@xxxxxxxxx; davem@xxxxxxxxxxxxx;
> edumazet@xxxxxxxxxx; kuba@xxxxxxxxxx; pabeni@xxxxxxxxxx; Brian Norris
> <briannorris@xxxxxxxxxxxx>
> Subject: [EXT] Re: [PATCH v4 1/1] wifi: mwifiex: added code to support host
> mlme.
>
> 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
>
>
> Hello David,
>
> For the next v5 please be sure to properly thread the series as git-send-email
> would normally do (if you are going to have a cover
> letter) or even better just add the changelog after the commit message
> (separated with ---).
>
>
> On Tue, Aug 15, 2023 at 07:09:25AM +0000, David Lin wrote:
> > 1. For station mode first.
> > 2. This feature is a must for WPA3.
> > 3. Firmware key api version 2 is needed for this feature.
> > 4. The code is only enabled and tested with IW416.
> > 5. This feature is disabled for other chips.
>
> I believe that this commit message should be rewritten, at least to me this was
> confusing to read at first.
>
> Maybe something like that?
>
> ```
> wifi: mwifiex: add MLME support
>
> Add host based MLME support for station mode to enable WPA3
> functionalities.
>
> This feature requires a firmware with key API major version 2 and is currently
> enabled and tested only for IW416.
> ```
>
> Was this patch tested to be wholly working with WPA3 or you expect follow up
> patches for proper enabling WPA3 support?
>

I will prepare cover letter with related patches for same thread for Patch v7.

>
> > Signed-off-by: David Lin <yu-hao.lin@xxxxxxx>
> > ---
> > .../net/wireless/marvell/mwifiex/cfg80211.c | 327
> ++++++++++++++++++
> > drivers/net/wireless/marvell/mwifiex/cmdevt.c | 14 +-
> > drivers/net/wireless/marvell/mwifiex/decl.h | 12 +
> > drivers/net/wireless/marvell/mwifiex/fw.h | 15 +
> > drivers/net/wireless/marvell/mwifiex/init.c | 3 +
> > drivers/net/wireless/marvell/mwifiex/join.c | 64 +++-
> > drivers/net/wireless/marvell/mwifiex/main.h | 10 +
> > 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 | 18 +-
> > .../net/wireless/marvell/mwifiex/sta_ioctl.c | 3 +-
> > drivers/net/wireless/marvell/mwifiex/sta_tx.c | 10 +-
> > .../net/wireless/marvell/mwifiex/uap_cmd.c | 26 ++
> > drivers/net/wireless/marvell/mwifiex/util.c | 73 ++++
> > 15 files changed, 583 insertions(+), 13 deletions(-)
> >
> > diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c
> > b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
> > index ba4e29713a8c..605952ee0aa9 100644
> > --- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c
> > +++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
> > @@ -57,6 +57,31 @@ ieee80211_iface_combination
> mwifiex_iface_comb_ap_sta_drcs = {
> > .beacon_int_infra_match = true,
> > };
> >
> > +struct mwifiex_ieee80211_mgmt {
> What's the reasoning for having this in cfg80211.c?
> Am I wrong or most of this binary structures are defined in fw.h?

Yes. You are right. I will move this definition to fw.h. Patch v7 will have this modification.

>
> > + __le16 frame_control;
> > + __le16 duration;
> > + u8 da[ETH_ALEN];
> > + u8 sa[ETH_ALEN];
> > + u8 bssid[ETH_ALEN];
> > + __le16 seq_ctrl;
> > + u8 addr4[ETH_ALEN];
> > + union {
> > + struct {
> > + __le16 auth_alg;
> > + __le16 auth_transaction;
> > + __le16 status_code;
> > + /* possibly followed by Challenge text */
> > + u8 variable[];
> > + } __packed auth;
> > + struct {
> > + __le16 capab_info;
> > + __le16 listen_interval;
> > + /* followed by SSID and Supported rates */
> > + u8 variable[];
> > + } __packed assoc_req;
> > + } u;
> > +} __pack;
>
> __packed
>

Modification will be included in Patch v7.

> > /*
> > * This function maps the nl802.11 channel type into driver channel type.
> > *
> > @@ -268,6 +293,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 +875,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, @@ -4201,6
> > +4229,292 @@ 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 addr[ETH_ALEN] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
> > + 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;
> > + }
> > + }
> > +
> > + 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);
> > + memcpy(mgmt->addr4, addr, ETH_ALEN);
> > +
> > + 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->u.auth.variable), req->auth_data +
> 4,
> > + req->auth_data_len - 4);
> > + varptr = (u8 *)&mgmt->u.auth.variable +
> > + (req->auth_data_len - 4);
> > + }
> > +
> > + mgmt->u.auth.auth_alg = cpu_to_le16(auth_alg);
> > + mgmt->u.auth.auth_transaction = trans;
> > + mgmt->u.auth.status_code = status_code;
> > +
> > + if (req->ie && req->ie_len) {
> > + if (!varptr)
> > + varptr = (u8 *)&mgmt->u.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;
> > + struct cfg80211_rx_assoc_resp assoc_resp = {
> > + .uapsd_queues = -1,
> > + };
> > +
> > + 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 (!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(priv->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(priv->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;
> > + ret = mwifiex_set_encode(priv, NULL, NULL, 0, 0, NULL, 1);
> > +
> > + 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)
> > + ret = mwifiex_set_gen_ie(priv, req->ie, req->ie_len);
> > +
> > + memcpy(priv->cfg_bssid, req->bss->bssid, ETH_ALEN);
> > +
> > + mwifiex_dbg(priv->adapter, MSG,
> > + "assoc: send association to %pM\n",
> > + req->bss->bssid);
> > +
> > + cfg80211_ref_bss(priv->adapter->wiphy, req->bss);
> > +
> > + ret = mwifiex_bss_start(priv, req->bss, &req_ssid);
> > +
> > + if (!ret) {
> > + assoc_resp.links[0].bss = priv->attempted_bss_desc->bss;
> > + assoc_resp.buf = priv->assoc_rsp_buf;
> > + assoc_resp.len = priv->assoc_rsp_size;
> > + cfg80211_rx_assoc_resp(priv->netdev,
> > + &assoc_resp);
> > + } else {
> > + priv->auth_flag = 0;
> > + priv->auth_alg = 0xFFFF;
> worth a define? you have it multiple times.
>

O.K. Modifications will be included in Patch v7.

> > + eth_zero_addr(priv->cfg_bssid);
> > + }
> > +
> > + 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 -1;
> > +}
> > +
> > /* station cfg80211 operations */
> > static struct cfg80211_ops mwifiex_cfg80211_ops = {
> > .add_virtual_intf = mwifiex_add_virtual_intf, @@ -4346,6
> > +4660,16 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter
> *adapter)
> > "%s: creating new wiphy\n", __func__);
> > return -ENOMEM;
> > }
> > + if (adapter->host_mlme) {
> I think this variable should be renamed to host_mlme_enabled or
> mlme_enabled, not sure what's the best.

I will change it as host_mlme_enabled. Patch v7 will include this modification.

>
> > + 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;
> do you need defining this to a function that just return -1? Is this required?
>
> > + }
> > wiphy->max_scan_ssids = MWIFIEX_MAX_SSID_LIST_LENGTH;
> > wiphy->max_scan_ie_len = MWIFIEX_MAX_VSIE_LEN;
> > wiphy->mgmt_stypes = mwifiex_mgmt_stypes; @@ -4427,6 +4751,9
> @@
> > int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
> > NL80211_FEATURE_LOW_PRIORITY_SCAN |
> > NL80211_FEATURE_NEED_OBSS_SCAN;
> >
> > + if (adapter->host_mlme)
> > + 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 3756aa247e77..311af5f40c3e 100644
> > --- a/drivers/net/wireless/marvell/mwifiex/cmdevt.c
> > +++ b/drivers/net/wireless/marvell/mwifiex/cmdevt.c
> > @@ -654,7 +654,7 @@ int mwifiex_send_cmd(struct mwifiex_private *priv,
> u16 cmd_no,
> > if (ret) {
> > mwifiex_dbg(adapter, ERROR,
> > "PREP_CMD: cmd %#x preparation
> failed\n",
> > - cmd_no);
> > + cmd_no);
> unrelated change
>

Fixed format.

> > mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
> > return -1;
> > }
> > @@ -1477,6 +1477,17 @@ int mwifiex_cmd_get_hw_spec(struct
> mwifiex_private *priv,
> > return 0;
> > }
> >
> > +static void mwifiex_check_key_api_ver(struct mwifiex_adapter
> > +*adapter) {
> > + if (adapter->host_mlme) {
> > + if (adapter->key_api_major_ver !=
> KEY_API_VER_MAJOR_V2)
> > + adapter->host_mlme = false;
> > + mwifiex_dbg(adapter, MSG, "host_mlme: %s, key_api:
> %d\n",
> > + adapter->host_mlme ? "enable" : "disable",
> > + adapter->key_api_major_ver);
> > + }
> > +}
> > +
> > /*
> > * This function handles the command response of get hardware
> > * specifications.
> > @@ -1586,6 +1597,7 @@ int mwifiex_ret_get_hw_spec(struct
> mwifiex_private *priv,
> > "key_api
> v%d.%d\n",
> >
> adapter->key_api_major_ver,
> >
> > adapter->key_api_minor_ver);
> > +
> > + mwifiex_check_key_api_ver(adapter);
> for other functionalities you have everything at the end of
> mwifiex_ret_get_hw_spec()
>
> why not doing the same here? Just do the check in a similar way as done for
> scan_chan_gap_enabled.
>

O.K. Patch v7 will include the modification.

>
>
> > break;
> > case FW_API_VER_ID:
> > adapter->fw_api_ver = diff
> --git
> > a/drivers/net/wireless/marvell/mwifiex/decl.h
> > b/drivers/net/wireless/marvell/mwifiex/decl.h
> > index 88648c062713..385b5119f2ee 100644
> > --- a/drivers/net/wireless/marvell/mwifiex/decl.h
> > +++ b/drivers/net/wireless/marvell/mwifiex/decl.h
> > @@ -24,6 +24,18 @@
> > #define MWIFIEX_RX_HEADROOM 64
> > #define MAX_TXPD_SZ 32
> > #define INTF_HDR_ALIGN 4
> > +/* frmctl + durationid + addr1 + addr2 + addr3 + seqctl + addr4 */
> > +#define MWIFIEX_MGMT_HEADER_LEN (2 + 2 + 6 + 6 + 6 + 2 + 6)
> > +/* 6 = auth_alg + auth_transaction + auth_status */
> > +#define MWIFIEX_AUTH_BODY_LEN 6
>
> those comments and magic number are quite confusing, in other part of the
> code (just a few lines after), proper defines are used. Maybe doing the same
> here would help and we could get rid of the comment?

O.K. I will redefine them.

>
> > +
> > +#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 MWIFIEX_MIN_DATA_HEADER_LEN (MWIFIEX_DMA_ALIGN_SZ +
> INTF_HDR_ALIGN + \
> > MAX_TXPD_SZ) diff --git
> > a/drivers/net/wireless/marvell/mwifiex/fw.h
> > b/drivers/net/wireless/marvell/mwifiex/fw.h
> > index f2168fac95ed..5e6bda38f22c 100644
> > --- a/drivers/net/wireless/marvell/mwifiex/fw.h
> > +++ b/drivers/net/wireless/marvell/mwifiex/fw.h
> > @@ -209,6 +209,9 @@ 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
> >
> > @@ -802,6 +805,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;
> > @@ -905,6 +913,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 7dddb4b5dea1..ca23be8d3ac3 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 = 0xFFFF;
> > +
> > priv->sec_info.wep_enabled = 0;
> > priv->sec_info.authentication_mode =
> NL80211_AUTHTYPE_OPEN_SYSTEM;
> > priv->sec_info.encryption_mode = 0; diff --git
> > a/drivers/net/wireless/marvell/mwifiex/join.c
> > b/drivers/net/wireless/marvell/mwifiex/join.c
> > index a6e254a1185c..ef7cc40c3ba4 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;
> > @@ -448,7 +450,7 @@ int mwifiex_cmd_802_11_associate(struct
> mwifiex_private *priv,
> > mwifiex_dbg(priv->adapter, INFO, "info: ASSOC_CMD: rates size =
> %d\n",
> > rates_size);
> >
> > - /* Add the Authentication type to be used for Auth frames */
> > + /* Add the Authentication type */
> > auth_tlv = (struct mwifiex_ie_types_auth_type *) pos;
> > auth_tlv->header.type = cpu_to_le16(TLV_TYPE_AUTH_TYPE);
> > auth_tlv->header.len = cpu_to_le16(sizeof(auth_tlv->auth_type));
> > @@ -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) {
> > + 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); @@ -634,6 +664,7 @@ int
> mwifiex_ret_802_11_associate(struct mwifiex_private *priv,
> > u16 cap_info, status_code, aid;
> > const u8 *ie_ptr;
> > struct ieee80211_ht_operation *assoc_resp_ht_oper;
> > + struct ieee80211_mgmt *hdr;
> >
> > if (!priv->attempted_bss_desc) {
> > mwifiex_dbg(priv->adapter, ERROR, @@ -641,7 +672,19
> @@
> > 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) {
> > + 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);
> > @@ -778,7 +821,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 +1535,20 @@ int mwifiex_deauthenticate(struct
> mwifiex_private *priv, u8 *mac)
> > if (!priv->media_connected)
> > return 0;
> >
> > + if (priv->adapter->host_mlme) {
> > + priv->auth_flag = 0;
> > + priv->auth_alg = 0xFFFF;
> > + 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.h
> > b/drivers/net/wireless/marvell/mwifiex/main.h
> > index b95886e1413e..6d0b9fcfe07c 100644
> > --- a/drivers/net/wireless/marvell/mwifiex/main.h
> > +++ b/drivers/net/wireless/marvell/mwifiex/main.h
> > @@ -384,6 +384,7 @@ struct ieee_types_aid {
> >
> > struct mwifiex_bssdescriptor {
> > u8 mac_address[ETH_ALEN];
> > + struct cfg80211_bss *bss;
> > struct cfg80211_ssid ssid;
> > u32 privacy;
> > s32 rssi;
> > @@ -426,6 +427,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;
> > @@ -536,6 +539,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;
> > @@ -658,6 +663,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;
> > @@ -1012,6 +1018,7 @@ struct mwifiex_adapter {
> > bool is_up;
> >
> > bool ext_scan;
> > + bool host_mlme;
> > u8 fw_api_ver;
> > u8 key_api_major_ver, key_api_minor_ver;
> > u8 max_p2p_conn, max_sta_conn;
> > @@ -1077,6 +1084,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);
> > +
> Remove? Not used
>

Yes. I will remove this function.

> > int mwifiex_process_mgmt_packet(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 644b1e134b01..27eb9a073666 100644
> > --- a/drivers/net/wireless/marvell/mwifiex/scan.c
> > +++ b/drivers/net/wireless/marvell/mwifiex/scan.c
> > @@ -1388,6 +1388,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 a24bd40dd41a..6ba0339ccc65 100644
> > --- a/drivers/net/wireless/marvell/mwifiex/sdio.c
> > +++ b/drivers/net/wireless/marvell/mwifiex/sdio.c
> > @@ -331,6 +331,7 @@ static const struct mwifiex_sdio_device
> mwifiex_sdio_sd8786 = {
> > .can_dump_fw = false,
> > .can_auto_tdls = false,
> > .can_ext_scan = false,
> > + .host_mlme = false,
> what about the PCIe devices? nothing needed there?
>

Since we only enabled and tested for IW416/SDIO, there is no need to modify PCIe related code.

> > };
> >
> > static const struct mwifiex_sdio_device mwifiex_sdio_sd8787 = { @@
> > -346,6 +347,7 @@ static const struct mwifiex_sdio_device
> mwifiex_sdio_sd8787 = {
> > .can_dump_fw = false,
> > .can_auto_tdls = false,
> > .can_ext_scan = true,
> > + .host_mlme = false,
> > };
> >
> > static const struct mwifiex_sdio_device mwifiex_sdio_sd8797 = { @@
> > -361,6 +363,7 @@ static const struct mwifiex_sdio_device
> mwifiex_sdio_sd8797 = {
> > .can_dump_fw = false,
> > .can_auto_tdls = false,
> > .can_ext_scan = true,
> > + .host_mlme = false,
> > };
> >
> > static const struct mwifiex_sdio_device mwifiex_sdio_sd8897 = { @@
> > -376,6 +379,7 @@ static const struct mwifiex_sdio_device
> mwifiex_sdio_sd8897 = {
> > .can_dump_fw = true,
> > .can_auto_tdls = false,
> > .can_ext_scan = true,
> > + .host_mlme = false,
> > };
> >
> > static const struct mwifiex_sdio_device mwifiex_sdio_sd8977 = { @@
> > -392,6 +396,7 @@ static const struct mwifiex_sdio_device
> mwifiex_sdio_sd8977 = {
> > .fw_dump_enh = true,
> > .can_auto_tdls = false,
> > .can_ext_scan = true,
> > + .host_mlme = false,
> > };
> >
> > static const struct mwifiex_sdio_device mwifiex_sdio_sd8978 = { @@
> > -408,6 +413,7 @@ static const struct mwifiex_sdio_device
> mwifiex_sdio_sd8978 = {
> > .fw_dump_enh = true,
> > .can_auto_tdls = false,
> > .can_ext_scan = true,
> > + .host_mlme = true,
> > };
> >
> > static const struct mwifiex_sdio_device mwifiex_sdio_sd8997 = { @@
> > -425,6 +431,7 @@ static const struct mwifiex_sdio_device
> mwifiex_sdio_sd8997 = {
> > .fw_dump_enh = true,
> > .can_auto_tdls = false,
> > .can_ext_scan = true,
> > + .host_mlme = false,
> > };
> >
> > static const struct mwifiex_sdio_device mwifiex_sdio_sd8887 = { @@
> > -440,6 +447,7 @@ static const struct mwifiex_sdio_device
> mwifiex_sdio_sd8887 = {
> > .can_dump_fw = false,
> > .can_auto_tdls = true,
> > .can_ext_scan = true,
> > + .host_mlme = false,
> > };
> >
> > static const struct mwifiex_sdio_device mwifiex_sdio_sd8987 = { @@
> > -456,6 +464,7 @@ static const struct mwifiex_sdio_device
> mwifiex_sdio_sd8987 = {
> > .fw_dump_enh = true,
> > .can_auto_tdls = true,
> > .can_ext_scan = true,
> > + .host_mlme = false,
> > };
> >
> > static const struct mwifiex_sdio_device mwifiex_sdio_sd8801 = { @@
> > -471,6 +480,7 @@ static const struct mwifiex_sdio_device
> mwifiex_sdio_sd8801 = {
> > .can_dump_fw = false,
> > .can_auto_tdls = false,
> > .can_ext_scan = true,
> > + .host_mlme = false,
> > };
> >
> > static struct memory_type_mapping generic_mem_type_map[] = { @@
> > -563,6 +573,7 @@ mwifiex_sdio_probe(struct sdio_func *func, const struct
> sdio_device_id *id)
> > card->fw_dump_enh = data->fw_dump_enh;
> > card->can_auto_tdls = data->can_auto_tdls;
> > card->can_ext_scan = data->can_ext_scan;
> > + card->host_mlme = data->host_mlme;
> > INIT_WORK(&card->work, mwifiex_sdio_work);
> > }
> >
> > @@ -2493,6 +2504,8 @@ static int mwifiex_register_dev(struct
> mwifiex_adapter *adapter)
> > adapter->num_mem_types =
> ARRAY_SIZE(mem_type_mapping_tbl);
> > }
> >
> > + adapter->host_mlme = card->host_mlme;
> > +
> > return 0;
> > }
> >
> > diff --git a/drivers/net/wireless/marvell/mwifiex/sdio.h
> > b/drivers/net/wireless/marvell/mwifiex/sdio.h
> > index ae94c172310f..d2da8c45a9be 100644
> > --- a/drivers/net/wireless/marvell/mwifiex/sdio.h
> > +++ b/drivers/net/wireless/marvell/mwifiex/sdio.h
> > @@ -258,6 +258,7 @@ struct sdio_mmc_card {
> > bool fw_dump_enh;
> > bool can_auto_tdls;
> > bool can_ext_scan;
> > + bool host_mlme;
> >
> > struct mwifiex_sdio_mpa_tx mpa_tx;
> > struct mwifiex_sdio_mpa_rx mpa_rx; @@ -281,6 +282,7 @@ struct
> > mwifiex_sdio_device {
> > bool fw_dump_enh;
> > bool can_auto_tdls;
> > bool can_ext_scan;
> > + 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..69426ddd9c3a 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 = 0xFFFF;
> > +
> > priv->scan_block = false;
> > priv->port_open = false;
> >
> > @@ -999,10 +1002,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 &&
> > + (priv->auth_flag & HOST_MLME_AUTH_PENDING)) {
> > + priv->auth_flag = 0;
> > + priv->auth_alg = 0xFFFF;
> > + } 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 a2ad2b53f016..046541713318 100644
> > --- a/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c
> > +++ b/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c
> > @@ -136,6 +136,7 @@ int mwifiex_fill_new_bss_desc(struct
> mwifiex_private *priv,
> > const struct cfg80211_bss_ies *ies;
> >
> > rcu_read_lock();
> > + bss_desc->bss = bss;
> > ies = rcu_dereference(bss->ies);
> > beacon_ie = kmemdup(ies->data, ies->len, GFP_ATOMIC);
> > beacon_ie_len = ies->len;
> > @@ -339,7 +340,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)
> > 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 13c0e67ededf..6aed6a334d15 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;
> >
> > if (!skb->len) {
> > @@ -58,9 +58,11 @@ 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/uap_cmd.c
> > b/drivers/net/wireless/marvell/mwifiex/uap_cmd.c
> > index e78a201cd150..eb0b8016d43d 100644
> > --- a/drivers/net/wireless/marvell/mwifiex/uap_cmd.c
> > +++ b/drivers/net/wireless/marvell/mwifiex/uap_cmd.c
> > @@ -743,6 +743,29 @@ mwifiex_cmd_uap_sys_config(struct
> host_cmd_ds_command *cmd, u16 cmd_action,
> > return 0;
> > }
> >
> > +/* This function prepares AP start up command with or without host
> > +MLME */ static int mwifiex_cmd_uap_bss_start(struct mwifiex_private
> > +*priv,
> > + struct host_cmd_ds_command
> *cmd) {
> > + struct mwifiex_ie_types_host_mlme *tlv;
> > +
> > + cmd->command = cpu_to_le16(HostCmd_CMD_UAP_BSS_START);
> > + cmd->size = S_DS_GEN;
> > +
> > + if (priv->adapter->host_mlme) {
> > + tlv = (struct mwifiex_ie_types_host_mlme *)((u8 *)cmd +
> cmd->size);
> > + tlv->header.type = cpu_to_le16(TLV_TYPE_HOST_MLME);
> > + tlv->header.len = cpu_to_le16(sizeof(tlv->host_mlme));
> > + tlv->host_mlme = 1;
> > + cmd->size += sizeof(struct mwifiex_ie_types_host_mlme);
> > + }
> > +
> > + cmd->size = cpu_to_le16(cmd->size);
> > +
> > + return 0;
> > +}
> > +
> > /* This function prepares AP specific deauth command with mac supplied
> in
> > * function parameter.
> > */
> > @@ -777,6 +800,9 @@ int mwifiex_uap_prepare_cmd(struct
> mwifiex_private *priv, u16 cmd_no,
> > return -1;
> > break;
> > case HostCmd_CMD_UAP_BSS_START:
> > + if (mwifiex_cmd_uap_bss_start(priv, cmd))
> > + return -1;
> > + break;
> > case HostCmd_CMD_UAP_BSS_STOP:
> > case HOST_CMD_APCMD_SYS_RESET:
> > case HOST_CMD_APCMD_STA_LIST:
> > diff --git a/drivers/net/wireless/marvell/mwifiex/util.c
> > b/drivers/net/wireless/marvell/mwifiex/util.c
> > index 745b1d925b21..bd9bf2888485 100644
> > --- a/drivers/net/wireless/marvell/mwifiex/util.c
> > +++ b/drivers/net/wireless/marvell/mwifiex/util.c
> > @@ -370,6 +370,46 @@ 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)
> Not used? Remove the whole function.
>

Yes.

> > /*
> > * This function processes the received management packet and send it
> > * to the kernel.
> > @@ -417,6 +457,39 @@ 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)) {
> > + priv->auth_flag = 0;
> > + priv->auth_alg = 0xFFFF;
> > + }
> > + }
> > +
> > + 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);
> > --
> > 2.25.1
> >
>