]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
brcmfmac: support the second p2p connection
authorWright Feng <wright.feng@cypress.com>
Mon, 4 May 2020 06:07:31 +0000 (01:07 -0500)
committerKalle Valo <kvalo@codeaurora.org>
Wed, 6 May 2020 08:39:17 +0000 (11:39 +0300)
With RSDB feature, firmware is able to support two P2P-AGO or two
P2P-GC at the same time. So we add the second p2p connection type
to map to the second P2P connection bsscfg.

Signed-off-by: Wright Feng <wright.feng@cypress.com>
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@cypress.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Link: https://lore.kernel.org/r/1588572453-194663-2-git-send-email-wright.feng@cypress.com
drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.h

index f8ece9f381a5f9a182e36aa1d04a7f65a2370bca..6612103305d8c08e84a9778bc33b60cef5cea10b 100644 (file)
@@ -17,6 +17,7 @@
 #include "fwil_types.h"
 #include "p2p.h"
 #include "cfg80211.h"
+#include "feature.h"
 
 /* parameters used for p2p escan */
 #define P2PAPI_SCAN_NPROBES 1
@@ -488,9 +489,13 @@ static void brcmf_p2p_generate_bss_mac(struct brcmf_p2p_info *p2p, u8 *dev_addr)
         * BSSCFGs need to simultaneously co-exist, then this address must be
         * different from the P2P Device Address, but also locally administered.
         */
