Search Linux Wireless

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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



> 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
> >
> 





[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Wireless Regulations]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux