1
0
Fork 0

pull in brcmfmac fixes from rpi

martin/broadcomfixes
Martin T. H. Sandsmark 2019-01-10 10:50:20 +01:00
parent 1076fe28af
commit c127360dc8
14 changed files with 384 additions and 70 deletions

View File

@ -266,7 +266,7 @@ brcmf_proto_bcdc_hdrpush(struct brcmf_pub *drvr, int ifidx, u8 offset,
if (pktbuf->ip_summed == CHECKSUM_PARTIAL)
h->flags |= BCDC_FLAG_SUM_NEEDED;
h->priority = (pktbuf->priority & BCDC_PRIORITY_MASK);
h->priority = 0;
h->flags2 = 0;
h->data_offset = offset;
BCDC_SET_IF_IDX(h, ifidx);

View File

@ -69,6 +69,7 @@ struct brcmf_bus_dcmd {
* @wowl_config: specify if dongle is configured for wowl when going to suspend
* @get_ramsize: obtain size of device memory.
* @get_memdump: obtain device memory dump in provided buffer.
* @get_fwname: obtain firmware name.
*
* This structure provides an abstract interface towards the
* bus specific driver. For control messages to common driver
@ -85,6 +86,8 @@ struct brcmf_bus_ops {
void (*wowl_config)(struct device *dev, bool enabled);
size_t (*get_ramsize)(struct device *dev);
int (*get_memdump)(struct device *dev, void *data, size_t len);
int (*get_fwname)(struct device *dev, uint chip, uint chiprev,
unsigned char *fw_name);
};
@ -208,6 +211,16 @@ int brcmf_bus_get_memdump(struct brcmf_bus *bus, void *data, size_t len)
return bus->ops->get_memdump(bus->dev, data, len);
}
static inline
int brcmf_bus_get_fwname(struct brcmf_bus *bus, uint chip, uint chiprev,
unsigned char *fw_name)
{
if (!bus->ops->get_fwname)
return -EOPNOTSUPP;
return bus->ops->get_fwname(bus->dev, chip, chiprev, fw_name);
}
/*
* interface functions from common layer
*/

View File

@ -479,47 +479,6 @@ send_key_to_dongle(struct brcmf_if *ifp, struct brcmf_wsec_key *key)
return err;
}
static s32
brcmf_configure_arp_nd_offload(struct brcmf_if *ifp, bool enable)
{
s32 err;
u32 mode;
if (enable)
mode = BRCMF_ARP_OL_AGENT | BRCMF_ARP_OL_PEER_AUTO_REPLY;
else
mode = 0;
/* Try to set and enable ARP offload feature, this may fail, then it */
/* is simply not supported and err 0 will be returned */
err = brcmf_fil_iovar_int_set(ifp, "arp_ol", mode);
if (err) {
brcmf_dbg(TRACE, "failed to set ARP offload mode to 0x%x, err = %d\n",
mode, err);
err = 0;
} else {
err = brcmf_fil_iovar_int_set(ifp, "arpoe", enable);
if (err) {
brcmf_dbg(TRACE, "failed to configure (%d) ARP offload err = %d\n",
enable, err);
err = 0;
} else
brcmf_dbg(TRACE, "successfully configured (%d) ARP offload to 0x%x\n",
enable, mode);
}
err = brcmf_fil_iovar_int_set(ifp, "ndoe", enable);
if (err) {
brcmf_dbg(TRACE, "failed to configure (%d) ND offload err = %d\n",
enable, err);
err = 0;
} else
brcmf_dbg(TRACE, "successfully configured (%d) ND offload to 0x%x\n",
enable, mode);
return err;
}
static void
brcmf_cfg80211_update_proto_addr_mode(struct wireless_dev *wdev)
{
@ -2743,6 +2702,8 @@ brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
* preference in cfg struct to apply this to
* FW later while initializing the dongle
*/
pr_info("power management disabled\n");
enabled = false;
cfg->pwr_save = enabled;
if (!check_vif_up(ifp->vif)) {
@ -3198,6 +3159,28 @@ static void brcmf_init_escan(struct brcmf_cfg80211_info *cfg)
brcmf_cfg80211_escan_timeout_worker);
}
static struct brcmf_pno_net_info_le *
brcmf_get_netinfo_array(struct brcmf_pno_scanresults_le *pfn_v1)
{
struct brcmf_pno_scanresults_v2_le *pfn_v2;
struct brcmf_pno_net_info_le *netinfo;
switch (pfn_v1->version) {
default:
WARN_ON(1);
/* fall-thru */
case cpu_to_le32(1):
netinfo = (struct brcmf_pno_net_info_le *)(pfn_v1 + 1);
break;
case cpu_to_le32(2):
pfn_v2 = (struct brcmf_pno_scanresults_v2_le *)pfn_v1;
netinfo = (struct brcmf_pno_net_info_le *)(pfn_v2 + 1);
break;
}
return netinfo;
}
/* PFN result doesn't have all the info which are required by the supplicant
* (For e.g IEs) Do a target Escan so that sched scan results are reported
* via wl_inform_single_bss in the required format. Escan does require the
@ -3254,8 +3237,7 @@ brcmf_notify_sched_scan_results(struct brcmf_if *ifp,
}
request->wiphy = wiphy;
data += sizeof(struct brcmf_pno_scanresults_le);
netinfo_start = (struct brcmf_pno_net_info_le *)data;
netinfo_start = brcmf_get_netinfo_array(pfn_result);
for (i = 0; i < result_count; i++) {
netinfo = &netinfo_start[i];
@ -4749,9 +4731,15 @@ static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
if (err < 0)
brcmf_err("BRCMF_C_DOWN error %d\n", err);
err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 0);
if (err < 0)
brcmf_err("setting INFRA mode failed %d\n", err);
err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 0);
if (err < 0)
brcmf_err("setting AP mode failed %d\n", err);
if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS))
brcmf_fil_iovar_int_set(ifp, "mbss", 0);
brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_REGULATORY,
@ -6739,12 +6727,18 @@ static s32 brcmf_translate_country_code(struct brcmf_pub *drvr, char alpha2[2],
struct brcmfmac_pd_cc *country_codes;
struct brcmfmac_pd_cc_entry *cc;
s32 found_index;
char ccode[BRCMF_COUNTRY_BUF_SZ];
int rev;
int i;
memcpy(ccode, alpha2, sizeof(ccode));
rev = -1;
country_codes = drvr->settings->country_codes;
if (!country_codes) {
brcmf_dbg(TRACE, "No country codes configured for device\n");
return -EINVAL;
brcmf_dbg(TRACE, "No country codes configured for device"
" - use requested value\n");
goto use_input_value;
}
if ((alpha2[0] == ccreq->country_abbrev[0]) &&
@ -6768,10 +6762,14 @@ static s32 brcmf_translate_country_code(struct brcmf_pub *drvr, char alpha2[2],
brcmf_dbg(TRACE, "No country code match found\n");
return -EINVAL;
}
memset(ccreq, 0, sizeof(*ccreq));
ccreq->rev = cpu_to_le32(country_codes->table[found_index].rev);
memcpy(ccreq->ccode, country_codes->table[found_index].cc,
rev = country_codes->table[found_index].rev;
memcpy(ccode, country_codes->table[found_index].cc,
BRCMF_COUNTRY_BUF_SZ);
use_input_value:
memset(ccreq, 0, sizeof(*ccreq));
ccreq->rev = cpu_to_le32(rev);
memcpy(ccreq->ccode, ccode, sizeof(ccode));
ccreq->country_abbrev[0] = alpha2[0];
ccreq->country_abbrev[1] = alpha2[1];
ccreq->country_abbrev[2] = 0;
@ -6791,6 +6789,8 @@ static void brcmf_cfg80211_reg_notifier(struct wiphy *wiphy,
/* ignore non-ISO3166 country codes */
for (i = 0; i < sizeof(req->alpha2); i++)
if (req->alpha2[i] < 'A' || req->alpha2[i] > 'Z') {
if (req->alpha2[0] == '0' && req->alpha2[1] == '0')
return;
brcmf_err("not a ISO3166 code (0x%02x 0x%02x)\n",
req->alpha2[0], req->alpha2[1]);
return;

View File

@ -18,6 +18,7 @@
#include <linux/string.h>
#include <linux/netdevice.h>
#include <linux/module.h>
#include <linux/firmware.h>
#include <brcmu_wifi.h>
#include <brcmu_utils.h>
#include "core.h"
@ -28,6 +29,7 @@
#include "tracepoint.h"
#include "common.h"
#include "of.h"
#include "firmware.h"
MODULE_AUTHOR("Broadcom Corporation");
MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver.");
@ -69,7 +71,7 @@ static int brcmf_fcmode;
module_param_named(fcmode, brcmf_fcmode, int, 0);
MODULE_PARM_DESC(fcmode, "Mode of firmware signalled flow control");
static int brcmf_roamoff;
static int brcmf_roamoff = 1;
module_param_named(roamoff, brcmf_roamoff, int, S_IRUSR);
MODULE_PARM_DESC(roamoff, "Do not use internal roaming engine");
@ -104,15 +106,170 @@ void brcmf_c_set_joinpref_default(struct brcmf_if *ifp)
brcmf_err("Set join_pref error (%d)\n", err);
}
int brcmf_c_download_2_dongle(struct brcmf_if *ifp, char *dcmd, u16 flag,
u16 dload_type, char *dload_buf, u32 len)
{
struct brcmf_dload_data_le *dload_ptr;
u32 dload_data_offset;
u16 flags;
s32 err;
dload_ptr = (struct brcmf_dload_data_le *)dload_buf;
dload_data_offset = offsetof(struct brcmf_dload_data_le, data);
flags = flag | (DLOAD_HANDLER_VER << DLOAD_FLAG_VER_SHIFT);
dload_ptr->flag = cpu_to_le16(flags);
dload_ptr->dload_type = cpu_to_le16(dload_type);
dload_ptr->len = cpu_to_le32(len - dload_data_offset);
dload_ptr->crc = cpu_to_le32(0);
len = len + 8 - (len % 8);
err = brcmf_fil_iovar_data_set(ifp, dcmd, (void *)dload_buf, len);
return err;
}
int brcmf_c_get_clm_name(struct brcmf_if *ifp, u8 *clm_name)
{
struct brcmf_rev_info_le revinfo;
struct brcmf_bus *bus = ifp->drvr->bus_if;
u8 fw_name[BRCMF_FW_NAME_LEN];
u8 *ptr;
size_t len;
u32 chipnum;
u32 chiprev;
s32 err;
err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_REVINFO, &revinfo,
sizeof(revinfo));
if (err < 0) {
brcmf_err("retrieving revision info failed (%d)\n", err);
goto done;
}
chipnum = le32_to_cpu(revinfo.chipnum);
chiprev = le32_to_cpu(revinfo.chiprev);
memset(fw_name, 0, BRCMF_FW_NAME_LEN);
err = brcmf_bus_get_fwname(bus, chipnum, chiprev, fw_name);
if (err) {
brcmf_err("get firmware name failed (%d)\n", err);
goto done;
}
/* generate CLM blob file name */
ptr = strrchr(fw_name, '.');
len = ptr - fw_name + 1;
if (len + strlen(".clm_blob") > BRCMF_FW_NAME_LEN) {
err = -E2BIG;
} else {
strlcpy(clm_name, fw_name, len);
strlcat(clm_name, ".clm_blob", BRCMF_FW_NAME_LEN);
}
done:
return err;
}
int brcmf_c_process_clm_blob(struct brcmf_if *ifp)
{
struct device *dev = ifp->drvr->bus_if->dev;
const struct firmware *clm = NULL;
u8 buf[BRCMF_DCMD_SMLEN];
u8 clm_name[BRCMF_FW_NAME_LEN];
u32 data_offset;
u32 size2alloc;
u8 *chunk_buf;
u32 chunk_len;
u32 datalen;
u32 cumulative_len = 0;
u16 dl_flag = DL_BEGIN;
s32 err;
brcmf_dbg(INFO, "Enter\n");
memset(clm_name, 0, BRCMF_FW_NAME_LEN);
err = brcmf_c_get_clm_name(ifp, clm_name);
if (err) {
brcmf_err("get CLM blob file name failed (%d)\n", err);
return err;
}
err = request_firmware_direct(&clm, clm_name, dev);
if (err) {
if (err == -ENOENT)
return 0;
brcmf_err("request CLM blob file failed (%d)\n", err);
return err;
}
datalen = clm->size;
data_offset = offsetof(struct brcmf_dload_data_le, data);
size2alloc = data_offset + MAX_CHUNK_LEN;
chunk_buf = kzalloc(size2alloc, GFP_KERNEL);
if (!chunk_buf) {
err = -ENOMEM;
goto done;
}
do {
if (datalen > MAX_CHUNK_LEN) {
chunk_len = MAX_CHUNK_LEN;
} else {
chunk_len = datalen;
dl_flag |= DL_END;
}
memcpy(chunk_buf + data_offset, clm->data + cumulative_len,
chunk_len);
err = brcmf_c_download_2_dongle(ifp, "clmload", dl_flag,
DL_TYPE_CLM, chunk_buf,
data_offset + chunk_len);
dl_flag &= ~DL_BEGIN;
cumulative_len += chunk_len;
datalen -= chunk_len;
} while ((datalen > 0) && (err == 0));
if (err) {
brcmf_err("clmload (%d byte file) failed (%d); ",
(u32)clm->size, err);
/* Retrieve clmload_status and print */
memset(buf, 0, BRCMF_DCMD_SMLEN);
err = brcmf_fil_iovar_data_get(ifp, "clmload_status", buf,
BRCMF_DCMD_SMLEN);
if (err)
brcmf_err("get clmload_status failed (%d)\n", err);
else
brcmf_err("clmload_status=%d\n", *((int *)buf));
err = -EIO;
}
kfree(chunk_buf);
done:
release_firmware(clm);
return err;
}
int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
{
s8 eventmask[BRCMF_EVENTING_MASK_LEN];
u8 buf[BRCMF_DCMD_SMLEN];
struct brcmf_rev_info_le revinfo;
struct brcmf_rev_info *ri;
char *clmver;
char *ptr;
s32 err;
/* Do any CLM downloading */
err = brcmf_c_process_clm_blob(ifp);
if (err < 0) {
brcmf_err("download CLM blob file failed, %d\n", err);
goto done;
}
/* retreive mac address */
err = brcmf_fil_iovar_data_get(ifp, "cur_etheraddr", ifp->mac_addr,
sizeof(ifp->mac_addr));
@ -161,12 +318,30 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
strsep(&ptr, "\n");
/* Print fw version info */
brcmf_err("Firmware version = %s\n", buf);
pr_info("Firmware version = %s\n", buf);
/* locate firmware version number for ethtool */
ptr = strrchr(buf, ' ') + 1;
strlcpy(ifp->drvr->fwver, ptr, sizeof(ifp->drvr->fwver));
/* Query for 'clmver' to get CLM version info from firmware */
memset(buf, 0, sizeof(buf));
err = brcmf_fil_iovar_data_get(ifp, "clmver", buf, sizeof(buf));
if (err) {
brcmf_err("retrieving clmver failed, %d\n", err);
goto done;
} else {
clmver = (char *)buf;
/* Replace all newline/linefeed characters with space
* character
*/
ptr = clmver;
while ((ptr = strchr(ptr, '\n')) != NULL)
*ptr = ' ';
brcmf_err("CLM version = %s\n", clmver);
}
/* set mpc */
err = brcmf_fil_iovar_int_set(ifp, "mpc", 1);
if (err) {
@ -335,21 +510,10 @@ static int brcmf_common_pd_remove(struct platform_device *pdev)
return 0;
}
#ifdef CONFIG_OF
static const struct of_device_id brcmfmac_of_table[] = {
{ .compatible = "brcm,bcm4329-fmac" },
{}
};
MODULE_DEVICE_TABLE(of, brcmfmac_of_table);
#endif
static struct platform_driver brcmf_pd = {
.remove = brcmf_common_pd_remove,
.driver = {
.name = BRCMFMAC_PDATA_NAME,
#ifdef CONFIG_OF
.of_match_table = of_match_ptr(brcmfmac_of_table),
#endif
}
};

View File

@ -71,6 +71,43 @@ struct brcmf_if *brcmf_get_ifp(struct brcmf_pub *drvr, int ifidx)
return ifp;
}
void brcmf_configure_arp_nd_offload(struct brcmf_if *ifp, bool enable)
{
s32 err;
u32 mode;
if (enable)
mode = BRCMF_ARP_OL_AGENT | BRCMF_ARP_OL_PEER_AUTO_REPLY;
else
mode = 0;
/* Try to set and enable ARP offload feature, this may fail, then it */
/* is simply not supported and err 0 will be returned */
err = brcmf_fil_iovar_int_set(ifp, "arp_ol", mode);
if (err) {
brcmf_dbg(TRACE, "failed to set ARP offload mode to 0x%x, err = %d\n",
mode, err);
err = 0;
} else {
err = brcmf_fil_iovar_int_set(ifp, "arpoe", enable);
if (err) {
brcmf_dbg(TRACE, "failed to configure (%d) ARP offload err = %d\n",
enable, err);
err = 0;
} else
brcmf_dbg(TRACE, "successfully configured (%d) ARP offload to 0x%x\n",
enable, mode);
}
err = brcmf_fil_iovar_int_set(ifp, "ndoe", enable);
if (err)
brcmf_dbg(TRACE, "failed to configure (%d) ND offload err = %d\n",
enable, err);
else
brcmf_dbg(TRACE, "successfully configured (%d) ND offload to 0x%x\n",
enable, mode);
}
static void _brcmf_set_multicast_list(struct work_struct *work)
{
struct brcmf_if *ifp;
@ -134,6 +171,8 @@ static void _brcmf_set_multicast_list(struct work_struct *work)
if (err < 0)
brcmf_err("Setting BRCMF_C_SET_PROMISC failed, %d\n",
err);
brcmf_configure_arp_nd_offload(ifp, !cmd_value);
}
#if IS_ENABLED(CONFIG_IPV6)

