Search Linux Wireless

Re: [PATCH 1/3] brcmfmac: Support DPP feature

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

 



On Tue, Sep 20, 2022 at 7:04 PM Ian Lin <ian.lin@xxxxxxxxxxxx> wrote:
>
> From: Kurt Lee <kurt.lee@xxxxxxxxxxx>
>
> Let driver parse DPP frames from upper layer and do conresponding

corresponding

> configuration to firmware.
> This change supports DPP handshake based on wpa_supplicant v2.9.
>
> Signed-off-by: Kurt Lee <kurt.lee@xxxxxxxxxxx>
> Signed-off-by: Ian Lin <ian.lin@xxxxxxxxxxxx>
> ---
>  .../broadcom/brcm80211/brcmfmac/cfg80211.c    | 85 ++++++++++++-------
>  .../broadcom/brcm80211/brcmfmac/p2p.c         | 72 ++++++++++++----
>  .../broadcom/brcm80211/brcmfmac/p2p.h         |  4 +-
>  .../broadcom/brcm80211/include/brcmu_wifi.h   |  5 ++
>  4 files changed, 117 insertions(+), 49 deletions(-)
>
> diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
> index 7c72ea26a7d7..4a8aceda8fe8 100644
> --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
> +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
> @@ -64,6 +64,9 @@
>  #define RSN_CAP_MFPC_MASK              BIT(7)
>  #define RSN_PMKID_COUNT_LEN            2
>
> +#define DPP_AKM_SUITE_TYPE             2
> +#define WLAN_AKM_SUITE_DPP             SUITE(WLAN_OUI_WFA, DPP_AKM_SUITE_TYPE)

Please use WLAN_AKM_SUITE_WFA_DPP.


