Merge tag 'wireless-drivers-next-for-davem-2018-11-30' of git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next
Kalle Valo says: ==================== wireless-drivers-next patches for 4.21 First set of patches for 4.21. Most notable here is support for Quantenna's QSR1000/QSR2000 chipsets and more flexible ways to provide nvram files for brcmfmac. Major changes: brcmfmac * add support for first trying to get a board specific nvram file * add support for getting nvram contents from EFI variables qtnfmac * use single PCIe driver for all platforms and rename Kconfig option CONFIG_QTNFMAC_PEARL_PCIE to CONFIG_QTNFMAC_PCIE * add support for QSR1000/QSR2000 (Topaz) family of chipsets ath10k * add support for WCN3990 firmware crash recovery * add firmware memory dump support for QCA4019 wil6210 * add firmware error recovery while in AP mode ath9k * remove experimental notice from dynack feature iwlwifi * PCI IDs for some new 9000-series cards * improve antenna usage on connection problems * new firmware debugging infrastructure * some more work on 802.11ax * improve support for multiple RF modules with 22000 devices cordic * move cordic macros and defines to a public header file * convert brcmsmac and b43 to fully use cordic library ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
@@ -54,3 +54,5 @@ brcmfmac-$(CONFIG_BRCM_TRACING) += \
|
||||
tracepoint.o
|
||||
brcmfmac-$(CONFIG_OF) += \
|
||||
of.o
|
||||
brcmfmac-$(CONFIG_DMI) += \
|
||||
dmi.o
|
||||
|
@@ -214,7 +214,7 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
|
||||
err = brcmf_fil_iovar_data_get(ifp, "cur_etheraddr", ifp->mac_addr,
|
||||
sizeof(ifp->mac_addr));
|
||||
if (err < 0) {
|
||||
brcmf_err("Retreiving cur_etheraddr failed, %d\n", err);
|
||||
brcmf_err("Retrieving cur_etheraddr failed, %d\n", err);
|
||||
goto done;
|
||||
}
|
||||
memcpy(ifp->drvr->wiphy->perm_addr, ifp->drvr->mac, ETH_ALEN);
|
||||
@@ -269,7 +269,7 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
|
||||
strcpy(buf, "ver");
|
||||
err = brcmf_fil_iovar_data_get(ifp, "ver", buf, sizeof(buf));
|
||||
if (err < 0) {
|
||||
brcmf_err("Retreiving version information failed, %d\n",
|
||||
brcmf_err("Retrieving version information failed, %d\n",
|
||||
err);
|
||||
goto done;
|
||||
}
|
||||
@@ -448,7 +448,8 @@ struct brcmf_mp_device *brcmf_get_module_param(struct device *dev,
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
/* No platform data for this device, try OF (Open Firwmare) */
|
||||
/* No platform data for this device, try OF and DMI data */
|
||||
brcmf_dmi_probe(settings, chip, chiprev);
|
||||
brcmf_of_probe(dev, bus_type, settings);
|
||||
}
|
||||
return settings;
|
||||
|
@@ -59,6 +59,7 @@ struct brcmf_mp_device {
|
||||
bool iapp;
|
||||
bool ignore_probe_fail;
|
||||
struct brcmfmac_pd_cc *country_codes;
|
||||
const char *board_type;
|
||||
union {
|
||||
struct brcmfmac_sdio_pd sdio;
|
||||
} bus;
|
||||
@@ -74,4 +75,11 @@ void brcmf_release_module_param(struct brcmf_mp_device *module_param);
|
||||
/* Sets dongle media info (drv_version, mac address). */
|
||||
int brcmf_c_preinit_dcmds(struct brcmf_if *ifp);
|
||||
|
||||
#ifdef CONFIG_DMI
|
||||
void brcmf_dmi_probe(struct brcmf_mp_device *settings, u32 chip, u32 chiprev);
|
||||
#else
|
||||
static inline void
|
||||
brcmf_dmi_probe(struct brcmf_mp_device *settings, u32 chip, u32 chiprev) {}
|
||||
#endif
|
||||
|
||||
#endif /* BRCMFMAC_COMMON_H */
|
||||
|
116
drivers/net/wireless/broadcom/brcm80211/brcmfmac/dmi.c
Normal file
116
drivers/net/wireless/broadcom/brcm80211/brcmfmac/dmi.c
Normal file
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright 2018 Hans de Goede <hdegoede@redhat.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include "core.h"
|
||||
#include "common.h"
|
||||
#include "brcm_hw_ids.h"
|
||||
|
||||
/* The DMI data never changes so we can use a static buf for this */
|
||||
static char dmi_board_type[128];
|
||||
|
||||
struct brcmf_dmi_data {
|
||||
u32 chip;
|
||||
u32 chiprev;
|
||||
const char *board_type;
|
||||
};
|
||||
|
||||
/* NOTE: Please keep all entries sorted alphabetically */
|
||||
|
||||
static const struct brcmf_dmi_data gpd_win_pocket_data = {
|
||||
BRCM_CC_4356_CHIP_ID, 2, "gpd-win-pocket"
|
||||
};
|
||||
|
||||
static const struct brcmf_dmi_data jumper_ezpad_mini3_data = {
|
||||
BRCM_CC_43430_CHIP_ID, 0, "jumper-ezpad-mini3"
|
||||
};
|
||||
|
||||
static const struct brcmf_dmi_data meegopad_t08_data = {
|
||||
BRCM_CC_43340_CHIP_ID, 2, "meegopad-t08"
|
||||
};
|
||||
|
||||
static const struct dmi_system_id dmi_platform_data[] = {
|
||||
{
|
||||
/* Match for the GPDwin which unfortunately uses somewhat
|
||||
* generic dmi strings, which is why we test for 4 strings.
|
||||
* Comparing against 23 other byt/cht boards, board_vendor
|
||||
* and board_name are unique to the GPDwin, where as only one
|
||||
* other board has the same board_serial and 3 others have
|
||||
* the same default product_name. Also the GPDwin is the
|
||||
* only device to have both board_ and product_name not set.
|
||||
*/
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "Default string"),
|
||||
DMI_MATCH(DMI_BOARD_SERIAL, "Default string"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Default string"),
|
||||
},
|
||||
.driver_data = (void *)&gpd_win_pocket_data,
|
||||
},
|
||||
{
|
||||
/* Jumper EZpad mini3 */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "CherryTrail"),
|
||||
/* jumperx.T87.KFBNEEA02 with the version-nr dropped */
|
||||
DMI_MATCH(DMI_BIOS_VERSION, "jumperx.T87.KFBNEEA"),
|
||||
},
|
||||
.driver_data = (void *)&jumper_ezpad_mini3_data,
|
||||
},
|
||||
{
|
||||
/* Meegopad T08 */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Default string"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Default string"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "T3 MRD"),
|
||||
DMI_MATCH(DMI_BOARD_VERSION, "V1.1"),
|
||||
},
|
||||
.driver_data = (void *)&meegopad_t08_data,
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
void brcmf_dmi_probe(struct brcmf_mp_device *settings, u32 chip, u32 chiprev)
|
||||
{
|
||||
const struct dmi_system_id *match;
|
||||
const struct brcmf_dmi_data *data;
|
||||
const char *sys_vendor;
|
||||
const char *product_name;
|
||||
|
||||
/* Some models have DMI strings which are too generic, e.g.
|
||||
* "Default string", we use a quirk table for these.
|
||||
*/
|
||||
for (match = dmi_first_match(dmi_platform_data);
|
||||
match;
|
||||
match = dmi_first_match(match + 1)) {
|
||||
data = match->driver_data;
|
||||
|
||||
if (data->chip == chip && data->chiprev == chiprev) {
|
||||
settings->board_type = data->board_type;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Not found in the quirk-table, use sys_vendor-product_name */
|
||||
sys_vendor = dmi_get_system_info(DMI_SYS_VENDOR);
|
||||
product_name = dmi_get_system_info(DMI_PRODUCT_NAME);
|
||||
if (sys_vendor && product_name) {
|
||||
snprintf(dmi_board_type, sizeof(dmi_board_type), "%s-%s",
|
||||
sys_vendor, product_name);
|
||||
settings->board_type = dmi_board_type;
|
||||
}
|
||||
}
|
@@ -14,6 +14,7 @@
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <linux/efi.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/device.h>
|
||||
@@ -445,6 +446,75 @@ struct brcmf_fw {
|
||||
|
||||
static void brcmf_fw_request_done(const struct firmware *fw, void *ctx);
|
||||
|
||||
#ifdef CONFIG_EFI
|
||||
/* In some cases the EFI-var stored nvram contains "ccode=ALL" or "ccode=XV"
|
||||
* to specify "worldwide" compatible settings, but these 2 ccode-s do not work
|
||||
* properly. "ccode=ALL" causes channels 12 and 13 to not be available,
|
||||
* "ccode=XV" causes all 5GHz channels to not be available. So we replace both
|
||||
* with "ccode=X2" which allows channels 12+13 and 5Ghz channels in
|
||||
* no-Initiate-Radiation mode. This means that we will never send on these
|
||||
* channels without first having received valid wifi traffic on the channel.
|
||||
*/
|
||||
static void brcmf_fw_fix_efi_nvram_ccode(char *data, unsigned long data_len)
|
||||
{
|
||||
char *ccode;
|
||||
|
||||
ccode = strnstr((char *)data, "ccode=ALL", data_len);
|
||||
if (!ccode)
|
||||
ccode = strnstr((char *)data, "ccode=XV\r", data_len);
|
||||
if (!ccode)
|
||||
return;
|
||||
|
||||
ccode[6] = 'X';
|
||||
ccode[7] = '2';
|
||||
ccode[8] = '\r';
|
||||
}
|
||||
|
||||
static u8 *brcmf_fw_nvram_from_efi(size_t *data_len_ret)
|
||||
{
|
||||
const u16 name[] = { 'n', 'v', 'r', 'a', 'm', 0 };
|
||||
struct efivar_entry *nvram_efivar;
|
||||
unsigned long data_len = 0;
|
||||
u8 *data = NULL;
|
||||
int err;
|
||||
|
||||
nvram_efivar = kzalloc(sizeof(*nvram_efivar), GFP_KERNEL);
|
||||
if (!nvram_efivar)
|
||||
return NULL;
|
||||
|
||||
memcpy(&nvram_efivar->var.VariableName, name, sizeof(name));
|
||||
nvram_efivar->var.VendorGuid = EFI_GUID(0x74b00bd9, 0x805a, 0x4d61,
|
||||
0xb5, 0x1f, 0x43, 0x26,
|
||||
0x81, 0x23, 0xd1, 0x13);
|
||||
|
||||
err = efivar_entry_size(nvram_efivar, &data_len);
|
||||
if (err)
|
||||
goto fail;
|
||||
|
||||
data = kmalloc(data_len, GFP_KERNEL);
|
||||
if (!data)
|
||||
goto fail;
|
||||
|
||||
err = efivar_entry_get(nvram_efivar, NULL, &data_len, data);
|
||||
if (err)
|
||||
goto fail;
|
||||
|
||||
brcmf_fw_fix_efi_nvram_ccode(data, data_len);
|
||||
brcmf_info("Using nvram EFI variable\n");
|
||||
|
||||
kfree(nvram_efivar);
|
||||
*data_len_ret = data_len;
|
||||
return data;
|
||||
|
||||
fail:
|
||||
kfree(data);
|
||||
kfree(nvram_efivar);
|
||||
return NULL;
|
||||
}
|
||||
#else
|
||||
static u8 *brcmf_fw_nvram_from_efi(size_t *data_len) { return NULL; }
|
||||
#endif
|
||||
|
||||
static void brcmf_fw_free_request(struct brcmf_fw_request *req)
|
||||
{
|
||||
struct brcmf_fw_item *item;
|
||||
@@ -463,11 +533,12 @@ static int brcmf_fw_request_nvram_done(const struct firmware *fw, void *ctx)
|
||||
{
|
||||
struct brcmf_fw *fwctx = ctx;
|
||||
struct brcmf_fw_item *cur;
|
||||
bool free_bcm47xx_nvram = false;
|
||||
bool kfree_nvram = false;
|
||||
u32 nvram_length = 0;
|
||||
void *nvram = NULL;
|
||||
u8 *data = NULL;
|
||||
size_t data_len;
|
||||
bool raw_nvram;
|
||||
|
||||
brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(fwctx->dev));
|
||||
|
||||
@@ -476,12 +547,13 @@ static int brcmf_fw_request_nvram_done(const struct firmware *fw, void *ctx)
|
||||
if (fw && fw->data) {
|
||||
data = (u8 *)fw->data;
|
||||
data_len = fw->size;
|
||||
raw_nvram = false;
|
||||
} else {
|
||||
data = bcm47xx_nvram_get_contents(&data_len);
|
||||
if (!data && !(cur->flags & BRCMF_FW_REQF_OPTIONAL))
|
||||
if ((data = bcm47xx_nvram_get_contents(&data_len)))
|
||||
free_bcm47xx_nvram = true;
|
||||
else if ((data = brcmf_fw_nvram_from_efi(&data_len)))
|
||||
kfree_nvram = true;
|
||||
else if (!(cur->flags & BRCMF_FW_REQF_OPTIONAL))
|
||||
goto fail;
|
||||
raw_nvram = true;
|
||||
}
|
||||
|
||||
if (data)
|
||||
@@ -489,8 +561,11 @@ static int brcmf_fw_request_nvram_done(const struct firmware *fw, void *ctx)
|
||||
fwctx->req->domain_nr,
|
||||
fwctx->req->bus_nr);
|
||||
|
||||
if (raw_nvram)
|
||||
if (free_bcm47xx_nvram)
|
||||
bcm47xx_nvram_release_contents(data);
|
||||
if (kfree_nvram)
|
||||
kfree(data);
|
||||
|
||||
release_firmware(fw);
|
||||
if (!nvram && !(cur->flags & BRCMF_FW_REQF_OPTIONAL))
|
||||
goto fail;
|
||||
@@ -504,90 +579,75 @@ fail:
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
static int brcmf_fw_request_next_item(struct brcmf_fw *fwctx, bool async)
|
||||
static int brcmf_fw_complete_request(const struct firmware *fw,
|
||||
struct brcmf_fw *fwctx)
|
||||
{
|
||||
struct brcmf_fw_item *cur;
|
||||
const struct firmware *fw = NULL;
|
||||
int ret;
|
||||
|
||||
cur = &fwctx->req->items[fwctx->curpos];
|
||||
|
||||
brcmf_dbg(TRACE, "%srequest for %s\n", async ? "async " : "",
|
||||
cur->path);
|
||||
|
||||
if (async)
|
||||
ret = request_firmware_nowait(THIS_MODULE, true, cur->path,
|
||||
fwctx->dev, GFP_KERNEL, fwctx,
|
||||
brcmf_fw_request_done);
|
||||
else
|
||||
ret = request_firmware(&fw, cur->path, fwctx->dev);
|
||||
|
||||
if (ret < 0) {
|
||||
brcmf_fw_request_done(NULL, fwctx);
|
||||
} else if (!async && fw) {
|
||||
brcmf_dbg(TRACE, "firmware %s %sfound\n", cur->path,
|
||||
fw ? "" : "not ");
|
||||
if (cur->type == BRCMF_FW_TYPE_BINARY)
|
||||
cur->binary = fw;
|
||||
else if (cur->type == BRCMF_FW_TYPE_NVRAM)
|
||||
brcmf_fw_request_nvram_done(fw, fwctx);
|
||||
else
|
||||
release_firmware(fw);
|
||||
|
||||
return -EAGAIN;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void brcmf_fw_request_done(const struct firmware *fw, void *ctx)
|
||||
{
|
||||
struct brcmf_fw *fwctx = ctx;
|
||||
struct brcmf_fw_item *cur;
|
||||
struct brcmf_fw_item *cur = &fwctx->req->items[fwctx->curpos];
|
||||
int ret = 0;
|
||||
|
||||
cur = &fwctx->req->items[fwctx->curpos];
|
||||
|
||||
brcmf_dbg(TRACE, "enter: firmware %s %sfound\n", cur->path,
|
||||
fw ? "" : "not ");
|
||||
|
||||
if (!fw)
|
||||
ret = -ENOENT;
|
||||
brcmf_dbg(TRACE, "firmware %s %sfound\n", cur->path, fw ? "" : "not ");
|
||||
|
||||
switch (cur->type) {
|
||||
case BRCMF_FW_TYPE_NVRAM:
|
||||
ret = brcmf_fw_request_nvram_done(fw, fwctx);
|
||||
break;
|
||||
case BRCMF_FW_TYPE_BINARY:
|
||||
cur->binary = fw;
|
||||
if (fw)
|
||||
cur->binary = fw;
|
||||
else
|
||||
ret = -ENOENT;
|
||||
break;
|
||||
default:
|
||||
/* something fishy here so bail out early */
|
||||
brcmf_err("unknown fw type: %d\n", cur->type);
|
||||
release_firmware(fw);
|
||||
ret = -EINVAL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (ret < 0 && !(cur->flags & BRCMF_FW_REQF_OPTIONAL))
|
||||
goto fail;
|
||||
return (cur->flags & BRCMF_FW_REQF_OPTIONAL) ? 0 : ret;
|
||||
}
|
||||
|
||||
do {
|
||||
if (++fwctx->curpos == fwctx->req->n_items) {
|
||||
ret = 0;
|
||||
goto done;
|
||||
}
|
||||
static int brcmf_fw_request_firmware(const struct firmware **fw,
|
||||
struct brcmf_fw *fwctx)
|
||||
{
|
||||
struct brcmf_fw_item *cur = &fwctx->req->items[fwctx->curpos];
|
||||
int ret;
|
||||
|
||||
ret = brcmf_fw_request_next_item(fwctx, false);
|
||||
} while (ret == -EAGAIN);
|
||||
/* nvram files are board-specific, first try a board-specific path */
|
||||
if (cur->type == BRCMF_FW_TYPE_NVRAM && fwctx->req->board_type) {
|
||||
char alt_path[BRCMF_FW_NAME_LEN];
|
||||
|
||||
return;
|
||||
strlcpy(alt_path, cur->path, BRCMF_FW_NAME_LEN);
|
||||
/* strip .txt at the end */
|
||||
alt_path[strlen(alt_path) - 4] = 0;
|
||||
strlcat(alt_path, ".", BRCMF_FW_NAME_LEN);
|
||||
strlcat(alt_path, fwctx->req->board_type, BRCMF_FW_NAME_LEN);
|
||||
strlcat(alt_path, ".txt", BRCMF_FW_NAME_LEN);
|
||||
|
||||
fail:
|
||||
brcmf_dbg(TRACE, "failed err=%d: dev=%s, fw=%s\n", ret,
|
||||
dev_name(fwctx->dev), cur->path);
|
||||
brcmf_fw_free_request(fwctx->req);
|
||||
fwctx->req = NULL;
|
||||
done:
|
||||
ret = request_firmware(fw, alt_path, fwctx->dev);
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return request_firmware(fw, cur->path, fwctx->dev);
|
||||
}
|
||||
|
||||
static void brcmf_fw_request_done(const struct firmware *fw, void *ctx)
|
||||
{
|
||||
struct brcmf_fw *fwctx = ctx;
|
||||
int ret;
|
||||
|
||||
ret = brcmf_fw_complete_request(fw, fwctx);
|
||||
|
||||
while (ret == 0 && ++fwctx->curpos < fwctx->req->n_items) {
|
||||
brcmf_fw_request_firmware(&fw, fwctx);
|
||||
ret = brcmf_fw_complete_request(fw, ctx);
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
brcmf_fw_free_request(fwctx->req);
|
||||
fwctx->req = NULL;
|
||||
}
|
||||
fwctx->done(fwctx->dev, ret, fwctx->req);
|
||||
kfree(fwctx);
|
||||
}
|
||||
@@ -611,7 +671,9 @@ int brcmf_fw_get_firmwares(struct device *dev, struct brcmf_fw_request *req,
|
||||
void (*fw_cb)(struct device *dev, int err,
|
||||
struct brcmf_fw_request *req))
|
||||
{
|
||||
struct brcmf_fw_item *first = &req->items[0];
|
||||
struct brcmf_fw *fwctx;
|
||||
int ret;
|
||||
|
||||
brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(dev));
|
||||
if (!fw_cb)
|
||||
@@ -628,7 +690,12 @@ int brcmf_fw_get_firmwares(struct device *dev, struct brcmf_fw_request *req,
|
||||
fwctx->req = req;
|
||||
fwctx->done = fw_cb;
|
||||
|
||||
brcmf_fw_request_next_item(fwctx, true);
|
||||
ret = request_firmware_nowait(THIS_MODULE, true, first->path,
|
||||
fwctx->dev, GFP_KERNEL, fwctx,
|
||||
brcmf_fw_request_done);
|
||||
if (ret < 0)
|
||||
brcmf_fw_request_done(NULL, fwctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -641,8 +708,9 @@ brcmf_fw_alloc_request(u32 chip, u32 chiprev,
|
||||
struct brcmf_fw_request *fwreq;
|
||||
char chipname[12];
|
||||
const char *mp_path;
|
||||
size_t mp_path_len;
|
||||
u32 i, j;
|
||||
char end;
|
||||
char end = '\0';
|
||||
size_t reqsz;
|
||||
|
||||
for (i = 0; i < table_size; i++) {
|
||||
@@ -667,7 +735,10 @@ brcmf_fw_alloc_request(u32 chip, u32 chiprev,
|
||||
mapping_table[i].fw_base, chipname);
|
||||
|
||||
mp_path = brcmf_mp_global.firmware_path;
|
||||
end = mp_path[strlen(mp_path) - 1];
|
||||
mp_path_len = strnlen(mp_path, BRCMF_FW_ALTPATH_LEN);
|
||||
if (mp_path_len)
|
||||
end = mp_path[mp_path_len - 1];
|
||||
|
||||
fwreq->n_items = n_fwnames;
|
||||
|
||||
for (j = 0; j < n_fwnames; j++) {
|
||||
|
@@ -70,6 +70,7 @@ struct brcmf_fw_request {
|
||||
u16 domain_nr;
|
||||
u16 bus_nr;
|
||||
u32 n_items;
|
||||
const char *board_type;
|
||||
struct brcmf_fw_item items[0];
|
||||
};
|
||||
|
||||
|
@@ -176,6 +176,8 @@
|
||||
|
||||
#define BRCMF_VHT_CAP_MCS_MAP_NSS_MAX 8
|
||||
|
||||
#define BRCMF_HE_CAP_MCS_MAP_NSS_MAX 8
|
||||
|
||||
/* MAX_CHUNK_LEN is the maximum length for data passing to firmware in each
|
||||
* ioctl. It is relatively small because firmware has small maximum size input
|
||||
* playload restriction for ioctls.
|
||||
@@ -601,13 +603,37 @@ struct brcmf_sta_info_le {
|
||||
__le32 rx_pkts_retried; /* # rx with retry bit set */
|
||||
__le32 tx_rate_fallback; /* lowest fallback TX rate */
|
||||
|
||||
/* Fields valid for ver >= 5 */
|
||||
struct {
|
||||
__le32 count; /* # rates in this set */
|
||||
u8 rates[BRCMF_MAXRATES_IN_SET]; /* rates in 500kbps units w/hi bit set if basic */
|
||||
u8 mcs[BRCMF_MCSSET_LEN]; /* supported mcs index bit map */
|
||||
__le16 vht_mcs[BRCMF_VHT_CAP_MCS_MAP_NSS_MAX]; /* supported mcs index bit map per nss */
|
||||
} rateset_adv;
|
||||
union {
|
||||
struct {
|
||||
struct {
|
||||
__le32 count; /* # rates in this set */
|
||||
u8 rates[BRCMF_MAXRATES_IN_SET]; /* rates in 500kbps units w/hi bit set if basic */
|
||||
u8 mcs[BRCMF_MCSSET_LEN]; /* supported mcs index bit map */
|
||||
__le16 vht_mcs[BRCMF_VHT_CAP_MCS_MAP_NSS_MAX]; /* supported mcs index bit map per nss */
|
||||
} rateset_adv;
|
||||
} v5;
|
||||
|
||||
struct {
|
||||
__le32 rx_dur_total; /* total user RX duration (estimated) */
|
||||
__le16 chanspec; /** chanspec this sta is on */
|
||||
__le16 pad_1;
|
||||
struct {
|
||||
__le16 version; /* version */
|
||||
__le16 len; /* length */
|
||||
__le32 count; /* # rates in this set */
|
||||
u8 rates[BRCMF_MAXRATES_IN_SET]; /* rates in 500kbps units w/hi bit set if basic */
|
||||
u8 mcs[BRCMF_MCSSET_LEN]; /* supported mcs index bit map */
|
||||
__le16 vht_mcs[BRCMF_VHT_CAP_MCS_MAP_NSS_MAX]; /* supported mcs index bit map per nss */
|
||||
__le16 he_mcs[BRCMF_HE_CAP_MCS_MAP_NSS_MAX]; /* supported he mcs index bit map per nss */
|
||||
} rateset_adv; /* rateset along with mcs index bitmap */
|
||||
__le16 wpauth; /* authentication type */
|
||||
u8 algo; /* crypto algorithm */
|
||||
u8 pad_2;
|
||||
__le32 tx_rspec; /* Rate of last successful tx frame */
|
||||
__le32 rx_rspec; /* Rate of last successful rx frame */
|
||||
__le32 wnm_cap; /* wnm capabilities */
|
||||
} v7;
|
||||
};
|
||||
};
|
||||
|
||||
struct brcmf_chanspec_list {
|
||||
|
@@ -27,11 +27,20 @@ void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type,
|
||||
struct brcmf_mp_device *settings)
|
||||
{
|
||||
struct brcmfmac_sdio_pd *sdio = &settings->bus.sdio;
|
||||
struct device_node *np = dev->of_node;
|
||||
struct device_node *root, *np = dev->of_node;
|
||||
struct property *prop;
|
||||
int irq;
|
||||
u32 irqf;
|
||||
u32 val;
|
||||
|
||||
/* Set board-type to the first string of the machine compatible prop */
|
||||
root = of_find_node_by_path("/");
|
||||
if (root) {
|
||||
prop = of_find_property(root, "compatible", NULL);
|
||||
settings->board_type = of_prop_next_string(prop, NULL);
|
||||
of_node_put(root);
|
||||
}
|
||||
|
||||
if (!np || bus_type != BRCMF_BUSTYPE_SDIO ||
|
||||
!of_device_is_compatible(np, "brcm,bcm4329-fmac"))
|
||||
return;
|
||||
|
@@ -1785,6 +1785,7 @@ brcmf_pcie_prepare_fw_request(struct brcmf_pciedev_info *devinfo)
|
||||
fwreq->items[BRCMF_PCIE_FW_CODE].type = BRCMF_FW_TYPE_BINARY;
|
||||
fwreq->items[BRCMF_PCIE_FW_NVRAM].type = BRCMF_FW_TYPE_NVRAM;
|
||||
fwreq->items[BRCMF_PCIE_FW_NVRAM].flags = BRCMF_FW_REQF_OPTIONAL;
|
||||
fwreq->board_type = devinfo->settings->board_type;
|
||||
/* NVRAM reserves PCI domain 0 for Broadcom's SDK faked bus */
|
||||
fwreq->domain_nr = pci_domain_nr(devinfo->pdev->bus) + 1;
|
||||
fwreq->bus_nr = devinfo->pdev->bus->number;
|
||||
|
@@ -4174,6 +4174,7 @@ brcmf_sdio_prepare_fw_request(struct brcmf_sdio *bus)
|
||||
|
||||
fwreq->items[BRCMF_SDIO_FW_CODE].type = BRCMF_FW_TYPE_BINARY;
|
||||
fwreq->items[BRCMF_SDIO_FW_NVRAM].type = BRCMF_FW_TYPE_NVRAM;
|
||||
fwreq->board_type = bus->sdiodev->settings->board_type;
|
||||
|
||||
return fwreq;
|
||||
}
|
||||
|
@@ -846,8 +846,8 @@ brcms_ops_ampdu_action(struct ieee80211_hw *hw,
|
||||
status = brcms_c_aggregatable(wl->wlc, tid);
|
||||
spin_unlock_bh(&wl->lock);
|
||||
if (!status) {
|
||||
brcms_err(wl->wlc->hw->d11core,
|
||||
"START: tid %d is not agg\'able\n", tid);
|
||||
brcms_dbg_ht(wl->wlc->hw->d11core,
|
||||
"START: tid %d is not agg\'able\n", tid);
|
||||
return -EINVAL;
|
||||
}
|
||||
ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
|
||||
|
@@ -220,13 +220,6 @@ enum phy_cal_mode {
|
||||
#define BB_MULT_MASK 0x0000ffff
|
||||
#define BB_MULT_VALID_MASK 0x80000000
|
||||
|
||||
#define CORDIC_AG 39797
|
||||
#define CORDIC_NI 18
|
||||
#define FIXED(X) ((s32)((X) << 16))
|
||||
|
||||
#define FLOAT(X) \
|
||||
(((X) >= 0) ? ((((X) >> 15) + 1) >> 1) : -((((-(X)) >> 15) + 1) >> 1))
|
||||
|
||||
#define PHY_CHAIN_TX_DISABLE_TEMP 115
|
||||
#define PHY_HYSTERESIS_DELTATEMP 5
|
||||
|
||||
|
@@ -3447,8 +3447,8 @@ wlc_lcnphy_start_tx_tone(struct brcms_phy *pi, s32 f_kHz, u16 max_val,
|
||||
|
||||
theta += rot;
|
||||
|
||||
i_samp = (u16) (FLOAT(tone_samp.i * max_val) & 0x3ff);
|
||||
q_samp = (u16) (FLOAT(tone_samp.q * max_val) & 0x3ff);
|
||||
i_samp = (u16)(CORDIC_FLOAT(tone_samp.i * max_val) & 0x3ff);
|
||||
q_samp = (u16)(CORDIC_FLOAT(tone_samp.q * max_val) & 0x3ff);
|
||||
data_buf[t] = (i_samp << 10) | q_samp;
|
||||
}
|
||||
|
||||
|
@@ -23089,8 +23089,8 @@ wlc_phy_gen_load_samples_nphy(struct brcms_phy *pi, u32 f_kHz, u16 max_val,
|
||||
|
||||
theta += rot;
|
||||
|
||||
tone_buf[t].q = (s32) FLOAT(tone_buf[t].q * max_val);
|
||||
tone_buf[t].i = (s32) FLOAT(tone_buf[t].i * max_val);
|
||||
tone_buf[t].q = (s32)CORDIC_FLOAT(tone_buf[t].q * max_val);
|
||||
tone_buf[t].i = (s32)CORDIC_FLOAT(tone_buf[t].i * max_val);
|
||||
}
|
||||
|
||||
wlc_phy_loadsampletable_nphy(pi, tone_buf, num_samps);
|
||||
|
@@ -128,7 +128,7 @@ static void brcmu_d11n_decchspec(struct brcmu_chan *ch)
|
||||
}
|
||||
break;
|
||||
default:
|
||||
WARN_ON_ONCE(1);
|
||||
WARN_ONCE(1, "Invalid chanspec 0x%04x\n", ch->chspec);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -140,7 +140,7 @@ static void brcmu_d11n_decchspec(struct brcmu_chan *ch)
|
||||
ch->band = BRCMU_CHAN_BAND_2G;
|
||||
break;
|
||||
default:
|
||||
WARN_ON_ONCE(1);
|
||||
WARN_ONCE(1, "Invalid chanspec 0x%04x\n", ch->chspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -167,7 +167,7 @@ static void brcmu_d11ac_decchspec(struct brcmu_chan *ch)
|
||||
ch->sb = BRCMU_CHAN_SB_U;
|
||||
ch->control_ch_num += CH_10MHZ_APART;
|
||||
} else {
|
||||
WARN_ON_ONCE(1);
|
||||
WARN_ONCE(1, "Invalid chanspec 0x%04x\n", ch->chspec);
|
||||
}
|
||||
break;
|
||||
case BRCMU_CHSPEC_D11AC_BW_80:
|
||||
@@ -188,7 +188,7 @@ static void brcmu_d11ac_decchspec(struct brcmu_chan *ch)
|
||||
ch->control_ch_num += CH_30MHZ_APART;
|
||||
break;
|
||||
default:
|
||||
WARN_ON_ONCE(1);
|
||||
WARN_ONCE(1, "Invalid chanspec 0x%04x\n", ch->chspec);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@@ -222,13 +222,13 @@ static void brcmu_d11ac_decchspec(struct brcmu_chan *ch)
|
||||
ch->control_ch_num += CH_70MHZ_APART;
|
||||
break;
|
||||
default:
|
||||
WARN_ON_ONCE(1);
|
||||
WARN_ONCE(1, "Invalid chanspec 0x%04x\n", ch->chspec);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case BRCMU_CHSPEC_D11AC_BW_8080:
|
||||
default:
|
||||
WARN_ON_ONCE(1);
|
||||
WARN_ONCE(1, "Invalid chanspec 0x%04x\n", ch->chspec);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -240,7 +240,7 @@ static void brcmu_d11ac_decchspec(struct brcmu_chan *ch)
|
||||
ch->band = BRCMU_CHAN_BAND_2G;
|
||||
break;
|
||||
default:
|
||||
WARN_ON_ONCE(1);
|
||||
WARN_ONCE(1, "Invalid chanspec 0x%04x\n", ch->chspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user