View File

@ -208,6 +208,7 @@ int brcmf_netdev_wait_pend8021x(struct brcmf_if *ifp);
char *brcmf_ifname(struct brcmf_if *ifp);
struct brcmf_if *brcmf_get_ifp(struct brcmf_pub *drvr, int ifidx);
int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked);
void brcmf_configure_arp_nd_offload(struct brcmf_if *ifp, bool enable);
struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bsscfgidx, s32 ifidx,
bool is_p2pdev, const char *name, u8 *mac_addr);
void brcmf_remove_interface(struct brcmf_if *ifp, bool rtnl_locked);

View File

@ -257,11 +257,6 @@ static void brcmf_fweh_event_worker(struct work_struct *work)
brcmf_dbg_hex_dump(BRCMF_EVENT_ON(), event->data,
min_t(u32, emsg.datalen, 64),
"event payload, len=%d\n", emsg.datalen);
if (emsg.datalen > event->datalen) {
brcmf_err("event invalid length header=%d, msg=%d\n",
event->datalen, emsg.datalen);
goto event_free;
}
/* special handling of interface event */
if (event->code == BRCMF_E_IF) {

View File

@ -151,6 +151,22 @@
#define BRCMF_MFP_CAPABLE 1
#define BRCMF_MFP_REQUIRED 2
/* MAX_CHUNK_LEN is the amount of the clm file we send in each ioctl.
* It is relatively small because dongles (FW) have a small maximum size
* input payload restriction for ioctls.
*/
#define MAX_CHUNK_LEN 1400
#define DLOAD_HANDLER_VER 1 /* Downloader version */
#define DLOAD_FLAG_VER_MASK 0xf000 /* Downloader version mask */
#define DLOAD_FLAG_VER_SHIFT 12 /* Downloader version shift */
#define DL_CRC_NOT_INUSE 0x0001
#define DL_BEGIN 0x0002
#define DL_END 0x0004
#define DL_TYPE_CLM 2
/* join preference types for join_pref iovar */
enum brcmf_join_pref_types {
BRCMF_JOIN_PREF_RSSI = 1,
@ -774,6 +790,13 @@ struct brcmf_pno_scanresults_le {
__le32 count;
};
struct brcmf_pno_scanresults_v2_le {
__le32 version;
__le32 status;
__le32 count;
__le32 scan_ch_bucket;
};
/**
* struct brcmf_pno_macaddr_le - to configure PNO macaddr randomization.
*
@ -817,4 +840,15 @@ struct brcmf_gtk_keyinfo_le {
u8 replay_counter[BRCMF_RSN_REPLAY_LEN];
};
/**
* struct brcmf_dload_data_le - data passing to firmware for downloading
*/
struct brcmf_dload_data_le {
__le16 flag;
__le16 dload_type;
__le32 len;
__le32 crc;
u8 data[1];
};
#endif /* FWIL_TYPES_H_ */

View File

@ -1853,7 +1853,6 @@ s32 brcmf_p2p_notify_rx_mgmt_p2p_probereq(struct brcmf_if *ifp,
struct afx_hdl *afx_hdl = &p2p->afx_hdl;
struct brcmf_cfg80211_vif *vif = ifp->vif;
struct brcmf_rx_mgmt_data *rxframe = (struct brcmf_rx_mgmt_data *)data;
u16 chanspec = be16_to_cpu(rxframe->chanspec);
struct brcmu_chan ch;
u8 *mgmt_frame;
u32 mgmt_frame_len;
@ -1906,7 +1905,7 @@ s32 brcmf_p2p_notify_rx_mgmt_p2p_probereq(struct brcmf_if *ifp,
cfg80211_rx_mgmt(&vif->wdev, freq, 0, mgmt_frame, mgmt_frame_len, 0);
brcmf_dbg(INFO, "mgmt_frame_len (%d) , e->datalen (%d), chanspec (%04x), freq (%d)\n",
mgmt_frame_len, e->datalen, chanspec, freq);
mgmt_frame_len, e->datalen, ch.chspec, freq);
return 0;
}

View File

@ -1317,6 +1317,24 @@ static int brcmf_pcie_get_memdump(struct device *dev, void *data, size_t len)
return 0;
}
static int brcmf_pcie_get_fwname(struct device *dev, u32 chip, u32 chiprev,
u8 *fw_name)
{
struct brcmf_bus *bus_if = dev_get_drvdata(dev);
struct brcmf_pciedev *buspub = bus_if->bus_priv.pcie;
struct brcmf_pciedev_info *devinfo = buspub->devinfo;
int ret = 0;
if (devinfo->fw_name[0] != '\0')
strlcpy(fw_name, devinfo->fw_name, BRCMF_FW_NAME_LEN);
else
ret = brcmf_fw_map_chip_to_name(chip, chiprev,
brcmf_pcie_fwnames,
ARRAY_SIZE(brcmf_pcie_fwnames),
fw_name, NULL);
return ret;
}
static const struct brcmf_bus_ops brcmf_pcie_bus_ops = {
.txdata = brcmf_pcie_tx,
@ -1326,6 +1344,7 @@ static const struct brcmf_bus_ops brcmf_pcie_bus_ops = {
.wowl_config = brcmf_pcie_wowl_config,
.get_ramsize = brcmf_pcie_get_ramsize,
.get_memdump = brcmf_pcie_get_memdump,
.get_fwname = brcmf_pcie_get_fwname,
};

View File

@ -604,6 +604,7 @@ BRCMF_FW_NVRAM_DEF(4329, "brcmfmac4329-sdio.bin", "brcmfmac4329-sdio.txt");
BRCMF_FW_NVRAM_DEF(4330, "brcmfmac4330-sdio.bin", "brcmfmac4330-sdio.txt");
BRCMF_FW_NVRAM_DEF(4334, "brcmfmac4334-sdio.bin", "brcmfmac4334-sdio.txt");
BRCMF_FW_NVRAM_DEF(43340, "brcmfmac43340-sdio.bin", "brcmfmac43340-sdio.txt");
BRCMF_FW_NVRAM_DEF(43341, "brcmfmac43341-sdio.bin", "brcmfmac43341-sdio.txt");
BRCMF_FW_NVRAM_DEF(4335, "brcmfmac4335-sdio.bin", "brcmfmac4335-sdio.txt");
BRCMF_FW_NVRAM_DEF(43362, "brcmfmac43362-sdio.bin", "brcmfmac43362-sdio.txt");
BRCMF_FW_NVRAM_DEF(4339, "brcmfmac4339-sdio.bin", "brcmfmac4339-sdio.txt");
@ -621,6 +622,7 @@ static struct brcmf_firmware_mapping brcmf_sdio_fwnames[] = {
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4330_CHIP_ID, 0xFFFFFFFF, 4330),
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4334_CHIP_ID, 0xFFFFFFFF, 4334),
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43340_CHIP_ID, 0xFFFFFFFF, 43340),
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43341_CHIP_ID, 0xFFFFFFFF, 43341),
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4335_CHIP_ID, 0xFFFFFFFF, 4335),
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43362_CHIP_ID, 0xFFFFFFFE, 43362),
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4339_CHIP_ID, 0xFFFFFFFF, 4339),
@ -2049,7 +2051,7 @@ static int brcmf_sdio_txpkt_hdalign(struct brcmf_sdio *bus, struct sk_buff *pkt)
return head_pad;
}
/*
/**
* struct brcmf_skbuff_cb reserves first two bytes in sk_buff::cb for
* bus layer usage.
*/
@ -3963,6 +3965,24 @@ brcmf_sdio_watchdog(unsigned long data)
}
}
static int brcmf_sdio_get_fwname(struct device *dev, u32 chip, u32 chiprev,
u8 *fw_name)
{
struct brcmf_bus *bus_if = dev_get_drvdata(dev);
struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
int ret = 0;
if (sdiodev->fw_name[0] != '\0')
strlcpy(fw_name, sdiodev->fw_name, BRCMF_FW_NAME_LEN);
else
ret = brcmf_fw_map_chip_to_name(chip, chiprev,
brcmf_sdio_fwnames,
ARRAY_SIZE(brcmf_sdio_fwnames),
fw_name, NULL);
return ret;
}
static const struct brcmf_bus_ops brcmf_sdio_bus_ops = {
.stop = brcmf_sdio_bus_stop,
.preinit = brcmf_sdio_bus_preinit,
@ -3973,6 +3993,7 @@ static const struct brcmf_bus_ops brcmf_sdio_bus_ops = {
.wowl_config = brcmf_sdio_wowl_config,
.get_ramsize = brcmf_sdio_bus_get_ramsize,
.get_memdump = brcmf_sdio_bus_get_memdump,
.get_fwname = brcmf_sdio_get_fwname,
};
static void brcmf_sdio_firmware_callback(struct device *dev, int err,

View File

@ -1125,12 +1125,30 @@ static void brcmf_usb_wowl_config(struct device *dev, bool enabled)
device_set_wakeup_enable(devinfo->dev, false);
}
static int brcmf_usb_get_fwname(struct device *dev, u32 chip, u32 chiprev,
u8 *fw_name)
{
struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);
int ret = 0;
if (devinfo->fw_name[0] != '\0')
strlcpy(fw_name, devinfo->fw_name, BRCMF_FW_NAME_LEN);
else
ret = brcmf_fw_map_chip_to_name(chip, chiprev,
brcmf_usb_fwnames,
ARRAY_SIZE(brcmf_usb_fwnames),
fw_name, NULL);
return ret;
}
static const struct brcmf_bus_ops brcmf_usb_bus_ops = {
.txdata = brcmf_usb_tx,
.stop = brcmf_usb_down,
.txctl = brcmf_usb_tx_ctlpkt,
.rxctl = brcmf_usb_rx_ctlpkt,
.wowl_config = brcmf_usb_wowl_config,
.get_fwname = brcmf_usb_get_fwname,
};
static int brcmf_usb_bus_setup(struct brcmf_usbdev_info *devinfo)

