diff mbox series

[1/3] brcmfmac: Support DPP feature

Message ID 20220921015951.16178-2-ian.lin@infineon.com (mailing list archive)
State Changes Requested
Delegated to: Kalle Valo
Headers show
Series brcmfmac: Support DPP feature series | expand

Commit Message

Ian Lin Sept. 21, 2022, 1:59 a.m. UTC
From: Kurt Lee <kurt.lee@cypress.com>

Let driver parse DPP frames from upper layer and do conresponding
configuration to firmware.
This change supports DPP handshake based on wpa_supplicant v2.9.

Signed-off-by: Kurt Lee <kurt.lee@cypress.com>
Signed-off-by: Ian Lin <ian.lin@infineon.com>
---
 .../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(-)

Comments

kernel test robot Sept. 21, 2022, 4:50 a.m. UTC | #1
Hi Ian,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on wireless-next/main]
[also build test WARNING on wireless/main linus/master v6.0-rc6 next-20220920]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Ian-Lin/brcmfmac-Support-DPP-feature-series/20220921-101658
base:   https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-next.git main
config: m68k-allyesconfig (https://download.01.org/0day-ci/archive/20220921/202209211219.PmRhFKDc-lkp@intel.com/config)
compiler: m68k-linux-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/intel-lab-lkp/linux/commit/a4592ec96782290389bab0b4ca9cd9bc0ae4672a
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Ian-Lin/brcmfmac-Support-DPP-feature-series/20220921-101658
        git checkout a4592ec96782290389bab0b4ca9cd9bc0ae4672a
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=m68k SHELL=/bin/bash drivers/net/wireless/broadcom/brcm80211/brcmfmac/

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

   drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c: In function 'brcmf_p2p_tx_action_frame':
>> drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c:1587:13: warning: variable 'action_frame_len' set but not used [-Wunused-but-set-variable]
    1587 |         u16 action_frame_len;
         |             ^~~~~~~~~~~~~~~~


vim +/action_frame_len +1587 drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c

  1564	
  1565	
  1566	/**
  1567	 * brcmf_p2p_tx_action_frame() - send action frame over fil.
  1568	 *
  1569	 * @p2p: p2p info struct for vif.
  1570	 * @af_params: action frame data/info.
  1571	 * @vif: vif to send
  1572	 *
  1573	 * Send an action frame immediately without doing channel synchronization.
  1574	 *
  1575	 * This function waits for a completion event before returning.
  1576	 * The WLC_E_ACTION_FRAME_COMPLETE event will be received when the action
  1577	 * frame is transmitted.
  1578	 */
  1579	static s32 brcmf_p2p_tx_action_frame(struct brcmf_p2p_info *p2p,
  1580					     struct brcmf_fil_af_params_le *af_params,
  1581					     struct brcmf_cfg80211_vif *vif
  1582					     )
  1583	{
  1584		struct brcmf_pub *drvr = p2p->cfg->pub;
  1585		s32 err = 0;
  1586		struct brcmf_fil_action_frame_le *action_frame;
> 1587		u16 action_frame_len;
  1588	
  1589		action_frame = &af_params->action_frame;
  1590		action_frame_len = le16_to_cpu(action_frame->len);
  1591	
  1592		brcmf_dbg(TRACE, "Enter\n");
  1593	
  1594		reinit_completion(&p2p->send_af_done);
  1595		clear_bit(BRCMF_P2P_STATUS_ACTION_TX_COMPLETED, &p2p->status);
  1596		clear_bit(BRCMF_P2P_STATUS_ACTION_TX_NOACK, &p2p->status);
  1597	
  1598		err = brcmf_fil_bsscfg_data_set(vif->ifp, "actframe", af_params,
  1599						sizeof(*af_params));
  1600		if (err) {
  1601			bphy_err(drvr, " sending action frame has failed\n");
  1602			goto exit;
  1603		}
  1604	
  1605		p2p->af_sent_channel = le32_to_cpu(af_params->channel);
  1606		p2p->af_tx_sent_jiffies = jiffies;
  1607	
  1608		if (test_bit(BRCMF_P2P_STATUS_DISCOVER_LISTEN, &p2p->status) &&
  1609		    p2p->af_sent_channel ==
  1610		    ieee80211_frequency_to_channel(p2p->remain_on_channel.center_freq))
  1611			p2p->wait_for_offchan_complete = false;
  1612		else
  1613			p2p->wait_for_offchan_complete = true;
  1614	
  1615		brcmf_dbg(TRACE, "Waiting for %s tx completion event\n",
  1616			  (p2p->wait_for_offchan_complete) ?
  1617			   "off-channel" : "on-channel");
  1618	
  1619		wait_for_completion_timeout(&p2p->send_af_done, P2P_AF_MAX_WAIT_TIME);
  1620	
  1621		if (test_bit(BRCMF_P2P_STATUS_ACTION_TX_COMPLETED, &p2p->status)) {
  1622			brcmf_dbg(TRACE, "TX action frame operation is success\n");
  1623		} else {
  1624			err = -EIO;
  1625			brcmf_dbg(TRACE, "TX action frame operation has failed\n");
  1626		}
  1627		/* clear status bit for action tx */
  1628		clear_bit(BRCMF_P2P_STATUS_ACTION_TX_COMPLETED, &p2p->status);
  1629		clear_bit(BRCMF_P2P_STATUS_ACTION_TX_NOACK, &p2p->status);
  1630	
  1631	exit:
  1632		return err;
  1633	}
  1634
Franky Lin Sept. 21, 2022, 5:10 p.m. UTC | #2
On Tue, Sep 20, 2022 at 7:04 PM Ian Lin <ian.lin@infineon.com> wrote:
>
> From: Kurt Lee <kurt.lee@cypress.com>
>
> 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@cypress.com>
> Signed-off-by: Ian Lin <ian.lin@infineon.com>
> ---
>  .../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
>
Ian Lin Sept. 23, 2022, 8:20 a.m. UTC | #3
On 9/22/2022 1:10 AM, Franky Lin wrote:
> On Tue, Sep 20, 2022 at 7:04 PM Ian Lin <ian.lin@infineon.com> wrote:
>> From: Kurt Lee <kurt.lee@cypress.com>
>>
>> Let driver parse DPP frames from upper layer and do conresponding
> corresponding
Will fix in next version.

>> configuration to firmware.
>> This change supports DPP handshake based on wpa_supplicant v2.9.
>>
>> Signed-off-by: Kurt Lee <kurt.lee@cypress.com>
>> Signed-off-by: Ian Lin <ian.lin@infineon.com>
>> ---
>>   .../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.
Will fix in next version.

>
>> +
>>   #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.
The two authentication type refer to equal value: DPP_AKM_SUITE_TYPE & 
RSN_AKM_PSK (both =2)
So I can not directly place DPP_AKM_SUITE_TYPE into switch case.

It's more reasonable that we firstly check if it's DPP by 
brcmf_valid_dpp_suite
  - need to check WFA_OUI and DPP_AKM_SUITE_TYPE
Then go to the other cases.

>>                          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.
Will fix in next version.

>> +               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
Will fix in next version.

>>   };
>>
>>   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.
We had extended the bit definition.
The authentication mode will be set to our FW so it's FW-dependent.
Do you suggest I change the name? like CY_WFA_AUTH_DPP?

