Skip to content

Commit

Permalink
brcmfmac: Add support for BCM4378 on Apple hardware (with their speci…
Browse files Browse the repository at this point in the history
…al OTP).

Signed-off-by: Stan Skowronek <stan@corellium.com>
  • Loading branch information
Stan-Corellium committed Jan 30, 2021
1 parent 3c94556 commit 02ad06f
Show file tree
Hide file tree
Showing 8 changed files with 344 additions and 67 deletions.
7 changes: 6 additions & 1 deletion drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
Original file line number Diff line number Diff line change
Expand Up @@ -5136,8 +5136,13 @@ brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
ie_offset = DOT11_MGMT_HDR_LEN +
DOT11_BCN_PRB_FIXED_LEN;
ie_len = len - ie_offset;
if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif)
if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif) {
vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
if (vif == NULL) {
bphy_err(drvr, "No p2p device available for probe response\n");
return -ENODEV;
}
}
err = brcmf_vif_set_mgmt_ie(vif,
BRCMF_VNDR_IE_PRBRSP_FLAG,
&buf[ie_offset],
Expand Down
4 changes: 4 additions & 0 deletions drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
Original file line number Diff line number Diff line change
Expand Up @@ -726,6 +726,8 @@ static u32 brcmf_chip_tcm_rambase(struct brcmf_chip_priv *ci)
case BRCM_CC_4364_CHIP_ID:
case CY_CC_4373_CHIP_ID:
return 0x160000;
case BRCM_CC_4378_CHIP_ID:
return 0x352000;
default:
brcmf_err("unknown chip: %s\n", ci->pub.name);
break;
Expand Down Expand Up @@ -1425,5 +1427,7 @@ bool brcmf_chip_sr_capable(struct brcmf_chip *pub)
reg = chip->ops->read32(chip->ctx, addr);
return (reg & (PMU_RCTL_MACPHY_DISABLE_MASK |
PMU_RCTL_LOGIC_DISABLE_MASK)) == 0;
case BRCM_CC_4378_CHIP_ID:
return false;
}
}
37 changes: 15 additions & 22 deletions drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,24 @@ static int brcmf_feature_disable;
module_param_named(feature_disable, brcmf_feature_disable, int, 0);
MODULE_PARM_DESC(feature_disable, "Disable features");

static char brcmf_firmware_path[BRCMF_FW_ALTPATH_LEN];
char brcmf_firmware_path[BRCMF_FW_ALTPATH_LEN];
module_param_string(alternative_fw_path, brcmf_firmware_path,
BRCMF_FW_ALTPATH_LEN, 0400);
BRCMF_FW_ALTPATH_LEN, 0600);
MODULE_PARM_DESC(alternative_fw_path, "Alternative firmware path");

char brcmf_mac_addr[18];
module_param_string(nvram_mac_addr, brcmf_mac_addr,
18, 0600);
MODULE_PARM_DESC(nvram_mac_addr, "Set MAC address in NVRAM");

char brcmf_otp_chip_id[BRCMF_OTP_VERSION_MAX];
module_param_string(otp_chip_id, brcmf_otp_chip_id, BRCMF_OTP_VERSION_MAX, 0400);
MODULE_PARM_DESC(otp_chip_id, "Chip ID and revision from OTP");

char brcmf_otp_nvram_id[BRCMF_OTP_VERSION_MAX];
module_param_string(otp_nvram_id, brcmf_otp_nvram_id, BRCMF_OTP_VERSION_MAX, 0400);
MODULE_PARM_DESC(otp_chip_id, "NVRAM variant from OTP");

static int brcmf_fcmode;
module_param_named(fcmode, brcmf_fcmode, int, 0);
MODULE_PARM_DESC(fcmode, "Mode of firmware signalled flow control");
Expand All @@ -75,7 +88,6 @@ MODULE_PARM_DESC(ignore_probe_fail, "always succeed probe for debugging");
#endif

static struct brcmfmac_platform_data *brcmfmac_pdata;
struct brcmf_mp_global_t brcmf_mp_global;