View File

@ -36,6 +36,7 @@
#define BRCM_CC_4330_CHIP_ID 0x4330
#define BRCM_CC_4334_CHIP_ID 0x4334
#define BRCM_CC_43340_CHIP_ID 43340
#define BRCM_CC_43341_CHIP_ID 43341
#define BRCM_CC_43362_CHIP_ID 43362
#define BRCM_CC_4335_CHIP_ID 0x4335
#define BRCM_CC_4339_CHIP_ID 0x4339

View File

@ -1,3 +1,4 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* SDIO Classes, Interface Types, Manufacturer IDs, etc.
*/
@ -34,11 +35,13 @@
#define SDIO_DEVICE_ID_BROADCOM_4335_4339 0x4335
#define SDIO_DEVICE_ID_BROADCOM_4339 0x4339
#define SDIO_DEVICE_ID_BROADCOM_43362 0xa962
#define SDIO_DEVICE_ID_BROADCOM_43364 0xa9a4
#define SDIO_DEVICE_ID_BROADCOM_43430 0xa9a6
#define SDIO_DEVICE_ID_BROADCOM_4345 0x4345
#define SDIO_DEVICE_ID_BROADCOM_43455 0xa9bf
#define SDIO_DEVICE_ID_BROADCOM_4354 0x4354
#define SDIO_DEVICE_ID_BROADCOM_4356 0x4356
#define SDIO_DEVICE_ID_CYPRESS_4373 0x4373
#define SDIO_VENDOR_ID_INTEL 0x0089
#define SDIO_DEVICE_ID_INTEL_IWMC3200WIMAX 0x1402
@ -52,6 +55,7 @@
#define SDIO_DEVICE_ID_MARVELL_LIBERTAS 0x9103
#define SDIO_DEVICE_ID_MARVELL_8688WLAN 0x9104
#define SDIO_DEVICE_ID_MARVELL_8688BT 0x9105
#define SDIO_DEVICE_ID_MARVELL_8797_F0 0x9128
#define SDIO_VENDOR_ID_SIANO 0x039a
#define SDIO_DEVICE_ID_SIANO_NOVA_B0 0x0201
@ -61,4 +65,10 @@
#define SDIO_DEVICE_ID_SIANO_NOVA_A0 0x1100
#define SDIO_DEVICE_ID_SIANO_STELLAR 0x5347
#define SDIO_VENDOR_ID_TI 0x0097
#define SDIO_DEVICE_ID_TI_WL1271 0x4076
#define SDIO_VENDOR_ID_STE 0x0020
#define SDIO_DEVICE_ID_STE_CW1200 0x2280
#endif /* LINUX_MMC_SDIO_IDS_H */