-       memcpy(p2p->int_addr, p2p->dev_addr, ETH_ALEN);
-       p2p->int_addr[0] |= 0x02;
-       p2p->int_addr[4] ^= 0x80;
+       memcpy(p2p->conn_int_addr, p2p->dev_addr, ETH_ALEN);
+       p2p->conn_int_addr[0] |= 0x02;
+       p2p->conn_int_addr[4] ^= 0x80;
+
+       memcpy(p2p->conn2_int_addr, p2p->dev_addr, ETH_ALEN);
+       p2p->conn2_int_addr[0] |= 0x02;
+       p2p->conn2_int_addr[4] ^= 0x90;
 }
 
 /**
@@ -2015,7 +2020,7 @@ int brcmf_p2p_ifchange(struct brcmf_cfg80211_info *cfg,
 
        if_request.type = cpu_to_le16((u16)if_type);
        if_request.chspec = cpu_to_le16(chanspec);
-       memcpy(if_request.addr, p2p->int_addr, sizeof(if_request.addr));
+       memcpy(if_request.addr, p2p->conn_int_addr, sizeof(if_request.addr));
 
        brcmf_cfg80211_arm_vif_event(cfg, vif);
        err = brcmf_fil_iovar_data_set(vif->ifp, "p2p_ifupd", &if_request,
@@ -2170,6 +2175,27 @@ fail:
        return ERR_PTR(err);
 }
 
+int brcmf_p2p_get_conn_idx(struct brcmf_cfg80211_info *cfg)
+{
+       int i;
+       struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
+
+       if (!ifp)
+               return -ENODEV;
+
+       for (i = P2PAPI_BSSCFG_CONNECTION; i < P2PAPI_BSSCFG_MAX; i++) {
+               if (!cfg->p2p.bss_idx[i].vif) {
+                       if (i == P2PAPI_BSSCFG_CONNECTION2 &&
+                           !(brcmf_feat_is_enabled(ifp, BRCMF_FEAT_RSDB))) {
+                               brcmf_err("Multi p2p not supported");
+                               return -EIO;
+                       }
+                       return i;
+               }
+       }
+       return -EIO;
+}
+
 /**
  * brcmf_p2p_add_vif() - create a new P2P virtual interface.
  *
@@ -2189,7 +2215,9 @@ struct wireless_dev *brcmf_p2p_add_vif(struct wiphy *wiphy, const char *name,
        struct brcmf_pub *drvr = cfg->pub;
        struct brcmf_cfg80211_vif *vif;
        enum brcmf_fil_p2p_if_types iftype;
-       int err;
+       int err = 0;
+       int connidx;
+       u8 *p2p_intf_addr;
 
        if (brcmf_cfg80211_vif_event_armed(cfg))
                return ERR_PTR(-EBUSY);
@@ -2215,9 +2243,21 @@ struct wireless_dev *brcmf_p2p_add_vif(struct wiphy *wiphy, const char *name,
                return (struct wireless_dev *)vif;
        brcmf_cfg80211_arm_vif_event(cfg, vif);
 
-       err = brcmf_p2p_request_p2p_if(&cfg->p2p, ifp, cfg->p2p.int_addr,
-                                      iftype);
+       connidx = brcmf_p2p_get_conn_idx(cfg);
+
+       if (connidx == P2PAPI_BSSCFG_CONNECTION)
+               p2p_intf_addr = cfg->p2p.conn_int_addr;
+       else if (connidx == P2PAPI_BSSCFG_CONNECTION2)
+               p2p_intf_addr = cfg->p2p.conn2_int_addr;
+       else
+               err = -EINVAL;
+
+       if (!err)
+               err =  brcmf_p2p_request_p2p_if(&cfg->p2p, ifp,
+                                               p2p_intf_addr, iftype);
+
        if (err) {
+               brcmf_err("request p2p interface failed\n");
                brcmf_cfg80211_arm_vif_event(cfg, NULL);
                goto fail;
        }
@@ -2249,7 +2289,7 @@ struct wireless_dev *brcmf_p2p_add_vif(struct wiphy *wiphy, const char *name,
                goto fail;
        }
 
-       cfg->p2p.bss_idx[P2PAPI_BSSCFG_CONNECTION].vif = vif;
+       cfg->p2p.bss_idx[connidx].vif = vif;
        /* Disable firmware roaming for P2P interface  */
        brcmf_fil_iovar_int_set(ifp, "roam_off", 1);
        if (iftype == BRCMF_FIL_P2P_IF_GO) {
index 64ab9b6a677df415e6dbb015cae8ce3447b91e8b..d2ecee565bf2e2c280f57029ab868c63ba77e2ef 100644 (file)
@@ -14,13 +14,15 @@ struct brcmf_cfg80211_info;
  *
  * @P2PAPI_BSSCFG_PRIMARY: maps to driver's primary bsscfg.
  * @P2PAPI_BSSCFG_DEVICE: maps to driver's P2P device discovery bsscfg.
- * @P2PAPI_BSSCFG_CONNECTION: maps to driver's P2P connection bsscfg.
+ * @P2PAPI_BSSCFG_CONNECTION: maps to driver's 1st P2P connection bsscfg.
+ * @P2PAPI_BSSCFG_CONNECTION2: maps to driver's 2nd P2P connection bsscfg.
  * @P2PAPI_BSSCFG_MAX: used for range checking.
  */
 enum p2p_bss_type {
        P2PAPI_BSSCFG_PRIMARY, /* maps to driver's primary bsscfg */
        P2PAPI_BSSCFG_DEVICE, /* maps to driver's P2P device discovery bsscfg */
-       P2PAPI_BSSCFG_CONNECTION, /* maps to driver's P2P connection bsscfg */
+       P2PAPI_BSSCFG_CONNECTION, /* driver's 1st P2P connection bsscfg */
+       P2PAPI_BSSCFG_CONNECTION2, /* driver's 2nd P2P connection bsscfg */
        P2PAPI_BSSCFG_MAX
 };
 
@@ -119,7 +121,8 @@ struct brcmf_p2p_info {
        struct brcmf_cfg80211_info *cfg;
        unsigned long status;
        u8 dev_addr[ETH_ALEN];
-       u8 int_addr[ETH_ALEN];
+       u8 conn_int_addr[ETH_ALEN];
+       u8 conn2_int_addr[ETH_ALEN];
        struct p2p_bss bss_idx[P2PAPI_BSSCFG_MAX];
        struct timer_list listen_timer;
        u8 listen_channel;