void brcmf_c_set_joinpref_default(struct brcmf_if *ifp)
{
Expand Down Expand Up @@ -376,22 +388,6 @@ void __brcmf_dbg(u32 level, const char *func, const char *fmt, ...)
}
#endif

static void brcmf_mp_attach(void)
{
/* If module param firmware path is set then this will always be used,
* if not set then if available use the platform data version. To make
* sure it gets initialized at all, always copy the module param version
*/
strlcpy(brcmf_mp_global.firmware_path, brcmf_firmware_path,
BRCMF_FW_ALTPATH_LEN);
if ((brcmfmac_pdata) && (brcmfmac_pdata->fw_alternative_path) &&
(brcmf_mp_global.firmware_path[0] == '\0')) {
strlcpy(brcmf_mp_global.firmware_path,
brcmfmac_pdata->fw_alternative_path,
BRCMF_FW_ALTPATH_LEN);
}
}

struct brcmf_mp_device *brcmf_get_module_param(struct device *dev,
enum brcmf_bus_type bus_type,
u32 chip, u32 chiprev)
Expand Down Expand Up @@ -492,9 +488,6 @@ static int __init brcmfmac_module_init(void)
if (err == -ENODEV)
brcmf_dbg(INFO, "No platform data available.\n");

/* Initialize global module paramaters */
brcmf_mp_attach();