> +
>  #define VNDR_IE_CMD_LEN                        4       /* length of the set command
>                                                  * string :"add", "del" (+ NUL)
>                                                  */
> @@ -1816,6 +1819,9 @@ brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
>                         val = WPA2_AUTH_PSK | WPA2_AUTH_FT;
>                         profile->is_ft = true;
>                         break;
> +               case WLAN_AKM_SUITE_DPP:
> +                       val = WFA_AUTH_DPP;
> +                       break;
>                 default:
>                         bphy_err(drvr, "invalid akm suite (%d)\n",
>                                  sme->crypto.akm_suites[0]);
> @@ -4144,6 +4150,12 @@ static bool brcmf_valid_wpa_oui(u8 *oui, bool is_rsn_ie)
>         return (memcmp(oui, WPA_OUI, TLV_OUI_LEN) == 0);
>  }
>
> +static bool brcmf_valid_dpp_suite(u8 *oui)
> +{
> +       return (memcmp(oui, WFA_OUI, TLV_OUI_LEN) == 0 &&
> +               *(oui + TLV_OUI_LEN) == DPP_AKM_SUITE_TYPE);
> +}
> +
>  static s32
>  brcmf_configure_wpaie(struct brcmf_if *ifp,
>                       const struct brcmf_vs_tlv *wpa_ie,
> @@ -4257,42 +4269,47 @@ brcmf_configure_wpaie(struct brcmf_if *ifp,
>                 goto exit;
>         }
>         for (i = 0; i < count; i++) {
> -               if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
> +               if (brcmf_valid_dpp_suite(&data[offset])) {
> +                       wpa_auth |= WFA_AUTH_DPP;
> +                       offset += TLV_OUI_LEN;
> +               } else if (brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
> +                       offset += TLV_OUI_LEN;
> +                       switch (data[offset]) {
> +                       case RSN_AKM_NONE:
> +                               brcmf_dbg(TRACE, "RSN_AKM_NONE\n");
> +                               wpa_auth |= WPA_AUTH_NONE;
> +                               break;
> +                       case RSN_AKM_UNSPECIFIED:
> +                               brcmf_dbg(TRACE, "RSN_AKM_UNSPECIFIED\n");
> +                               is_rsn_ie ?
> +                                       (wpa_auth |= WPA2_AUTH_UNSPECIFIED) :
> +                                       (wpa_auth |= WPA_AUTH_UNSPECIFIED);
> +                               break;
> +                       case RSN_AKM_PSK:
> +                               brcmf_dbg(TRACE, "RSN_AKM_PSK\n");
> +                               is_rsn_ie ? (wpa_auth |= WPA2_AUTH_PSK) :
> +                                           (wpa_auth |= WPA_AUTH_PSK);
> +                               break;
> +                       case RSN_AKM_SHA256_PSK:
> +                               brcmf_dbg(TRACE, "RSN_AKM_MFP_PSK\n");
> +                               wpa_auth |= WPA2_AUTH_PSK_SHA256;
> +                               break;
> +                       case RSN_AKM_SHA256_1X:
> +                               brcmf_dbg(TRACE, "RSN_AKM_MFP_1X\n");
> +                               wpa_auth |= WPA2_AUTH_1X_SHA256;
> +                               break;
> +                       case RSN_AKM_SAE:
> +                               brcmf_dbg(TRACE, "RSN_AKM_SAE\n");
> +                               wpa_auth |= WPA3_AUTH_SAE_PSK;
> +                               break;
> +                       default:
> +                               bphy_err(drvr, "Invalid key mgmt info\n");
> +                       }
> +               } else {

Only check for invalid case here
    if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie) &&
            !brcmf_valid_dpp_suite(&data[offset])) {

And keep the switch below but add a new case for DPP_AKM_SUITE_TYPE.

>                         err = -EINVAL;
>                         bphy_err(drvr, "ivalid OUI\n");
>                         goto exit;
>                 }
> -               offset += TLV_OUI_LEN;
> -               switch (data[offset]) {
> -               case RSN_AKM_NONE:
> -                       brcmf_dbg(TRACE, "RSN_AKM_NONE\n");
> -                       wpa_auth |= WPA_AUTH_NONE;
> -                       break;
> -               case RSN_AKM_UNSPECIFIED:
> -                       brcmf_dbg(TRACE, "RSN_AKM_UNSPECIFIED\n");
> -                       is_rsn_ie ? (wpa_auth |= WPA2_AUTH_UNSPECIFIED) :
> -                                   (wpa_auth |= WPA_AUTH_UNSPECIFIED);
> -                       break;
> -               case RSN_AKM_PSK:
> -                       brcmf_dbg(TRACE, "RSN_AKM_PSK\n");
> -                       is_rsn_ie ? (wpa_auth |= WPA2_AUTH_PSK) :
> -                                   (wpa_auth |= WPA_AUTH_PSK);
> -                       break;
> -               case RSN_AKM_SHA256_PSK:
> -                       brcmf_dbg(TRACE, "RSN_AKM_MFP_PSK\n");
> -                       wpa_auth |= WPA2_AUTH_PSK_SHA256;
> -                       break;
> -               case RSN_AKM_SHA256_1X:
> -                       brcmf_dbg(TRACE, "RSN_AKM_MFP_1X\n");
> -                       wpa_auth |= WPA2_AUTH_1X_SHA256;
> -                       break;
> -               case RSN_AKM_SAE:
> -                       brcmf_dbg(TRACE, "RSN_AKM_SAE\n");
> -                       wpa_auth |= WPA3_AUTH_SAE_PSK;
> -                       break;
> -               default:
> -                       bphy_err(drvr, "Invalid key mgmt info\n");
> -               }
>                 offset++;
>         }
>
> @@ -4312,10 +4329,12 @@ brcmf_configure_wpaie(struct brcmf_if *ifp,
>                                  */
>                                 if (!(wpa_auth & (WPA2_AUTH_PSK_SHA256 |
>                                                   WPA2_AUTH_1X_SHA256 |
> +                                                 WFA_AUTH_DPP |
>                                                   WPA3_AUTH_SAE_PSK))) {
>                                         err = -EINVAL;
>                                         goto exit;
>                                 }
> +
>                                 /* Firmware has requirement that WPA2_AUTH_PSK/
>                                  * WPA2_AUTH_UNSPECIFIED be set, if SHA256 OUI
>                                  * is to be included in the rsn ie.
> @@ -5225,7 +5244,7 @@ brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
>                           *cookie, le16_to_cpu(action_frame->len), freq);
>
>                 ack = brcmf_p2p_send_action_frame(cfg, cfg_to_ndev(cfg),
> -                                                 af_params);
> +                                                 af_params, vif);
>
>                 cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, ack,
>                                         GFP_KERNEL);
> diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
> index 479041f070f9..4636fc27e915 100644
> --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
> +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
> @@ -231,7 +231,35 @@ static bool brcmf_p2p_is_pub_action(void *frame, u32 frame_len)
>         if (pact_frm->category == P2P_PUB_AF_CATEGORY &&
>             pact_frm->action == P2P_PUB_AF_ACTION &&
>             pact_frm->oui_type == P2P_VER &&
> -           memcmp(pact_frm->oui, P2P_OUI, P2P_OUI_LEN) == 0)
> +           memcmp(pact_frm->oui, WFA_OUI, P2P_OUI_LEN) == 0)

This change is irrelevant although the two macros are the same. Please
have a separate patch to clean up P2P_OUI.

> +               return true;
> +
> +       return false;
> +}
> +
> +/**
> + * brcmf_p2p_is_dpp_pub_action() - true if dpp public type frame.
> + *
> + * @frame: action frame data.
> + * @frame_len: length of action frame data.
> + *
> + * Determine if action frame is dpp public action type
> + */
> +static bool brcmf_p2p_is_dpp_pub_action(void *frame, u32 frame_len)
> +{
> +       struct brcmf_p2p_pub_act_frame *pact_frm;
> +
> +       if (!frame)
> +               return false;
> +
> +       pact_frm = (struct brcmf_p2p_pub_act_frame *)frame;
> +       if (frame_len < sizeof(struct brcmf_p2p_pub_act_frame) - 1)
> +               return false;
> +
> +       if (pact_frm->category == WLAN_CATEGORY_PUBLIC &&
> +           pact_frm->action == WLAN_PUB_ACTION_VENDOR_SPECIFIC &&
> +           pact_frm->oui_type == DPP_VER &&
> +           memcmp(pact_frm->oui, WFA_OUI, TLV_OUI_LEN) == 0)
>                 return true;
>
>         return false;
> @@ -991,6 +1019,8 @@ int brcmf_p2p_remain_on_channel(struct wiphy *wiphy, struct wireless_dev *wdev,
>         if (err)
>                 goto exit;
>
> +       p2p->remin_on_channel_wdev = wdev;
> +
>         memcpy(&p2p->remain_on_channel, channel, sizeof(*channel));
>         *cookie = p2p->remain_on_channel_cookie;
>         cfg80211_ready_on_channel(wdev, *cookie, channel, duration, GFP_KERNEL);
> @@ -1014,6 +1044,7 @@ int brcmf_p2p_notify_listen_complete(struct brcmf_if *ifp,
>  {
>         struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
>         struct brcmf_p2p_info *p2p = &cfg->p2p;
> +       struct wireless_dev *wdev = p2p->remin_on_channel_wdev;
>
>         brcmf_dbg(TRACE, "Enter\n");
>         if (test_and_clear_bit(BRCMF_P2P_STATUS_DISCOVER_LISTEN,
> @@ -1026,10 +1057,16 @@ int brcmf_p2p_notify_listen_complete(struct brcmf_if *ifp,
>                         complete(&p2p->wait_next_af);
>                 }
>
> -               cfg80211_remain_on_channel_expired(&ifp->vif->wdev,
> +               wdev = p2p->remin_on_channel_wdev ?
> +                       p2p->remin_on_channel_wdev :
> +                       &ifp->vif->wdev;
> +
> +               cfg80211_remain_on_channel_expired(wdev,
>                                                    p2p->remain_on_channel_cookie,
>                                                    &p2p->remain_on_channel,
>                                                    GFP_KERNEL);
> +               p2p->remin_on_channel_wdev = NULL;
> +
>         }
>         return 0;
>  }
> @@ -1531,6 +1568,7 @@ int brcmf_p2p_notify_action_tx_complete(struct brcmf_if *ifp,
>   *
>   * @p2p: p2p info struct for vif.
>   * @af_params: action frame data/info.
> + * @vif: vif to send
>   *
>   * Send an action frame immediately without doing channel synchronization.
>   *
> @@ -1539,12 +1577,17 @@ int brcmf_p2p_notify_action_tx_complete(struct brcmf_if *ifp,
>   * frame is transmitted.
>   */
>  static s32 brcmf_p2p_tx_action_frame(struct brcmf_p2p_info *p2p,
> -                                    struct brcmf_fil_af_params_le *af_params)
> +                                    struct brcmf_fil_af_params_le *af_params,
> +                                    struct brcmf_cfg80211_vif *vif
> +                                    )
>  {
>         struct brcmf_pub *drvr = p2p->cfg->pub;
> -       struct brcmf_cfg80211_vif *vif;
> -       struct brcmf_p2p_action_frame *p2p_af;
>         s32 err = 0;
> +       struct brcmf_fil_action_frame_le *action_frame;
> +       u16 action_frame_len;
> +
> +       action_frame = &af_params->action_frame;
> +       action_frame_len = le16_to_cpu(action_frame->len);
>
>         brcmf_dbg(TRACE, "Enter\n");
>
> @@ -1552,13 +1595,6 @@ static s32 brcmf_p2p_tx_action_frame(struct brcmf_p2p_info *p2p,
>         clear_bit(BRCMF_P2P_STATUS_ACTION_TX_COMPLETED, &p2p->status);
>         clear_bit(BRCMF_P2P_STATUS_ACTION_TX_NOACK, &p2p->status);
>
> -       /* check if it is a p2p_presence response */
> -       p2p_af = (struct brcmf_p2p_action_frame *)af_params->action_frame.data;
> -       if (p2p_af->subtype == P2P_AF_PRESENCE_RSP)
> -               vif = p2p->bss_idx[P2PAPI_BSSCFG_CONNECTION].vif;
> -       else
> -               vif = p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
> -
>         err = brcmf_fil_bsscfg_data_set(vif->ifp, "actframe", af_params,
>                                         sizeof(*af_params));
>         if (err) {
> @@ -1714,10 +1750,13 @@ static bool brcmf_p2p_check_dwell_overflow(u32 requested_dwell,
>   * @cfg: driver private data for cfg80211 interface.
>   * @ndev: net device to transmit on.
>   * @af_params: configuration data for action frame.
> + * @vif: virtual interface to send
>   */
>  bool brcmf_p2p_send_action_frame(struct brcmf_cfg80211_info *cfg,
>                                  struct net_device *ndev,
> -                                struct brcmf_fil_af_params_le *af_params)
> +                                struct brcmf_fil_af_params_le *af_params,
> +                                struct brcmf_cfg80211_vif *vif
> +                                )
>  {
>         struct brcmf_p2p_info *p2p = &cfg->p2p;
>         struct brcmf_if *ifp = netdev_priv(ndev);
> @@ -1789,7 +1828,9 @@ bool brcmf_p2p_send_action_frame(struct brcmf_cfg80211_info *cfg,
>                         goto exit;
>                 }
>         } else if (brcmf_p2p_is_p2p_action(action_frame->data,
> -                                          action_frame_len)) {
> +                                          action_frame_len) ||
> +                  brcmf_p2p_is_dpp_pub_action(action_frame->data,
> +                                              action_frame_len)) {
>                 /* do not configure anything. it will be */
>                 /* sent with a default configuration     */
>         } else {
> @@ -1857,7 +1898,7 @@ bool brcmf_p2p_send_action_frame(struct brcmf_cfg80211_info *cfg,
>                 if (af_params->channel)
>                         msleep(P2P_AF_RETRY_DELAY_TIME);
>
> -               ack = !brcmf_p2p_tx_action_frame(p2p, af_params);
> +               ack = !brcmf_p2p_tx_action_frame(p2p, af_params, vif);
>                 tx_retry++;
>                 dwell_overflow = brcmf_p2p_check_dwell_overflow(requested_dwell,
>                                                                 dwell_jiffies);
> @@ -2508,6 +2549,7 @@ s32 brcmf_p2p_attach(struct brcmf_cfg80211_info *cfg, bool p2pdev_forced)
>
>         pri_ifp = brcmf_get_ifp(cfg->pub, 0);
>         p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif = pri_ifp->vif;
> +       init_completion(&p2p->send_af_done);
>
>         if (p2pdev_forced) {
>                 err_ptr = brcmf_p2p_create_p2pdev(p2p, NULL, NULL);
> diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.h
> index d2ecee565bf2..bbc455238707 100644
> --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.h
> +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.h
> @@ -138,6 +138,7 @@ struct brcmf_p2p_info {
>         bool block_gon_req_tx;
>         bool p2pdev_dynamically;
>         bool wait_for_offchan_complete;
> +       struct wireless_dev *remin_on_channel_wdev;

Docstring needs update. Also s/remin/remain

>  };
>
>  s32 brcmf_p2p_attach(struct brcmf_cfg80211_info *cfg, bool p2pdev_forced);
> @@ -170,7 +171,8 @@ int brcmf_p2p_notify_action_tx_complete(struct brcmf_if *ifp,
>                                         void *data);
>  bool brcmf_p2p_send_action_frame(struct brcmf_cfg80211_info *cfg,
>                                  struct net_device *ndev,
> -                                struct brcmf_fil_af_params_le *af_params);
> +                                struct brcmf_fil_af_params_le *af_params,
> +                                struct brcmf_cfg80211_vif *vif);
>  bool brcmf_p2p_scan_finding_common_channel(struct brcmf_cfg80211_info *cfg,
>                                            struct brcmf_bss_info_le *bi);
>  s32 brcmf_p2p_notify_rx_mgmt_p2p_probereq(struct brcmf_if *ifp,
> diff --git a/drivers/net/wireless/broadcom/brcm80211/include/brcmu_wifi.h b/drivers/net/wireless/broadcom/brcm80211/include/brcmu_wifi.h
> index 7552bdb91991..3a9cad3730b8 100644
> --- a/drivers/net/wireless/broadcom/brcm80211/include/brcmu_wifi.h
> +++ b/drivers/net/wireless/broadcom/brcm80211/include/brcmu_wifi.h
> @@ -233,6 +233,11 @@ static inline bool ac_bitmap_tst(u8 bitmap, int prec)
>
>  #define WPA3_AUTH_SAE_PSK      0x40000 /* SAE with 4-way handshake */
>
> +#define WFA_AUTH_DPP           0x200000 /* WFA DPP AUTH */

This is incompatible with Broadcom's bit definitions. Please use a per
vendor approach.

> +
> +#define WFA_OUI                        "\x50\x6F\x9A"  /* WFA OUI */
> +#define DPP_VER                        0x1A    /* WFA DPP v1.0 */
> +
>  #define DOT11_DEFAULT_RTS_LEN          2347
>  #define DOT11_DEFAULT_FRAG_LEN         2346
>
> --
> 2.25.0
>

-- 
This electronic communication and the information and any files transmitted 
with it, or attached to it, are confidential and are intended solely for 
the use of the individual or entity to whom it is addressed and may contain 
information that is confidential, legally privileged, protected by privacy 
laws, or otherwise restricted from disclosure to anyone else. If you are 
not the intended recipient or the person responsible for delivering the 
e-mail to the intended recipient, you are hereby notified that any use, 
copying, distributing, dissemination, forwarding, printing, or copying of 
this e-mail is strictly prohibited. If you received this e-mail in error, 
please return the e-mail to the sender, delete it from your computer, and 
destroy any printed copy of it.

Attachment: smime.p7s
Description: S/MIME Cryptographic Signature


[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