Thank you for the review.

>> +
>> +#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
>>
Franky Lin Sept. 23, 2022, 4:36 p.m. UTC | #4
On Fri, Sep 23, 2022 at 1:20 AM Lin Ian (CSSITB CSS ICW SW WFS / EE)
<ian.lin@infineon.com> wrote:
>
>
>
> On 9/22/2022 1:10 AM, Franky Lin wrote:
> > On Tue, Sep 20, 2022 at 7:04 PM Ian Lin <ian.lin@infineon.com> wrote:
> >> From: Kurt Lee <kurt.lee@cypress.com>
> >>
> >> Let driver parse DPP frames from upper layer and do conresponding
> > corresponding
> Will fix in next version.
>
> >> configuration to firmware.
> >> This change supports DPP handshake based on wpa_supplicant v2.9.
> >>
> >> Signed-off-by: Kurt Lee <kurt.lee@cypress.com>
> >> Signed-off-by: Ian Lin <ian.lin@infineon.com>
> >> ---
> >>   .../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.
> Will fix in next version.
>
> >
> >> +
> >>   #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.
> The two authentication type refer to equal value: DPP_AKM_SUITE_TYPE &
> RSN_AKM_PSK (both =2)
> So I can not directly place DPP_AKM_SUITE_TYPE into switch case.
>
> It's more reasonable that we firstly check if it's DPP by
> brcmf_valid_dpp_suite
>   - need to check WFA_OUI and DPP_AKM_SUITE_TYPE
> Then go to the other cases.
>
> >>                          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.
> Will fix in next version.
>
> >> +               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
> Will fix in next version.
>
> >>   };
> >>
> >>   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.
> We had extended the bit definition.
> The authentication mode will be set to our FW so it's FW-dependent.
> Do you suggest I change the name? like CY_WFA_AUTH_DPP?

Being firmware dependent is exactly the problem here. The user
functions of this macro are in common code path so this bit could go
to firmware from any vendor. A mechanism should be in place to only
set this bit when the driver is working with a infineon/cypress
firmware.

Regards,
- Franky


>
> Thank you for the review.
>
> >> +
> >> +#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
> >>
>
Ian Lin Sept. 28, 2022, 4:26 a.m. UTC | #5
On 9/24/2022 12:36 AM, Franky Lin wrote:
>
>>>>    };
>>>>
>>>>    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.
>> We had extended the bit definition.
>> The authentication mode will be set to our FW so it's FW-dependent.
>> Do you suggest I change the name? like CY_WFA_AUTH_DPP?
> Being firmware dependent is exactly the problem here. The user
> functions of this macro are in common code path so this bit could go
> to firmware from any vendor. A mechanism should be in place to only
> set this bit when the driver is working with a infineon/cypress
> firmware.
>
> Regards,
> - Franky
>

Currently we don't have such mechanism.
Please abandon this review series.
Thank you.
diff mbox series

Patch

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)
+
 #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 {
 			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)
+		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;
 };
 
 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 */
+
+#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