1
0
Fork 0

brcmfmac: support the second p2p connection

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
alistair/sunxi64-5.8
Wright Feng 2020-05-04 01:07:31 -05:00 committed by Kalle Valo
parent 191f6b08bf
commit babfd3caf3
2 changed files with 54 additions and 11 deletions

View 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) {

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