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
This commit is contained in:
parent
191f6b08bf
commit
babfd3caf3
|
@ -17,6 +17,7 @@
|
||||||
#include "fwil_types.h"
|
#include "fwil_types.h"
|
||||||
#include "p2p.h"
|
#include "p2p.h"
|
||||||
#include "cfg80211.h"
|
#include "cfg80211.h"
|
||||||
|
#include "feature.h"
|
||||||
|
|
||||||
/* parameters used for p2p escan */
|
/* parameters used for p2p escan */
|
||||||
#define P2PAPI_SCAN_NPROBES 1
|
#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
|
* BSSCFGs need to simultaneously co-exist, then this address must be
|
||||||
* different from the P2P Device Address, but also locally administered.
|
* different from the P2P Device Address, but also locally administered.
|
||||||
*/
|
*/
|
||||||
memcpy(p2p->int_addr, p2p->dev_addr, ETH_ALEN);
|
memcpy(p2p->conn_int_addr, p2p->dev_addr, ETH_ALEN);
|
||||||
p2p->int_addr[0] |= 0x02;
|
p2p->conn_int_addr[0] |= 0x02;
|
||||||
p2p->int_addr[4] ^= 0x80;
|
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.type = cpu_to_le16((u16)if_type);
|
||||||
if_request.chspec = cpu_to_le16(chanspec);
|
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);
|
brcmf_cfg80211_arm_vif_event(cfg, vif);
|
||||||
err = brcmf_fil_iovar_data_set(vif->ifp, "p2p_ifupd", &if_request,
|
err = brcmf_fil_iovar_data_set(vif->ifp, "p2p_ifupd", &if_request,
|
||||||
|
@ -2170,6 +2175,27 @@ fail:
|
||||||
return ERR_PTR(err);
|
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.
|
* 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_pub *drvr = cfg->pub;
|
||||||
struct brcmf_cfg80211_vif *vif;
|
struct brcmf_cfg80211_vif *vif;
|
||||||
enum brcmf_fil_p2p_if_types iftype;
|
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))
|
if (brcmf_cfg80211_vif_event_armed(cfg))
|
||||||
return ERR_PTR(-EBUSY);
|
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;
|
return (struct wireless_dev *)vif;
|
||||||
brcmf_cfg80211_arm_vif_event(cfg, vif);
|
brcmf_cfg80211_arm_vif_event(cfg, vif);
|
||||||
|
|
||||||
err = brcmf_p2p_request_p2p_if(&cfg->p2p, ifp, cfg->p2p.int_addr,
|
connidx = brcmf_p2p_get_conn_idx(cfg);
|
||||||
iftype);
|
|
||||||
|
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) {
|
if (err) {
|
||||||
|
brcmf_err("request p2p interface failed\n");
|
||||||
brcmf_cfg80211_arm_vif_event(cfg, NULL);
|
brcmf_cfg80211_arm_vif_event(cfg, NULL);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
@ -2249,7 +2289,7 @@ struct wireless_dev *brcmf_p2p_add_vif(struct wiphy *wiphy, const char *name,
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg->p2p.bss_idx[P2PAPI_BSSCFG_CONNECTION].vif = vif;
|
cfg->p2p.bss_idx[connidx].vif = vif;
|
||||||
/* Disable firmware roaming for P2P interface */
|
/* Disable firmware roaming for P2P interface */
|
||||||
brcmf_fil_iovar_int_set(ifp, "roam_off", 1);
|
brcmf_fil_iovar_int_set(ifp, "roam_off", 1);
|
||||||
if (iftype == BRCMF_FIL_P2P_IF_GO) {
|
if (iftype == BRCMF_FIL_P2P_IF_GO) {
|
||||||
|
|
|
@ -14,13 +14,15 @@ struct brcmf_cfg80211_info;
|
||||||
*
|
*
|
||||||
* @P2PAPI_BSSCFG_PRIMARY: maps to driver's primary bsscfg.
|
* @P2PAPI_BSSCFG_PRIMARY: maps to driver's primary bsscfg.
|
||||||
* @P2PAPI_BSSCFG_DEVICE: maps to driver's P2P device discovery 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.
|
* @P2PAPI_BSSCFG_MAX: used for range checking.
|
||||||
*/
|
*/
|
||||||
enum p2p_bss_type {
|
enum p2p_bss_type {
|
||||||
P2PAPI_BSSCFG_PRIMARY, /* maps to driver's primary bsscfg */
|
P2PAPI_BSSCFG_PRIMARY, /* maps to driver's primary bsscfg */
|
||||||
P2PAPI_BSSCFG_DEVICE, /* maps to driver's P2P device discovery 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
|
P2PAPI_BSSCFG_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -119,7 +121,8 @@ struct brcmf_p2p_info {
|
||||||
struct brcmf_cfg80211_info *cfg;
|
struct brcmf_cfg80211_info *cfg;
|
||||||
unsigned long status;
|
unsigned long status;
|
||||||
u8 dev_addr[ETH_ALEN];
|
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 p2p_bss bss_idx[P2PAPI_BSSCFG_MAX];
|
||||||
struct timer_list listen_timer;
|
struct timer_list listen_timer;
|
||||||
u8 listen_channel;
|
u8 listen_channel;
|
||||||
|
|
Loading…
Reference in New Issue