/* Continue the initialization by registering the different busses */
err = brcmf_core_init();
if (err) {
Expand Down
23 changes: 5 additions & 18 deletions drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,12 @@
#include "fwil_types.h"

#define BRCMF_FW_ALTPATH_LEN 256
#define BRCMF_OTP_VERSION_MAX 64

/* Definitions for the module global and device specific settings are defined
* here. Two structs are used for them. brcmf_mp_global_t and brcmf_mp_device.
* The mp_global is instantiated once in a global struct and gets initialized
* by the common_attach function which should be called before any other
* (module) initiliazation takes place. The device specific settings is part
* of the drvr struct and should be initialized on every brcmf_attach.
*/

/**
* struct brcmf_mp_global_t - Global module paramaters.
*
* @firmware_path: Alternative firmware path.
*/
struct brcmf_mp_global_t {
char firmware_path[BRCMF_FW_ALTPATH_LEN];
};

extern struct brcmf_mp_global_t brcmf_mp_global;
extern char brcmf_firmware_path[BRCMF_FW_ALTPATH_LEN];
extern char brcmf_mac_addr[18];
extern char brcmf_otp_chip_id[BRCMF_OTP_VERSION_MAX];
extern char brcmf_otp_nvram_id[BRCMF_OTP_VERSION_MAX];

/**
* struct brcmf_mp_device - Device module paramaters.
Expand Down
38 changes: 35 additions & 3 deletions drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,35 @@ static void brcmf_fw_add_defaults(struct nvram_parser *nvp)
nvp->nvram_len++;
}

static void brcmf_fw_set_macaddr(struct nvram_parser *nvp, const char *mac_addr)
{
uint8_t mac[6] = { 0 };
size_t len = strlen("macaddr=") + 17 + 1; /* 17 = "aa:bb:cc:dd:ee:ff" */
unsigned i = 0;
unsigned long res = 0;
char tmp[3];

while(mac_addr[0] && mac_addr[1] && i < 6) {
tmp[0] = mac_addr[0];
tmp[1] = mac_addr[1];
tmp[2] = 0;
if(kstrtoul(tmp, 16, &res))
break;
mac[i] = res;
mac_addr += 2;
i ++;
while(*mac_addr == ':' || *mac_addr == ' ' || *mac_addr == '-')
mac_addr ++;
}
if(i < 6)
pr_warn("invalid MAC address supplied for brcmfmac!\n");

memmove(&nvp->nvram[len], &nvp->nvram[0], nvp->nvram_len);
nvp->nvram_len += len;
sprintf(&nvp->nvram[0], "macaddr=%02x:%02x:%02x:%02x:%02x:%02x",
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
}

/* brcmf_nvram_strip :Takes a buffer of "<var>=<value>\n" lines read from a fil
* and ending in a NUL. Removes carriage returns, empty lines, comment lines,
* and converts newlines to NULs. Shortens buffer as needed and pads with NULs.
Expand Down Expand Up @@ -404,8 +433,11 @@ static void *brcmf_fw_nvram_strip(const u8 *data, size_t data_len,

brcmf_fw_add_defaults(&nvp);

if(brcmf_mac_addr[0])
brcmf_fw_set_macaddr(&nvp, brcmf_mac_addr);

pad = nvp.nvram_len;
*new_length = roundup(nvp.nvram_len + 1, 4);
*new_length = roundup(nvp.nvram_len + 1, 8) + 4;
while (pad != *new_length) {
nvp.nvram[pad] = 0;
pad++;
Expand Down Expand Up @@ -721,7 +753,7 @@ brcmf_fw_alloc_request(u32 chip, u32 chiprev,
brcmf_info("using %s for chip %s\n",
mapping_table[i].fw_base, chipname);

mp_path = brcmf_mp_global.firmware_path;
mp_path = brcmf_firmware_path;
mp_path_len = strnlen(mp_path, BRCMF_FW_ALTPATH_LEN);
if (mp_path_len)
end = mp_path[mp_path_len - 1];
Expand All @@ -732,7 +764,7 @@ brcmf_fw_alloc_request(u32 chip, u32 chiprev,
fwreq->items[j].path = fwnames[j].path;
fwnames[j].path[0] = '\0';
/* check if firmware path is provided by module parameter */
if (brcmf_mp_global.firmware_path[0] != '\0') {
if (brcmf_firmware_path[0] != '\0') {
strlcpy(fwnames[j].path, mp_path,
BRCMF_FW_NAME_LEN);

Expand Down
14 changes: 12 additions & 2 deletions drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
Original file line number Diff line number Diff line change
Expand Up @@ -565,7 +565,8 @@ static s32 brcmf_p2p_deinit_discovery(struct brcmf_p2p_info *p2p)

/* Set the discovery state to SCAN */
vif = p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
(void)brcmf_p2p_set_discover_state(vif->ifp, WL_P2P_DISC_ST_SCAN, 0, 0);
if (vif != NULL)
(void)brcmf_p2p_set_discover_state(vif->ifp, WL_P2P_DISC_ST_SCAN, 0, 0);

/* Disable P2P discovery in the firmware */
vif = p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif;
Expand Down Expand Up @@ -1351,6 +1352,8 @@ brcmf_p2p_gon_req_collision(struct brcmf_p2p_info *p2p, u8 *mac)
* if not (sa addr > da addr),
* this device will process gon request and drop gon req of peer.
*/
if(p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif == NULL)
return false;
ifp = p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif->ifp;
if (memcmp(mac, ifp->mac_addr, ETH_ALEN) < 0) {
brcmf_dbg(INFO, "Block transmit gon req !!!\n");
Expand Down Expand Up @@ -1559,6 +1562,10 @@ static s32 brcmf_p2p_tx_action_frame(struct brcmf_p2p_info *p2p,
else
vif = p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif;

if (vif == NULL) {
bphy_err(drvr, " no P2P interface available\n");
goto exit;
}
err = brcmf_fil_bsscfg_data_set(vif->ifp, "actframe", af_params,
sizeof(*af_params));
if (err) {
Expand Down Expand Up @@ -1734,8 +1741,11 @@ bool brcmf_p2p_send_action_frame(struct brcmf_cfg80211_info *cfg,
uint delta_ms;
unsigned long dwell_jiffies = 0;
bool dwell_overflow = false;

u32 requested_dwell = le32_to_cpu(af_params->dwell_time);

if(p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif == NULL)
goto exit;

action_frame = &af_params->action_frame;
action_frame_len = le16_to_cpu(action_frame->len);

Expand Down
Loading

0 comments on commit 02ad06f

Please sign in to comment.