mirror of https://gitee.com/openkylin/linux.git
Merge remote-tracking branch 'wireless-next/master' into iwlwifi-next
This commit is contained in:
commit
ae0008c71a
|
@ -148,6 +148,13 @@ L: linux-scsi@vger.kernel.org
|
|||
S: Maintained
|
||||
F: drivers/scsi/53c700*
|
||||
|
||||
6LOWPAN GENERIC (BTLE/IEEE 802.15.4)
|
||||
M: Alexander Aring <alex.aring@gmail.com>
|
||||
L: linux-zigbee-devel@lists.sourceforge.net (moderated for non-subscribers)
|
||||
L: linux-bluetooth@vger.kernel.org
|
||||
S: Maintained
|
||||
F: net/6lowpan/
|
||||
|
||||
6PACK NETWORK DRIVER FOR AX.25
|
||||
M: Andreas Koensgen <ajk@comnets.uni-bremen.de>
|
||||
L: linux-hams@vger.kernel.org
|
||||
|
|
|
@ -3,6 +3,7 @@ bcma-y += driver_chipcommon.o driver_chipcommon_pmu.o
|
|||
bcma-$(CONFIG_BCMA_SFLASH) += driver_chipcommon_sflash.o
|
||||
bcma-$(CONFIG_BCMA_NFLASH) += driver_chipcommon_nflash.o
|
||||
bcma-y += driver_pci.o
|
||||
bcma-y += driver_pcie2.o
|
||||
bcma-$(CONFIG_BCMA_DRIVER_PCI_HOSTMODE) += driver_pci_host.o
|
||||
bcma-$(CONFIG_BCMA_DRIVER_MIPS) += driver_mips.o
|
||||
bcma-$(CONFIG_BCMA_DRIVER_GMAC_CMN) += driver_gmac_cmn.o
|
||||
|
|
|
@ -603,6 +603,7 @@ void bcma_pmu_spuravoid_pllupdate(struct bcma_drv_cc *cc, int spuravoid)
|
|||
tmp = BCMA_CC_PMU_CTL_PLL_UPD | BCMA_CC_PMU_CTL_NOILPONW;
|
||||
break;
|
||||
|
||||
case BCMA_CHIP_ID_BCM43217:
|
||||
case BCMA_CHIP_ID_BCM43227:
|
||||
case BCMA_CHIP_ID_BCM43228:
|
||||
case BCMA_CHIP_ID_BCM43428:
|
||||
|
|
|
@ -0,0 +1,175 @@
|
|||
/*
|
||||
* Broadcom specific AMBA
|
||||
* PCIe Gen 2 Core
|
||||
*
|
||||
* Copyright 2014, Broadcom Corporation
|
||||
* Copyright 2014, Rafał Miłecki <zajec5@gmail.com>
|
||||
*
|
||||
* Licensed under the GNU/GPL. See COPYING for details.
|
||||
*/
|
||||
|
||||
#include "bcma_private.h"
|
||||
#include <linux/bcma/bcma.h>
|
||||
|
||||
/**************************************************
|
||||
* R/W ops.
|
||||
**************************************************/
|
||||
|
||||
#if 0
|
||||
static u32 bcma_core_pcie2_cfg_read(struct bcma_drv_pcie2 *pcie2, u32 addr)
|
||||
{
|
||||
pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR, addr);
|
||||
pcie2_read32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR);
|
||||
return pcie2_read32(pcie2, BCMA_CORE_PCIE2_CONFIGINDDATA);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void bcma_core_pcie2_cfg_write(struct bcma_drv_pcie2 *pcie2, u32 addr,
|
||||
u32 val)
|
||||
{
|
||||
pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR, addr);
|
||||
pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDDATA, val);
|
||||
}
|
||||
|
||||
/**************************************************
|
||||
* Init.
|
||||
**************************************************/
|
||||
|
||||
static u32 bcma_core_pcie2_war_delay_perst_enab(struct bcma_drv_pcie2 *pcie2,
|
||||
bool enable)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
/* restore back to default */
|
||||
val = pcie2_read32(pcie2, BCMA_CORE_PCIE2_CLK_CONTROL);
|
||||
val |= PCIE2_CLKC_DLYPERST;
|
||||
val &= ~PCIE2_CLKC_DISSPROMLD;
|
||||
if (enable) {
|
||||
val &= ~PCIE2_CLKC_DLYPERST;
|
||||
val |= PCIE2_CLKC_DISSPROMLD;
|
||||
}
|
||||
pcie2_write32(pcie2, (BCMA_CORE_PCIE2_CLK_CONTROL), val);
|
||||
/* flush */
|
||||
return pcie2_read32(pcie2, BCMA_CORE_PCIE2_CLK_CONTROL);
|
||||
}
|
||||
|
||||
static void bcma_core_pcie2_set_ltr_vals(struct bcma_drv_pcie2 *pcie2)
|
||||
{
|
||||
/* LTR0 */
|
||||
pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR, 0x844);
|
||||
pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDDATA, 0x883c883c);
|
||||
/* LTR1 */
|
||||
pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR, 0x848);
|
||||
pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDDATA, 0x88648864);
|
||||
/* LTR2 */
|
||||
pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR, 0x84C);
|
||||
pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDDATA, 0x90039003);
|
||||
}
|
||||
|
||||
static void bcma_core_pcie2_hw_ltr_war(struct bcma_drv_pcie2 *pcie2)
|
||||
{
|
||||
u8 core_rev = pcie2->core->id.rev;
|
||||
u32 devstsctr2;
|
||||
|
||||
if (core_rev < 2 || core_rev == 10 || core_rev > 13)
|
||||
return;
|
||||
|
||||
pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR,
|
||||
PCIE2_CAP_DEVSTSCTRL2_OFFSET);
|
||||
devstsctr2 = pcie2_read32(pcie2, BCMA_CORE_PCIE2_CONFIGINDDATA);
|
||||
if (devstsctr2 & PCIE2_CAP_DEVSTSCTRL2_LTRENAB) {
|
||||
/* force the right LTR values */
|
||||
bcma_core_pcie2_set_ltr_vals(pcie2);
|
||||
|
||||
/* TODO:
|
||||
si_core_wrapperreg(pcie2, 3, 0x60, 0x8080, 0); */
|
||||
|
||||
/* enable the LTR */
|
||||
devstsctr2 |= PCIE2_CAP_DEVSTSCTRL2_LTRENAB;
|
||||
pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR,
|
||||
PCIE2_CAP_DEVSTSCTRL2_OFFSET);
|
||||
pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDDATA, devstsctr2);
|
||||
|
||||
/* set the LTR state to be active */
|
||||
pcie2_write32(pcie2, BCMA_CORE_PCIE2_LTR_STATE,
|
||||
PCIE2_LTR_ACTIVE);
|
||||
usleep_range(1000, 2000);
|
||||
|
||||
/* set the LTR state to be sleep */
|
||||
pcie2_write32(pcie2, BCMA_CORE_PCIE2_LTR_STATE,
|
||||
PCIE2_LTR_SLEEP);
|
||||
usleep_range(1000, 2000);
|
||||
}
|
||||
}
|
||||
|
||||
static void pciedev_crwlpciegen2(struct bcma_drv_pcie2 *pcie2)
|
||||
{
|
||||
u8 core_rev = pcie2->core->id.rev;
|
||||
bool pciewar160, pciewar162;
|
||||
|
||||
pciewar160 = core_rev == 7 || core_rev == 9 || core_rev == 11;
|
||||
pciewar162 = core_rev == 5 || core_rev == 7 || core_rev == 8 ||
|
||||
core_rev == 9 || core_rev == 11;
|
||||
|
||||
if (!pciewar160 && !pciewar162)
|
||||
return;
|
||||
|
||||
/* TODO */
|
||||
#if 0
|
||||
pcie2_set32(pcie2, BCMA_CORE_PCIE2_CLK_CONTROL,
|
||||
PCIE_DISABLE_L1CLK_GATING);
|
||||
#if 0
|
||||
pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR,
|
||||
PCIEGEN2_COE_PVT_TL_CTRL_0);
|
||||
pcie2_mask32(pcie2, BCMA_CORE_PCIE2_CONFIGINDDATA,
|
||||
~(1 << COE_PVT_TL_CTRL_0_PM_DIS_L1_REENTRY_BIT));
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
static void pciedev_crwlpciegen2_180(struct bcma_drv_pcie2 *pcie2)
|
||||
{
|
||||
pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR, PCIE2_PMCR_REFUP);
|
||||
pcie2_set32(pcie2, BCMA_CORE_PCIE2_CONFIGINDDATA, 0x1f);
|
||||
}
|
||||
|
||||
static void pciedev_crwlpciegen2_182(struct bcma_drv_pcie2 *pcie2)
|
||||
{
|
||||
pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR, PCIE2_SBMBX);
|
||||
pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDDATA, 1 << 0);
|
||||
}
|
||||
|
||||
static void pciedev_reg_pm_clk_period(struct bcma_drv_pcie2 *pcie2)
|
||||
{
|
||||
struct bcma_drv_cc *drv_cc = &pcie2->core->bus->drv_cc;
|
||||
u8 core_rev = pcie2->core->id.rev;
|
||||
u32 alp_khz, pm_value;
|
||||
|
||||
if (core_rev <= 13) {
|
||||
alp_khz = bcma_pmu_get_alp_clock(drv_cc) / 1000;
|
||||
pm_value = (1000000 * 2) / alp_khz;
|
||||
pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR,
|
||||
PCIE2_PVT_REG_PM_CLK_PERIOD);
|
||||
pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDDATA, pm_value);
|
||||
}
|
||||
}
|
||||
|
||||
void bcma_core_pcie2_init(struct bcma_drv_pcie2 *pcie2)
|
||||
{
|
||||
struct bcma_chipinfo *ci = &pcie2->core->bus->chipinfo;
|
||||
u32 tmp;
|
||||
|
||||
tmp = pcie2_read32(pcie2, BCMA_CORE_PCIE2_SPROM(54));
|
||||
if ((tmp & 0xe) >> 1 == 2)
|
||||
bcma_core_pcie2_cfg_write(pcie2, 0x4e0, 0x17);
|
||||
|
||||
/* TODO: Do we need pcie_reqsize? */
|
||||
|
||||
if (ci->id == BCMA_CHIP_ID_BCM4360 && ci->rev > 3)
|
||||
bcma_core_pcie2_war_delay_perst_enab(pcie2, true);
|
||||
bcma_core_pcie2_hw_ltr_war(pcie2);
|
||||
pciedev_crwlpciegen2(pcie2);
|
||||
pciedev_reg_pm_clk_period(pcie2);
|
||||
pciedev_crwlpciegen2_180(pcie2);
|
||||
pciedev_crwlpciegen2_182(pcie2);
|
||||
}
|
|
@ -279,6 +279,7 @@ static const struct pci_device_id bcma_pci_bridge_tbl[] = {
|
|||
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4358) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4359) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4365) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43a9) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4727) },
|
||||
{ 0, },
|
||||
};
|
||||
|
|
|
@ -132,6 +132,7 @@ static int bcma_register_cores(struct bcma_bus *bus)
|
|||
case BCMA_CORE_CHIPCOMMON:
|
||||
case BCMA_CORE_PCI:
|
||||
case BCMA_CORE_PCIE:
|
||||
case BCMA_CORE_PCIE2:
|
||||
case BCMA_CORE_MIPS_74K:
|
||||
case BCMA_CORE_4706_MAC_GBIT_COMMON:
|
||||
continue;
|
||||
|
@ -281,6 +282,13 @@ int bcma_bus_register(struct bcma_bus *bus)
|
|||
bcma_core_pci_init(&bus->drv_pci[1]);
|
||||
}
|
||||
|
||||
/* Init PCIe Gen 2 core */
|
||||
core = bcma_find_core_unit(bus, BCMA_CORE_PCIE2, 0);
|
||||
if (core) {
|
||||
bus->drv_pcie2.core = core;
|
||||
bcma_core_pcie2_init(&bus->drv_pcie2);
|
||||
}
|
||||
|
||||
/* Init GBIT MAC COMMON core */
|
||||
core = bcma_find_core(bus, BCMA_CORE_4706_MAC_GBIT_COMMON);
|
||||
if (core) {
|
||||
|
|
|
@ -201,6 +201,23 @@ static int bcma_sprom_valid(struct bcma_bus *bus, const u16 *sprom,
|
|||
SPEX(_field[7], _offset + 14, _mask, _shift); \
|
||||
} while (0)
|
||||
|
||||
static s8 sprom_extract_antgain(const u16 *in, u16 offset, u16 mask, u16 shift)
|
||||
{
|
||||
u16 v;
|
||||
u8 gain;
|
||||
|
||||
v = in[SPOFF(offset)];
|
||||
gain = (v & mask) >> shift;
|
||||
if (gain == 0xFF) {
|
||||
gain = 8; /* If unset use 2dBm */
|
||||
} else {
|
||||
/* Q5.2 Fractional part is stored in 0xC0 */
|
||||
gain = ((gain & 0xC0) >> 6) | ((gain & 0x3F) << 2);
|
||||
}
|
||||
|
||||
return (s8)gain;
|
||||
}
|
||||
|
||||
static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom)
|
||||
{
|
||||
u16 v, o;
|
||||
|
@ -381,14 +398,22 @@ static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom)
|
|||
SPEX32(ofdm5ghpo, SSB_SPROM8_OFDM5GHPO, ~0, 0);
|
||||
|
||||
/* Extract the antenna gain values. */
|
||||
SPEX(antenna_gain.a0, SSB_SPROM8_AGAIN01,
|
||||
SSB_SPROM8_AGAIN0, SSB_SPROM8_AGAIN0_SHIFT);
|
||||
SPEX(antenna_gain.a1, SSB_SPROM8_AGAIN01,
|
||||
SSB_SPROM8_AGAIN1, SSB_SPROM8_AGAIN1_SHIFT);
|
||||
SPEX(antenna_gain.a2, SSB_SPROM8_AGAIN23,
|
||||
SSB_SPROM8_AGAIN2, SSB_SPROM8_AGAIN2_SHIFT);
|
||||
SPEX(antenna_gain.a3, SSB_SPROM8_AGAIN23,
|
||||
SSB_SPROM8_AGAIN3, SSB_SPROM8_AGAIN3_SHIFT);
|
||||
bus->sprom.antenna_gain.a0 = sprom_extract_antgain(sprom,
|
||||
SSB_SPROM8_AGAIN01,
|
||||
SSB_SPROM8_AGAIN0,
|
||||
SSB_SPROM8_AGAIN0_SHIFT);
|
||||
bus->sprom.antenna_gain.a1 = sprom_extract_antgain(sprom,
|
||||
SSB_SPROM8_AGAIN01,
|
||||
SSB_SPROM8_AGAIN1,
|
||||
SSB_SPROM8_AGAIN1_SHIFT);
|
||||
bus->sprom.antenna_gain.a2 = sprom_extract_antgain(sprom,
|
||||
SSB_SPROM8_AGAIN23,
|
||||
SSB_SPROM8_AGAIN2,
|
||||
SSB_SPROM8_AGAIN2_SHIFT);
|
||||
bus->sprom.antenna_gain.a3 = sprom_extract_antgain(sprom,
|
||||
SSB_SPROM8_AGAIN23,
|
||||
SSB_SPROM8_AGAIN3,
|
||||
SSB_SPROM8_AGAIN3_SHIFT);
|
||||
|
||||
SPEX(leddc_on_time, SSB_SPROM8_LEDDC, SSB_SPROM8_LEDDC_ON,
|
||||
SSB_SPROM8_LEDDC_ON_SHIFT);
|
||||
|
@ -509,6 +534,7 @@ static bool bcma_sprom_onchip_available(struct bcma_bus *bus)
|
|||
/* for these chips OTP is always available */
|
||||
present = true;
|
||||
break;
|
||||
case BCMA_CHIP_ID_BCM43217:
|
||||
case BCMA_CHIP_ID_BCM43227:
|
||||
case BCMA_CHIP_ID_BCM43228:
|
||||
case BCMA_CHIP_ID_BCM43428:
|
||||
|
|
|
@ -90,7 +90,6 @@ static const struct usb_device_id ath3k_table[] = {
|
|||
{ USB_DEVICE(0x0b05, 0x17d0) },
|
||||
{ USB_DEVICE(0x0CF3, 0x0036) },
|
||||
{ USB_DEVICE(0x0CF3, 0x3004) },
|
||||
{ USB_DEVICE(0x0CF3, 0x3005) },
|
||||
{ USB_DEVICE(0x0CF3, 0x3008) },
|
||||
{ USB_DEVICE(0x0CF3, 0x311D) },
|
||||
{ USB_DEVICE(0x0CF3, 0x311E) },
|
||||
|
@ -104,6 +103,7 @@ static const struct usb_device_id ath3k_table[] = {
|
|||
{ USB_DEVICE(0x13d3, 0x3375) },
|
||||
{ USB_DEVICE(0x13d3, 0x3393) },
|
||||
{ USB_DEVICE(0x13d3, 0x3402) },
|
||||
{ USB_DEVICE(0x13d3, 0x3432) },
|
||||
|
||||
/* Atheros AR5BBU12 with sflash firmware */
|
||||
{ USB_DEVICE(0x0489, 0xE02C) },
|
||||
|
@ -140,7 +140,6 @@ static const struct usb_device_id ath3k_blist_tbl[] = {
|
|||
{ USB_DEVICE(0x0b05, 0x17d0), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x0CF3, 0x0036), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x0cf3, 0x3005), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x0cf3, 0x311D), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x0cf3, 0x311E), .driver_info = BTUSB_ATH3012 },
|
||||
|
@ -154,6 +153,7 @@ static const struct usb_device_id ath3k_blist_tbl[] = {
|
|||
{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x13d3, 0x3432), .driver_info = BTUSB_ATH3012 },
|
||||
|
||||
/* Atheros AR5BBU22 with sflash firmware */
|
||||
{ USB_DEVICE(0x0489, 0xE036), .driver_info = BTUSB_ATH3012 },
|
||||
|
@ -290,10 +290,10 @@ static int ath3k_load_fwfile(struct usb_device *udev,
|
|||
sent += size;
|
||||
count -= size;
|
||||
|
||||
pipe = usb_sndbulkpipe(udev, 0x02);
|
||||
|
||||
while (count) {
|
||||
size = min_t(uint, count, BULK_SIZE);
|
||||
pipe = usb_sndbulkpipe(udev, 0x02);
|
||||
|
||||
memcpy(send_buf, firmware->data + sent, size);
|
||||
|
||||
err = usb_bulk_msg(udev, pipe, send_buf, size,
|
||||
|
|
|
@ -68,6 +68,7 @@ struct btmrvl_adapter {
|
|||
u8 hs_state;
|
||||
u8 wakeup_tries;
|
||||
wait_queue_head_t cmd_wait_q;
|
||||
wait_queue_head_t event_hs_wait_q;
|
||||
u8 cmd_complete;
|
||||
bool is_suspended;
|
||||
};
|
||||
|
@ -89,6 +90,7 @@ struct btmrvl_private {
|
|||
#define MRVL_VENDOR_PKT 0xFE
|
||||
|
||||
/* Vendor specific Bluetooth commands */
|
||||
#define BT_CMD_PSCAN_WIN_REPORT_ENABLE 0xFC03
|
||||
#define BT_CMD_AUTO_SLEEP_MODE 0xFC23
|
||||
#define BT_CMD_HOST_SLEEP_CONFIG 0xFC59
|
||||
#define BT_CMD_HOST_SLEEP_ENABLE 0xFC5A
|
||||
|
@ -143,6 +145,7 @@ bool btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb);
|
|||
int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb);
|
||||
|
||||
int btmrvl_send_module_cfg_cmd(struct btmrvl_private *priv, u8 subcmd);
|
||||
int btmrvl_pscan_window_reporting(struct btmrvl_private *priv, u8 subcmd);
|
||||
int btmrvl_send_hscfg_cmd(struct btmrvl_private *priv);
|
||||
int btmrvl_enable_ps(struct btmrvl_private *priv);
|
||||
int btmrvl_prepare_command(struct btmrvl_private *priv);
|
||||
|
|
|
@ -114,6 +114,7 @@ int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb)
|
|||
adapter->hs_state = HS_ACTIVATED;
|
||||
if (adapter->psmode)
|
||||
adapter->ps_state = PS_SLEEP;
|
||||
wake_up_interruptible(&adapter->event_hs_wait_q);
|
||||
BT_DBG("HS ACTIVATED!");
|
||||
} else {
|
||||
BT_DBG("HS Enable failed");
|
||||
|
@ -214,6 +215,23 @@ int btmrvl_send_module_cfg_cmd(struct btmrvl_private *priv, u8 subcmd)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(btmrvl_send_module_cfg_cmd);
|
||||
|
||||
int btmrvl_pscan_window_reporting(struct btmrvl_private *priv, u8 subcmd)
|
||||
{
|
||||
struct btmrvl_sdio_card *card = priv->btmrvl_dev.card;
|
||||
int ret;
|
||||
|
||||
if (!card->support_pscan_win_report)
|
||||
return 0;
|
||||
|
||||
ret = btmrvl_send_sync_cmd(priv, BT_CMD_PSCAN_WIN_REPORT_ENABLE,
|
||||
&subcmd, 1);
|
||||
if (ret)
|
||||
BT_ERR("PSCAN_WIN_REPORT_ENABLE command failed: %#x", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(btmrvl_pscan_window_reporting);
|
||||
|
||||
int btmrvl_send_hscfg_cmd(struct btmrvl_private *priv)
|
||||
{
|
||||
int ret;
|
||||
|
@ -253,11 +271,31 @@ EXPORT_SYMBOL_GPL(btmrvl_enable_ps);
|
|||
|
||||
int btmrvl_enable_hs(struct btmrvl_private *priv)
|
||||
{
|
||||
struct btmrvl_adapter *adapter = priv->adapter;
|
||||
int ret;
|
||||
|
||||
ret = btmrvl_send_sync_cmd(priv, BT_CMD_HOST_SLEEP_ENABLE, NULL, 0);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
BT_ERR("Host sleep enable command failed\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = wait_event_interruptible_timeout(adapter->event_hs_wait_q,
|
||||
adapter->hs_state,
|
||||
msecs_to_jiffies(WAIT_UNTIL_HS_STATE_CHANGED));
|
||||
if (ret < 0) {
|
||||
BT_ERR("event_hs_wait_q terminated (%d): %d,%d,%d",
|
||||
ret, adapter->hs_state, adapter->ps_state,
|
||||
adapter->wakeup_tries);
|
||||
} else if (!ret) {
|
||||
BT_ERR("hs_enable timeout: %d,%d,%d", adapter->hs_state,
|
||||
adapter->ps_state, adapter->wakeup_tries);
|
||||
ret = -ETIMEDOUT;
|
||||
} else {
|
||||
BT_DBG("host sleep enabled: %d,%d,%d", adapter->hs_state,
|
||||
adapter->ps_state, adapter->wakeup_tries);
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -358,6 +396,7 @@ static void btmrvl_init_adapter(struct btmrvl_private *priv)
|
|||
}
|
||||
|
||||
init_waitqueue_head(&priv->adapter->cmd_wait_q);
|
||||
init_waitqueue_head(&priv->adapter->event_hs_wait_q);
|
||||
}
|
||||
|
||||
static void btmrvl_free_adapter(struct btmrvl_private *priv)
|
||||
|
@ -489,6 +528,8 @@ static int btmrvl_setup(struct hci_dev *hdev)
|
|||
|
||||
btmrvl_cal_data_dt(priv);
|
||||
|
||||
btmrvl_pscan_window_reporting(priv, 0x01);
|
||||
|
||||
priv->btmrvl_dev.psmode = 1;
|
||||
btmrvl_enable_ps(priv);
|
||||
|
||||
|
@ -666,6 +707,7 @@ int btmrvl_remove_card(struct btmrvl_private *priv)
|
|||
hdev = priv->btmrvl_dev.hcidev;
|
||||
|
||||
wake_up_interruptible(&priv->adapter->cmd_wait_q);
|
||||
wake_up_interruptible(&priv->adapter->event_hs_wait_q);
|
||||
|
||||
kthread_stop(priv->main_thread.task);
|
||||
|
||||
|
|
|
@ -108,6 +108,7 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8688 = {
|
|||
.helper = "mrvl/sd8688_helper.bin",
|
||||
.firmware = "mrvl/sd8688.bin",
|
||||
.reg = &btmrvl_reg_8688,
|
||||
.support_pscan_win_report = false,
|
||||
.sd_blksz_fw_dl = 64,
|
||||
};
|
||||
|
||||
|
@ -115,6 +116,7 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8787 = {
|
|||
.helper = NULL,
|
||||
.firmware = "mrvl/sd8787_uapsta.bin",
|
||||
.reg = &btmrvl_reg_87xx,
|
||||
.support_pscan_win_report = false,
|
||||
.sd_blksz_fw_dl = 256,
|
||||
};
|
||||
|
||||
|
@ -122,6 +124,7 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8797 = {
|
|||
.helper = NULL,
|
||||
.firmware = "mrvl/sd8797_uapsta.bin",
|
||||
.reg = &btmrvl_reg_87xx,
|
||||
.support_pscan_win_report = false,
|
||||
.sd_blksz_fw_dl = 256,
|
||||
};
|
||||
|
||||
|
@ -129,6 +132,7 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8897 = {
|
|||
.helper = NULL,
|
||||
.firmware = "mrvl/sd8897_uapsta.bin",
|
||||
.reg = &btmrvl_reg_88xx,
|
||||
.support_pscan_win_report = true,
|
||||
.sd_blksz_fw_dl = 256,
|
||||
};
|
||||
|
||||
|
@ -1067,6 +1071,7 @@ static int btmrvl_sdio_probe(struct sdio_func *func,
|
|||
card->firmware = data->firmware;
|
||||
card->reg = data->reg;
|
||||
card->sd_blksz_fw_dl = data->sd_blksz_fw_dl;
|
||||
card->support_pscan_win_report = data->support_pscan_win_report;
|
||||
}
|
||||
|
||||
if (btmrvl_sdio_register_dev(card) < 0) {
|
||||
|
|
|
@ -89,6 +89,7 @@ struct btmrvl_sdio_card {
|
|||
const char *helper;
|
||||
const char *firmware;
|
||||
const struct btmrvl_sdio_card_reg *reg;
|
||||
bool support_pscan_win_report;
|
||||
u16 sd_blksz_fw_dl;
|
||||
u8 rx_unit;
|
||||
struct btmrvl_private *priv;
|
||||
|
@ -98,6 +99,7 @@ struct btmrvl_sdio_device {
|
|||
const char *helper;
|
||||
const char *firmware;
|
||||
const struct btmrvl_sdio_card_reg *reg;
|
||||
const bool support_pscan_win_report;
|
||||
u16 sd_blksz_fw_dl;
|
||||
};
|
||||
|
||||
|
|
|
@ -30,9 +30,6 @@
|
|||
|
||||
#define VERSION "0.6"
|
||||
|
||||
static bool ignore_dga;
|
||||
static bool ignore_csr;
|
||||
static bool ignore_sniffer;
|
||||
static bool disable_scofix;
|
||||
static bool force_scofix;
|
||||
|
||||
|
@ -49,7 +46,8 @@ static struct usb_driver btusb_driver;
|
|||
#define BTUSB_WRONG_SCO_MTU 0x40
|
||||
#define BTUSB_ATH3012 0x80
|
||||
#define BTUSB_INTEL 0x100
|
||||
#define BTUSB_BCM_PATCHRAM 0x200
|
||||
#define BTUSB_INTEL_BOOT 0x200
|
||||
#define BTUSB_BCM_PATCHRAM 0x400
|
||||
|
||||
static const struct usb_device_id btusb_table[] = {
|
||||
/* Generic Bluetooth USB device */
|
||||
|
@ -121,6 +119,10 @@ static const struct usb_device_id btusb_table[] = {
|
|||
/* IMC Networks - Broadcom based */
|
||||
{ USB_VENDOR_AND_INTERFACE_INFO(0x13d3, 0xff, 0x01, 0x01) },
|
||||
|
||||
/* Intel Bluetooth USB Bootloader (RAM module) */
|
||||
{ USB_DEVICE(0x8087, 0x0a5a),
|
||||
.driver_info = BTUSB_INTEL_BOOT | BTUSB_BROKEN_ISOC },
|
||||
|
||||
{ } /* Terminating entry */
|
||||
};
|
||||
|
||||
|
@ -162,7 +164,6 @@ static const struct usb_device_id blacklist_table[] = {
|
|||
{ USB_DEVICE(0x0b05, 0x17d0), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x0cf3, 0x0036), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x0cf3, 0x3005), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x0cf3, 0x311e), .driver_info = BTUSB_ATH3012 },
|
||||
|
@ -176,6 +177,7 @@ static const struct usb_device_id blacklist_table[] = {
|
|||
{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x13d3, 0x3432), .driver_info = BTUSB_ATH3012 },
|
||||
|
||||
/* Atheros AR5BBU12 with sflash firmware */
|
||||
{ USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE },
|
||||
|
@ -229,10 +231,12 @@ static const struct usb_device_id blacklist_table[] = {
|
|||
{ USB_DEVICE(0x08fd, 0x0002), .driver_info = BTUSB_IGNORE },
|
||||
|
||||
/* CSR BlueCore Bluetooth Sniffer */
|
||||
{ USB_DEVICE(0x0a12, 0x0002), .driver_info = BTUSB_SNIFFER },
|
||||
{ USB_DEVICE(0x0a12, 0x0002),
|
||||
.driver_info = BTUSB_SNIFFER | BTUSB_BROKEN_ISOC },
|
||||
|
||||
/* Frontline ComProbe Bluetooth Sniffer */
|
||||
{ USB_DEVICE(0x16d3, 0x0002), .driver_info = BTUSB_SNIFFER },
|
||||
{ USB_DEVICE(0x16d3, 0x0002),
|
||||
.driver_info = BTUSB_SNIFFER | BTUSB_BROKEN_ISOC },
|
||||
|
||||
/* Intel Bluetooth device */
|
||||
{ USB_DEVICE(0x8087, 0x07dc), .driver_info = BTUSB_INTEL },
|
||||
|
@ -1183,6 +1187,51 @@ static int btusb_setup_intel_patching(struct hci_dev *hdev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
#define BDADDR_INTEL (&(bdaddr_t) {{0x00, 0x8b, 0x9e, 0x19, 0x03, 0x00}})
|
||||
|
||||
static int btusb_check_bdaddr_intel(struct hci_dev *hdev)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
struct hci_rp_read_bd_addr *rp;
|
||||
|
||||
skb = __hci_cmd_sync(hdev, HCI_OP_READ_BD_ADDR, 0, NULL,
|
||||
HCI_INIT_TIMEOUT);
|
||||
if (IS_ERR(skb)) {
|
||||
BT_ERR("%s reading Intel device address failed (%ld)",
|
||||
hdev->name, PTR_ERR(skb));
|
||||
return PTR_ERR(skb);
|
||||
}
|
||||
|
||||
if (skb->len != sizeof(*rp)) {
|
||||
BT_ERR("%s Intel device address length mismatch", hdev->name);
|
||||
kfree_skb(skb);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
rp = (struct hci_rp_read_bd_addr *) skb->data;
|
||||
if (rp->status) {
|
||||
BT_ERR("%s Intel device address result failed (%02x)",
|
||||
hdev->name, rp->status);
|
||||
kfree_skb(skb);
|
||||
return -bt_to_errno(rp->status);
|
||||
}
|
||||
|
||||
/* For some Intel based controllers, the default Bluetooth device
|
||||
* address 00:03:19:9E:8B:00 can be found. These controllers are
|
||||
* fully operational, but have the danger of duplicate addresses
|
||||
* and that in turn can cause problems with Bluetooth operation.
|
||||
*/
|
||||
if (!bacmp(&rp->bdaddr, BDADDR_INTEL)) {
|
||||
BT_ERR("%s found Intel default device address (%pMR)",
|
||||
hdev->name, &rp->bdaddr);
|
||||
set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks);
|
||||
}
|
||||
|
||||
kfree_skb(skb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int btusb_setup_intel(struct hci_dev *hdev)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
@ -1255,6 +1304,7 @@ static int btusb_setup_intel(struct hci_dev *hdev)
|
|||
BT_INFO("%s: Intel device is already patched. patch num: %02x",
|
||||
hdev->name, ver->fw_patch_num);
|
||||
kfree_skb(skb);
|
||||
btusb_check_bdaddr_intel(hdev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1267,6 +1317,7 @@ static int btusb_setup_intel(struct hci_dev *hdev)
|
|||
fw = btusb_setup_intel_get_fw(hdev, ver);
|
||||
if (!fw) {
|
||||
kfree_skb(skb);
|
||||
btusb_check_bdaddr_intel(hdev);
|
||||
return 0;
|
||||
}
|
||||
fw_ptr = fw->data;
|
||||
|
@ -1346,6 +1397,7 @@ static int btusb_setup_intel(struct hci_dev *hdev)
|
|||
BT_INFO("%s: Intel Bluetooth firmware patch completed and activated",
|
||||
hdev->name);
|
||||
|
||||
btusb_check_bdaddr_intel(hdev);
|
||||
return 0;
|
||||
|
||||
exit_mfg_disable:
|
||||
|
@ -1360,6 +1412,8 @@ static int btusb_setup_intel(struct hci_dev *hdev)
|
|||
kfree_skb(skb);
|
||||
|
||||
BT_INFO("%s: Intel Bluetooth firmware patch completed", hdev->name);
|
||||
|
||||
btusb_check_bdaddr_intel(hdev);
|
||||
return 0;
|
||||
|
||||
exit_mfg_deactivate:
|
||||
|
@ -1380,9 +1434,29 @@ static int btusb_setup_intel(struct hci_dev *hdev)
|
|||
BT_INFO("%s: Intel Bluetooth firmware patch completed and deactivated",
|
||||
hdev->name);
|
||||
|
||||
btusb_check_bdaddr_intel(hdev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int btusb_set_bdaddr_intel(struct hci_dev *hdev, const bdaddr_t *bdaddr)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
long ret;
|
||||
|
||||
skb = __hci_cmd_sync(hdev, 0xfc31, 6, bdaddr, HCI_INIT_TIMEOUT);
|
||||
if (IS_ERR(skb)) {
|
||||
ret = PTR_ERR(skb);
|
||||
BT_ERR("%s: changing Intel device address failed (%ld)",
|
||||
hdev->name, ret);
|
||||
return ret;
|
||||
}
|
||||
kfree_skb(skb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define BDADDR_BCM20702A0 (&(bdaddr_t) {{0x00, 0xa0, 0x02, 0x70, 0x20, 0x00}})
|
||||
|
||||
static int btusb_setup_bcm_patchram(struct hci_dev *hdev)
|
||||
{
|
||||
struct btusb_data *data = hci_get_drvdata(hdev);
|
||||
|
@ -1396,6 +1470,7 @@ static int btusb_setup_bcm_patchram(struct hci_dev *hdev)
|
|||
u16 opcode;
|
||||
struct sk_buff *skb;
|
||||
struct hci_rp_read_local_version *ver;
|
||||
struct hci_rp_read_bd_addr *bda;
|
||||
long ret;
|
||||
|
||||
snprintf(fw_name, sizeof(fw_name), "brcm/%s-%04x-%04x.hcd",
|
||||
|
@ -1405,8 +1480,7 @@ static int btusb_setup_bcm_patchram(struct hci_dev *hdev)
|
|||
|
||||
ret = request_firmware(&fw, fw_name, &hdev->dev);
|
||||
if (ret < 0) {
|
||||
BT_INFO("%s: BCM: patch %s not found", hdev->name,
|
||||
fw_name);
|
||||
BT_INFO("%s: BCM: patch %s not found", hdev->name, fw_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1525,12 +1599,67 @@ static int btusb_setup_bcm_patchram(struct hci_dev *hdev)
|
|||
ver->lmp_ver, ver->lmp_subver);
|
||||
kfree_skb(skb);
|
||||
|
||||
/* Read BD Address */
|
||||
skb = __hci_cmd_sync(hdev, HCI_OP_READ_BD_ADDR, 0, NULL,
|
||||
HCI_INIT_TIMEOUT);
|
||||
if (IS_ERR(skb)) {
|
||||
ret = PTR_ERR(skb);
|
||||
BT_ERR("%s: HCI_OP_READ_BD_ADDR failed (%ld)",
|
||||
hdev->name, ret);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (skb->len != sizeof(*bda)) {
|
||||
BT_ERR("%s: HCI_OP_READ_BD_ADDR event length mismatch",
|
||||
hdev->name);
|
||||
kfree_skb(skb);
|
||||
ret = -EIO;
|
||||
goto done;
|
||||
}
|
||||
|
||||
bda = (struct hci_rp_read_bd_addr *) skb->data;
|
||||
if (bda->status) {
|
||||
BT_ERR("%s: HCI_OP_READ_BD_ADDR error status (%02x)",
|
||||
hdev->name, bda->status);
|
||||
kfree_skb(skb);
|
||||
ret = -bt_to_errno(bda->status);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* The address 00:20:70:02:A0:00 indicates a BCM20702A0 controller
|
||||
* with no configured address.
|
||||
*/
|
||||
if (!bacmp(&bda->bdaddr, BDADDR_BCM20702A0)) {
|
||||
BT_INFO("%s: BCM: using default device address (%pMR)",
|
||||
hdev->name, &bda->bdaddr);
|
||||
set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks);
|
||||
}
|
||||
|
||||
kfree_skb(skb);
|
||||
|
||||
done:
|
||||
release_firmware(fw);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int btusb_set_bdaddr_bcm(struct hci_dev *hdev, const bdaddr_t *bdaddr)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
long ret;
|
||||
|
||||
skb = __hci_cmd_sync(hdev, 0xfc01, 6, bdaddr, HCI_INIT_TIMEOUT);
|
||||
if (IS_ERR(skb)) {
|
||||
ret = PTR_ERR(skb);
|
||||
BT_ERR("%s: BCM: Change address command failed (%ld)",
|
||||
hdev->name, ret);
|
||||
return ret;
|
||||
}
|
||||
kfree_skb(skb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int btusb_probe(struct usb_interface *intf,
|
||||
const struct usb_device_id *id)
|
||||
{
|
||||
|
@ -1555,15 +1684,6 @@ static int btusb_probe(struct usb_interface *intf,
|
|||
if (id->driver_info == BTUSB_IGNORE)
|
||||
return -ENODEV;
|
||||
|
||||
if (ignore_dga && id->driver_info & BTUSB_DIGIANSWER)
|
||||
return -ENODEV;
|
||||
|
||||
if (ignore_csr && id->driver_info & BTUSB_CSR)
|
||||
return -ENODEV;
|
||||
|
||||
if (ignore_sniffer && id->driver_info & BTUSB_SNIFFER)
|
||||
return -ENODEV;
|
||||
|
||||
if (id->driver_info & BTUSB_ATH3012) {
|
||||
struct usb_device *udev = interface_to_usbdev(intf);
|
||||
|
||||
|
@ -1636,11 +1756,18 @@ static int btusb_probe(struct usb_interface *intf,
|
|||
if (id->driver_info & BTUSB_BCM92035)
|
||||
hdev->setup = btusb_setup_bcm92035;
|
||||
|
||||
if (id->driver_info & BTUSB_BCM_PATCHRAM)
|
||||
if (id->driver_info & BTUSB_BCM_PATCHRAM) {
|
||||
hdev->setup = btusb_setup_bcm_patchram;
|
||||
hdev->set_bdaddr = btusb_set_bdaddr_bcm;
|
||||
}
|
||||
|
||||
if (id->driver_info & BTUSB_INTEL)
|
||||
if (id->driver_info & BTUSB_INTEL) {
|
||||
hdev->setup = btusb_setup_intel;
|
||||
hdev->set_bdaddr = btusb_set_bdaddr_intel;
|
||||
}
|
||||
|
||||
if (id->driver_info & BTUSB_INTEL_BOOT)
|
||||
set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);
|
||||
|
||||
/* Interface numbers are hardcoded in the specification */
|
||||
data->isoc = usb_ifnum_to_if(data->udev, 1);
|
||||
|
@ -1680,8 +1807,18 @@ static int btusb_probe(struct usb_interface *intf,
|
|||
/* New sniffer firmware has crippled HCI interface */
|
||||
if (le16_to_cpu(udev->descriptor.bcdDevice) > 0x997)
|
||||
set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);
|
||||
}
|
||||
|
||||
data->isoc = NULL;
|
||||
if (id->driver_info & BTUSB_INTEL_BOOT) {
|
||||
/* A bug in the bootloader causes that interrupt interface is
|
||||
* only enabled after receiving SetInterface(0, AltSetting=0).
|
||||
*/
|
||||
err = usb_set_interface(data->udev, 0, 0);
|
||||
if (err < 0) {
|
||||
BT_ERR("failed to set interface 0, alt 0 %d", err);
|
||||
hci_free_dev(hdev);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
if (data->isoc) {
|
||||
|
@ -1846,15 +1983,6 @@ static struct usb_driver btusb_driver = {
|
|||
|
||||
module_usb_driver(btusb_driver);
|
||||
|
||||
module_param(ignore_dga, bool, 0644);
|
||||
MODULE_PARM_DESC(ignore_dga, "Ignore devices with id 08fd:0001");
|
||||
|
||||
module_param(ignore_csr, bool, 0644);
|
||||
MODULE_PARM_DESC(ignore_csr, "Ignore devices with id 0a12:0001");
|
||||
|
||||
module_param(ignore_sniffer, bool, 0644);
|
||||
MODULE_PARM_DESC(ignore_sniffer, "Ignore devices with id 0a12:0002");
|
||||
|
||||
module_param(disable_scofix, bool, 0644);
|
||||
MODULE_PARM_DESC(disable_scofix, "Disable fixup of wrong SCO buffer size");
|
||||
|
||||
|
|
|
@ -355,10 +355,7 @@ static void h5_complete_rx_pkt(struct hci_uart *hu)
|
|||
|
||||
static int h5_rx_crc(struct hci_uart *hu, unsigned char c)
|
||||
{
|
||||
struct h5 *h5 = hu->priv;
|
||||
|
||||
h5_complete_rx_pkt(hu);
|
||||
h5_reset_rx(h5);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -373,7 +370,6 @@ static int h5_rx_payload(struct hci_uart *hu, unsigned char c)
|
|||
h5->rx_pending = 2;
|
||||
} else {
|
||||
h5_complete_rx_pkt(hu);
|
||||
h5_reset_rx(h5);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -406,6 +402,7 @@ static int h5_rx_3wire_hdr(struct hci_uart *hu, unsigned char c)
|
|||
H5_HDR_PKT_TYPE(hdr) != HCI_3WIRE_LINK_PKT) {
|
||||
BT_ERR("Non-link packet received in non-active state");
|
||||
h5_reset_rx(h5);
|
||||
return 0;
|
||||
}
|
||||
|
||||
h5->rx_func = h5_rx_payload;
|
||||
|
|
|
@ -431,6 +431,9 @@ static int hci_uart_register_dev(struct hci_uart *hu)
|
|||
if (test_bit(HCI_UART_RAW_DEVICE, &hu->hdev_flags))
|
||||
set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);
|
||||
|
||||
if (test_bit(HCI_UART_EXT_CONFIG, &hu->hdev_flags))
|
||||
set_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks);
|
||||
|
||||
if (!test_bit(HCI_UART_RESET_ON_INIT, &hu->hdev_flags))
|
||||
set_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks);
|
||||
|
||||
|
@ -477,6 +480,22 @@ static int hci_uart_set_proto(struct hci_uart *hu, int id)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int hci_uart_set_flags(struct hci_uart *hu, unsigned long flags)
|
||||
{
|
||||
unsigned long valid_flags = BIT(HCI_UART_RAW_DEVICE) |
|
||||
BIT(HCI_UART_RESET_ON_INIT) |
|
||||
BIT(HCI_UART_CREATE_AMP) |
|
||||
BIT(HCI_UART_INIT_PENDING) |
|
||||
BIT(HCI_UART_EXT_CONFIG);
|
||||
|
||||
if ((flags & ~valid_flags))
|
||||
return -EINVAL;
|
||||
|
||||
hu->hdev_flags = flags;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* hci_uart_tty_ioctl()
|
||||
*
|
||||
* Process IOCTL system call for the tty device.
|
||||
|
@ -520,14 +539,16 @@ static int hci_uart_tty_ioctl(struct tty_struct *tty, struct file * file,
|
|||
return -EUNATCH;
|
||||
|
||||
case HCIUARTGETDEVICE:
|
||||
if (test_bit(HCI_UART_PROTO_SET, &hu->flags))
|
||||
if (test_bit(HCI_UART_REGISTERED, &hu->flags))
|
||||
return hu->hdev->id;
|
||||
return -EUNATCH;
|
||||
|
||||
case HCIUARTSETFLAGS:
|
||||
if (test_bit(HCI_UART_PROTO_SET, &hu->flags))
|
||||
return -EBUSY;
|
||||
hu->hdev_flags = arg;
|
||||
err = hci_uart_set_flags(hu, arg);
|
||||
if (err)
|
||||
return err;
|
||||
break;
|
||||
|
||||
case HCIUARTGETFLAGS:
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#define HCI_UART_RESET_ON_INIT 1
|
||||
#define HCI_UART_CREATE_AMP 2
|
||||
#define HCI_UART_INIT_PENDING 3
|
||||
#define HCI_UART_EXT_CONFIG 4
|
||||
|
||||
struct hci_uart;
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
#include <net/bluetooth/bluetooth.h>
|
||||
#include <net/bluetooth/hci_core.h>
|
||||
|
||||
#define VERSION "1.4"
|
||||
#define VERSION "1.5"
|
||||
|
||||
static bool amp;
|
||||
|
||||
|
@ -95,10 +95,21 @@ static int vhci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int vhci_create_device(struct vhci_data *data, __u8 dev_type)
|
||||
static int vhci_create_device(struct vhci_data *data, __u8 opcode)
|
||||
{
|
||||
struct hci_dev *hdev;
|
||||
struct sk_buff *skb;
|
||||
__u8 dev_type;
|
||||
|
||||
/* bits 0-1 are dev_type (BR/EDR or AMP) */
|
||||
dev_type = opcode & 0x03;
|
||||
|
||||
if (dev_type != HCI_BREDR && dev_type != HCI_AMP)
|
||||
return -EINVAL;
|
||||
|
||||
/* bits 2-5 are reserved (must be zero) */
|
||||
if (opcode & 0x3c)
|
||||
return -EINVAL;
|
||||
|
||||
skb = bt_skb_alloc(4, GFP_KERNEL);
|
||||
if (!skb)
|
||||
|
@ -121,6 +132,14 @@ static int vhci_create_device(struct vhci_data *data, __u8 dev_type)
|
|||
hdev->flush = vhci_flush;
|
||||
hdev->send = vhci_send_frame;
|
||||
|
||||
/* bit 6 is for external configuration */
|
||||
if (opcode & 0x40)
|
||||
set_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks);
|
||||
|
||||
/* bit 7 is for raw device */
|
||||
if (opcode & 0x80)
|
||||
set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);
|
||||
|
||||
if (hci_register_dev(hdev) < 0) {
|
||||
BT_ERR("Can't register HCI device");
|
||||
hci_free_dev(hdev);
|
||||
|
@ -132,7 +151,7 @@ static int vhci_create_device(struct vhci_data *data, __u8 dev_type)
|
|||
bt_cb(skb)->pkt_type = HCI_VENDOR_PKT;
|
||||
|
||||
*skb_put(skb, 1) = 0xff;
|
||||
*skb_put(skb, 1) = dev_type;
|
||||
*skb_put(skb, 1) = opcode;
|
||||
put_unaligned_le16(hdev->id, skb_put(skb, 2));
|
||||
skb_queue_tail(&data->readq, skb);
|
||||
|
||||
|
@ -146,7 +165,7 @@ static inline ssize_t vhci_get_user(struct vhci_data *data,
|
|||
{
|
||||
size_t len = iov_length(iov, count);
|
||||
struct sk_buff *skb;
|
||||
__u8 pkt_type, dev_type;
|
||||
__u8 pkt_type, opcode;
|
||||
unsigned long i;
|
||||
int ret;
|
||||
|
||||
|
@ -190,7 +209,7 @@ static inline ssize_t vhci_get_user(struct vhci_data *data,
|
|||
|
||||
cancel_delayed_work_sync(&data->open_timeout);
|
||||
|
||||
dev_type = *((__u8 *) skb->data);
|
||||
opcode = *((__u8 *) skb->data);
|
||||
skb_pull(skb, 1);
|
||||
|
||||
if (skb->len > 0) {
|
||||
|
@ -200,10 +219,7 @@ static inline ssize_t vhci_get_user(struct vhci_data *data,
|
|||
|
||||
kfree_skb(skb);
|
||||
|
||||
if (dev_type != HCI_BREDR && dev_type != HCI_AMP)
|
||||
return -EINVAL;
|
||||
|
||||
ret = vhci_create_device(data, dev_type);
|
||||
ret = vhci_create_device(data, opcode);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -603,16 +603,19 @@ static int ath10k_ce_completed_send_next_nolock(struct ath10k_ce_pipe *ce_state,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
src_ring->hw_index =
|
||||
ath10k_ce_src_ring_read_index_get(ar, ctrl_addr);
|
||||
src_ring->hw_index &= nentries_mask;
|
||||
read_index = ath10k_ce_src_ring_read_index_get(ar, ctrl_addr);
|
||||
if (read_index == 0xffffffff)
|
||||
return -ENODEV;
|
||||
|
||||
read_index &= nentries_mask;
|
||||
src_ring->hw_index = read_index;
|
||||
|
||||
ath10k_pci_sleep(ar);
|
||||
}
|
||||
|
||||
read_index = src_ring->hw_index;
|
||||
|
||||
if ((read_index == sw_index) || (read_index == 0xffffffff))
|
||||
if (read_index == sw_index)
|
||||
return -EIO;
|
||||
|
||||
sbase = src_ring->shadow_base;
|
||||
|
|
|
@ -795,10 +795,14 @@ int ath10k_core_start(struct ath10k *ar)
|
|||
if (status)
|
||||
goto err_htc_stop;
|
||||
|
||||
ar->free_vdev_map = (1 << TARGET_NUM_VDEVS) - 1;
|
||||
if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features))
|
||||
ar->free_vdev_map = (1 << TARGET_10X_NUM_VDEVS) - 1;
|
||||
else
|
||||
ar->free_vdev_map = (1 << TARGET_NUM_VDEVS) - 1;
|
||||
|
||||
INIT_LIST_HEAD(&ar->arvifs);
|
||||
|
||||
if (!test_bit(ATH10K_FLAG_FIRST_BOOT_DONE, &ar->dev_flags))
|
||||
if (!test_bit(ATH10K_FLAG_FIRST_BOOT_DONE, &ar->dev_flags)) {
|
||||
ath10k_info("%s (0x%08x, 0x%08x) fw %s api %d htt %d.%d\n",
|
||||
ar->hw_params.name,
|
||||
ar->target_version,
|
||||
|
@ -807,6 +811,12 @@ int ath10k_core_start(struct ath10k *ar)
|
|||
ar->fw_api,
|
||||
ar->htt.target_version_major,
|
||||
ar->htt.target_version_minor);
|
||||
ath10k_info("debug %d debugfs %d tracing %d dfs %d\n",
|
||||
config_enabled(CONFIG_ATH10K_DEBUG),
|
||||
config_enabled(CONFIG_ATH10K_DEBUGFS),
|
||||
config_enabled(CONFIG_ATH10K_TRACING),
|
||||
config_enabled(CONFIG_ATH10K_DFS_CERTIFIED));
|
||||
}
|
||||
|
||||
__set_bit(ATH10K_FLAG_FIRST_BOOT_DONE, &ar->dev_flags);
|
||||
|
||||
|
@ -984,7 +994,9 @@ static void ath10k_core_register_work(struct work_struct *work)
|
|||
err_release_fw:
|
||||
ath10k_core_free_firmware_files(ar);
|
||||
err:
|
||||
device_release_driver(ar->dev);
|
||||
/* TODO: It's probably a good idea to release device from the driver
|
||||
* but calling device_release_driver() here will cause a deadlock.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -290,6 +290,9 @@ struct ath10k_debug {
|
|||
struct ath_dfs_pool_stats dfs_pool_stats;
|
||||
|
||||
u32 fw_dbglog_mask;
|
||||
|
||||
u8 htt_max_amsdu;
|
||||
u8 htt_max_ampdu;
|
||||
};
|
||||
|
||||
enum ath10k_state {
|
||||
|
|
|
@ -671,6 +671,72 @@ static const struct file_operations fops_htt_stats_mask = {
|
|||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
static ssize_t ath10k_read_htt_max_amsdu_ampdu(struct file *file,
|
||||
char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct ath10k *ar = file->private_data;
|
||||
char buf[64];
|
||||
u8 amsdu = 3, ampdu = 64;
|
||||
unsigned int len;
|
||||
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
|
||||
if (ar->debug.htt_max_amsdu)
|
||||
amsdu = ar->debug.htt_max_amsdu;
|
||||
|
||||
if (ar->debug.htt_max_ampdu)
|
||||
ampdu = ar->debug.htt_max_ampdu;
|
||||
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
|
||||
len = scnprintf(buf, sizeof(buf), "%u %u\n", amsdu, ampdu);
|
||||
|
||||
return simple_read_from_buffer(user_buf, count, ppos, buf, len);
|
||||
}
|
||||
|
||||
static ssize_t ath10k_write_htt_max_amsdu_ampdu(struct file *file,
|
||||
const char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct ath10k *ar = file->private_data;
|
||||
int res;
|
||||
char buf[64];
|
||||
unsigned int amsdu, ampdu;
|
||||
|
||||
simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count);
|
||||
|
||||
/* make sure that buf is null terminated */
|
||||
buf[sizeof(buf) - 1] = 0;
|
||||
|
||||
res = sscanf(buf, "%u %u", &amsdu, &du);
|
||||
|
||||
if (res != 2)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
|
||||
res = ath10k_htt_h2t_aggr_cfg_msg(&ar->htt, ampdu, amsdu);
|
||||
if (res)
|
||||
goto out;
|
||||
|
||||
res = count;
|
||||
ar->debug.htt_max_amsdu = amsdu;
|
||||
ar->debug.htt_max_ampdu = ampdu;
|
||||
|
||||
out:
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
return res;
|
||||
}
|
||||
|
||||
static const struct file_operations fops_htt_max_amsdu_ampdu = {
|
||||
.read = ath10k_read_htt_max_amsdu_ampdu,
|
||||
.write = ath10k_write_htt_max_amsdu_ampdu,
|
||||
.open = simple_open,
|
||||
.owner = THIS_MODULE,
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
static ssize_t ath10k_read_fw_dbglog(struct file *file,
|
||||
char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
|
@ -757,6 +823,9 @@ void ath10k_debug_stop(struct ath10k *ar)
|
|||
* warning from del_timer(). */
|
||||
if (ar->debug.htt_stats_mask != 0)
|
||||
cancel_delayed_work(&ar->debug.htt_stats_dwork);
|
||||
|
||||
ar->debug.htt_max_amsdu = 0;
|
||||
ar->debug.htt_max_ampdu = 0;
|
||||
}
|
||||
|
||||
static ssize_t ath10k_write_simulate_radar(struct file *file,
|
||||
|
@ -867,6 +936,10 @@ int ath10k_debug_create(struct ath10k *ar)
|
|||
debugfs_create_file("htt_stats_mask", S_IRUSR, ar->debug.debugfs_phy,
|
||||
ar, &fops_htt_stats_mask);
|
||||
|
||||
debugfs_create_file("htt_max_amsdu_ampdu", S_IRUSR | S_IWUSR,
|
||||
ar->debug.debugfs_phy, ar,
|
||||
&fops_htt_max_amsdu_ampdu);
|
||||
|
||||
debugfs_create_file("fw_dbglog", S_IRUSR, ar->debug.debugfs_phy,
|
||||
ar, &fops_fw_dbglog);
|
||||
|
||||
|
|
|
@ -240,16 +240,10 @@ struct htt_oob_sync_req {
|
|||
__le16 rsvd0;
|
||||
} __packed;
|
||||
|
||||
#define HTT_AGGR_CONF_MAX_NUM_AMSDU_SUBFRAMES_MASK 0x1F
|
||||
#define HTT_AGGR_CONF_MAX_NUM_AMSDU_SUBFRAMES_LSB 0
|
||||
|
||||
struct htt_aggr_conf {
|
||||
u8 max_num_ampdu_subframes;
|
||||
union {
|
||||
/* dont use bitfields; undefined behaviour */
|
||||
u8 flags; /* see %HTT_AGGR_CONF_MAX_NUM_AMSDU_SUBFRAMES_ */
|
||||
u8 max_num_amsdu_subframes:5;
|
||||
} __packed;
|
||||
/* amsdu_subframes is limited by 0x1F mask */
|
||||
u8 max_num_amsdu_subframes;
|
||||
} __packed;
|
||||
|
||||
#define HTT_MGMT_FRM_HDR_DOWNLOAD_LEN 32
|
||||
|
@ -1343,6 +1337,9 @@ void ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb);
|
|||
int ath10k_htt_h2t_ver_req_msg(struct ath10k_htt *htt);
|
||||
int ath10k_htt_h2t_stats_req(struct ath10k_htt *htt, u8 mask, u64 cookie);
|
||||
int ath10k_htt_send_rx_ring_cfg_ll(struct ath10k_htt *htt);
|
||||
int ath10k_htt_h2t_aggr_cfg_msg(struct ath10k_htt *htt,
|
||||
u8 max_subfrms_ampdu,
|
||||
u8 max_subfrms_amsdu);
|
||||
|
||||
void __ath10k_htt_tx_dec_pending(struct ath10k_htt *htt);
|
||||
int ath10k_htt_tx_alloc_msdu_id(struct ath10k_htt *htt);
|
||||
|
|
|
@ -312,7 +312,6 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt,
|
|||
int msdu_len, msdu_chaining = 0;
|
||||
struct sk_buff *msdu;
|
||||
struct htt_rx_desc *rx_desc;
|
||||
bool corrupted = false;
|
||||
|
||||
lockdep_assert_held(&htt->rx_ring.lock);
|
||||
|
||||
|
@ -439,9 +438,6 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt,
|
|||
last_msdu = __le32_to_cpu(rx_desc->msdu_end.info0) &
|
||||
RX_MSDU_END_INFO0_LAST_MSDU;
|
||||
|
||||
if (msdu_chaining && !last_msdu)
|
||||
corrupted = true;
|
||||
|
||||
if (last_msdu) {
|
||||
msdu->next = NULL;
|
||||
break;
|
||||
|
@ -456,20 +452,6 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt,
|
|||
if (*head_msdu == NULL)
|
||||
msdu_chaining = -1;
|
||||
|
||||
/*
|
||||
* Apparently FW sometimes reports weird chained MSDU sequences with
|
||||
* more than one rx descriptor. This seems like a bug but needs more
|
||||
* analyzing. For the time being fix it by dropping such sequences to
|
||||
* avoid blowing up the host system.
|
||||
*/
|
||||
if (corrupted) {
|
||||
ath10k_warn("failed to pop chained msdus, dropping\n");
|
||||
ath10k_htt_rx_free_msdu_chain(*head_msdu);
|
||||
*head_msdu = NULL;
|
||||
*tail_msdu = NULL;
|
||||
msdu_chaining = -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Don't refill the ring yet.
|
||||
*
|
||||
|
|
|
@ -307,6 +307,52 @@ int ath10k_htt_send_rx_ring_cfg_ll(struct ath10k_htt *htt)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int ath10k_htt_h2t_aggr_cfg_msg(struct ath10k_htt *htt,
|
||||
u8 max_subfrms_ampdu,
|
||||
u8 max_subfrms_amsdu)
|
||||
{
|
||||
struct htt_aggr_conf *aggr_conf;
|
||||
struct sk_buff *skb;
|
||||
struct htt_cmd *cmd;
|
||||
int len;
|
||||
int ret;
|
||||
|
||||
/* Firmware defaults are: amsdu = 3 and ampdu = 64 */
|
||||
|
||||
if (max_subfrms_ampdu == 0 || max_subfrms_ampdu > 64)
|
||||
return -EINVAL;
|
||||
|
||||
if (max_subfrms_amsdu == 0 || max_subfrms_amsdu > 31)
|
||||
return -EINVAL;
|
||||
|
||||
len = sizeof(cmd->hdr);
|
||||
len += sizeof(cmd->aggr_conf);
|
||||
|
||||
skb = ath10k_htc_alloc_skb(len);
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
skb_put(skb, len);
|
||||
cmd = (struct htt_cmd *)skb->data;
|
||||
cmd->hdr.msg_type = HTT_H2T_MSG_TYPE_AGGR_CFG;
|
||||
|
||||
aggr_conf = &cmd->aggr_conf;
|
||||
aggr_conf->max_num_ampdu_subframes = max_subfrms_ampdu;
|
||||
aggr_conf->max_num_amsdu_subframes = max_subfrms_amsdu;
|
||||
|
||||
ath10k_dbg(ATH10K_DBG_HTT, "htt h2t aggr cfg msg amsdu %d ampdu %d",
|
||||
aggr_conf->max_num_amsdu_subframes,
|
||||
aggr_conf->max_num_ampdu_subframes);
|
||||
|
||||
ret = ath10k_htc_send(&htt->ar->htc, htt->eid, skb);
|
||||
if (ret) {
|
||||
dev_kfree_skb_any(skb);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
|
||||
{
|
||||
struct device *dev = htt->ar->dev;
|
||||
|
|
|
@ -1362,8 +1362,6 @@ static int ath10k_pci_hif_exchange_bmi_msg(struct ath10k *ar,
|
|||
ath10k_ce_recv_buf_enqueue(ce_rx, &xfer, resp_paddr);
|
||||
}
|
||||
|
||||
init_completion(&xfer.done);
|
||||
|
||||
ret = ath10k_ce_send(ce_tx, &xfer, req_paddr, req_len, -1, 0);
|
||||
if (ret)
|
||||
goto err_resp;
|
||||
|
@ -1414,10 +1412,7 @@ static void ath10k_pci_bmi_send_done(struct ath10k_ce_pipe *ce_state)
|
|||
&nbytes, &transfer_id))
|
||||
return;
|
||||
|
||||
if (xfer->wait_for_resp)
|
||||
return;
|
||||
|
||||
complete(&xfer->done);
|
||||
xfer->tx_done = true;
|
||||
}
|
||||
|
||||
static void ath10k_pci_bmi_recv_data(struct ath10k_ce_pipe *ce_state)
|
||||
|
@ -1438,7 +1433,7 @@ static void ath10k_pci_bmi_recv_data(struct ath10k_ce_pipe *ce_state)
|
|||
}
|
||||
|
||||
xfer->resp_len = nbytes;
|
||||
complete(&xfer->done);
|
||||
xfer->rx_done = true;
|
||||
}
|
||||
|
||||
static int ath10k_pci_bmi_wait(struct ath10k_ce_pipe *tx_pipe,
|
||||
|
@ -1451,7 +1446,7 @@ static int ath10k_pci_bmi_wait(struct ath10k_ce_pipe *tx_pipe,
|
|||
ath10k_pci_bmi_send_done(tx_pipe);
|
||||
ath10k_pci_bmi_recv_data(rx_pipe);
|
||||
|
||||
if (completion_done(&xfer->done))
|
||||
if (xfer->tx_done && (xfer->rx_done == xfer->wait_for_resp))
|
||||
return 0;
|
||||
|
||||
schedule();
|
||||
|
|
|
@ -38,7 +38,8 @@
|
|||
#define DIAG_TRANSFER_LIMIT 2048
|
||||
|
||||
struct bmi_xfer {
|
||||
struct completion done;
|
||||
bool tx_done;
|
||||
bool rx_done;
|
||||
bool wait_for_resp;
|
||||
u32 resp_len;
|
||||
};
|
||||
|
|
|
@ -2106,7 +2106,6 @@ static void ath10k_wmi_main_process_rx(struct ath10k *ar, struct sk_buff *skb)
|
|||
{
|
||||
struct wmi_cmd_hdr *cmd_hdr;
|
||||
enum wmi_event_id id;
|
||||
u16 len;
|
||||
|
||||
cmd_hdr = (struct wmi_cmd_hdr *)skb->data;
|
||||
id = MS(__le32_to_cpu(cmd_hdr->cmd_id), WMI_CMD_HDR_CMD_ID);
|
||||
|
@ -2114,8 +2113,6 @@ static void ath10k_wmi_main_process_rx(struct ath10k *ar, struct sk_buff *skb)
|
|||
if (skb_pull(skb, sizeof(struct wmi_cmd_hdr)) == NULL)
|
||||
return;
|
||||
|
||||
len = skb->len;
|
||||
|
||||
trace_ath10k_wmi_event(id, skb->data, skb->len);
|
||||
|
||||
switch (id) {
|
||||
|
@ -2225,7 +2222,6 @@ static void ath10k_wmi_10x_process_rx(struct ath10k *ar, struct sk_buff *skb)
|
|||
{
|
||||
struct wmi_cmd_hdr *cmd_hdr;
|
||||
enum wmi_10x_event_id id;
|
||||
u16 len;
|
||||
|
||||
cmd_hdr = (struct wmi_cmd_hdr *)skb->data;
|
||||
id = MS(__le32_to_cpu(cmd_hdr->cmd_id), WMI_CMD_HDR_CMD_ID);
|
||||
|
@ -2233,8 +2229,6 @@ static void ath10k_wmi_10x_process_rx(struct ath10k *ar, struct sk_buff *skb)
|
|||
if (skb_pull(skb, sizeof(struct wmi_cmd_hdr)) == NULL)
|
||||
return;
|
||||
|
||||
len = skb->len;
|
||||
|
||||
trace_ath10k_wmi_event(id, skb->data, skb->len);
|
||||
|
||||
switch (id) {
|
||||
|
|
|
@ -242,7 +242,8 @@ struct ath6kl_bmi_target_info {
|
|||
(void) (check_type == val); \
|
||||
addr = ath6kl_get_hi_item_addr(ar, HI_ITEM(item)); \
|
||||
ret = ath6kl_bmi_read(ar, addr, (u8 *) &tmp, 4); \
|
||||
*val = le32_to_cpu(tmp); \
|
||||
if (!ret) \
|
||||
*val = le32_to_cpu(tmp); \
|
||||
ret; \
|
||||
})
|
||||
|
||||
|
|
|
@ -2899,7 +2899,8 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev,
|
|||
if (info->inactivity_timeout) {
|
||||
inactivity_timeout = info->inactivity_timeout;
|
||||
|
||||
if (ar->hw.flags & ATH6KL_HW_AP_INACTIVITY_MINS)
|
||||
if (test_bit(ATH6KL_FW_CAPABILITY_AP_INACTIVITY_MINS,
|
||||
ar->fw_capabilities))
|
||||
inactivity_timeout = DIV_ROUND_UP(inactivity_timeout,
|
||||
60);
|
||||
|
||||
|
@ -3782,7 +3783,8 @@ int ath6kl_cfg80211_init(struct ath6kl *ar)
|
|||
ath6kl_band_5ghz.ht_cap.ht_supported = false;
|
||||
}
|
||||
|
||||
if (ar->hw.flags & ATH6KL_HW_64BIT_RATES) {
|
||||
if (test_bit(ATH6KL_FW_CAPABILITY_64BIT_RATES,
|
||||
ar->fw_capabilities)) {
|
||||
ath6kl_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
|
||||
ath6kl_band_5ghz.ht_cap.mcs.rx_mask[0] = 0xff;
|
||||
ath6kl_band_2ghz.ht_cap.mcs.rx_mask[1] = 0xff;
|
||||
|
|
|
@ -123,6 +123,22 @@ int ath6kl_core_init(struct ath6kl *ar, enum ath6kl_htc_type htc_type)
|
|||
|
||||
/* FIXME: we should free all firmwares in the error cases below */
|
||||
|
||||
/*
|
||||
* Backwards compatibility support for older ar6004 firmware images
|
||||
* which do not set these feature flags.
|
||||
*/
|
||||
if (ar->target_type == TARGET_TYPE_AR6004 &&
|
||||
ar->fw_api <= 4) {
|
||||
__set_bit(ATH6KL_FW_CAPABILITY_64BIT_RATES,
|
||||
ar->fw_capabilities);
|
||||
__set_bit(ATH6KL_FW_CAPABILITY_AP_INACTIVITY_MINS,
|
||||
ar->fw_capabilities);
|
||||
|
||||
if (ar->hw.id == AR6004_HW_1_3_VERSION)
|
||||
__set_bit(ATH6KL_FW_CAPABILITY_MAP_LP_ENDPOINT,
|
||||
ar->fw_capabilities);
|
||||
}
|
||||
|
||||
/* Indicate that WMI is enabled (although not ready yet) */
|
||||
set_bit(WMI_ENABLED, &ar->flag);
|
||||
ar->wmi = ath6kl_wmi_init(ar);
|
||||
|
|
|
@ -136,6 +136,21 @@ enum ath6kl_fw_capability {
|
|||
*/
|
||||
ATH6KL_FW_CAPABILITY_HEART_BEAT_POLL,
|
||||
|
||||
/* WMI_SET_TX_SELECT_RATES_CMDID uses 64 bit size rate table */
|
||||
ATH6KL_FW_CAPABILITY_64BIT_RATES,
|
||||
|
||||
/* WMI_AP_CONN_INACT_CMDID uses minutes as units */
|
||||
ATH6KL_FW_CAPABILITY_AP_INACTIVITY_MINS,
|
||||
|
||||
/* use low priority endpoint for all data */
|
||||
ATH6KL_FW_CAPABILITY_MAP_LP_ENDPOINT,
|
||||
|
||||
/* ratetable is the 2 stream version (max MCS15) */
|
||||
ATH6KL_FW_CAPABILITY_RATETABLE_MCS15,
|
||||
|
||||
/* firmare doesn't support IP checksumming */
|
||||
ATH6KL_FW_CAPABILITY_NO_IP_CHECKSUM,
|
||||
|
||||
/* this needs to be last */
|
||||
ATH6KL_FW_CAPABILITY_MAX,
|
||||
};
|
||||
|
@ -149,15 +164,13 @@ struct ath6kl_fw_ie {
|
|||
};
|
||||
|
||||
enum ath6kl_hw_flags {
|
||||
ATH6KL_HW_64BIT_RATES = BIT(0),
|
||||
ATH6KL_HW_AP_INACTIVITY_MINS = BIT(1),
|
||||
ATH6KL_HW_MAP_LP_ENDPOINT = BIT(2),
|
||||
ATH6KL_HW_SDIO_CRC_ERROR_WAR = BIT(3),
|
||||
};
|
||||
|
||||
#define ATH6KL_FW_API2_FILE "fw-2.bin"
|
||||
#define ATH6KL_FW_API3_FILE "fw-3.bin"
|
||||
#define ATH6KL_FW_API4_FILE "fw-4.bin"
|
||||
#define ATH6KL_FW_API5_FILE "fw-5.bin"
|
||||
|
||||
/* AR6003 1.0 definitions */
|
||||
#define AR6003_HW_1_0_VERSION 0x300002ba
|
||||
|
@ -215,8 +228,21 @@ enum ath6kl_hw_flags {
|
|||
#define AR6004_HW_1_3_VERSION 0x31c8088a
|
||||
#define AR6004_HW_1_3_FW_DIR "ath6k/AR6004/hw1.3"
|
||||
#define AR6004_HW_1_3_FIRMWARE_FILE "fw.ram.bin"
|
||||
#define AR6004_HW_1_3_BOARD_DATA_FILE "ath6k/AR6004/hw1.3/bdata.bin"
|
||||
#define AR6004_HW_1_3_DEFAULT_BOARD_DATA_FILE "ath6k/AR6004/hw1.3/bdata.bin"
|
||||
#define AR6004_HW_1_3_TCMD_FIRMWARE_FILE "utf.bin"
|
||||
#define AR6004_HW_1_3_UTF_FIRMWARE_FILE "utf.bin"
|
||||
#define AR6004_HW_1_3_TESTSCRIPT_FILE "nullTestFlow.bin"
|
||||
#define AR6004_HW_1_3_BOARD_DATA_FILE AR6004_HW_1_3_FW_DIR "/bdata.bin"
|
||||
#define AR6004_HW_1_3_DEFAULT_BOARD_DATA_FILE AR6004_HW_1_3_FW_DIR "/bdata.bin"
|
||||
|
||||
/* AR6004 3.0 definitions */
|
||||
#define AR6004_HW_3_0_VERSION 0x31C809F8
|
||||
#define AR6004_HW_3_0_FW_DIR "ath6k/AR6004/hw3.0"
|
||||
#define AR6004_HW_3_0_FIRMWARE_FILE "fw.ram.bin"
|
||||
#define AR6004_HW_3_0_TCMD_FIRMWARE_FILE "utf.bin"
|
||||
#define AR6004_HW_3_0_UTF_FIRMWARE_FILE "utf.bin"
|
||||
#define AR6004_HW_3_0_TESTSCRIPT_FILE "nullTestFlow.bin"
|
||||
#define AR6004_HW_3_0_BOARD_DATA_FILE AR6004_HW_3_0_FW_DIR "/bdata.bin"
|
||||
#define AR6004_HW_3_0_DEFAULT_BOARD_DATA_FILE AR6004_HW_3_0_FW_DIR "/bdata.bin"
|
||||
|
||||
/* Per STA data, used in AP mode */
|
||||
#define STA_PS_AWAKE BIT(0)
|
||||
|
|
|
@ -1170,8 +1170,12 @@ static int htc_wait_recv_ctrl_message(struct htc_target *target)
|
|||
static void htc_rxctrl_complete(struct htc_target *context,
|
||||
struct htc_packet *packet)
|
||||
{
|
||||
/* TODO, can't really receive HTC control messages yet.... */
|
||||
ath6kl_dbg(ATH6KL_DBG_HTC, "%s: invalid call function\n", __func__);
|
||||
struct sk_buff *skb = packet->skb;
|
||||
|
||||
if (packet->endpoint == ENDPOINT_0 &&
|
||||
packet->status == -ECANCELED &&
|
||||
skb != NULL)
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
|
||||
/* htc pipe initialization */
|
||||
|
@ -1678,7 +1682,29 @@ static void ath6kl_htc_pipe_activity_changed(struct htc_target *target,
|
|||
|
||||
static void ath6kl_htc_pipe_flush_rx_buf(struct htc_target *target)
|
||||
{
|
||||
/* TODO */
|
||||
struct htc_endpoint *endpoint;
|
||||
struct htc_packet *packet, *tmp_pkt;
|
||||
int i;
|
||||
|
||||
for (i = ENDPOINT_0; i < ENDPOINT_MAX; i++) {
|
||||
endpoint = &target->endpoint[i];
|
||||
|
||||
spin_lock_bh(&target->rx_lock);
|
||||
|
||||
list_for_each_entry_safe(packet, tmp_pkt,
|
||||
&endpoint->rx_bufq, list) {
|
||||
list_del(&packet->list);
|
||||
spin_unlock_bh(&target->rx_lock);
|
||||
ath6kl_dbg(ATH6KL_DBG_HTC,
|
||||
"htc rx flush pkt 0x%p len %d ep %d\n",
|
||||
packet, packet->buf_len,
|
||||
packet->endpoint);
|
||||
dev_kfree_skb(packet->pkt_cntxt);
|
||||
spin_lock_bh(&target->rx_lock);
|
||||
}
|
||||
|
||||
spin_unlock_bh(&target->rx_lock);
|
||||
}
|
||||
}
|
||||
|
||||
static int ath6kl_htc_pipe_credit_setup(struct htc_target *target,
|
||||
|
|
|
@ -93,8 +93,7 @@ static const struct ath6kl_hw hw_list[] = {
|
|||
.board_addr = 0x433900,
|
||||
.refclk_hz = 26000000,
|
||||
.uarttx_pin = 11,
|
||||
.flags = ATH6KL_HW_64BIT_RATES |
|
||||
ATH6KL_HW_AP_INACTIVITY_MINS,
|
||||
.flags = 0,
|
||||
|
||||
.fw = {
|
||||
.dir = AR6004_HW_1_0_FW_DIR,
|
||||
|
@ -114,8 +113,7 @@ static const struct ath6kl_hw hw_list[] = {
|
|||
.board_addr = 0x43d400,
|
||||
.refclk_hz = 40000000,
|
||||
.uarttx_pin = 11,
|
||||
.flags = ATH6KL_HW_64BIT_RATES |
|
||||
ATH6KL_HW_AP_INACTIVITY_MINS,
|
||||
.flags = 0,
|
||||
.fw = {
|
||||
.dir = AR6004_HW_1_1_FW_DIR,
|
||||
.fw = AR6004_HW_1_1_FIRMWARE_FILE,
|
||||
|
@ -134,8 +132,7 @@ static const struct ath6kl_hw hw_list[] = {
|
|||
.board_addr = 0x435c00,
|
||||
.refclk_hz = 40000000,
|
||||
.uarttx_pin = 11,
|
||||
.flags = ATH6KL_HW_64BIT_RATES |
|
||||
ATH6KL_HW_AP_INACTIVITY_MINS,
|
||||
.flags = 0,
|
||||
|
||||
.fw = {
|
||||
.dir = AR6004_HW_1_2_FW_DIR,
|
||||
|
@ -152,20 +149,43 @@ static const struct ath6kl_hw hw_list[] = {
|
|||
.board_ext_data_addr = 0x437000,
|
||||
.reserved_ram_size = 7168,
|
||||
.board_addr = 0x436400,
|
||||
.refclk_hz = 40000000,
|
||||
.refclk_hz = 0,
|
||||
.uarttx_pin = 11,
|
||||
.flags = ATH6KL_HW_64BIT_RATES |
|
||||
ATH6KL_HW_AP_INACTIVITY_MINS |
|
||||
ATH6KL_HW_MAP_LP_ENDPOINT,
|
||||
.flags = 0,
|
||||
|
||||
.fw = {
|
||||
.dir = AR6004_HW_1_3_FW_DIR,
|
||||
.fw = AR6004_HW_1_3_FIRMWARE_FILE,
|
||||
.tcmd = AR6004_HW_1_3_TCMD_FIRMWARE_FILE,
|
||||
.utf = AR6004_HW_1_3_UTF_FIRMWARE_FILE,
|
||||
.testscript = AR6004_HW_1_3_TESTSCRIPT_FILE,
|
||||
},
|
||||
|
||||
.fw_board = AR6004_HW_1_3_BOARD_DATA_FILE,
|
||||
.fw_default_board = AR6004_HW_1_3_DEFAULT_BOARD_DATA_FILE,
|
||||
},
|
||||
{
|
||||
.id = AR6004_HW_3_0_VERSION,
|
||||
.name = "ar6004 hw 3.0",
|
||||
.dataset_patch_addr = 0,
|
||||
.app_load_addr = 0x1234,
|
||||
.board_ext_data_addr = 0,
|
||||
.reserved_ram_size = 7168,
|
||||
.board_addr = 0x436400,
|
||||
.testscript_addr = 0,
|
||||
.flags = 0,
|
||||
|
||||
.fw = {
|
||||
.dir = AR6004_HW_3_0_FW_DIR,
|
||||
.fw = AR6004_HW_3_0_FIRMWARE_FILE,
|
||||
.tcmd = AR6004_HW_3_0_TCMD_FIRMWARE_FILE,
|
||||
.utf = AR6004_HW_3_0_UTF_FIRMWARE_FILE,
|
||||
.testscript = AR6004_HW_3_0_TESTSCRIPT_FILE,
|
||||
},
|
||||
|
||||
.fw_board = AR6004_HW_3_0_BOARD_DATA_FILE,
|
||||
.fw_default_board = AR6004_HW_3_0_DEFAULT_BOARD_DATA_FILE,
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -601,7 +621,9 @@ int ath6kl_configure_target(struct ath6kl *ar)
|
|||
* but possible in theory.
|
||||
*/
|
||||
|
||||
if (ar->target_type == TARGET_TYPE_AR6003) {
|
||||
if ((ar->target_type == TARGET_TYPE_AR6003) ||
|
||||
(ar->version.target_ver == AR6004_HW_1_3_VERSION) ||
|
||||
(ar->version.target_ver == AR6004_HW_3_0_VERSION)) {
|
||||
param = ar->hw.board_ext_data_addr;
|
||||
ram_reserved_size = ar->hw.reserved_ram_size;
|
||||
|
||||
|
@ -629,9 +651,12 @@ int ath6kl_configure_target(struct ath6kl *ar)
|
|||
return status;
|
||||
|
||||
/* Configure target refclk_hz */
|
||||
status = ath6kl_bmi_write_hi32(ar, hi_refclk_hz, ar->hw.refclk_hz);
|
||||
if (status)
|
||||
return status;
|
||||
if (ar->hw.refclk_hz != 0) {
|
||||
status = ath6kl_bmi_write_hi32(ar, hi_refclk_hz,
|
||||
ar->hw.refclk_hz);
|
||||
if (status)
|
||||
return status;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1112,6 +1137,12 @@ int ath6kl_init_fetch_firmwares(struct ath6kl *ar)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = ath6kl_fetch_fw_apin(ar, ATH6KL_FW_API5_FILE);
|
||||
if (ret == 0) {
|
||||
ar->fw_api = 5;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = ath6kl_fetch_fw_apin(ar, ATH6KL_FW_API4_FILE);
|
||||
if (ret == 0) {
|
||||
ar->fw_api = 4;
|
||||
|
@ -1161,11 +1192,19 @@ static int ath6kl_upload_board_file(struct ath6kl *ar)
|
|||
ath6kl_bmi_write_hi32(ar, hi_board_data,
|
||||
board_address);
|
||||
} else {
|
||||
ath6kl_bmi_read_hi32(ar, hi_board_data, &board_address);
|
||||
ret = ath6kl_bmi_read_hi32(ar, hi_board_data, &board_address);
|
||||
if (ret) {
|
||||
ath6kl_err("Failed to get board file target address.\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* determine where in target ram to write extended board data */
|
||||
ath6kl_bmi_read_hi32(ar, hi_board_ext_data, &board_ext_address);
|
||||
ret = ath6kl_bmi_read_hi32(ar, hi_board_ext_data, &board_ext_address);
|
||||
if (ret) {
|
||||
ath6kl_err("Failed to get extended board file target address.\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (ar->target_type == TARGET_TYPE_AR6003 &&
|
||||
board_ext_address == 0) {
|
||||
|
@ -1230,7 +1269,13 @@ static int ath6kl_upload_board_file(struct ath6kl *ar)
|
|||
}
|
||||
|
||||
/* record the fact that Board Data IS initialized */
|
||||
ath6kl_bmi_write_hi32(ar, hi_board_data_initialized, 1);
|
||||
if ((ar->version.target_ver == AR6004_HW_1_3_VERSION) ||
|
||||
(ar->version.target_ver == AR6004_HW_3_0_VERSION))
|
||||
param = board_data_size;
|
||||
else
|
||||
param = 1;
|
||||
|
||||
ath6kl_bmi_write_hi32(ar, hi_board_data_initialized, param);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -1361,7 +1406,11 @@ static int ath6kl_upload_testscript(struct ath6kl *ar)
|
|||
}
|
||||
|
||||
ath6kl_bmi_write_hi32(ar, hi_ota_testscript, address);
|
||||
ath6kl_bmi_write_hi32(ar, hi_end_ram_reserve_sz, 4096);
|
||||
|
||||
if ((ar->version.target_ver != AR6004_HW_1_3_VERSION) &&
|
||||
(ar->version.target_ver != AR6004_HW_3_0_VERSION))
|
||||
ath6kl_bmi_write_hi32(ar, hi_end_ram_reserve_sz, 4096);
|
||||
|
||||
ath6kl_bmi_write_hi32(ar, hi_test_apps_related, 1);
|
||||
|
||||
return 0;
|
||||
|
@ -1567,6 +1616,11 @@ static const struct fw_capa_str_map {
|
|||
{ ATH6KL_FW_CAPABILITY_REGDOMAIN, "regdomain" },
|
||||
{ ATH6KL_FW_CAPABILITY_SCHED_SCAN_V2, "sched-scan-v2" },
|
||||
{ ATH6KL_FW_CAPABILITY_HEART_BEAT_POLL, "hb-poll" },
|
||||
{ ATH6KL_FW_CAPABILITY_64BIT_RATES, "64bit-rates" },
|
||||
{ ATH6KL_FW_CAPABILITY_AP_INACTIVITY_MINS, "ap-inactivity-mins" },
|
||||
{ ATH6KL_FW_CAPABILITY_MAP_LP_ENDPOINT, "map-lp-endpoint" },
|
||||
{ ATH6KL_FW_CAPABILITY_RATETABLE_MCS15, "ratetable-mcs15" },
|
||||
{ ATH6KL_FW_CAPABILITY_NO_IP_CHECKSUM, "no-ip-checksum" },
|
||||
};
|
||||
|
||||
static const char *ath6kl_init_get_fw_capa_name(unsigned int id)
|
||||
|
|
|
@ -702,6 +702,7 @@ static void ath6kl_update_target_stats(struct ath6kl_vif *vif, u8 *ptr, u32 len)
|
|||
struct ath6kl *ar = vif->ar;
|
||||
struct target_stats *stats = &vif->target_stats;
|
||||
struct tkip_ccmp_stats *ccmp_stats;
|
||||
s32 rate;
|
||||
u8 ac;
|
||||
|
||||
if (len < sizeof(*tgt_stats))
|
||||
|
@ -731,8 +732,9 @@ static void ath6kl_update_target_stats(struct ath6kl_vif *vif, u8 *ptr, u32 len)
|
|||
le32_to_cpu(tgt_stats->stats.tx.mult_retry_cnt);
|
||||
stats->tx_rts_fail_cnt +=
|
||||
le32_to_cpu(tgt_stats->stats.tx.rts_fail_cnt);
|
||||
stats->tx_ucast_rate =
|
||||
ath6kl_wmi_get_rate(a_sle32_to_cpu(tgt_stats->stats.tx.ucast_rate));
|
||||
|
||||
rate = a_sle32_to_cpu(tgt_stats->stats.tx.ucast_rate);
|
||||
stats->tx_ucast_rate = ath6kl_wmi_get_rate(ar->wmi, rate);
|
||||
|
||||
stats->rx_pkt += le32_to_cpu(tgt_stats->stats.rx.pkt);
|
||||
stats->rx_byte += le32_to_cpu(tgt_stats->stats.rx.byte);
|
||||
|
@ -749,8 +751,9 @@ static void ath6kl_update_target_stats(struct ath6kl_vif *vif, u8 *ptr, u32 len)
|
|||
le32_to_cpu(tgt_stats->stats.rx.key_cache_miss);
|
||||
stats->rx_decrypt_err += le32_to_cpu(tgt_stats->stats.rx.decrypt_err);
|
||||
stats->rx_dupl_frame += le32_to_cpu(tgt_stats->stats.rx.dupl_frame);
|
||||
stats->rx_ucast_rate =
|
||||
ath6kl_wmi_get_rate(a_sle32_to_cpu(tgt_stats->stats.rx.ucast_rate));
|
||||
|
||||
rate = a_sle32_to_cpu(tgt_stats->stats.rx.ucast_rate);
|
||||
stats->rx_ucast_rate = ath6kl_wmi_get_rate(ar->wmi, rate);
|
||||
|
||||
ccmp_stats = &tgt_stats->stats.tkip_ccmp_stats;
|
||||
|
||||
|
@ -1290,6 +1293,8 @@ static const struct net_device_ops ath6kl_netdev_ops = {
|
|||
|
||||
void init_netdev(struct net_device *dev)
|
||||
{
|
||||
struct ath6kl *ar = ath6kl_priv(dev);
|
||||
|
||||
dev->netdev_ops = &ath6kl_netdev_ops;
|
||||
dev->destructor = free_netdev;
|
||||
dev->watchdog_timeo = ATH6KL_TX_TIMEOUT;
|
||||
|
@ -1301,7 +1306,9 @@ void init_netdev(struct net_device *dev)
|
|||
WMI_MAX_TX_META_SZ +
|
||||
ATH6KL_HTC_ALIGN_BYTES, 4);
|
||||
|
||||
dev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_RXCSUM;
|
||||
if (!test_bit(ATH6KL_FW_CAPABILITY_NO_IP_CHECKSUM,
|
||||
ar->fw_capabilities))
|
||||
dev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_RXCSUM;
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -802,7 +802,8 @@ static int ath6kl_usb_map_service_pipe(struct ath6kl *ar, u16 svc_id,
|
|||
break;
|
||||
case WMI_DATA_VI_SVC:
|
||||
|
||||
if (ar->hw.flags & ATH6KL_HW_MAP_LP_ENDPOINT)
|
||||
if (test_bit(ATH6KL_FW_CAPABILITY_MAP_LP_ENDPOINT,
|
||||
ar->fw_capabilities))
|
||||
*ul_pipe = ATH6KL_USB_PIPE_TX_DATA_LP;
|
||||
else
|
||||
*ul_pipe = ATH6KL_USB_PIPE_TX_DATA_MP;
|
||||
|
@ -814,7 +815,8 @@ static int ath6kl_usb_map_service_pipe(struct ath6kl *ar, u16 svc_id,
|
|||
break;
|
||||
case WMI_DATA_VO_SVC:
|
||||
|
||||
if (ar->hw.flags & ATH6KL_HW_MAP_LP_ENDPOINT)
|
||||
if (test_bit(ATH6KL_FW_CAPABILITY_MAP_LP_ENDPOINT,
|
||||
ar->fw_capabilities))
|
||||
*ul_pipe = ATH6KL_USB_PIPE_TX_DATA_LP;
|
||||
else
|
||||
*ul_pipe = ATH6KL_USB_PIPE_TX_DATA_MP;
|
||||
|
@ -1208,6 +1210,7 @@ static int ath6kl_usb_pm_reset_resume(struct usb_interface *intf)
|
|||
|
||||
/* table of devices that work with this driver */
|
||||
static struct usb_device_id ath6kl_usb_ids[] = {
|
||||
{USB_DEVICE(0x0cf3, 0x9375)},
|
||||
{USB_DEVICE(0x0cf3, 0x9374)},
|
||||
{ /* Terminating entry */ },
|
||||
};
|
||||
|
|
|
@ -59,6 +59,55 @@ static const s32 wmi_rate_tbl[][2] = {
|
|||
{0, 0}
|
||||
};
|
||||
|
||||
static const s32 wmi_rate_tbl_mcs15[][2] = {
|
||||
/* {W/O SGI, with SGI} */
|
||||
{1000, 1000},
|
||||
{2000, 2000},
|
||||
{5500, 5500},
|
||||
{11000, 11000},
|
||||
{6000, 6000},
|
||||
{9000, 9000},
|
||||
{12000, 12000},
|
||||
{18000, 18000},
|
||||
{24000, 24000},
|
||||
{36000, 36000},
|
||||
{48000, 48000},
|
||||
{54000, 54000},
|
||||
{6500, 7200}, /* HT 20, MCS 0 */
|
||||
{13000, 14400},
|
||||
{19500, 21700},
|
||||
{26000, 28900},
|
||||
{39000, 43300},
|
||||
{52000, 57800},
|
||||
{58500, 65000},
|
||||
{65000, 72200},
|
||||
{13000, 14400}, /* HT 20, MCS 8 */
|
||||
{26000, 28900},
|
||||
{39000, 43300},
|
||||
{52000, 57800},
|
||||
{78000, 86700},
|
||||
{104000, 115600},
|
||||
{117000, 130000},
|
||||
{130000, 144400}, /* HT 20, MCS 15 */
|
||||
{13500, 15000}, /*HT 40, MCS 0 */
|
||||
{27000, 30000},
|
||||
{40500, 45000},
|
||||
{54000, 60000},
|
||||
{81000, 90000},
|
||||
{108000, 120000},
|
||||
{121500, 135000},
|
||||
{135000, 150000},
|
||||
{27000, 30000}, /*HT 40, MCS 8 */
|
||||
{54000, 60000},
|
||||
{81000, 90000},
|
||||
{108000, 120000},
|
||||
{162000, 180000},
|
||||
{216000, 240000},
|
||||
{243000, 270000},
|
||||
{270000, 300000}, /*HT 40, MCS 15 */
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
/* 802.1d to AC mapping. Refer pg 57 of WMM-test-plan-v1.2 */
|
||||
static const u8 up_to_ac[] = {
|
||||
WMM_AC_BE,
|
||||
|
@ -2838,7 +2887,8 @@ int ath6kl_wmi_set_bitrate_mask(struct wmi *wmi, u8 if_idx,
|
|||
{
|
||||
struct ath6kl *ar = wmi->parent_dev;
|
||||
|
||||
if (ar->hw.flags & ATH6KL_HW_64BIT_RATES)
|
||||
if (test_bit(ATH6KL_FW_CAPABILITY_64BIT_RATES,
|
||||
ar->fw_capabilities))
|
||||
return ath6kl_set_bitrate_mask64(wmi, if_idx, mask);
|
||||
else
|
||||
return ath6kl_set_bitrate_mask32(wmi, if_idx, mask);
|
||||
|
@ -3279,9 +3329,11 @@ int ath6kl_wmi_set_regdomain_cmd(struct wmi *wmi, const char *alpha2)
|
|||
NO_SYNC_WMIFLAG);
|
||||
}
|
||||
|
||||
s32 ath6kl_wmi_get_rate(s8 rate_index)
|
||||
s32 ath6kl_wmi_get_rate(struct wmi *wmi, s8 rate_index)
|
||||
{
|
||||
struct ath6kl *ar = wmi->parent_dev;
|
||||
u8 sgi = 0;
|
||||
s32 ret;
|
||||
|
||||
if (rate_index == RATE_AUTO)
|
||||
return 0;
|
||||
|
@ -3292,10 +3344,20 @@ s32 ath6kl_wmi_get_rate(s8 rate_index)
|
|||
sgi = 1;
|
||||
}
|
||||
|
||||
if (WARN_ON(rate_index > RATE_MCS_7_40))
|
||||
rate_index = RATE_MCS_7_40;
|
||||
if (test_bit(ATH6KL_FW_CAPABILITY_RATETABLE_MCS15,
|
||||
ar->fw_capabilities)) {
|
||||
if (WARN_ON(rate_index >= ARRAY_SIZE(wmi_rate_tbl_mcs15)))
|
||||
return 0;
|
||||
|
||||
return wmi_rate_tbl[(u32) rate_index][sgi];
|
||||
ret = wmi_rate_tbl_mcs15[(u32) rate_index][sgi];
|
||||
} else {
|
||||
if (WARN_ON(rate_index >= ARRAY_SIZE(wmi_rate_tbl)))
|
||||
return 0;
|
||||
|
||||
ret = wmi_rate_tbl[(u32) rate_index][sgi];
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ath6kl_wmi_get_pmkid_list_event_rx(struct wmi *wmi, u8 *datap,
|
||||
|
|
|
@ -2632,7 +2632,7 @@ int ath6kl_wmi_set_htcap_cmd(struct wmi *wmi, u8 if_idx,
|
|||
struct ath6kl_htcap *htcap);
|
||||
int ath6kl_wmi_test_cmd(struct wmi *wmi, void *buf, size_t len);
|
||||
|
||||
s32 ath6kl_wmi_get_rate(s8 rate_index);
|
||||
s32 ath6kl_wmi_get_rate(struct wmi *wmi, s8 rate_index);
|
||||
|
||||
int ath6kl_wmi_set_ip_cmd(struct wmi *wmi, u8 if_idx,
|
||||
__be32 ips0, __be32 ips1);
|
||||
|
|
|
@ -281,7 +281,7 @@ ar9002_set_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_info *i)
|
|||
|
||||
ACCESS_ONCE(ads->ds_ctl0) = (i->pkt_len & AR_FrameLen)
|
||||
| (i->flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
|
||||
| SM(i->txpower, AR_XmitPower)
|
||||
| SM(i->txpower, AR_XmitPower0)
|
||||
| (i->flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
|
||||
| (i->flags & ATH9K_TXDESC_INTREQ ? AR_TxIntrReq : 0)
|
||||
| (i->keyix != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0)
|
||||
|
@ -306,6 +306,10 @@ ar9002_set_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_info *i)
|
|||
| set11nRateFlags(i->rates, 2)
|
||||
| set11nRateFlags(i->rates, 3)
|
||||
| SM(i->rtscts_rate, AR_RTSCTSRate);
|
||||
|
||||
ACCESS_ONCE(ads->ds_ctl9) = SM(i->txpower, AR_XmitPower1);
|
||||
ACCESS_ONCE(ads->ds_ctl10) = SM(i->txpower, AR_XmitPower2);
|
||||
ACCESS_ONCE(ads->ds_ctl11) = SM(i->txpower, AR_XmitPower3);
|
||||
}
|
||||
|
||||
static int ar9002_hw_proc_txdesc(struct ath_hw *ah, void *ds,
|
||||
|
|
|
@ -101,7 +101,7 @@ ar9003_set_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_info *i)
|
|||
|
||||
ACCESS_ONCE(ads->ctl11) = (i->pkt_len & AR_FrameLen)
|
||||
| (i->flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
|
||||
| SM(i->txpower, AR_XmitPower)
|
||||
| SM(i->txpower, AR_XmitPower0)
|
||||
| (i->flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
|
||||
| (i->keyix != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0)
|
||||
| (i->flags & ATH9K_TXDESC_LOWRXCHAIN ? AR_LowRxChain : 0)
|
||||
|
@ -151,6 +151,10 @@ ar9003_set_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_info *i)
|
|||
| SM(i->rtscts_rate, AR_RTSCTSRate);
|
||||
|
||||
ACCESS_ONCE(ads->ctl19) = AR_Not_Sounding;
|
||||
|
||||
ACCESS_ONCE(ads->ctl20) = SM(i->txpower, AR_XmitPower1);
|
||||
ACCESS_ONCE(ads->ctl21) = SM(i->txpower, AR_XmitPower2);
|
||||
ACCESS_ONCE(ads->ctl22) = SM(i->txpower, AR_XmitPower3);
|
||||
}
|
||||
|
||||
static u16 ar9003_calc_ptr_chksum(struct ar9003_txc *ads)
|
||||
|
|
|
@ -182,7 +182,8 @@ struct ath_atx_ac {
|
|||
|
||||
struct ath_frame_info {
|
||||
struct ath_buf *bf;
|
||||
int framelen;
|
||||
u16 framelen;
|
||||
s8 txq;
|
||||
enum ath9k_key_type keytype;
|
||||
u8 keyix;
|
||||
u8 rtscts_rate;
|
||||
|
|
|
@ -202,7 +202,7 @@ static ssize_t write_file_ani(struct file *file,
|
|||
if (kstrtoul(buf, 0, &ani))
|
||||
return -EINVAL;
|
||||
|
||||
if (ani < 0 || ani > 1)
|
||||
if (ani > 1)
|
||||
return -EINVAL;
|
||||
|
||||
common->disable_ani = !ani;
|
||||
|
|
|
@ -346,8 +346,14 @@ struct ar5416_desc {
|
|||
#define AR_FrameLen 0x00000fff
|
||||
#define AR_VirtMoreFrag 0x00001000
|
||||
#define AR_TxCtlRsvd00 0x0000e000
|
||||
#define AR_XmitPower 0x003f0000
|
||||
#define AR_XmitPower_S 16
|
||||
#define AR_XmitPower0 0x003f0000
|
||||
#define AR_XmitPower0_S 16
|
||||
#define AR_XmitPower1 0x3f000000
|
||||
#define AR_XmitPower1_S 24
|
||||
#define AR_XmitPower2 0x3f000000
|
||||
#define AR_XmitPower2_S 24
|
||||
#define AR_XmitPower3 0x3f000000
|
||||
#define AR_XmitPower3_S 24
|
||||
#define AR_RTSEnable 0x00400000
|
||||
#define AR_VEOL 0x00800000
|
||||
#define AR_ClrDestMask 0x01000000
|
||||
|
|
|
@ -313,7 +313,7 @@ static ssize_t write_file_spectral_short_repeat(struct file *file,
|
|||
if (kstrtoul(buf, 0, &val))
|
||||
return -EINVAL;
|
||||
|
||||
if (val < 0 || val > 1)
|
||||
if (val > 1)
|
||||
return -EINVAL;
|
||||
|
||||
sc->spec_config.short_repeat = val;
|
||||
|
@ -361,7 +361,7 @@ static ssize_t write_file_spectral_count(struct file *file,
|
|||
if (kstrtoul(buf, 0, &val))
|
||||
return -EINVAL;
|
||||
|
||||
if (val < 0 || val > 255)
|
||||
if (val > 255)
|
||||
return -EINVAL;
|
||||
|
||||
sc->spec_config.count = val;
|
||||
|
@ -409,7 +409,7 @@ static ssize_t write_file_spectral_period(struct file *file,
|
|||
if (kstrtoul(buf, 0, &val))
|
||||
return -EINVAL;
|
||||
|
||||
if (val < 0 || val > 255)
|
||||
if (val > 255)
|
||||
return -EINVAL;
|
||||
|
||||
sc->spec_config.period = val;
|
||||
|
@ -457,7 +457,7 @@ static ssize_t write_file_spectral_fft_period(struct file *file,
|
|||
if (kstrtoul(buf, 0, &val))
|
||||
return -EINVAL;
|
||||
|
||||
if (val < 0 || val > 15)
|
||||
if (val > 15)
|
||||
return -EINVAL;
|
||||
|
||||
sc->spec_config.fft_period = val;
|
||||
|
|
|
@ -157,15 +157,14 @@ static void ath_txq_skb_done(struct ath_softc *sc, struct ath_txq *txq,
|
|||
struct sk_buff *skb)
|
||||
{
|
||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||
int q, hw_queue;
|
||||
struct ath_frame_info *fi = get_frame_info(skb);
|
||||
int hw_queue;
|
||||
int q = fi->txq;
|
||||
|
||||
q = skb_get_queue_mapping(skb);
|
||||
if (txq == sc->tx.uapsdq)
|
||||
txq = sc->tx.txq_map[q];
|
||||
|
||||
if (txq != sc->tx.txq_map[q])
|
||||
if (q < 0)
|
||||
return;
|
||||
|
||||
txq = sc->tx.txq_map[q];
|
||||
if (WARN_ON(--txq->pending_frames < 0))
|
||||
txq->pending_frames = 0;
|
||||
|
||||
|
@ -2036,6 +2035,7 @@ static void setup_frame_info(struct ieee80211_hw *hw,
|
|||
an = (struct ath_node *) sta->drv_priv;
|
||||
|
||||
memset(fi, 0, sizeof(*fi));
|
||||
fi->txq = -1;
|
||||
if (hw_key)
|
||||
fi->keyix = hw_key->hw_key_idx;
|
||||
else if (an && ieee80211_is_data(hdr->frame_control) && an->ps_key > 0)
|
||||
|
@ -2187,6 +2187,7 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
|
|||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||
struct ieee80211_sta *sta = txctl->sta;
|
||||
struct ieee80211_vif *vif = info->control.vif;
|
||||
struct ath_frame_info *fi = get_frame_info(skb);
|
||||
struct ath_vif *avp = NULL;
|
||||
struct ath_softc *sc = hw->priv;
|
||||
struct ath_txq *txq = txctl->txq;
|
||||
|
@ -2216,11 +2217,13 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
|
|||
hw_queue = (info->hw_queue >= sc->hw->queues - 2) ? q : info->hw_queue;
|
||||
|
||||
ath_txq_lock(sc, txq);
|
||||
if (txq == sc->tx.txq_map[q] &&
|
||||
++txq->pending_frames > sc->tx.txq_max_pending[q] &&
|
||||
!txq->stopped) {
|
||||
ieee80211_stop_queue(sc->hw, hw_queue);
|
||||
txq->stopped = true;
|
||||
if (txq == sc->tx.txq_map[q]) {
|
||||
fi->txq = q;
|
||||
if (++txq->pending_frames > sc->tx.txq_max_pending[q] &&
|
||||
!txq->stopped) {
|
||||
ieee80211_stop_queue(sc->hw, hw_queue);
|
||||
txq->stopped = true;
|
||||
}
|
||||
}
|
||||
|
||||
queue = ieee80211_is_data_present(hdr->frame_control);
|
||||
|
|
|
@ -448,8 +448,10 @@ static ssize_t wil_write_file_rxon(struct file *file, const char __user *buf,
|
|||
char *kbuf = kmalloc(len + 1, GFP_KERNEL);
|
||||
if (!kbuf)
|
||||
return -ENOMEM;
|
||||
if (copy_from_user(kbuf, buf, len))
|
||||
if (copy_from_user(kbuf, buf, len)) {
|
||||
kfree(kbuf);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
kbuf[len] = '\0';
|
||||
rc = kstrtol(kbuf, 0, &channel);
|
||||
|
@ -963,6 +965,26 @@ static const struct file_operations fops_sta = {
|
|||
};
|
||||
|
||||
/*----------------*/
|
||||
static void wil6210_debugfs_init_blobs(struct wil6210_priv *wil,
|
||||
struct dentry *dbg)
|
||||
{
|
||||
int i;
|
||||
char name[32];
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(fw_mapping); i++) {
|
||||
struct debugfs_blob_wrapper *blob = &wil->blobs[i];
|
||||
const struct fw_map *map = &fw_mapping[i];
|
||||
|
||||
if (!map->name)
|
||||
continue;
|
||||
|
||||
blob->data = (void * __force)wil->csr + HOSTADDR(map->host);
|
||||
blob->size = map->to - map->from;
|
||||
snprintf(name, sizeof(name), "blob_%s", map->name);
|
||||
wil_debugfs_create_ioblob(name, S_IRUGO, dbg, blob);
|
||||
}
|
||||
}
|
||||
|
||||
int wil6210_debugfs_init(struct wil6210_priv *wil)
|
||||
{
|
||||
struct dentry *dbg = wil->debug = debugfs_create_dir(WIL_NAME,
|
||||
|
@ -986,6 +1008,8 @@ int wil6210_debugfs_init(struct wil6210_priv *wil)
|
|||
&wil->secure_pcp);
|
||||
wil_debugfs_create_ulong("status", S_IRUGO | S_IWUSR, dbg,
|
||||
&wil->status);
|
||||
debugfs_create_u32("fw_version", S_IRUGO, dbg, &wil->fw_version);
|
||||
debugfs_create_x32("hw_version", S_IRUGO, dbg, &wil->hw_version);
|
||||
|
||||
wil6210_debugfs_create_ISR(wil, "USER_ICR", dbg,
|
||||
HOSTADDR(RGF_USER_USER_ICR));
|
||||
|
@ -998,6 +1022,9 @@ int wil6210_debugfs_init(struct wil6210_priv *wil)
|
|||
wil6210_debugfs_create_pseudo_ISR(wil, dbg);
|
||||
wil6210_debugfs_create_ITR_CNT(wil, dbg);
|
||||
|
||||
wil_debugfs_create_iomem_x32("RGF_USER_USAGE_1", S_IRUGO, dbg,
|
||||
wil->csr +
|
||||
HOSTADDR(RGF_USER_USAGE_1));
|
||||
debugfs_create_u32("mem_addr", S_IRUGO | S_IWUSR, dbg, &mem_addr);
|
||||
debugfs_create_file("mem_val", S_IRUGO, dbg, wil, &fops_memread);
|
||||
|
||||
|
@ -1010,34 +1037,7 @@ int wil6210_debugfs_init(struct wil6210_priv *wil)
|
|||
debugfs_create_file("link", S_IRUGO, dbg, wil, &fops_link);
|
||||
debugfs_create_file("info", S_IRUGO, dbg, wil, &fops_info);
|
||||
|
||||
wil->rgf_blob.data = (void * __force)wil->csr + 0;
|
||||
wil->rgf_blob.size = 0xa000;
|
||||
wil_debugfs_create_ioblob("blob_rgf", S_IRUGO, dbg, &wil->rgf_blob);
|
||||
|
||||
wil->fw_code_blob.data = (void * __force)wil->csr + 0x40000;
|
||||
wil->fw_code_blob.size = 0x40000;
|
||||
wil_debugfs_create_ioblob("blob_fw_code", S_IRUGO, dbg,
|
||||
&wil->fw_code_blob);
|
||||
|
||||
wil->fw_data_blob.data = (void * __force)wil->csr + 0x80000;
|
||||
wil->fw_data_blob.size = 0x8000;
|
||||
wil_debugfs_create_ioblob("blob_fw_data", S_IRUGO, dbg,
|
||||
&wil->fw_data_blob);
|
||||
|
||||
wil->fw_peri_blob.data = (void * __force)wil->csr + 0x88000;
|
||||
wil->fw_peri_blob.size = 0x18000;
|
||||
wil_debugfs_create_ioblob("blob_fw_peri", S_IRUGO, dbg,
|
||||
&wil->fw_peri_blob);
|
||||
|
||||
wil->uc_code_blob.data = (void * __force)wil->csr + 0xa0000;
|
||||
wil->uc_code_blob.size = 0x10000;
|
||||
wil_debugfs_create_ioblob("blob_uc_code", S_IRUGO, dbg,
|
||||
&wil->uc_code_blob);
|
||||
|
||||
wil->uc_data_blob.data = (void * __force)wil->csr + 0xb0000;
|
||||
wil->uc_data_blob.size = 0x4000;
|
||||
wil_debugfs_create_ioblob("blob_uc_data", S_IRUGO, dbg,
|
||||
&wil->uc_data_blob);
|
||||
wil6210_debugfs_init_blobs(wil, dbg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -314,8 +314,9 @@ static void wil_target_reset(struct wil6210_priv *wil)
|
|||
int delay = 0;
|
||||
u32 hw_state;
|
||||
u32 rev_id;
|
||||
bool is_sparrow = (wil->board->board == WIL_BOARD_SPARROW);
|
||||
|
||||
wil_dbg_misc(wil, "Resetting...\n");
|
||||
wil_dbg_misc(wil, "Resetting \"%s\"...\n", wil->board->name);
|
||||
|
||||
/* register read */
|
||||
#define R(a) ioread32(wil->csr + HOSTADDR(a))
|
||||
|
@ -328,35 +329,59 @@ static void wil_target_reset(struct wil6210_priv *wil)
|
|||
|
||||
wil->hw_version = R(RGF_USER_FW_REV_ID);
|
||||
rev_id = wil->hw_version & 0xff;
|
||||
|
||||
/* Clear MAC link up */
|
||||
S(RGF_HP_CTRL, BIT(15));
|
||||
/* hpal_perst_from_pad_src_n_mask */
|
||||
S(RGF_USER_CLKS_CTL_SW_RST_MASK_0, BIT(6));
|
||||
/* car_perst_rst_src_n_mask */
|
||||
S(RGF_USER_CLKS_CTL_SW_RST_MASK_0, BIT(7));
|
||||
wmb(); /* order is important here */
|
||||
|
||||
if (is_sparrow) {
|
||||
W(RGF_USER_CLKS_CTL_EXT_SW_RST_VEC_0, 0x3ff81f);
|
||||
wmb(); /* order is important here */
|
||||
}
|
||||
|
||||
W(RGF_USER_MAC_CPU_0, BIT(1)); /* mac_cpu_man_rst */
|
||||
W(RGF_USER_USER_CPU_0, BIT(1)); /* user_cpu_man_rst */
|
||||
wmb(); /* order is important here */
|
||||
|
||||
W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0xFE000000);
|
||||
W(RGF_USER_CLKS_CTL_SW_RST_VEC_1, 0x0000003F);
|
||||
W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0x00000170);
|
||||
W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, is_sparrow ? 0x000000B0 : 0x00000170);
|
||||
W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0xFFE7FC00);
|
||||
wmb(); /* order is important here */
|
||||
|
||||
if (is_sparrow) {
|
||||
W(RGF_USER_CLKS_CTL_EXT_SW_RST_VEC_0, 0x0);
|
||||
wmb(); /* order is important here */
|
||||
}
|
||||
|
||||
W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0);
|
||||
W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0);
|
||||
W(RGF_USER_CLKS_CTL_SW_RST_VEC_1, 0);
|
||||
W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0);
|
||||
wmb(); /* order is important here */
|
||||
|
||||
W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0x00000001);
|
||||
if (rev_id == 1) {
|
||||
W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0x00000080);
|
||||
} else {
|
||||
W(RGF_PCIE_LOS_COUNTER_CTL, BIT(6) | BIT(8));
|
||||
if (is_sparrow) {
|
||||
W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0x00000003);
|
||||
/* reset A2 PCIE AHB */
|
||||
W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0x00008000);
|
||||
|
||||
} else {
|
||||
W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0x00000001);
|
||||
if (rev_id == 1) {
|
||||
/* reset A1 BOTH PCIE AHB & PCIE RGF */
|
||||
W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0x00000080);
|
||||
} else {
|
||||
W(RGF_PCIE_LOS_COUNTER_CTL, BIT(6) | BIT(8));
|
||||
W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0x00008000);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* TODO: check order here!!! Erez code is different */
|
||||
W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0);
|
||||
wmb(); /* order is important here */
|
||||
|
||||
|
@ -371,7 +396,8 @@ static void wil_target_reset(struct wil6210_priv *wil)
|
|||
}
|
||||
} while (hw_state != HW_MACHINE_BOOT_DONE);
|
||||
|
||||
if (rev_id == 2)
|
||||
/* TODO: Erez check rev_id != 1 */
|
||||
if (!is_sparrow && (rev_id != 1))
|
||||
W(RGF_PCIE_LOS_COUNTER_CTL, BIT(8));
|
||||
|
||||
C(RGF_USER_CLKS_CTL_0, BIT_USER_CLKS_RST_PWGD);
|
||||
|
|
|
@ -122,10 +122,12 @@ static int wil_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||
struct wil6210_priv *wil;
|
||||
struct device *dev = &pdev->dev;
|
||||
void __iomem *csr;
|
||||
struct wil_board *board = (struct wil_board *)id->driver_data;
|
||||
int rc;
|
||||
|
||||
/* check HW */
|
||||
dev_info(&pdev->dev, WIL_NAME " device found [%04x:%04x] (rev %x)\n",
|
||||
dev_info(&pdev->dev, WIL_NAME
|
||||
" \"%s\" device found [%04x:%04x] (rev %x)\n", board->name,
|
||||
(int)pdev->vendor, (int)pdev->device, (int)pdev->revision);
|
||||
|
||||
if (pci_resource_len(pdev, 0) != WIL6210_MEM_SIZE) {
|
||||
|
@ -175,6 +177,7 @@ static int wil_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||
|
||||
pci_set_drvdata(pdev, wil);
|
||||
wil->pdev = pdev;
|
||||
wil->board = board;
|
||||
|
||||
wil6210_clear_irq(wil);
|
||||
/* FW should raise IRQ when ready */
|
||||
|
@ -225,8 +228,21 @@ static void wil_pcie_remove(struct pci_dev *pdev)
|
|||
pci_disable_device(pdev);
|
||||
}
|
||||
|
||||
static DEFINE_PCI_DEVICE_TABLE(wil6210_pcie_ids) = {
|
||||
{ PCI_DEVICE(0x1ae9, 0x0301) },
|
||||
static const struct wil_board wil_board_marlon = {
|
||||
.board = WIL_BOARD_MARLON,
|
||||
.name = "marlon",
|
||||
};
|
||||
|
||||
static const struct wil_board wil_board_sparrow = {
|
||||
.board = WIL_BOARD_SPARROW,
|
||||
.name = "sparrow",
|
||||
};
|
||||
|
||||
static const struct pci_device_id wil6210_pcie_ids[] = {
|
||||
{ PCI_DEVICE(0x1ae9, 0x0301),
|
||||
.driver_data = (kernel_ulong_t)&wil_board_marlon },
|
||||
{ PCI_DEVICE(0x1ae9, 0x0310),
|
||||
.driver_data = (kernel_ulong_t)&wil_board_sparrow },
|
||||
{ /* end: all zeroes */ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, wil6210_pcie_ids);
|
||||
|
|
|
@ -1108,8 +1108,10 @@ int wil_tx_complete(struct wil6210_priv *wil, int ringid)
|
|||
while (vring->swtail != new_swtail) {
|
||||
struct vring_tx_desc dd, *d = ⅆ
|
||||
u16 dmalen;
|
||||
struct wil_ctx *ctx = &vring->ctx[vring->swtail];
|
||||
struct sk_buff *skb = ctx->skb;
|
||||
struct sk_buff *skb;
|
||||
|
||||
ctx = &vring->ctx[vring->swtail];
|
||||
skb = ctx->skb;
|
||||
_d = &vring->va[vring->swtail].tx;
|
||||
|
||||
*d = *_d;
|
||||
|
|
|
@ -24,6 +24,13 @@
|
|||
|
||||
#define WIL_NAME "wil6210"
|
||||
|
||||
struct wil_board {
|
||||
int board;
|
||||
#define WIL_BOARD_MARLON (1)
|
||||
#define WIL_BOARD_SPARROW (2)
|
||||
const char * const name;
|
||||
};
|
||||
|
||||
/**
|
||||
* extract bits [@b0:@b1] (inclusive) from the value @x
|
||||
* it should be @b0 <= @b1, or result is incorrect
|
||||
|
@ -78,6 +85,7 @@ struct RGF_ICR {
|
|||
} __packed;
|
||||
|
||||
/* registers - FW addresses */
|
||||
#define RGF_USER_USAGE_1 (0x880004)
|
||||
#define RGF_USER_HW_MACHINE_STATE (0x8801dc)
|
||||
#define HW_MACHINE_BOOT_DONE (0x3fffffd)
|
||||
#define RGF_USER_USER_CPU_0 (0x8801e0)
|
||||
|
@ -93,6 +101,7 @@ struct RGF_ICR {
|
|||
#define RGF_USER_CLKS_CTL_SW_RST_MASK_0 (0x880b14)
|
||||
#define RGF_USER_USER_ICR (0x880b4c) /* struct RGF_ICR */
|
||||
#define BIT_USER_USER_ICR_SW_INT_2 BIT(18)
|
||||
#define RGF_USER_CLKS_CTL_EXT_SW_RST_VEC_0 (0x880c18)
|
||||
|
||||
#define RGF_DMA_EP_TX_ICR (0x881bb4) /* struct RGF_ICR */
|
||||
#define BIT_DMA_EP_TX_ICR_TX_DONE BIT(0)
|
||||
|
@ -121,6 +130,7 @@ struct RGF_ICR {
|
|||
#define BIT_DMA_PSEUDO_CAUSE_TX BIT(1)
|
||||
#define BIT_DMA_PSEUDO_CAUSE_MISC BIT(2)
|
||||
|
||||
#define RGF_HP_CTRL (0x88265c)
|
||||
#define RGF_PCIE_LOS_COUNTER_CTL (0x882dc4)
|
||||
|
||||
/* popular locations */
|
||||
|
@ -135,6 +145,14 @@ struct RGF_ICR {
|
|||
#define ISR_MISC_FW_ERROR BIT_DMA_EP_MISC_ICR_FW_INT(3)
|
||||
|
||||
/* Hardware definitions end */
|
||||
struct fw_map {
|
||||
u32 from; /* linker address - from, inclusive */
|
||||
u32 to; /* linker address - to, exclusive */
|
||||
u32 host; /* PCI/Host address - BAR0 + 0x880000 */
|
||||
const char *name; /* for debugfs */
|
||||
};
|
||||
/* array size should be in sync with actual definition in the wmi.c */
|
||||
extern const struct fw_map fw_mapping[7];
|
||||
|
||||
/**
|
||||
* mk_cidxtid - construct @cidxtid field
|
||||
|
@ -365,6 +383,7 @@ struct wil6210_priv {
|
|||
ulong status;
|
||||
u32 fw_version;
|
||||
u32 hw_version;
|
||||
struct wil_board *board;
|
||||
u8 n_mids; /* number of additional MIDs as reported by FW */
|
||||
int recovery_count; /* num of FW recovery attempts in a short time */
|
||||
unsigned long last_fw_recovery; /* jiffies of last fw recovery */
|
||||
|
@ -415,12 +434,7 @@ struct wil6210_priv {
|
|||
atomic_t isr_count_rx, isr_count_tx;
|
||||
/* debugfs */
|
||||
struct dentry *debug;
|
||||
struct debugfs_blob_wrapper fw_code_blob;
|
||||
struct debugfs_blob_wrapper fw_data_blob;
|
||||
struct debugfs_blob_wrapper fw_peri_blob;
|
||||
struct debugfs_blob_wrapper uc_code_blob;
|
||||
struct debugfs_blob_wrapper uc_data_blob;
|
||||
struct debugfs_blob_wrapper rgf_blob;
|
||||
struct debugfs_blob_wrapper blobs[ARRAY_SIZE(fw_mapping)];
|
||||
};
|
||||
|
||||
#define wil_to_wiphy(i) (i->wdev->wiphy)
|
||||
|
|
|
@ -65,18 +65,17 @@
|
|||
|
||||
/**
|
||||
* @fw_mapping provides memory remapping table
|
||||
*
|
||||
* array size should be in sync with the declaration in the wil6210.h
|
||||
*/
|
||||
static const struct {
|
||||
u32 from; /* linker address - from, inclusive */
|
||||
u32 to; /* linker address - to, exclusive */
|
||||
u32 host; /* PCI/Host address - BAR0 + 0x880000 */
|
||||
} fw_mapping[] = {
|
||||
{0x000000, 0x040000, 0x8c0000}, /* FW code RAM 256k */
|
||||
{0x800000, 0x808000, 0x900000}, /* FW data RAM 32k */
|
||||
{0x840000, 0x860000, 0x908000}, /* peripheral data RAM 128k/96k used */
|
||||
{0x880000, 0x88a000, 0x880000}, /* various RGF */
|
||||
{0x88b000, 0x88c000, 0x88b000}, /* Pcie_ext_rgf */
|
||||
{0x8c0000, 0x949000, 0x8c0000}, /* trivial mapping for upper area */
|
||||
const struct fw_map fw_mapping[] = {
|
||||
{0x000000, 0x040000, 0x8c0000, "fw_code"}, /* FW code RAM 256k */
|
||||
{0x800000, 0x808000, 0x900000, "fw_data"}, /* FW data RAM 32k */
|
||||
{0x840000, 0x860000, 0x908000, "fw_peri"}, /* periph. data RAM 128k */
|
||||
{0x880000, 0x88a000, 0x880000, "rgf"}, /* various RGF 40k */
|
||||
{0x88a000, 0x88b000, 0x88a000, "AGC_tbl"}, /* AGC table 4k */
|
||||
{0x88b000, 0x88c000, 0x88b000, "rgf_ext"}, /* Pcie_ext_rgf 4k */
|
||||
{0x8c0000, 0x949000, 0x8c0000, "upper"}, /* upper area 548k */
|
||||
/*
|
||||
* 920000..930000 ucode code RAM
|
||||
* 930000..932000 ucode data RAM
|
||||
|
|
|
@ -36,7 +36,7 @@ config B43_SSB
|
|||
choice
|
||||
prompt "Supported bus types"
|
||||
depends on B43
|
||||
default B43_BCMA_AND_SSB
|
||||
default B43_BUSES_BCMA_AND_SSB
|
||||
|
||||
config B43_BUSES_BCMA_AND_SSB
|
||||
bool "BCMA and SSB"
|
||||
|
|
|
@ -210,6 +210,9 @@ static struct ieee80211_channel b43_2ghz_chantable[] = {
|
|||
CHAN2G(13, 2472, 0),
|
||||
CHAN2G(14, 2484, 0),
|
||||
};
|
||||
|
||||
/* No support for the last 3 channels (12, 13, 14) */
|
||||
#define b43_2ghz_chantable_limited_size 11
|
||||
#undef CHAN2G
|
||||
|
||||
#define CHAN4G(_channel, _flags) { \
|
||||
|
@ -335,6 +338,14 @@ static struct ieee80211_supported_band b43_band_2GHz = {
|
|||
.n_bitrates = b43_g_ratetable_size,
|
||||
};
|
||||
|
||||
static struct ieee80211_supported_band b43_band_2ghz_limited = {
|
||||
.band = IEEE80211_BAND_2GHZ,
|
||||
.channels = b43_2ghz_chantable,
|
||||
.n_channels = b43_2ghz_chantable_limited_size,
|
||||
.bitrates = b43_g_ratetable,
|
||||
.n_bitrates = b43_g_ratetable_size,
|
||||
};
|
||||
|
||||
static void b43_wireless_core_exit(struct b43_wldev *dev);
|
||||
static int b43_wireless_core_init(struct b43_wldev *dev);
|
||||
static struct b43_wldev * b43_wireless_core_stop(struct b43_wldev *dev);
|
||||
|
@ -2953,6 +2964,45 @@ void b43_mac_phy_clock_set(struct b43_wldev *dev, bool on)
|
|||
}
|
||||
}
|
||||
|
||||
/* brcms_b_switch_macfreq */
|
||||
void b43_mac_switch_freq(struct b43_wldev *dev, u8 spurmode)
|
||||
{
|
||||
u16 chip_id = dev->dev->chip_id;
|
||||
|
||||
if (chip_id == BCMA_CHIP_ID_BCM43217 ||
|
||||
chip_id == BCMA_CHIP_ID_BCM43222 ||
|
||||
chip_id == BCMA_CHIP_ID_BCM43224 ||
|
||||
chip_id == BCMA_CHIP_ID_BCM43225 ||
|
||||
chip_id == BCMA_CHIP_ID_BCM43227 ||
|
||||
chip_id == BCMA_CHIP_ID_BCM43228) {
|
||||
switch (spurmode) {
|
||||
case 2: /* 126 Mhz */
|
||||
b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, 0x2082);
|
||||
b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0x8);
|
||||
break;
|
||||
case 1: /* 123 Mhz */
|
||||
b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, 0x5341);
|
||||
b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0x8);
|
||||
break;
|
||||
default: /* 120 Mhz */
|
||||
b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, 0x8889);
|
||||
b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0x8);
|
||||
break;
|
||||
}
|
||||
} else if (dev->phy.type == B43_PHYTYPE_LCN) {
|
||||
switch (spurmode) {
|
||||
case 1: /* 82 Mhz */
|
||||
b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, 0x7CE0);
|
||||
b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0xC);
|
||||
break;
|
||||
default: /* 80 Mhz */
|
||||
b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, 0xCCCD);
|
||||
b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0xC);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void b43_adjust_opmode(struct b43_wldev *dev)
|
||||
{
|
||||
struct b43_wl *wl = dev->wl;
|
||||
|
@ -4329,6 +4379,7 @@ static char *b43_phy_name(struct b43_wldev *dev, u8 phy_type)
|
|||
static int b43_phy_versioning(struct b43_wldev *dev)
|
||||
{
|
||||
struct b43_phy *phy = &dev->phy;
|
||||
const u8 core_rev = dev->dev->core_rev;
|
||||
u32 tmp;
|
||||
u8 analog_type;
|
||||
u8 phy_type;
|
||||
|
@ -4359,7 +4410,7 @@ static int b43_phy_versioning(struct b43_wldev *dev)
|
|||
#endif
|
||||
#ifdef CONFIG_B43_PHY_N
|
||||
case B43_PHYTYPE_N:
|
||||
if (phy_rev > 9)
|
||||
if (phy_rev >= 19)
|
||||
unsupported = 1;
|
||||
break;
|
||||
#endif
|
||||
|
@ -4394,7 +4445,15 @@ static int b43_phy_versioning(struct b43_wldev *dev)
|
|||
analog_type, phy_type, b43_phy_name(dev, phy_type), phy_rev);
|
||||
|
||||
/* Get RADIO versioning */
|
||||
if (dev->dev->core_rev >= 24) {
|
||||
if (core_rev == 40 || core_rev == 42) {
|
||||
radio_manuf = 0x17F;
|
||||
|
||||
b43_write16(dev, B43_MMIO_RADIO24_CONTROL, 0);
|
||||
radio_rev = b43_read16(dev, B43_MMIO_RADIO24_DATA);
|
||||
|
||||
b43_write16(dev, B43_MMIO_RADIO24_CONTROL, 1);
|
||||
radio_ver = b43_read16(dev, B43_MMIO_RADIO24_DATA);
|
||||
} else if (core_rev >= 24) {
|
||||
u16 radio24[3];
|
||||
|
||||
for (tmp = 0; tmp < 3; tmp++) {
|
||||
|
@ -4450,7 +4509,10 @@ static int b43_phy_versioning(struct b43_wldev *dev)
|
|||
unsupported = 1;
|
||||
break;
|
||||
case B43_PHYTYPE_N:
|
||||
if (radio_ver != 0x2055 && radio_ver != 0x2056)
|
||||
if (radio_ver != 0x2055 && radio_ver != 0x2056 &&
|
||||
radio_ver != 0x2057)
|
||||
unsupported = 1;
|
||||
if (radio_ver == 0x2057 && !(radio_rev == 9))
|
||||
unsupported = 1;
|
||||
break;
|
||||
case B43_PHYTYPE_LP:
|
||||
|
@ -4469,13 +4531,13 @@ static int b43_phy_versioning(struct b43_wldev *dev)
|
|||
B43_WARN_ON(1);
|
||||
}
|
||||
if (unsupported) {
|
||||
b43err(dev->wl, "FOUND UNSUPPORTED RADIO "
|
||||
"(Manuf 0x%X, Version 0x%X, Revision %u)\n",
|
||||
b43err(dev->wl,
|
||||
"FOUND UNSUPPORTED RADIO (Manuf 0x%X, ID 0x%X, Revision %u)\n",
|
||||
radio_manuf, radio_ver, radio_rev);
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
b43dbg(dev->wl, "Found Radio: Manuf 0x%X, Version 0x%X, Revision %u\n",
|
||||
radio_manuf, radio_ver, radio_rev);
|
||||
b43info(dev->wl, "Found Radio: Manuf 0x%X, ID 0x%X, Revision %u\n",
|
||||
radio_manuf, radio_ver, radio_rev);
|
||||
|
||||
phy->radio_manuf = radio_manuf;
|
||||
phy->radio_ver = radio_ver;
|
||||
|
@ -5086,9 +5148,15 @@ static int b43_setup_bands(struct b43_wldev *dev,
|
|||
bool have_2ghz_phy, bool have_5ghz_phy)
|
||||
{
|
||||
struct ieee80211_hw *hw = dev->wl->hw;
|
||||
struct b43_phy *phy = &dev->phy;
|
||||
bool limited_2g;
|
||||
|
||||
/* We don't support all 2 GHz channels on some devices */
|
||||
limited_2g = phy->radio_ver == 0x2057 && phy->radio_rev == 9;
|
||||
|
||||
if (have_2ghz_phy)
|
||||
hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &b43_band_2GHz;
|
||||
hw->wiphy->bands[IEEE80211_BAND_2GHZ] = limited_2g ?
|
||||
&b43_band_2ghz_limited : &b43_band_2GHz;
|
||||
if (dev->phy.type == B43_PHYTYPE_N) {
|
||||
if (have_5ghz_phy)
|
||||
hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &b43_band_5GHz_nphy;
|
||||
|
@ -5239,13 +5307,16 @@ static int b43_wireless_core_attach(struct b43_wldev *dev)
|
|||
b43_supported_bands(dev, &have_2ghz_phy, &have_5ghz_phy);
|
||||
|
||||
/* We don't support 5 GHz on some PHYs yet */
|
||||
switch (dev->phy.type) {
|
||||
case B43_PHYTYPE_A:
|
||||
case B43_PHYTYPE_N:
|
||||
case B43_PHYTYPE_LP:
|
||||
case B43_PHYTYPE_HT:
|
||||
b43warn(wl, "5 GHz band is unsupported on this PHY\n");
|
||||
have_5ghz_phy = false;
|
||||
if (have_5ghz_phy) {
|
||||
switch (dev->phy.type) {
|
||||
case B43_PHYTYPE_A:
|
||||
case B43_PHYTYPE_G:
|
||||
case B43_PHYTYPE_N:
|
||||
case B43_PHYTYPE_LP:
|
||||
case B43_PHYTYPE_HT:
|
||||
b43warn(wl, "5 GHz band is unsupported on this PHY\n");
|
||||
have_5ghz_phy = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!have_2ghz_phy && !have_5ghz_phy) {
|
||||
|
|
|
@ -99,6 +99,7 @@ void b43_power_saving_ctl_bits(struct b43_wldev *dev, unsigned int ps_flags);
|
|||
void b43_mac_suspend(struct b43_wldev *dev);
|
||||
void b43_mac_enable(struct b43_wldev *dev);
|
||||
void b43_mac_phy_clock_set(struct b43_wldev *dev, bool on);
|
||||
void b43_mac_switch_freq(struct b43_wldev *dev, u8 spurmode);
|
||||
|
||||
|
||||
struct b43_request_fw_context;
|
||||
|
|
|
@ -54,39 +54,6 @@ enum lcn_sense_type {
|
|||
B43_SENSE_VBAT,
|
||||
};
|
||||
|
||||
/* In theory it's PHY common function, move if needed */
|
||||
/* brcms_b_switch_macfreq */
|
||||
static void b43_phy_switch_macfreq(struct b43_wldev *dev, u8 spurmode)
|
||||
{
|
||||
if (dev->dev->chip_id == 43224 || dev->dev->chip_id == 43225) {
|
||||
switch (spurmode) {
|
||||
case 2: /* 126 Mhz */
|
||||
b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, 0x2082);
|
||||
b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0x8);
|
||||
break;
|
||||
case 1: /* 123 Mhz */
|
||||
b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, 0x5341);
|
||||
b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0x8);
|
||||
break;
|
||||
default: /* 120 Mhz */
|
||||
b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, 0x8889);
|
||||
b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0x8);
|
||||
break;
|
||||
}
|
||||
} else if (dev->phy.type == B43_PHYTYPE_LCN) {
|
||||
switch (spurmode) {
|
||||
case 1: /* 82 Mhz */
|
||||
b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, 0x7CE0);
|
||||
b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0xC);
|
||||
break;
|
||||
default: /* 80 Mhz */
|
||||
b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, 0xCCCD);
|
||||
b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0xC);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************
|
||||
* Radio 2064.
|
||||
**************************************************/
|
||||
|
@ -609,7 +576,7 @@ static void b43_phy_lcn_txrx_spur_avoidance_mode(struct b43_wldev *dev,
|
|||
b43_phy_write(dev, 0x93b, ((0 << 13) + 23));
|
||||
b43_phy_write(dev, 0x93c, ((0 << 13) + 1989));
|
||||
}
|
||||
b43_phy_switch_macfreq(dev, enable);
|
||||
b43_mac_switch_freq(dev, enable);
|
||||
}
|
||||
|
||||
/**************************************************
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -366,11 +366,13 @@
|
|||
#define B43_NPHY_TXF_40CO_B1S0 B43_PHY_N(0x0E5) /* TX filter 40 coeff B1 stage 0 */
|
||||
#define B43_NPHY_TXF_40CO_B32S1 B43_PHY_N(0x0E6) /* TX filter 40 coeff B32 stage 1 */
|
||||
#define B43_NPHY_TXF_40CO_B1S1 B43_PHY_N(0x0E7) /* TX filter 40 coeff B1 stage 1 */
|
||||
#define B43_NPHY_REV3_RFCTL_OVER0 B43_PHY_N(0x0E7)
|
||||
#define B43_NPHY_TXF_40CO_B32S2 B43_PHY_N(0x0E8) /* TX filter 40 coeff B32 stage 2 */
|
||||
#define B43_NPHY_TXF_40CO_B1S2 B43_PHY_N(0x0E9) /* TX filter 40 coeff B1 stage 2 */
|
||||
#define B43_NPHY_BIST_STAT2 B43_PHY_N(0x0EA) /* BIST status 2 */
|
||||
#define B43_NPHY_BIST_STAT3 B43_PHY_N(0x0EB) /* BIST status 3 */
|
||||
#define B43_NPHY_RFCTL_OVER B43_PHY_N(0x0EC) /* RF control override */
|
||||
#define B43_NPHY_REV3_RFCTL_OVER1 B43_PHY_N(0x0EC)
|
||||
#define B43_NPHY_MIMOCFG B43_PHY_N(0x0ED) /* MIMO config */
|
||||
#define B43_NPHY_MIMOCFG_GFMIX 0x0004 /* Greenfield or mixed mode */
|
||||
#define B43_NPHY_MIMOCFG_AUTO 0x0100 /* Greenfield/mixed mode auto */
|
||||
|
@ -857,7 +859,18 @@
|
|||
#define B43_NPHY_REV3_C2_CLIP2_GAIN_A B43_PHY_N(0x2AF)
|
||||
#define B43_NPHY_REV3_C2_CLIP2_GAIN_B B43_PHY_N(0x2B0)
|
||||
|
||||
#define B43_NPHY_REV7_RF_CTL_MISC_REG3 B43_PHY_N(0x340)
|
||||
#define B43_NPHY_REV7_RF_CTL_MISC_REG4 B43_PHY_N(0x341)
|
||||
#define B43_NPHY_REV7_RF_CTL_OVER3 B43_PHY_N(0x342)
|
||||
#define B43_NPHY_REV7_RF_CTL_OVER4 B43_PHY_N(0x343)
|
||||
#define B43_NPHY_REV7_RF_CTL_MISC_REG5 B43_PHY_N(0x344)
|
||||
#define B43_NPHY_REV7_RF_CTL_MISC_REG6 B43_PHY_N(0x345)
|
||||
#define B43_NPHY_REV7_RF_CTL_OVER5 B43_PHY_N(0x346)
|
||||
#define B43_NPHY_REV7_RF_CTL_OVER6 B43_PHY_N(0x347)
|
||||
|
||||
#define B43_PHY_B_BBCFG B43_PHY_N_BMODE(0x001) /* BB config */
|
||||
#define B43_PHY_B_BBCFG_RSTCCA 0x4000 /* Reset CCA */
|
||||
#define B43_PHY_B_BBCFG_RSTRX 0x8000 /* Reset RX */
|
||||
#define B43_PHY_B_TEST B43_PHY_N_BMODE(0x00A)
|
||||
|
||||
struct b43_wldev;
|
||||
|
@ -935,6 +948,8 @@ struct b43_phy_n {
|
|||
bool gain_boost;
|
||||
bool elna_gain_config;
|
||||
bool band5g_pwrgain;
|
||||
bool use_int_tx_iq_lo_cal;
|
||||
bool lpf_bw_overrode_for_sample_play;
|
||||
|
||||
u8 mphase_cal_phase_id;
|
||||
u16 mphase_txcal_cmdidx;
|
||||
|
|
|
@ -105,6 +105,27 @@ static u16 r2057_rev8_init[][2] = {
|
|||
};
|
||||
*/
|
||||
|
||||
/* Extracted from MMIO dump of 6.30.223.141 */
|
||||
static u16 r2057_rev9_init[][2] = {
|
||||
{ 0x27, 0x1f }, { 0x28, 0x0a }, { 0x29, 0x2f }, { 0x42, 0x1f },
|
||||
{ 0x48, 0x3f }, { 0x5c, 0x41 }, { 0x63, 0x14 }, { 0x64, 0x12 },
|
||||
{ 0x66, 0xff }, { 0x74, 0xa3 }, { 0x7b, 0x14 }, { 0x7c, 0x14 },
|
||||
{ 0x7d, 0xee }, { 0x86, 0xc0 }, { 0xc4, 0x10 }, { 0xc9, 0x01 },
|
||||
{ 0xe1, 0x41 }, { 0xe8, 0x14 }, { 0xe9, 0x12 }, { 0xeb, 0xff },
|
||||
{ 0xf5, 0x0a }, { 0xf8, 0x09 }, { 0xf9, 0xa3 }, { 0x100, 0x14 },
|
||||
{ 0x101, 0x10 }, { 0x102, 0xee }, { 0x10b, 0xc0 }, { 0x149, 0x10 },
|
||||
{ 0x14e, 0x01 }, { 0x1b7, 0x05 }, { 0x1c2, 0xa0 },
|
||||
};
|
||||
|
||||
/* Extracted from MMIO dump of 6.30.223.248 */
|
||||
static u16 r2057_rev14_init[][2] = {
|
||||
{ 0x011, 0xfc }, { 0x030, 0x24 }, { 0x040, 0x1c }, { 0x082, 0x08 },
|
||||
{ 0x0b4, 0x44 }, { 0x0c8, 0x01 }, { 0x0c9, 0x01 }, { 0x107, 0x08 },
|
||||
{ 0x14d, 0x01 }, { 0x14e, 0x01 }, { 0x1af, 0x40 }, { 0x1b0, 0x40 },
|
||||
{ 0x1cc, 0x01 }, { 0x1cf, 0x10 }, { 0x1d0, 0x0f }, { 0x1d3, 0x10 },
|
||||
{ 0x1d4, 0x0f },
|
||||
};
|
||||
|
||||
#define RADIOREGS7(r00, r01, r02, r03, r04, r05, r06, r07, r08, r09, \
|
||||
r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, \
|
||||
r20, r21, r22, r23, r24, r25, r26, r27) \
|
||||
|
@ -137,6 +158,27 @@ static u16 r2057_rev8_init[][2] = {
|
|||
.radio_lna2g_tune_core1 = r26, \
|
||||
.radio_lna5g_tune_core1 = r27
|
||||
|
||||
#define RADIOREGS7_2G(r00, r01, r02, r03, r04, r05, r06, r07, r08, r09, \
|
||||
r10, r11, r12, r13, r14, r15, r16, r17) \
|
||||
.radio_vcocal_countval0 = r00, \
|
||||
.radio_vcocal_countval1 = r01, \
|
||||
.radio_rfpll_refmaster_sparextalsize = r02, \
|
||||
.radio_rfpll_loopfilter_r1 = r03, \
|
||||
.radio_rfpll_loopfilter_c2 = r04, \
|
||||
.radio_rfpll_loopfilter_c1 = r05, \
|
||||
.radio_cp_kpd_idac = r06, \
|
||||
.radio_rfpll_mmd0 = r07, \
|
||||
.radio_rfpll_mmd1 = r08, \
|
||||
.radio_vcobuf_tune = r09, \
|
||||
.radio_logen_mx2g_tune = r10, \
|
||||
.radio_logen_indbuf2g_tune = r11, \
|
||||
.radio_txmix2g_tune_boost_pu_core0 = r12, \
|
||||
.radio_pad2g_tune_pus_core0 = r13, \
|
||||
.radio_lna2g_tune_core0 = r14, \
|
||||
.radio_txmix2g_tune_boost_pu_core1 = r15, \
|
||||
.radio_pad2g_tune_pus_core1 = r16, \
|
||||
.radio_lna2g_tune_core1 = r17
|
||||
|
||||
#define PHYREGS(r0, r1, r2, r3, r4, r5) \
|
||||
.phy_regs.phy_bw1a = r0, \
|
||||
.phy_regs.phy_bw2 = r1, \
|
||||
|
@ -145,6 +187,353 @@ static u16 r2057_rev8_init[][2] = {
|
|||
.phy_regs.phy_bw5 = r4, \
|
||||
.phy_regs.phy_bw6 = r5
|
||||
|
||||
/* Copied from brcmsmac (5.75.11): chan_info_nphyrev8_2057_rev5 */
|
||||
static const struct b43_nphy_chantabent_rev7_2g b43_nphy_chantab_phy_rev8_radio_rev5[] = {
|
||||
{
|
||||
.freq = 2412,
|
||||
RADIOREGS7_2G(0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c,
|
||||
0x09, 0x0d, 0x08, 0x0e, 0x61, 0x03, 0xff, 0x61,
|
||||
0x03, 0xff),
|
||||
PHYREGS(0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443),
|
||||
},
|
||||
{
|
||||
.freq = 2417,
|
||||
RADIOREGS7_2G(0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71,
|
||||
0x09, 0x0d, 0x08, 0x0e, 0x61, 0x03, 0xff, 0x61,
|
||||
0x03, 0xff),
|
||||
PHYREGS(0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441),
|
||||
},
|
||||
{
|
||||
.freq = 2422,
|
||||
RADIOREGS7_2G(0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76,
|
||||
0x09, 0x0d, 0x08, 0x0e, 0x61, 0x03, 0xef, 0x61,
|
||||
0x03, 0xef),
|
||||
PHYREGS(0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f),
|
||||
},
|
||||
{
|
||||
.freq = 2427,
|
||||
RADIOREGS7_2G(0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b,
|
||||
0x09, 0x0c, 0x08, 0x0e, 0x61, 0x03, 0xdf, 0x61,
|
||||
0x03, 0xdf),
|
||||
PHYREGS(0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d),
|
||||
},
|
||||
{
|
||||
.freq = 2432,
|
||||
RADIOREGS7_2G(0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80,
|
||||
0x09, 0x0c, 0x07, 0x0d, 0x61, 0x03, 0xcf, 0x61,
|
||||
0x03, 0xcf),
|
||||
PHYREGS(0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a),
|
||||
},
|
||||
{
|
||||
.freq = 2437,
|
||||
RADIOREGS7_2G(0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85,
|
||||
0x09, 0x0c, 0x07, 0x0d, 0x61, 0x03, 0xbf, 0x61,
|
||||
0x03, 0xbf),
|
||||
PHYREGS(0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438),
|
||||
},
|
||||
{
|
||||
.freq = 2442,
|
||||
RADIOREGS7_2G(0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a,
|
||||
0x09, 0x0b, 0x07, 0x0d, 0x61, 0x03, 0xaf, 0x61,
|
||||
0x03, 0xaf),
|
||||
PHYREGS(0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436),
|
||||
},
|
||||
{
|
||||
.freq = 2447,
|
||||
RADIOREGS7_2G(0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f,
|
||||
0x09, 0x0b, 0x07, 0x0d, 0x61, 0x03, 0x9f, 0x61,
|
||||
0x03, 0x9f),
|
||||
PHYREGS(0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434),
|
||||
},
|
||||
{
|
||||
.freq = 2452,
|
||||
RADIOREGS7_2G(0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94,
|
||||
0x09, 0x0b, 0x07, 0x0d, 0x61, 0x03, 0x8f, 0x61,
|
||||
0x03, 0x8f),
|
||||
PHYREGS(0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431),
|
||||
},
|
||||
{
|
||||
.freq = 2457,
|
||||
RADIOREGS7_2G(0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99,
|
||||
0x09, 0x0b, 0x07, 0x0c, 0x61, 0x03, 0x7f, 0x61,
|
||||
0x03, 0x7f),
|
||||
PHYREGS(0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f),
|
||||
},
|
||||
{
|
||||
.freq = 2462,
|
||||
RADIOREGS7_2G(0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e,
|
||||
0x09, 0x0b, 0x07, 0x0c, 0x61, 0x03, 0x6f, 0x61,
|
||||
0x03, 0x6f),
|
||||
PHYREGS(0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d),
|
||||
},
|
||||
{
|
||||
.freq = 2467,
|
||||
RADIOREGS7_2G(0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3,
|
||||
0x09, 0x0b, 0x06, 0x0c, 0x61, 0x03, 0x5f, 0x61,
|
||||
0x03, 0x5f),
|
||||
PHYREGS(0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b),
|
||||
},
|
||||
{
|
||||
.freq = 2472,
|
||||
RADIOREGS7_2G(0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8,
|
||||
0x09, 0x0a, 0x06, 0x0b, 0x61, 0x03, 0x4f, 0x61,
|
||||
0x03, 0x4f),
|
||||
PHYREGS(0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429),
|
||||
},
|
||||
{
|
||||
.freq = 2484,
|
||||
RADIOREGS7_2G(0x78, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xb4,
|
||||
0x09, 0x0a, 0x06, 0x0b, 0x61, 0x03, 0x3f, 0x61,
|
||||
0x03, 0x3f),
|
||||
PHYREGS(0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424),
|
||||
}
|
||||
};
|
||||
|
||||
/* Extracted from MMIO dump of 6.30.223.248 */
|
||||
static const struct b43_nphy_chantabent_rev7_2g b43_nphy_chantab_phy_rev17_radio_rev14[] = {
|
||||
{
|
||||
.freq = 2412,
|
||||
RADIOREGS7_2G(0x48, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x6c,
|
||||
0x09, 0x0d, 0x09, 0x03, 0x21, 0x53, 0xff, 0x21,
|
||||
0x53, 0xff),
|
||||
PHYREGS(0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443),
|
||||
},
|
||||
{
|
||||
.freq = 2417,
|
||||
RADIOREGS7_2G(0x4b, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x71,
|
||||
0x09, 0x0d, 0x08, 0x03, 0x21, 0x53, 0xff, 0x21,
|
||||
0x53, 0xff),
|
||||
PHYREGS(0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441),
|
||||
},
|
||||
{
|
||||
.freq = 2422,
|
||||
RADIOREGS7_2G(0x4e, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x76,
|
||||
0x09, 0x0d, 0x08, 0x03, 0x21, 0x53, 0xff, 0x21,
|
||||
0x53, 0xff),
|
||||
PHYREGS(0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f),
|
||||
},
|
||||
{
|
||||
.freq = 2427,
|
||||
RADIOREGS7_2G(0x52, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x7b,
|
||||
0x09, 0x0c, 0x08, 0x03, 0x21, 0x53, 0xff, 0x21,
|
||||
0x53, 0xff),
|
||||
PHYREGS(0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d),
|
||||
},
|
||||
{
|
||||
.freq = 2432,
|
||||
RADIOREGS7_2G(0x55, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x80,
|
||||
0x09, 0x0c, 0x08, 0x03, 0x21, 0x53, 0xff, 0x21,
|
||||
0x53, 0xff),
|
||||
PHYREGS(0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a),
|
||||
},
|
||||
{
|
||||
.freq = 2437,
|
||||
RADIOREGS7_2G(0x58, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x85,
|
||||
0x09, 0x0c, 0x08, 0x03, 0x21, 0x53, 0xff, 0x21,
|
||||
0x53, 0xff),
|
||||
PHYREGS(0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438),
|
||||
},
|
||||
{
|
||||
.freq = 2442,
|
||||
RADIOREGS7_2G(0x5c, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x8a,
|
||||
0x09, 0x0c, 0x08, 0x03, 0x21, 0x43, 0xff, 0x21,
|
||||
0x43, 0xff),
|
||||
PHYREGS(0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436),
|
||||
},
|
||||
{
|
||||
.freq = 2447,
|
||||
RADIOREGS7_2G(0x5f, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x8f,
|
||||
0x09, 0x0c, 0x08, 0x03, 0x21, 0x43, 0xff, 0x21,
|
||||
0x43, 0xff),
|
||||
PHYREGS(0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434),
|
||||
},
|
||||
{
|
||||
.freq = 2452,
|
||||
RADIOREGS7_2G(0x62, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x94,
|
||||
0x09, 0x0c, 0x08, 0x03, 0x21, 0x43, 0xff, 0x21,
|
||||
0x43, 0xff),
|
||||
PHYREGS(0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431),
|
||||
},
|
||||
{
|
||||
.freq = 2457,
|
||||
RADIOREGS7_2G(0x66, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x99,
|
||||
0x09, 0x0b, 0x07, 0x03, 0x21, 0x43, 0xff, 0x21,
|
||||
0x43, 0xff),
|
||||
PHYREGS(0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f),
|
||||
},
|
||||
{
|
||||
.freq = 2462,
|
||||
RADIOREGS7_2G(0x69, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x9e,
|
||||
0x09, 0x0b, 0x07, 0x03, 0x01, 0x43, 0xff, 0x01,
|
||||
0x43, 0xff),
|
||||
PHYREGS(0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d),
|
||||
},
|
||||
};
|
||||
|
||||
/* Extracted from MMIO dump of 6.30.223.141 */
|
||||
static const struct b43_nphy_chantabent_rev7 b43_nphy_chantab_phy_rev16_radio_rev9[] = {
|
||||
{
|
||||
.freq = 2412,
|
||||
RADIOREGS7(0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c,
|
||||
0x09, 0x0f, 0x0a, 0x00, 0x0a, 0x00, 0x41, 0x63,
|
||||
0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
|
||||
0x00, 0x00, 0xf0, 0x00),
|
||||
PHYREGS(0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443),
|
||||
},
|
||||
{
|
||||
.freq = 2417,
|
||||
RADIOREGS7(0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71,
|
||||
0x09, 0x0f, 0x0a, 0x00, 0x0a, 0x00, 0x41, 0x63,
|
||||
0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
|
||||
0x00, 0x00, 0xf0, 0x00),
|
||||
PHYREGS(0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441),
|
||||
},
|
||||
{
|
||||
.freq = 2422,
|
||||
RADIOREGS7(0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76,
|
||||
0x09, 0x0f, 0x09, 0x00, 0x09, 0x00, 0x41, 0x63,
|
||||
0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
|
||||
0x00, 0x00, 0xf0, 0x00),
|
||||
PHYREGS(0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f),
|
||||
},
|
||||
{
|
||||
.freq = 2427,
|
||||
RADIOREGS7(0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b,
|
||||
0x09, 0x0f, 0x09, 0x00, 0x09, 0x00, 0x41, 0x63,
|
||||
0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
|
||||
0x00, 0x00, 0xf0, 0x00),
|
||||
PHYREGS(0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d),
|
||||
},
|
||||
{
|
||||
.freq = 2432,
|
||||
RADIOREGS7(0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80,
|
||||
0x09, 0x0f, 0x08, 0x00, 0x08, 0x00, 0x41, 0x63,
|
||||
0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
|
||||
0x00, 0x00, 0xf0, 0x00),
|
||||
PHYREGS(0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a),
|
||||
},
|
||||
{
|
||||
.freq = 2437,
|
||||
RADIOREGS7(0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85,
|
||||
0x09, 0x0f, 0x08, 0x00, 0x08, 0x00, 0x41, 0x63,
|
||||
0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
|
||||
0x00, 0x00, 0xf0, 0x00),
|
||||
PHYREGS(0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438),
|
||||
},
|
||||
{
|
||||
.freq = 2442,
|
||||
RADIOREGS7(0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a,
|
||||
0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x41, 0x63,
|
||||
0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
|
||||
0x00, 0x00, 0xf0, 0x00),
|
||||
PHYREGS(0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436),
|
||||
},
|
||||
{
|
||||
.freq = 2447,
|
||||
RADIOREGS7(0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f,
|
||||
0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x41, 0x63,
|
||||
0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
|
||||
0x00, 0x00, 0xf0, 0x00),
|
||||
PHYREGS(0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434),
|
||||
},
|
||||
{
|
||||
.freq = 2452,
|
||||
RADIOREGS7(0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94,
|
||||
0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x41, 0x63,
|
||||
0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
|
||||
0x00, 0x00, 0xf0, 0x00),
|
||||
PHYREGS(0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431),
|
||||
},
|
||||
{
|
||||
.freq = 2457,
|
||||
RADIOREGS7(0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99,
|
||||
0x09, 0x0f, 0x06, 0x00, 0x06, 0x00, 0x41, 0x63,
|
||||
0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
|
||||
0x00, 0x00, 0xf0, 0x00),
|
||||
PHYREGS(0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f),
|
||||
},
|
||||
{
|
||||
.freq = 2462,
|
||||
RADIOREGS7(0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e,
|
||||
0x09, 0x0f, 0x06, 0x00, 0x06, 0x00, 0x41, 0x63,
|
||||
0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
|
||||
0x00, 0x00, 0xf0, 0x00),
|
||||
PHYREGS(0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d),
|
||||
},
|
||||
{
|
||||
.freq = 5180,
|
||||
RADIOREGS7(0xbe, 0x16, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x06,
|
||||
0x02, 0x0e, 0x00, 0x0e, 0x00, 0x9e, 0x00, 0x00,
|
||||
0x9f, 0x2f, 0xa3, 0x00, 0xfc, 0x00, 0x00, 0x4f,
|
||||
0x3a, 0x83, 0x00, 0xfc),
|
||||
PHYREGS(0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb),
|
||||
},
|
||||
{
|
||||
.freq = 5200,
|
||||
RADIOREGS7(0xc5, 0x16, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x08,
|
||||
0x02, 0x0e, 0x00, 0x0e, 0x00, 0x9e, 0x00, 0x00,
|
||||
0x7f, 0x2f, 0x83, 0x00, 0xf8, 0x00, 0x00, 0x4c,
|
||||
0x4a, 0x83, 0x00, 0xf8),
|
||||
PHYREGS(0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9),
|
||||
},
|
||||
{
|
||||
.freq = 5220,
|
||||
RADIOREGS7(0xcc, 0x16, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x0a,
|
||||
0x02, 0x0e, 0x00, 0x0e, 0x00, 0x9e, 0x00, 0x00,
|
||||
0x6d, 0x3d, 0x83, 0x00, 0xf8, 0x00, 0x00, 0x2d,
|
||||
0x2a, 0x73, 0x00, 0xf8),
|
||||
PHYREGS(0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7),
|
||||
},
|
||||
{
|
||||
.freq = 5240,
|
||||
RADIOREGS7(0xd2, 0x16, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x0c,
|
||||
0x02, 0x0d, 0x00, 0x0d, 0x00, 0x8d, 0x00, 0x00,
|
||||
0x4d, 0x1c, 0x73, 0x00, 0xf8, 0x00, 0x00, 0x4d,
|
||||
0x2b, 0x73, 0x00, 0xf8),
|
||||
PHYREGS(0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5),
|
||||
},
|
||||
{
|
||||
.freq = 5745,
|
||||
RADIOREGS7(0x7b, 0x17, 0x20, 0x1f, 0x08, 0x08, 0x3f, 0x7d,
|
||||
0x04, 0x08, 0x00, 0x06, 0x00, 0x15, 0x00, 0x00,
|
||||
0x08, 0x03, 0x03, 0x00, 0x30, 0x00, 0x00, 0x06,
|
||||
0x02, 0x03, 0x00, 0x30),
|
||||
PHYREGS(0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9),
|
||||
},
|
||||
{
|
||||
.freq = 5765,
|
||||
RADIOREGS7(0x81, 0x17, 0x20, 0x1f, 0x08, 0x08, 0x3f, 0x81,
|
||||
0x04, 0x08, 0x00, 0x06, 0x00, 0x15, 0x00, 0x00,
|
||||
0x06, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x05,
|
||||
0x02, 0x03, 0x00, 0x00),
|
||||
PHYREGS(0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8),
|
||||
},
|
||||
{
|
||||
.freq = 5785,
|
||||
RADIOREGS7(0x88, 0x17, 0x20, 0x1f, 0x08, 0x08, 0x3f, 0x85,
|
||||
0x04, 0x08, 0x00, 0x06, 0x00, 0x15, 0x00, 0x00,
|
||||
0x08, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x05,
|
||||
0x21, 0x03, 0x00, 0x00),
|
||||
PHYREGS(0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6),
|
||||
},
|
||||
{
|
||||
.freq = 5805,
|
||||
RADIOREGS7(0x8f, 0x17, 0x20, 0x1f, 0x08, 0x08, 0x3f, 0x89,
|
||||
0x04, 0x07, 0x00, 0x06, 0x00, 0x04, 0x00, 0x00,
|
||||
0x06, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x03,
|
||||
0x00, 0x03, 0x00, 0x00),
|
||||
PHYREGS(0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4),
|
||||
},
|
||||
{
|
||||
.freq = 5825,
|
||||
RADIOREGS7(0x95, 0x17, 0x20, 0x1f, 0x08, 0x08, 0x3f, 0x8d,
|
||||
0x04, 0x07, 0x00, 0x05, 0x00, 0x03, 0x00, 0x00,
|
||||
0x05, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x03,
|
||||
0x00, 0x03, 0x00, 0x00),
|
||||
PHYREGS(0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3),
|
||||
},
|
||||
};
|
||||
|
||||
void r2057_upload_inittabs(struct b43_wldev *dev)
|
||||
{
|
||||
struct b43_phy *phy = &dev->phy;
|
||||
|
@ -171,6 +560,18 @@ void r2057_upload_inittabs(struct b43_wldev *dev)
|
|||
size = ARRAY_SIZE(r2057_rev5a_init);
|
||||
}
|
||||
break;
|
||||
case 16:
|
||||
if (phy->radio_rev == 9) {
|
||||
table = r2057_rev9_init[0];
|
||||
size = ARRAY_SIZE(r2057_rev9_init);
|
||||
}
|
||||
break;
|
||||
case 17:
|
||||
if (phy->radio_rev == 14) {
|
||||
table = r2057_rev14_init[0];
|
||||
size = ARRAY_SIZE(r2057_rev14_init);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
B43_WARN_ON(!table);
|
||||
|
@ -193,8 +594,25 @@ void r2057_get_chantabent_rev7(struct b43_wldev *dev, u16 freq,
|
|||
*tabent_r7 = NULL;
|
||||
*tabent_r7_2g = NULL;
|
||||
|
||||
/* TODO */
|
||||
switch (phy->rev) {
|
||||
case 8:
|
||||
if (phy->radio_rev == 5) {
|
||||
e_r7_2g = b43_nphy_chantab_phy_rev8_radio_rev5;
|
||||
len = ARRAY_SIZE(b43_nphy_chantab_phy_rev8_radio_rev5);
|
||||
}
|
||||
break;
|
||||
case 16:
|
||||
if (phy->radio_rev == 9) {
|
||||
e_r7 = b43_nphy_chantab_phy_rev16_radio_rev9;
|
||||
len = ARRAY_SIZE(b43_nphy_chantab_phy_rev16_radio_rev9);
|
||||
}
|
||||
break;
|
||||
case 17:
|
||||
if (phy->radio_rev == 14) {
|
||||
e_r7_2g = b43_nphy_chantab_phy_rev17_radio_rev14;
|
||||
len = ARRAY_SIZE(b43_nphy_chantab_phy_rev17_radio_rev14);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -84,6 +84,8 @@
|
|||
#define R2057_CMOSBUF_RX_RCCR 0x04c
|
||||
#define R2057_LOGEN_SEL_PKDET 0x04d
|
||||
#define R2057_CMOSBUF_SHAREIQ_PTAT 0x04e
|
||||
|
||||
/* MISC core 0 */
|
||||
#define R2057_RXTXBIAS_CONFIG_CORE0 0x04f
|
||||
#define R2057_TXGM_TXRF_PUS_CORE0 0x050
|
||||
#define R2057_TXGM_IDAC_BLEED_CORE0 0x051
|
||||
|
@ -204,6 +206,8 @@
|
|||
#define R2057_RXBB_GPAIOSEL_RXLPF_RCCAL_CORE0 0x0d1
|
||||
#define R2057_LPF_GAIN_CORE0 0x0d2
|
||||
#define R2057_DACBUF_IDACS_BW_CORE0 0x0d3
|
||||
|
||||
/* MISC core 1 */
|
||||
#define R2057_RXTXBIAS_CONFIG_CORE1 0x0d4
|
||||
#define R2057_TXGM_TXRF_PUS_CORE1 0x0d5
|
||||
#define R2057_TXGM_IDAC_BLEED_CORE1 0x0d6
|
||||
|
@ -324,6 +328,7 @@
|
|||
#define R2057_RXBB_GPAIOSEL_RXLPF_RCCAL_CORE1 0x156
|
||||
#define R2057_LPF_GAIN_CORE1 0x157
|
||||
#define R2057_DACBUF_IDACS_BW_CORE1 0x158
|
||||
|
||||
#define R2057_DACBUF_VINCM_CORE1 0x159
|
||||
#define R2057_RCCAL_START_R1_Q1_P1 0x15a
|
||||
#define R2057_RCCAL_X1 0x15b
|
||||
|
@ -345,6 +350,8 @@
|
|||
#define R2057_RCCAL_BCAP_VAL 0x16b
|
||||
#define R2057_RCCAL_HPC_VAL 0x16c
|
||||
#define R2057_RCCAL_OVERRIDES 0x16d
|
||||
|
||||
/* TX core 0 */
|
||||
#define R2057_TX0_IQCAL_GAIN_BW 0x170
|
||||
#define R2057_TX0_LOFT_FINE_I 0x171
|
||||
#define R2057_TX0_LOFT_FINE_Q 0x172
|
||||
|
@ -362,6 +369,8 @@
|
|||
#define R2057_TX0_TXRXCOUPLE_2G_PWRUP 0x17e
|
||||
#define R2057_TX0_TXRXCOUPLE_5G_ATTEN 0x17f
|
||||
#define R2057_TX0_TXRXCOUPLE_5G_PWRUP 0x180
|
||||
|
||||
/* TX core 1 */
|
||||
#define R2057_TX1_IQCAL_GAIN_BW 0x190
|
||||
#define R2057_TX1_LOFT_FINE_I 0x191
|
||||
#define R2057_TX1_LOFT_FINE_Q 0x192
|
||||
|
@ -379,6 +388,7 @@
|
|||
#define R2057_TX1_TXRXCOUPLE_2G_PWRUP 0x19e
|
||||
#define R2057_TX1_TXRXCOUPLE_5G_ATTEN 0x19f
|
||||
#define R2057_TX1_TXRXCOUPLE_5G_PWRUP 0x1a0
|
||||
|
||||
#define R2057_AFE_VCM_CAL_MASTER_CORE0 0x1a1
|
||||
#define R2057_AFE_SET_VCM_I_CORE0 0x1a2
|
||||
#define R2057_AFE_SET_VCM_Q_CORE0 0x1a3
|
||||
|
|
|
@ -2146,7 +2146,196 @@ static const u16 b43_ntab_antswctl_r3[4][32] = {
|
|||
}
|
||||
};
|
||||
|
||||
/* TX gain tables */
|
||||
/* static tables, PHY revision >= 7 */
|
||||
|
||||
/* Copied from brcmsmac (5.75.11) */
|
||||
static const u32 b43_ntab_tmap_r7[] = {
|
||||
0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00000888,
|
||||
0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
|
||||
0xf1111110, 0x11111111, 0x11f11111, 0x00000111,
|
||||
0x11000000, 0x1111f111, 0x11111111, 0x111111f1,
|
||||
0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x000aa888,
|
||||
0x88880000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
|
||||
0xa1111110, 0x11111111, 0x11c11111, 0x00000111,
|
||||
0x11000000, 0x1111a111, 0x11111111, 0x111111a1,
|
||||
0xa2222220, 0x22222222, 0x22c22222, 0x00000222,
|
||||
0x22000000, 0x2222a222, 0x22222222, 0x222222a2,
|
||||
0xf1111110, 0x11111111, 0x11f11111, 0x00011111,
|
||||
0x11110000, 0x1111f111, 0x11111111, 0x111111f1,
|
||||
0xa8aa88a0, 0xa88888a8, 0xa8a8a88a, 0x00088aaa,
|
||||
0xaaaa0000, 0xa8a8aa88, 0xa88aaaaa, 0xaaaa8a8a,
|
||||
0xaaa8aaa0, 0x8aaa8aaa, 0xaa8a8a8a, 0x000aaa88,
|
||||
0x8aaa0000, 0xaaa8a888, 0x8aa88a8a, 0x8a88a888,
|
||||
0x08080a00, 0x0a08080a, 0x080a0a08, 0x00080808,
|
||||
0x080a0000, 0x080a0808, 0x080a0808, 0x0a0a0a08,
|
||||
0xa0a0a0a0, 0x80a0a080, 0x8080a0a0, 0x00008080,
|
||||
0x80a00000, 0x80a080a0, 0xa080a0a0, 0x8080a0a0,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x99999000, 0x9b9b99bb, 0x9bb99999, 0x9999b9b9,
|
||||
0x9b99bb90, 0x9bbbbb9b, 0x9b9b9bb9, 0x00000999,
|
||||
0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
|
||||
0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00aaa888,
|
||||
0x22000000, 0x2222b222, 0x22222222, 0x222222b2,
|
||||
0xb2222220, 0x22222222, 0x22d22222, 0x00000222,
|
||||
0x11000000, 0x1111a111, 0x11111111, 0x111111a1,
|
||||
0xa1111110, 0x11111111, 0x11c11111, 0x00000111,
|
||||
0x33000000, 0x3333b333, 0x33333333, 0x333333b3,
|
||||
0xb3333330, 0x33333333, 0x33d33333, 0x00000333,
|
||||
0x22000000, 0x2222a222, 0x22222222, 0x222222a2,
|
||||
0xa2222220, 0x22222222, 0x22c22222, 0x00000222,
|
||||
0x99b99b00, 0x9b9b99bb, 0x9bb99999, 0x9999b9b9,
|
||||
0x9b99bb99, 0x9bbbbb9b, 0x9b9b9bb9, 0x00000999,
|
||||
0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
|
||||
0x8a88aa88, 0x8aaaaa8a, 0x8a8a8aa8, 0x08aaa888,
|
||||
0x22222200, 0x2222f222, 0x22222222, 0x222222f2,
|
||||
0x22222222, 0x22222222, 0x22f22222, 0x00000222,
|
||||
0x11000000, 0x1111f111, 0x11111111, 0x11111111,
|
||||
0xf1111111, 0x11111111, 0x11f11111, 0x01111111,
|
||||
0xbb9bb900, 0xb9b9bb99, 0xb99bbbbb, 0xbbbb9b9b,
|
||||
0xb9bb99bb, 0xb99999b9, 0xb9b9b99b, 0x00000bbb,
|
||||
0xaa000000, 0xa8a8aa88, 0xa88aaaaa, 0xaaaa8a8a,
|
||||
0xa8aa88aa, 0xa88888a8, 0xa8a8a88a, 0x0a888aaa,
|
||||
0xaa000000, 0xa8a8aa88, 0xa88aaaaa, 0xaaaa8a8a,
|
||||
0xa8aa88a0, 0xa88888a8, 0xa8a8a88a, 0x00000aaa,
|
||||
0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
|
||||
0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00000888,
|
||||
0xbbbbbb00, 0x999bbbbb, 0x9bb99b9b, 0xb9b9b9bb,
|
||||
0xb9b99bbb, 0xb9b9b9bb, 0xb9bb9b99, 0x00000999,
|
||||
0x8a000000, 0xaa88a888, 0xa88888aa, 0xa88a8a88,
|
||||
0xa88aa88a, 0x88a8aaaa, 0xa8aa8aaa, 0x0888a88a,
|
||||
0x0b0b0b00, 0x090b0b0b, 0x0b090b0b, 0x0909090b,
|
||||
0x09090b0b, 0x09090b0b, 0x09090b09, 0x00000909,
|
||||
0x0a000000, 0x0a080808, 0x080a080a, 0x080a0a08,
|
||||
0x080a080a, 0x0808080a, 0x0a0a0a08, 0x0808080a,
|
||||
0xb0b0b000, 0x9090b0b0, 0x90b09090, 0xb0b0b090,
|
||||
0xb0b090b0, 0x90b0b0b0, 0xb0b09090, 0x00000090,
|
||||
0x80000000, 0xa080a080, 0xa08080a0, 0xa0808080,
|
||||
0xa080a080, 0x80a0a0a0, 0xa0a080a0, 0x00a0a0a0,
|
||||
0x22000000, 0x2222f222, 0x22222222, 0x222222f2,
|
||||
0xf2222220, 0x22222222, 0x22f22222, 0x00000222,
|
||||
0x11000000, 0x1111f111, 0x11111111, 0x111111f1,
|
||||
0xf1111110, 0x11111111, 0x11f11111, 0x00000111,
|
||||
0x33000000, 0x3333f333, 0x33333333, 0x333333f3,
|
||||
0xf3333330, 0x33333333, 0x33f33333, 0x00000333,
|
||||
0x22000000, 0x2222f222, 0x22222222, 0x222222f2,
|
||||
0xf2222220, 0x22222222, 0x22f22222, 0x00000222,
|
||||
0x99000000, 0x9b9b99bb, 0x9bb99999, 0x9999b9b9,
|
||||
0x9b99bb90, 0x9bbbbb9b, 0x9b9b9bb9, 0x00000999,
|
||||
0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
|
||||
0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00000888,
|
||||
0x88888000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
|
||||
0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00000888,
|
||||
0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
|
||||
0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00aaa888,
|
||||
0x88a88a00, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
|
||||
0x8a88aa88, 0x8aaaaa8a, 0x8a8a8aa8, 0x000aa888,
|
||||
0x88880000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
|
||||
0x8a88aa88, 0x8aaaaa8a, 0x8a8a8aa8, 0x08aaa888,
|
||||
0x11000000, 0x1111a111, 0x11111111, 0x111111a1,
|
||||
0xa1111110, 0x11111111, 0x11c11111, 0x00000111,
|
||||
0x11000000, 0x1111a111, 0x11111111, 0x111111a1,
|
||||
0xa1111110, 0x11111111, 0x11c11111, 0x00000111,
|
||||
0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
|
||||
0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00000888,
|
||||
0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
|
||||
0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00000888,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
};
|
||||
|
||||
/* Extracted from MMIO dump of 6.30.223.141 */
|
||||
static const u32 b43_ntab_noisevar_r7[] = {
|
||||
0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
|
||||
0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
|
||||
0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
|
||||
0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
|
||||
0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
|
||||
0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
|
||||
0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
|
||||
0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
|
||||
0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
|
||||
0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
|
||||
0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
|
||||
0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
|
||||
0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
|
||||
0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
|
||||
0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
|
||||
0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
|
||||
0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
|
||||
0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
|
||||
0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
|
||||
0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
|
||||
0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
|
||||
0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
|
||||
0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
|
||||
0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
|
||||
0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
|
||||
0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
|
||||
0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
|
||||
0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
|
||||
0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
|
||||
0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
|
||||
0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
|
||||
0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
|
||||
0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
|
||||
0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
|
||||
0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
|
||||
0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
|
||||
0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
|
||||
0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
|
||||
0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
|
||||
0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
|
||||
0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
|
||||
0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
|
||||
0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
|
||||
0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
|
||||
0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
|
||||
0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
|
||||
0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
|
||||
0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
|
||||
0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
|
||||
0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
|
||||
0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
|
||||
0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
|
||||
0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
|
||||
0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
|
||||
0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
|
||||
0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
|
||||
0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
|
||||
0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
|
||||
0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
|
||||
0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
|
||||
0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
|
||||
0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
|
||||
0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
|
||||
0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
|
||||
};
|
||||
|
||||
/**************************************************
|
||||
* TX gain tables
|
||||
**************************************************/
|
||||
|
||||
static const u32 b43_ntab_tx_gain_rev0_1_2[] = {
|
||||
0x03cc2b44, 0x03cc2b42, 0x03cc2a44, 0x03cc2a42,
|
||||
0x03cc2944, 0x03c82b44, 0x03c82b42, 0x03c82a44,
|
||||
|
@ -2182,7 +2371,9 @@ static const u32 b43_ntab_tx_gain_rev0_1_2[] = {
|
|||
0x03801442, 0x03801344, 0x03801342, 0x00002b00,
|
||||
};
|
||||
|
||||
static const u32 b43_ntab_tx_gain_rev3plus_2ghz[] = {
|
||||
/* EPA 2 GHz */
|
||||
|
||||
static const u32 b43_ntab_tx_gain_epa_rev3_2g[] = {
|
||||
0x1f410044, 0x1f410042, 0x1f410040, 0x1f41003e,
|
||||
0x1f41003c, 0x1f41003b, 0x1f410039, 0x1f410037,
|
||||
0x1e410044, 0x1e410042, 0x1e410040, 0x1e41003e,
|
||||
|
@ -2217,7 +2408,44 @@ static const u32 b43_ntab_tx_gain_rev3plus_2ghz[] = {
|
|||
0x1041003c, 0x1041003b, 0x10410039, 0x10410037,
|
||||
};
|
||||
|
||||
static const u32 b43_ntab_tx_gain_rev3_5ghz[] = {
|
||||
static const u32 b43_ntab_tx_gain_epa_rev3_hi_pwr_2g[] = {
|
||||
0x0f410044, 0x0f410042, 0x0f410040, 0x0f41003e,
|
||||
0x0f41003c, 0x0f41003b, 0x0f410039, 0x0f410037,
|
||||
0x0e410044, 0x0e410042, 0x0e410040, 0x0e41003e,
|
||||
0x0e41003c, 0x0e41003b, 0x0e410039, 0x0e410037,
|
||||
0x0d410044, 0x0d410042, 0x0d410040, 0x0d41003e,
|
||||
0x0d41003c, 0x0d41003b, 0x0d410039, 0x0d410037,
|
||||
0x0c410044, 0x0c410042, 0x0c410040, 0x0c41003e,
|
||||
0x0c41003c, 0x0c41003b, 0x0c410039, 0x0c410037,
|
||||
0x0b410044, 0x0b410042, 0x0b410040, 0x0b41003e,
|
||||
0x0b41003c, 0x0b41003b, 0x0b410039, 0x0b410037,
|
||||
0x0a410044, 0x0a410042, 0x0a410040, 0x0a41003e,
|
||||
0x0a41003c, 0x0a41003b, 0x0a410039, 0x0a410037,
|
||||
0x09410044, 0x09410042, 0x09410040, 0x0941003e,
|
||||
0x0941003c, 0x0941003b, 0x09410039, 0x09410037,
|
||||
0x08410044, 0x08410042, 0x08410040, 0x0841003e,
|
||||
0x0841003c, 0x0841003b, 0x08410039, 0x08410037,
|
||||
0x07410044, 0x07410042, 0x07410040, 0x0741003e,
|
||||
0x0741003c, 0x0741003b, 0x07410039, 0x07410037,
|
||||
0x06410044, 0x06410042, 0x06410040, 0x0641003e,
|
||||
0x0641003c, 0x0641003b, 0x06410039, 0x06410037,
|
||||
0x05410044, 0x05410042, 0x05410040, 0x0541003e,
|
||||
0x0541003c, 0x0541003b, 0x05410039, 0x05410037,
|
||||
0x04410044, 0x04410042, 0x04410040, 0x0441003e,
|
||||
0x0441003c, 0x0441003b, 0x04410039, 0x04410037,
|
||||
0x03410044, 0x03410042, 0x03410040, 0x0341003e,
|
||||
0x0341003c, 0x0341003b, 0x03410039, 0x03410037,
|
||||
0x02410044, 0x02410042, 0x02410040, 0x0241003e,
|
||||
0x0241003c, 0x0241003b, 0x02410039, 0x02410037,
|
||||
0x01410044, 0x01410042, 0x01410040, 0x0141003e,
|
||||
0x0141003c, 0x0141003b, 0x01410039, 0x01410037,
|
||||
0x00410044, 0x00410042, 0x00410040, 0x0041003e,
|
||||
0x0041003c, 0x0041003b, 0x00410039, 0x00410037
|
||||
};
|
||||
|
||||
/* EPA 5 GHz */
|
||||
|
||||
static const u32 b43_ntab_tx_gain_epa_rev3_5g[] = {
|
||||
0xcff70044, 0xcff70042, 0xcff70040, 0xcff7003e,
|
||||
0xcff7003c, 0xcff7003b, 0xcff70039, 0xcff70037,
|
||||
0xcef70044, 0xcef70042, 0xcef70040, 0xcef7003e,
|
||||
|
@ -2252,7 +2480,7 @@ static const u32 b43_ntab_tx_gain_rev3_5ghz[] = {
|
|||
0xc0f7003c, 0xc0f7003b, 0xc0f70039, 0xc0f70037,
|
||||
};
|
||||
|
||||
static const u32 b43_ntab_tx_gain_rev4_5ghz[] = {
|
||||
static const u32 b43_ntab_tx_gain_epa_rev4_5g[] = {
|
||||
0x2ff20044, 0x2ff20042, 0x2ff20040, 0x2ff2003e,
|
||||
0x2ff2003c, 0x2ff2003b, 0x2ff20039, 0x2ff20037,
|
||||
0x2ef20044, 0x2ef20042, 0x2ef20040, 0x2ef2003e,
|
||||
|
@ -2287,7 +2515,42 @@ static const u32 b43_ntab_tx_gain_rev4_5ghz[] = {
|
|||
0x20d2003a, 0x20d20038, 0x20d20036, 0x20d20034,
|
||||
};
|
||||
|
||||
static const u32 b43_ntab_tx_gain_rev5plus_5ghz[] = {
|
||||
static const u32 b43_ntab_tx_gain_epa_rev4_hi_pwr_5g[] = {
|
||||
0x2ff10044, 0x2ff10042, 0x2ff10040, 0x2ff1003e,
|
||||
0x2ff1003c, 0x2ff1003b, 0x2ff10039, 0x2ff10037,
|
||||
0x2ef10044, 0x2ef10042, 0x2ef10040, 0x2ef1003e,
|
||||
0x2ef1003c, 0x2ef1003b, 0x2ef10039, 0x2ef10037,
|
||||
0x2df10044, 0x2df10042, 0x2df10040, 0x2df1003e,
|
||||
0x2df1003c, 0x2df1003b, 0x2df10039, 0x2df10037,
|
||||
0x2cf10044, 0x2cf10042, 0x2cf10040, 0x2cf1003e,
|
||||
0x2cf1003c, 0x2cf1003b, 0x2cf10039, 0x2cf10037,
|
||||
0x2bf10044, 0x2bf10042, 0x2bf10040, 0x2bf1003e,
|
||||
0x2bf1003c, 0x2bf1003b, 0x2bf10039, 0x2bf10037,
|
||||
0x2af10044, 0x2af10042, 0x2af10040, 0x2af1003e,
|
||||
0x2af1003c, 0x2af1003b, 0x2af10039, 0x2af10037,
|
||||
0x29f10044, 0x29f10042, 0x29f10040, 0x29f1003e,
|
||||
0x29f1003c, 0x29f1003b, 0x29f10039, 0x29f10037,
|
||||
0x28f10044, 0x28f10042, 0x28f10040, 0x28f1003e,
|
||||
0x28f1003c, 0x28f1003b, 0x28f10039, 0x28f10037,
|
||||
0x27f10044, 0x27f10042, 0x27f10040, 0x27f1003e,
|
||||
0x27f1003c, 0x27f1003b, 0x27f10039, 0x27f10037,
|
||||
0x26f10044, 0x26f10042, 0x26f10040, 0x26f1003e,
|
||||
0x26f1003c, 0x26f1003b, 0x26f10039, 0x26f10037,
|
||||
0x25f10044, 0x25f10042, 0x25f10040, 0x25f1003e,
|
||||
0x25f1003c, 0x25f1003b, 0x25f10039, 0x25f10037,
|
||||
0x24f10044, 0x24f10042, 0x24f10040, 0x24f1003e,
|
||||
0x24f1003c, 0x24f1003b, 0x24f10039, 0x24f10038,
|
||||
0x23f10041, 0x23f10040, 0x23f1003f, 0x23f1003e,
|
||||
0x23f1003c, 0x23f1003b, 0x23f10039, 0x23f10037,
|
||||
0x22f10044, 0x22f10042, 0x22f10040, 0x22f1003e,
|
||||
0x22f1003c, 0x22f1003b, 0x22f10039, 0x22f10037,
|
||||
0x21f10044, 0x21f10042, 0x21f10040, 0x21f1003e,
|
||||
0x21f1003c, 0x21f1003b, 0x21f10039, 0x21f10037,
|
||||
0x20d10043, 0x20d10041, 0x20d1003e, 0x20d1003c,
|
||||
0x20d1003a, 0x20d10038, 0x20d10036, 0x20d10034
|
||||
};
|
||||
|
||||
static const u32 b43_ntab_tx_gain_epa_rev5_5g[] = {
|
||||
0x0f62004a, 0x0f620048, 0x0f620046, 0x0f620044,
|
||||
0x0f620042, 0x0f620040, 0x0f62003e, 0x0f62003c,
|
||||
0x0e620044, 0x0e620042, 0x0e620040, 0x0e62003e,
|
||||
|
@ -2322,7 +2585,9 @@ static const u32 b43_ntab_tx_gain_rev5plus_5ghz[] = {
|
|||
0x0062003b, 0x00620039, 0x00620037, 0x00620035,
|
||||
};
|
||||
|
||||
static const u32 txpwrctrl_tx_gain_ipa[] = {
|
||||
/* IPA 2 GHz */
|
||||
|
||||
static const u32 b43_ntab_tx_gain_ipa_rev3_2g[] = {
|
||||
0x5ff7002d, 0x5ff7002b, 0x5ff7002a, 0x5ff70029,
|
||||
0x5ff70028, 0x5ff70027, 0x5ff70026, 0x5ff70025,
|
||||
0x5ef7002d, 0x5ef7002b, 0x5ef7002a, 0x5ef70029,
|
||||
|
@ -2357,7 +2622,7 @@ static const u32 txpwrctrl_tx_gain_ipa[] = {
|
|||
0x50f70028, 0x50f70027, 0x50f70026, 0x50f70025,
|
||||
};
|
||||
|
||||
static const u32 txpwrctrl_tx_gain_ipa_rev5[] = {
|
||||
static const u32 b43_ntab_tx_gain_ipa_rev5_2g[] = {
|
||||
0x1ff7002d, 0x1ff7002b, 0x1ff7002a, 0x1ff70029,
|
||||
0x1ff70028, 0x1ff70027, 0x1ff70026, 0x1ff70025,
|
||||
0x1ef7002d, 0x1ef7002b, 0x1ef7002a, 0x1ef70029,
|
||||
|
@ -2392,7 +2657,7 @@ static const u32 txpwrctrl_tx_gain_ipa_rev5[] = {
|
|||
0x10f70028, 0x10f70027, 0x10f70026, 0x10f70025,
|
||||
};
|
||||
|
||||
static const u32 txpwrctrl_tx_gain_ipa_rev6[] = {
|
||||
static const u32 b43_ntab_tx_gain_ipa_rev6_2g[] = {
|
||||
0x0ff7002d, 0x0ff7002b, 0x0ff7002a, 0x0ff70029,
|
||||
0x0ff70028, 0x0ff70027, 0x0ff70026, 0x0ff70025,
|
||||
0x0ef7002d, 0x0ef7002b, 0x0ef7002a, 0x0ef70029,
|
||||
|
@ -2427,7 +2692,117 @@ static const u32 txpwrctrl_tx_gain_ipa_rev6[] = {
|
|||
0x00f70028, 0x00f70027, 0x00f70026, 0x00f70025,
|
||||
};
|
||||
|
||||
static const u32 txpwrctrl_tx_gain_ipa_5g[] = {
|
||||
/* Copied from brcmsmac (5.75.11): nphy_tpc_txgain_ipa_2g_2057rev5 */
|
||||
static const u32 b43_ntab_tx_gain_ipa_2057_rev5_2g[] = {
|
||||
0x30ff0031, 0x30e70031, 0x30e7002e, 0x30cf002e,
|
||||
0x30bf002e, 0x30af002e, 0x309f002f, 0x307f0033,
|
||||
0x307f0031, 0x307f002e, 0x3077002e, 0x306f002e,
|
||||
0x3067002e, 0x305f002f, 0x30570030, 0x3057002d,
|
||||
0x304f002e, 0x30470031, 0x3047002e, 0x3047002c,
|
||||
0x30470029, 0x303f002c, 0x303f0029, 0x3037002d,
|
||||
0x3037002a, 0x30370028, 0x302f002c, 0x302f002a,
|
||||
0x302f0028, 0x302f0026, 0x3027002c, 0x30270029,
|
||||
0x30270027, 0x30270025, 0x30270023, 0x301f002c,
|
||||
0x301f002a, 0x301f0028, 0x301f0025, 0x301f0024,
|
||||
0x301f0022, 0x301f001f, 0x3017002d, 0x3017002b,
|
||||
0x30170028, 0x30170026, 0x30170024, 0x30170022,
|
||||
0x30170020, 0x3017001e, 0x3017001d, 0x3017001b,
|
||||
0x3017001a, 0x30170018, 0x30170017, 0x30170015,
|
||||
0x300f002c, 0x300f0029, 0x300f0027, 0x300f0024,
|
||||
0x300f0022, 0x300f0021, 0x300f001f, 0x300f001d,
|
||||
0x300f001b, 0x300f001a, 0x300f0018, 0x300f0017,
|
||||
0x300f0016, 0x300f0015, 0x300f0115, 0x300f0215,
|
||||
0x300f0315, 0x300f0415, 0x300f0515, 0x300f0615,
|
||||
0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
|
||||
0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
|
||||
0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
|
||||
0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
|
||||
0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
|
||||
0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
|
||||
0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
|
||||
0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
|
||||
0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
|
||||
0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
|
||||
0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
|
||||
0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
|
||||
0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
|
||||
};
|
||||
|
||||
/* Extracted from MMIO dump of 6.30.223.141 */
|
||||
static const u32 b43_ntab_tx_gain_ipa_2057_rev9_2g[] = {
|
||||
0x60ff0031, 0x60e7002c, 0x60cf002a, 0x60c70029,
|
||||
0x60b70029, 0x60a70029, 0x609f002a, 0x6097002b,
|
||||
0x6087002e, 0x60770031, 0x606f0032, 0x60670034,
|
||||
0x60670031, 0x605f0033, 0x605f0031, 0x60570033,
|
||||
0x60570030, 0x6057002d, 0x6057002b, 0x604f002d,
|
||||
0x604f002b, 0x604f0029, 0x604f0026, 0x60470029,
|
||||
0x60470027, 0x603f0029, 0x603f0027, 0x603f0025,
|
||||
0x60370029, 0x60370027, 0x60370024, 0x602f002a,
|
||||
0x602f0028, 0x602f0026, 0x602f0024, 0x6027002a,
|
||||
0x60270028, 0x60270026, 0x60270024, 0x60270022,
|
||||
0x601f002b, 0x601f0029, 0x601f0027, 0x601f0024,
|
||||
0x601f0022, 0x601f0020, 0x601f001f, 0x601f001d,
|
||||
0x60170029, 0x60170027, 0x60170025, 0x60170023,
|
||||
0x60170021, 0x6017001f, 0x6017001d, 0x6017001c,
|
||||
0x6017001a, 0x60170018, 0x60170018, 0x60170016,
|
||||
0x60170015, 0x600f0029, 0x600f0027, 0x600f0025,
|
||||
0x600f0023, 0x600f0021, 0x600f001f, 0x600f001d,
|
||||
0x600f001c, 0x600f001a, 0x600f0019, 0x600f0018,
|
||||
0x600f0016, 0x600f0015, 0x600f0115, 0x600f0215,
|
||||
0x600f0315, 0x600f0415, 0x600f0515, 0x600f0615,
|
||||
0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
|
||||
0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
|
||||
0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
|
||||
0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
|
||||
0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
|
||||
0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
|
||||
0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
|
||||
0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
|
||||
0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
|
||||
0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
|
||||
0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
|
||||
0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
|
||||
};
|
||||
|
||||
/* Extracted from MMIO dump of 6.30.223.248 */
|
||||
static const u32 b43_ntab_tx_gain_ipa_2057_rev14_2g[] = {
|
||||
0x50df002e, 0x50cf002d, 0x50bf002c, 0x50b7002b,
|
||||
0x50af002a, 0x50a70029, 0x509f0029, 0x50970028,
|
||||
0x508f0027, 0x50870027, 0x507f0027, 0x50770027,
|
||||
0x506f0027, 0x50670027, 0x505f0028, 0x50570029,
|
||||
0x504f002b, 0x5047002e, 0x5047002b, 0x50470029,
|
||||
0x503f002c, 0x503f0029, 0x5037002c, 0x5037002a,
|
||||
0x50370028, 0x502f002d, 0x502f002b, 0x502f0028,
|
||||
0x502f0026, 0x5027002d, 0x5027002a, 0x50270028,
|
||||
0x50270026, 0x50270024, 0x501f002e, 0x501f002b,
|
||||
0x501f0029, 0x501f0027, 0x501f0024, 0x501f0022,
|
||||
0x501f0020, 0x501f001f, 0x5017002c, 0x50170029,
|
||||
0x50170027, 0x50170024, 0x50170022, 0x50170021,
|
||||
0x5017001f, 0x5017001d, 0x5017001b, 0x5017001a,
|
||||
0x50170018, 0x50170017, 0x50170015, 0x500f002c,
|
||||
0x500f002a, 0x500f0027, 0x500f0025, 0x500f0023,
|
||||
0x500f0022, 0x500f001f, 0x500f001e, 0x500f001c,
|
||||
0x500f001a, 0x500f0019, 0x500f0018, 0x500f0016,
|
||||
0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
|
||||
0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
|
||||
0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
|
||||
0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
|
||||
0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
|
||||
0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
|
||||
0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
|
||||
0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
|
||||
0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
|
||||
0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
|
||||
0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
|
||||
0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
|
||||
0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
|
||||
0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
|
||||
0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
|
||||
};
|
||||
|
||||
/* IPA 2 5Hz */
|
||||
|
||||
static const u32 b43_ntab_tx_gain_ipa_rev3_5g[] = {
|
||||
0x7ff70035, 0x7ff70033, 0x7ff70032, 0x7ff70031,
|
||||
0x7ff7002f, 0x7ff7002e, 0x7ff7002d, 0x7ff7002b,
|
||||
0x7ff7002a, 0x7ff70029, 0x7ff70028, 0x7ff70027,
|
||||
|
@ -2462,6 +2837,42 @@ static const u32 txpwrctrl_tx_gain_ipa_5g[] = {
|
|||
0x70f70021, 0x70f70020, 0x70f70020, 0x70f7001f,
|
||||
};
|
||||
|
||||
/* Extracted from MMIO dump of 6.30.223.141 */
|
||||
static const u32 b43_ntab_tx_gain_ipa_2057_rev9_5g[] = {
|
||||
0x7f7f0053, 0x7f7f004b, 0x7f7f0044, 0x7f7f003f,
|
||||
0x7f7f0039, 0x7f7f0035, 0x7f7f0032, 0x7f7f0030,
|
||||
0x7f7f002d, 0x7e7f0030, 0x7e7f002d, 0x7d7f0032,
|
||||
0x7d7f002f, 0x7d7f002c, 0x7c7f0032, 0x7c7f0030,
|
||||
0x7c7f002d, 0x7b7f0030, 0x7b7f002e, 0x7b7f002b,
|
||||
0x7a7f0032, 0x7a7f0030, 0x7a7f002d, 0x7a7f002b,
|
||||
0x797f0030, 0x797f002e, 0x797f002b, 0x797f0029,
|
||||
0x787f0030, 0x787f002d, 0x787f002b, 0x777f0032,
|
||||
0x777f0030, 0x777f002d, 0x777f002b, 0x767f0031,
|
||||
0x767f002f, 0x767f002c, 0x767f002a, 0x757f0031,
|
||||
0x757f002f, 0x757f002c, 0x757f002a, 0x747f0030,
|
||||
0x747f002d, 0x747f002b, 0x737f0032, 0x737f002f,
|
||||
0x737f002c, 0x737f002a, 0x727f0030, 0x727f002d,
|
||||
0x727f002b, 0x727f0029, 0x717f0030, 0x717f002d,
|
||||
0x717f002b, 0x707f0031, 0x707f002f, 0x707f002c,
|
||||
0x707f002a, 0x707f0027, 0x707f0025, 0x707f0023,
|
||||
0x707f0021, 0x707f001f, 0x707f001d, 0x707f001c,
|
||||
0x707f001a, 0x707f0019, 0x707f0017, 0x707f0016,
|
||||
0x707f0015, 0x707f0014, 0x707f0012, 0x707f0012,
|
||||
0x707f0011, 0x707f0010, 0x707f000f, 0x707f000e,
|
||||
0x707f000d, 0x707f000d, 0x707f000c, 0x707f000b,
|
||||
0x707f000a, 0x707f000a, 0x707f0009, 0x707f0008,
|
||||
0x707f0008, 0x707f0008, 0x707f0008, 0x707f0007,
|
||||
0x707f0007, 0x707f0006, 0x707f0006, 0x707f0006,
|
||||
0x707f0005, 0x707f0005, 0x707f0005, 0x707f0004,
|
||||
0x707f0004, 0x707f0004, 0x707f0003, 0x707f0003,
|
||||
0x707f0003, 0x707f0003, 0x707f0003, 0x707f0003,
|
||||
0x707f0003, 0x707f0003, 0x707f0003, 0x707f0003,
|
||||
0x707f0002, 0x707f0002, 0x707f0002, 0x707f0002,
|
||||
0x707f0002, 0x707f0002, 0x707f0002, 0x707f0002,
|
||||
0x707f0002, 0x707f0001, 0x707f0001, 0x707f0001,
|
||||
0x707f0001, 0x707f0001, 0x707f0001, 0x707f0001,
|
||||
};
|
||||
|
||||
const s8 b43_ntab_papd_pga_gain_delta_ipa_2g[] = {
|
||||
-114, -108, -98, -91, -84, -78, -70, -62,
|
||||
-54, -46, -39, -31, -23, -15, -8, 0
|
||||
|
@ -3031,6 +3442,91 @@ void b43_ntab_write_bulk(struct b43_wldev *dev, u32 offset,
|
|||
b43_ntab_write_bulk(dev, offset, ARRAY_SIZE(data), data); \
|
||||
} while (0)
|
||||
|
||||
static void b43_nphy_tables_init_shared_lut(struct b43_wldev *dev)
|
||||
{
|
||||
ntab_upload(dev, B43_NTAB_C0_ESTPLT_R3, b43_ntab_estimatepowerlt0_r3);
|
||||
ntab_upload(dev, B43_NTAB_C1_ESTPLT_R3, b43_ntab_estimatepowerlt1_r3);
|
||||
ntab_upload(dev, B43_NTAB_C0_ADJPLT_R3, b43_ntab_adjustpower0_r3);
|
||||
ntab_upload(dev, B43_NTAB_C1_ADJPLT_R3, b43_ntab_adjustpower1_r3);
|
||||
ntab_upload(dev, B43_NTAB_C0_GAINCTL_R3, b43_ntab_gainctl0_r3);
|
||||
ntab_upload(dev, B43_NTAB_C1_GAINCTL_R3, b43_ntab_gainctl1_r3);
|
||||
ntab_upload(dev, B43_NTAB_C0_IQLT_R3, b43_ntab_iqlt0_r3);
|
||||
ntab_upload(dev, B43_NTAB_C1_IQLT_R3, b43_ntab_iqlt1_r3);
|
||||
ntab_upload(dev, B43_NTAB_C0_LOFEEDTH_R3, b43_ntab_loftlt0_r3);
|
||||
ntab_upload(dev, B43_NTAB_C1_LOFEEDTH_R3, b43_ntab_loftlt1_r3);
|
||||
}
|
||||
|
||||
static void b43_nphy_tables_init_rev7_volatile(struct b43_wldev *dev)
|
||||
{
|
||||
struct ssb_sprom *sprom = dev->dev->bus_sprom;
|
||||
u8 antswlut;
|
||||
int core, offset, i;
|
||||
|
||||
const int antswlut0_offsets[] = { 0, 4, 8, }; /* Offsets for values */
|
||||
const u8 antswlut0_values[][3] = {
|
||||
{ 0x2, 0x12, 0x8 }, /* Core 0 */
|
||||
{ 0x2, 0x18, 0x2 }, /* Core 1 */
|
||||
};
|
||||
|
||||
if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
|
||||
antswlut = sprom->fem.ghz5.antswlut;
|
||||
else
|
||||
antswlut = sprom->fem.ghz2.antswlut;
|
||||
|
||||
switch (antswlut) {
|
||||
case 0:
|
||||
for (core = 0; core < 2; core++) {
|
||||
for (i = 0; i < ARRAY_SIZE(antswlut0_values[0]); i++) {
|
||||
offset = core ? 0x20 : 0x00;
|
||||
offset += antswlut0_offsets[i];
|
||||
b43_ntab_write(dev, B43_NTAB8(9, offset),
|
||||
antswlut0_values[core][i]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
b43err(dev->wl, "Unsupported antswlut: %d\n", antswlut);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void b43_nphy_tables_init_rev16(struct b43_wldev *dev)
|
||||
{
|
||||
/* Static tables */
|
||||
if (dev->phy.do_full_init) {
|
||||
ntab_upload(dev, B43_NTAB_NOISEVAR_R7, b43_ntab_noisevar_r7);
|
||||
b43_nphy_tables_init_shared_lut(dev);
|
||||
}
|
||||
|
||||
/* Volatile tables */
|
||||
b43_nphy_tables_init_rev7_volatile(dev);
|
||||
}
|
||||
|
||||
static void b43_nphy_tables_init_rev7(struct b43_wldev *dev)
|
||||
{
|
||||
/* Static tables */
|
||||
if (dev->phy.do_full_init) {
|
||||
ntab_upload(dev, B43_NTAB_FRAMESTRUCT_R3, b43_ntab_framestruct_r3);
|
||||
ntab_upload(dev, B43_NTAB_PILOT_R3, b43_ntab_pilot_r3);
|
||||
ntab_upload(dev, B43_NTAB_TMAP_R7, b43_ntab_tmap_r7);
|
||||
ntab_upload(dev, B43_NTAB_INTLEVEL_R3, b43_ntab_intlevel_r3);
|
||||
ntab_upload(dev, B43_NTAB_TDTRN_R3, b43_ntab_tdtrn_r3);
|
||||
ntab_upload(dev, B43_NTAB_NOISEVAR_R7, b43_ntab_noisevar_r7);
|
||||
ntab_upload(dev, B43_NTAB_MCS_R3, b43_ntab_mcs_r3);
|
||||
ntab_upload(dev, B43_NTAB_TDI20A0_R3, b43_ntab_tdi20a0_r3);
|
||||
ntab_upload(dev, B43_NTAB_TDI20A1_R3, b43_ntab_tdi20a1_r3);
|
||||
ntab_upload(dev, B43_NTAB_TDI40A0_R3, b43_ntab_tdi40a0_r3);
|
||||
ntab_upload(dev, B43_NTAB_TDI40A1_R3, b43_ntab_tdi40a1_r3);
|
||||
ntab_upload(dev, B43_NTAB_PILOTLT_R3, b43_ntab_pilotlt_r3);
|
||||
ntab_upload(dev, B43_NTAB_CHANEST_R3, b43_ntab_channelest_r3);
|
||||
ntab_upload(dev, B43_NTAB_FRAMELT_R3, b43_ntab_framelookup_r3);
|
||||
b43_nphy_tables_init_shared_lut(dev);
|
||||
}
|
||||
|
||||
/* Volatile tables */
|
||||
b43_nphy_tables_init_rev7_volatile(dev);
|
||||
}
|
||||
|
||||
static void b43_nphy_tables_init_rev3(struct b43_wldev *dev)
|
||||
{
|
||||
struct ssb_sprom *sprom = dev->dev->bus_sprom;
|
||||
|
@ -3057,16 +3553,7 @@ static void b43_nphy_tables_init_rev3(struct b43_wldev *dev)
|
|||
ntab_upload(dev, B43_NTAB_PILOTLT_R3, b43_ntab_pilotlt_r3);
|
||||
ntab_upload(dev, B43_NTAB_CHANEST_R3, b43_ntab_channelest_r3);
|
||||
ntab_upload(dev, B43_NTAB_FRAMELT_R3, b43_ntab_framelookup_r3);
|
||||
ntab_upload(dev, B43_NTAB_C0_ESTPLT_R3, b43_ntab_estimatepowerlt0_r3);
|
||||
ntab_upload(dev, B43_NTAB_C1_ESTPLT_R3, b43_ntab_estimatepowerlt1_r3);
|
||||
ntab_upload(dev, B43_NTAB_C0_ADJPLT_R3, b43_ntab_adjustpower0_r3);
|
||||
ntab_upload(dev, B43_NTAB_C1_ADJPLT_R3, b43_ntab_adjustpower1_r3);
|
||||
ntab_upload(dev, B43_NTAB_C0_GAINCTL_R3, b43_ntab_gainctl0_r3);
|
||||
ntab_upload(dev, B43_NTAB_C1_GAINCTL_R3, b43_ntab_gainctl1_r3);
|
||||
ntab_upload(dev, B43_NTAB_C0_IQLT_R3, b43_ntab_iqlt0_r3);
|
||||
ntab_upload(dev, B43_NTAB_C1_IQLT_R3, b43_ntab_iqlt1_r3);
|
||||
ntab_upload(dev, B43_NTAB_C0_LOFEEDTH_R3, b43_ntab_loftlt0_r3);
|
||||
ntab_upload(dev, B43_NTAB_C1_LOFEEDTH_R3, b43_ntab_loftlt1_r3);
|
||||
b43_nphy_tables_init_shared_lut(dev);
|
||||
}
|
||||
|
||||
/* Volatile tables */
|
||||
|
@ -3115,7 +3602,11 @@ static void b43_nphy_tables_init_rev0(struct b43_wldev *dev)
|
|||
/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/InitTables */
|
||||
void b43_nphy_tables_init(struct b43_wldev *dev)
|
||||
{
|
||||
if (dev->phy.rev >= 3)
|
||||
if (dev->phy.rev >= 16)
|
||||
b43_nphy_tables_init_rev16(dev);
|
||||
else if (dev->phy.rev >= 7)
|
||||
b43_nphy_tables_init_rev7(dev);
|
||||
else if (dev->phy.rev >= 3)
|
||||
b43_nphy_tables_init_rev3(dev);
|
||||
else
|
||||
b43_nphy_tables_init_rev0(dev);
|
||||
|
@ -3124,23 +3615,55 @@ void b43_nphy_tables_init(struct b43_wldev *dev)
|
|||
/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/GetIpaGainTbl */
|
||||
static const u32 *b43_nphy_get_ipa_gain_table(struct b43_wldev *dev)
|
||||
{
|
||||
struct b43_phy *phy = &dev->phy;
|
||||
|
||||
if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
|
||||
if (dev->phy.rev >= 6) {
|
||||
if (dev->dev->chip_id == 47162)
|
||||
return txpwrctrl_tx_gain_ipa_rev5;
|
||||
return txpwrctrl_tx_gain_ipa_rev6;
|
||||
} else if (dev->phy.rev >= 5) {
|
||||
return txpwrctrl_tx_gain_ipa_rev5;
|
||||
} else {
|
||||
return txpwrctrl_tx_gain_ipa;
|
||||
switch (phy->rev) {
|
||||
case 17:
|
||||
if (phy->radio_rev == 14)
|
||||
return b43_ntab_tx_gain_ipa_2057_rev14_2g;
|
||||
break;
|
||||
case 16:
|
||||
if (phy->radio_rev == 9)
|
||||
return b43_ntab_tx_gain_ipa_2057_rev9_2g;
|
||||
break;
|
||||
case 8:
|
||||
if (phy->radio_rev == 5)
|
||||
return b43_ntab_tx_gain_ipa_2057_rev5_2g;
|
||||
break;
|
||||
case 6:
|
||||
if (dev->dev->chip_id == BCMA_CHIP_ID_BCM47162)
|
||||
return b43_ntab_tx_gain_ipa_rev5_2g;
|
||||
return b43_ntab_tx_gain_ipa_rev6_2g;
|
||||
case 5:
|
||||
return b43_ntab_tx_gain_ipa_rev5_2g;
|
||||
case 4:
|
||||
case 3:
|
||||
return b43_ntab_tx_gain_ipa_rev3_2g;
|
||||
}
|
||||
|
||||
b43err(dev->wl,
|
||||
"No 2GHz IPA gain table available for this device\n");
|
||||
return NULL;
|
||||
} else {
|
||||
return txpwrctrl_tx_gain_ipa_5g;
|
||||
switch (phy->rev) {
|
||||
case 16:
|
||||
if (phy->radio_rev == 9)
|
||||
return b43_ntab_tx_gain_ipa_2057_rev9_5g;
|
||||
break;
|
||||
case 3 ... 6:
|
||||
return b43_ntab_tx_gain_ipa_rev3_5g;
|
||||
}
|
||||
|
||||
b43err(dev->wl,
|
||||
"No 5GHz IPA gain table available for this device\n");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
const u32 *b43_nphy_get_tx_gain_table(struct b43_wldev *dev)
|
||||
{
|
||||
struct b43_phy *phy = &dev->phy;
|
||||
enum ieee80211_band band = b43_current_band(dev->wl);
|
||||
struct ssb_sprom *sprom = dev->dev->bus_sprom;
|
||||
|
||||
|
@ -3152,19 +3675,36 @@ const u32 *b43_nphy_get_tx_gain_table(struct b43_wldev *dev)
|
|||
(dev->phy.n->ipa5g_on && band == IEEE80211_BAND_5GHZ)) {
|
||||
return b43_nphy_get_ipa_gain_table(dev);
|
||||
} else if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
|
||||
if (dev->phy.rev == 3)
|
||||
return b43_ntab_tx_gain_rev3_5ghz;
|
||||
if (dev->phy.rev == 4)
|
||||
switch (phy->rev) {
|
||||
case 6:
|
||||
case 5:
|
||||
return b43_ntab_tx_gain_epa_rev5_5g;
|
||||
case 4:
|
||||
return sprom->fem.ghz5.extpa_gain == 3 ?
|
||||
b43_ntab_tx_gain_rev4_5ghz :
|
||||
b43_ntab_tx_gain_rev4_5ghz; /* FIXME */
|
||||
else
|
||||
return b43_ntab_tx_gain_rev5plus_5ghz;
|
||||
b43_ntab_tx_gain_epa_rev4_5g :
|
||||
b43_ntab_tx_gain_epa_rev4_hi_pwr_5g;
|
||||
case 3:
|
||||
return b43_ntab_tx_gain_epa_rev3_5g;
|
||||
default:
|
||||
b43err(dev->wl,
|
||||
"No 5GHz EPA gain table available for this device\n");
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
if (dev->phy.rev >= 5 && sprom->fem.ghz5.extpa_gain == 3)
|
||||
return b43_ntab_tx_gain_rev3plus_2ghz; /* FIXME */
|
||||
else
|
||||
return b43_ntab_tx_gain_rev3plus_2ghz;
|
||||
switch (phy->rev) {
|
||||
case 6:
|
||||
case 5:
|
||||
if (sprom->fem.ghz5.extpa_gain == 3)
|
||||
return b43_ntab_tx_gain_epa_rev3_hi_pwr_2g;
|
||||
/* fall through */
|
||||
case 4:
|
||||
case 3:
|
||||
return b43_ntab_tx_gain_epa_rev3_2g;
|
||||
default:
|
||||
b43err(dev->wl,
|
||||
"No 2GHz EPA gain table available for this device\n");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -165,6 +165,10 @@ struct nphy_gain_ctl_workaround_entry *b43_nphy_get_gain_ctl_workaround_ent(
|
|||
#define B43_NTAB_C1_LOFEEDTH_R3 B43_NTAB16(27, 448) /* Local Oscillator Feed Through lookup 1 */
|
||||
#define B43_NTAB_C1_PAPD_COMP_R3 B43_NTAB16(27, 576)
|
||||
|
||||
/* Static N-PHY tables, PHY revision >= 7 */
|
||||
#define B43_NTAB_TMAP_R7 B43_NTAB32(12, 0) /* TM AP */
|
||||
#define B43_NTAB_NOISEVAR_R7 B43_NTAB32(16, 0) /* noise variance */
|
||||
|
||||
#define B43_NTAB_TX_IQLO_CAL_LOFT_LADDER_40_SIZE 18
|
||||
#define B43_NTAB_TX_IQLO_CAL_LOFT_LADDER_20_SIZE 18
|
||||
#define B43_NTAB_TX_IQLO_CAL_IQIMB_LADDER_40_SIZE 18
|
||||
|
|
|
@ -811,9 +811,13 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
|
|||
break;
|
||||
case B43_PHYTYPE_G:
|
||||
status.band = IEEE80211_BAND_2GHZ;
|
||||
/* chanid is the radio channel cookie value as used
|
||||
* to tune the radio. */
|
||||
status.freq = chanid + 2400;
|
||||
/* Somewhere between 478.104 and 508.1084 firmware for G-PHY
|
||||
* has been modified to be compatible with N-PHY and others.
|
||||
*/
|
||||
if (dev->fw.rev >= 508)
|
||||
status.freq = ieee80211_channel_to_frequency(chanid, status.band);
|
||||
else
|
||||
status.freq = chanid + 2400;
|
||||
break;
|
||||
case B43_PHYTYPE_N:
|
||||
case B43_PHYTYPE_LP:
|
||||
|
|
|
@ -34,6 +34,7 @@ brcmfmac-objs += \
|
|||
dhd_common.o \
|
||||
dhd_linux.o \
|
||||
firmware.o \
|
||||
feature.o \
|
||||
btcoex.o \
|
||||
vendor.o
|
||||
brcmfmac-$(CONFIG_BRCMFMAC_SDIO) += \
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
#include <linux/mmc/sdio.h>
|
||||
#include <linux/mmc/core.h>
|
||||
#include <linux/mmc/sdio_func.h>
|
||||
#include <linux/mmc/sdio_ids.h>
|
||||
#include <linux/mmc/card.h>
|
||||
#include <linux/mmc/host.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
@ -979,18 +978,20 @@ static int brcmf_sdiod_probe(struct brcmf_sdio_dev *sdiodev)
|
|||
return ret;
|
||||
}
|
||||
|
||||
#define BRCMF_SDIO_DEVICE(dev_id) \
|
||||
{SDIO_DEVICE(BRCM_SDIO_VENDOR_ID_BROADCOM, dev_id)}
|
||||
|
||||
/* devices we support, null terminated */
|
||||
static const struct sdio_device_id brcmf_sdmmc_ids[] = {
|
||||
{SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_43143)},
|
||||
{SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_43241)},
|
||||
{SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4329)},
|
||||
{SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4330)},
|
||||
{SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4334)},
|
||||
{SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_43362)},
|
||||
{SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM,
|
||||
SDIO_DEVICE_ID_BROADCOM_4335_4339)},
|
||||
{SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4354)},
|
||||
{ /* end: all zeroes */ },
|
||||
BRCMF_SDIO_DEVICE(BRCM_SDIO_43143_DEVICE_ID),
|
||||
BRCMF_SDIO_DEVICE(BRCM_SDIO_43241_DEVICE_ID),
|
||||
BRCMF_SDIO_DEVICE(BRCM_SDIO_4329_DEVICE_ID),
|
||||
BRCMF_SDIO_DEVICE(BRCM_SDIO_4330_DEVICE_ID),
|
||||
BRCMF_SDIO_DEVICE(BRCM_SDIO_4334_DEVICE_ID),
|
||||
BRCMF_SDIO_DEVICE(BRCM_SDIO_43362_DEVICE_ID),
|
||||
BRCMF_SDIO_DEVICE(BRCM_SDIO_4335_4339_DEVICE_ID),
|
||||
BRCMF_SDIO_DEVICE(BRCM_SDIO_4354_DEVICE_ID),
|
||||
{ /* end: all zeroes */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids);
|
||||
|
||||
|
|
|
@ -482,30 +482,30 @@ static inline int brcmf_chip_cores_check(struct brcmf_chip_priv *ci)
|
|||
static void brcmf_chip_get_raminfo(struct brcmf_chip_priv *ci)
|
||||
{
|
||||
switch (ci->pub.chip) {
|
||||
case BCM4329_CHIP_ID:
|
||||
case BRCM_CC_4329_CHIP_ID:
|
||||
ci->pub.ramsize = BCM4329_RAMSIZE;
|
||||
break;
|
||||
case BCM43143_CHIP_ID:
|
||||
case BRCM_CC_43143_CHIP_ID:
|
||||
ci->pub.ramsize = BCM43143_RAMSIZE;
|
||||
break;
|
||||
case BCM43241_CHIP_ID:
|
||||
case BRCM_CC_43241_CHIP_ID:
|
||||
ci->pub.ramsize = 0x90000;
|
||||
break;
|
||||
case BCM4330_CHIP_ID:
|
||||
case BRCM_CC_4330_CHIP_ID:
|
||||
ci->pub.ramsize = 0x48000;
|
||||
break;
|
||||
case BCM4334_CHIP_ID:
|
||||
case BRCM_CC_4334_CHIP_ID:
|
||||
ci->pub.ramsize = 0x80000;
|
||||
break;
|
||||
case BCM4335_CHIP_ID:
|
||||
case BRCM_CC_4335_CHIP_ID:
|
||||
ci->pub.ramsize = 0xc0000;
|
||||
ci->pub.rambase = 0x180000;
|
||||
break;
|
||||
case BCM43362_CHIP_ID:
|
||||
case BRCM_CC_43362_CHIP_ID:
|
||||
ci->pub.ramsize = 0x3c000;
|
||||
break;
|
||||
case BCM4339_CHIP_ID:
|
||||
case BCM4354_CHIP_ID:
|
||||
case BRCM_CC_4339_CHIP_ID:
|
||||
case BRCM_CC_4354_CHIP_ID:
|
||||
ci->pub.ramsize = 0xc0000;
|
||||
ci->pub.rambase = 0x180000;
|
||||
break;
|
||||
|
@ -682,7 +682,7 @@ static int brcmf_chip_recognition(struct brcmf_chip_priv *ci)
|
|||
ci->pub.chiprev);
|
||||
|
||||
if (socitype == SOCI_SB) {
|
||||
if (ci->pub.chip != BCM4329_CHIP_ID) {
|
||||
if (ci->pub.chip != BRCM_CC_4329_CHIP_ID) {
|
||||
brcmf_err("SB chip is not supported\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
@ -1008,13 +1008,13 @@ bool brcmf_chip_sr_capable(struct brcmf_chip *pub)
|
|||
chip = container_of(pub, struct brcmf_chip_priv, pub);
|
||||
|
||||
switch (pub->chip) {
|
||||
case BCM4354_CHIP_ID:
|
||||
case BRCM_CC_4354_CHIP_ID:
|
||||
/* explicitly check SR engine enable bit */
|
||||
pmu_cc3_mask = BIT(2);
|
||||
/* fall-through */
|
||||
case BCM43241_CHIP_ID:
|
||||
case BCM4335_CHIP_ID:
|
||||
case BCM4339_CHIP_ID:
|
||||
case BRCM_CC_43241_CHIP_ID:
|
||||
case BRCM_CC_4335_CHIP_ID:
|
||||
case BRCM_CC_4339_CHIP_ID:
|
||||
/* read PMU chipcontrol register 3 */
|
||||
addr = CORE_CC_REG(base, chipcontrol_addr);
|
||||
chip->ops->write32(chip->ctx, addr, 3);
|
||||
|
|
|
@ -103,6 +103,10 @@ struct brcmf_pub {
|
|||
|
||||
struct brcmf_ampdu_rx_reorder
|
||||
*reorder_flows[BRCMF_AMPDU_RX_REORDER_MAXFLOWS];
|
||||
|
||||
u32 feat_flags;
|
||||
u32 chip_quirks;
|
||||
|
||||
#ifdef DEBUG
|
||||
struct dentry *dbgfs_dir;
|
||||
#endif
|
||||
|
@ -175,7 +179,6 @@ struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx, s32 ifidx,
|
|||
void brcmf_del_if(struct brcmf_pub *drvr, s32 bssidx);
|
||||
void brcmf_txflowblock_if(struct brcmf_if *ifp,
|
||||
enum brcmf_netif_stop_reason reason, bool state);
|
||||
u32 brcmf_get_chip_info(struct brcmf_if *ifp);
|
||||
void brcmf_txfinalize(struct brcmf_pub *drvr, struct sk_buff *txp, u8 ifidx,
|
||||
bool success);
|
||||
|
||||
|
|
|
@ -41,37 +41,12 @@ void brcmf_debugfs_exit(void)
|
|||
root_folder = NULL;
|
||||
}
|
||||
|
||||
static
|
||||
ssize_t brcmf_debugfs_chipinfo_read(struct file *f, char __user *data,
|
||||
size_t count, loff_t *ppos)
|
||||
static int brcmf_debugfs_chipinfo_read(struct seq_file *seq, void *data)
|
||||
{
|
||||
struct brcmf_pub *drvr = f->private_data;
|
||||
struct brcmf_bus *bus = drvr->bus_if;
|
||||
char buf[40];
|
||||
int res;
|
||||
struct brcmf_bus *bus = dev_get_drvdata(seq->private);
|
||||
|
||||
/* only allow read from start */
|
||||
if (*ppos > 0)
|
||||
return 0;
|
||||
|
||||
res = scnprintf(buf, sizeof(buf), "chip: %x(%u) rev %u\n",
|
||||
bus->chip, bus->chip, bus->chiprev);
|
||||
return simple_read_from_buffer(data, count, ppos, buf, res);
|
||||
}
|
||||
|
||||
static const struct file_operations brcmf_debugfs_chipinfo_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = simple_open,
|
||||
.read = brcmf_debugfs_chipinfo_read
|
||||
};
|
||||
|
||||
static int brcmf_debugfs_create_chipinfo(struct brcmf_pub *drvr)
|
||||
{
|
||||
struct dentry *dentry = drvr->dbgfs_dir;
|
||||
|
||||
if (!IS_ERR_OR_NULL(dentry))
|
||||
debugfs_create_file("chipinfo", S_IRUGO, dentry, drvr,
|
||||
&brcmf_debugfs_chipinfo_ops);
|
||||
seq_printf(seq, "chip: %x(%u) rev %u\n",
|
||||
bus->chip, bus->chip, bus->chiprev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -83,7 +58,8 @@ int brcmf_debugfs_attach(struct brcmf_pub *drvr)
|
|||
return -ENODEV;
|
||||
|
||||
drvr->dbgfs_dir = debugfs_create_dir(dev_name(dev), root_folder);
|
||||
brcmf_debugfs_create_chipinfo(drvr);
|
||||
brcmf_debugfs_add_entry(drvr, "chipinfo", brcmf_debugfs_chipinfo_read);
|
||||
|
||||
return PTR_ERR_OR_ZERO(drvr->dbgfs_dir);
|
||||
}
|
||||
|
||||
|
@ -98,148 +74,44 @@ struct dentry *brcmf_debugfs_get_devdir(struct brcmf_pub *drvr)
|
|||
return drvr->dbgfs_dir;
|
||||
}
|
||||
|
||||
static
|
||||
ssize_t brcmf_debugfs_sdio_counter_read(struct file *f, char __user *data,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct brcmf_sdio_count *sdcnt = f->private_data;
|
||||
char buf[750];
|
||||
int res;
|
||||
|
||||
/* only allow read from start */
|
||||
if (*ppos > 0)
|
||||
return 0;
|
||||
|
||||
res = scnprintf(buf, sizeof(buf),
|
||||
"intrcount: %u\nlastintrs: %u\n"
|
||||
"pollcnt: %u\nregfails: %u\n"
|
||||
"tx_sderrs: %u\nfcqueued: %u\n"
|
||||
"rxrtx: %u\nrx_toolong: %u\n"
|
||||
"rxc_errors: %u\nrx_hdrfail: %u\n"
|
||||
"rx_badhdr: %u\nrx_badseq: %u\n"
|
||||
"fc_rcvd: %u\nfc_xoff: %u\n"
|
||||
"fc_xon: %u\nrxglomfail: %u\n"
|
||||
"rxglomframes: %u\nrxglompkts: %u\n"
|
||||
"f2rxhdrs: %u\nf2rxdata: %u\n"
|
||||
"f2txdata: %u\nf1regdata: %u\n"
|
||||
"tickcnt: %u\ntx_ctlerrs: %lu\n"
|
||||
"tx_ctlpkts: %lu\nrx_ctlerrs: %lu\n"
|
||||
"rx_ctlpkts: %lu\nrx_readahead: %lu\n",
|
||||
sdcnt->intrcount, sdcnt->lastintrs,
|
||||
sdcnt->pollcnt, sdcnt->regfails,
|
||||
sdcnt->tx_sderrs, sdcnt->fcqueued,
|
||||
sdcnt->rxrtx, sdcnt->rx_toolong,
|
||||
sdcnt->rxc_errors, sdcnt->rx_hdrfail,
|
||||
sdcnt->rx_badhdr, sdcnt->rx_badseq,
|
||||
sdcnt->fc_rcvd, sdcnt->fc_xoff,
|
||||
sdcnt->fc_xon, sdcnt->rxglomfail,
|
||||
sdcnt->rxglomframes, sdcnt->rxglompkts,
|
||||
sdcnt->f2rxhdrs, sdcnt->f2rxdata,
|
||||
sdcnt->f2txdata, sdcnt->f1regdata,
|
||||
sdcnt->tickcnt, sdcnt->tx_ctlerrs,
|
||||
sdcnt->tx_ctlpkts, sdcnt->rx_ctlerrs,
|
||||
sdcnt->rx_ctlpkts, sdcnt->rx_readahead_cnt);
|
||||
|
||||
return simple_read_from_buffer(data, count, ppos, buf, res);
|
||||
}
|
||||
|
||||
static const struct file_operations brcmf_debugfs_sdio_counter_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = simple_open,
|
||||
.read = brcmf_debugfs_sdio_counter_read
|
||||
struct brcmf_debugfs_entry {
|
||||
int (*read)(struct seq_file *seq, void *data);
|
||||
struct brcmf_pub *drvr;
|
||||
};
|
||||
|
||||
void brcmf_debugfs_create_sdio_count(struct brcmf_pub *drvr,
|
||||
struct brcmf_sdio_count *sdcnt)
|
||||
static int brcmf_debugfs_entry_open(struct inode *inode, struct file *f)
|
||||
{
|
||||
struct dentry *dentry = drvr->dbgfs_dir;
|
||||
struct brcmf_debugfs_entry *entry = inode->i_private;
|
||||
|
||||
if (!IS_ERR_OR_NULL(dentry))
|
||||
debugfs_create_file("counters", S_IRUGO, dentry,
|
||||
sdcnt, &brcmf_debugfs_sdio_counter_ops);
|
||||
return single_open(f, entry->read, entry->drvr->bus_if->dev);
|
||||
}
|
||||
|
||||
static
|
||||
ssize_t brcmf_debugfs_fws_stats_read(struct file *f, char __user *data,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct brcmf_fws_stats *fwstats = f->private_data;
|
||||
char buf[650];
|
||||
int res;
|
||||
|
||||
/* only allow read from start */
|
||||
if (*ppos > 0)
|
||||
return 0;
|
||||
|
||||
res = scnprintf(buf, sizeof(buf),
|
||||
"header_pulls: %u\n"
|
||||
"header_only_pkt: %u\n"
|
||||
"tlv_parse_failed: %u\n"
|
||||
"tlv_invalid_type: %u\n"
|
||||
"mac_update_fails: %u\n"
|
||||
"ps_update_fails: %u\n"
|
||||
"if_update_fails: %u\n"
|
||||
"pkt2bus: %u\n"
|
||||
"generic_error: %u\n"
|
||||
"rollback_success: %u\n"
|
||||
"rollback_failed: %u\n"
|
||||
"delayq_full: %u\n"
|
||||
"supprq_full: %u\n"
|
||||
"txs_indicate: %u\n"
|
||||
"txs_discard: %u\n"
|
||||
"txs_suppr_core: %u\n"
|
||||
"txs_suppr_ps: %u\n"
|
||||
"txs_tossed: %u\n"
|
||||
"txs_host_tossed: %u\n"
|
||||
"bus_flow_block: %u\n"
|
||||
"fws_flow_block: %u\n"
|
||||
"send_pkts: BK:%u BE:%u VO:%u VI:%u BCMC:%u\n"
|
||||
"requested_sent: BK:%u BE:%u VO:%u VI:%u BCMC:%u\n",
|
||||
fwstats->header_pulls,
|
||||
fwstats->header_only_pkt,
|
||||
fwstats->tlv_parse_failed,
|
||||
fwstats->tlv_invalid_type,
|
||||
fwstats->mac_update_failed,
|
||||
fwstats->mac_ps_update_failed,
|
||||
fwstats->if_update_failed,
|
||||
fwstats->pkt2bus,
|
||||
fwstats->generic_error,
|
||||
fwstats->rollback_success,
|
||||
fwstats->rollback_failed,
|
||||
fwstats->delayq_full_error,
|
||||
fwstats->supprq_full_error,
|
||||
fwstats->txs_indicate,
|
||||
fwstats->txs_discard,
|
||||
fwstats->txs_supp_core,
|
||||
fwstats->txs_supp_ps,
|
||||
fwstats->txs_tossed,
|
||||
fwstats->txs_host_tossed,
|
||||
fwstats->bus_flow_block,
|
||||
fwstats->fws_flow_block,
|
||||
fwstats->send_pkts[0], fwstats->send_pkts[1],
|
||||
fwstats->send_pkts[2], fwstats->send_pkts[3],
|
||||
fwstats->send_pkts[4],
|
||||
fwstats->requested_sent[0],
|
||||
fwstats->requested_sent[1],
|
||||
fwstats->requested_sent[2],
|
||||
fwstats->requested_sent[3],
|
||||
fwstats->requested_sent[4]);
|
||||
|
||||
return simple_read_from_buffer(data, count, ppos, buf, res);
|
||||
}
|
||||
|
||||
static const struct file_operations brcmf_debugfs_fws_stats_ops = {
|
||||
static const struct file_operations brcmf_debugfs_def_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = simple_open,
|
||||
.read = brcmf_debugfs_fws_stats_read
|
||||
.open = brcmf_debugfs_entry_open,
|
||||
.release = single_release,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek
|
||||
};
|
||||
|
||||
void brcmf_debugfs_create_fws_stats(struct brcmf_pub *drvr,
|
||||
struct brcmf_fws_stats *stats)
|
||||
int brcmf_debugfs_add_entry(struct brcmf_pub *drvr, const char *fn,
|
||||
int (*read_fn)(struct seq_file *seq, void *data))
|
||||
{
|
||||
struct dentry *dentry = drvr->dbgfs_dir;
|
||||
struct brcmf_debugfs_entry *entry;
|
||||
|
||||
if (!IS_ERR_OR_NULL(dentry))
|
||||
debugfs_create_file("fws_stats", S_IRUGO, dentry,
|
||||
stats, &brcmf_debugfs_fws_stats_ops);
|
||||
if (IS_ERR_OR_NULL(dentry))
|
||||
return -ENOENT;
|
||||
|
||||
entry = devm_kzalloc(drvr->bus_if->dev, sizeof(*entry), GFP_KERNEL);
|
||||
if (!entry)
|
||||
return -ENOMEM;
|
||||
|
||||
entry->read = read_fn;
|
||||
entry->drvr = drvr;
|
||||
|
||||
dentry = debugfs_create_file(fn, S_IRUGO, dentry, entry,
|
||||
&brcmf_debugfs_def_ops);
|
||||
|
||||
return PTR_ERR_OR_ZERO(dentry);
|
||||
}
|
||||
|
|
|
@ -100,68 +100,6 @@ do { \
|
|||
|
||||
extern int brcmf_msg_level;
|
||||
|
||||
/*
|
||||
* hold counter variables used in brcmfmac sdio driver.
|
||||
*/
|
||||
struct brcmf_sdio_count {
|
||||
uint intrcount; /* Count of device interrupt callbacks */
|
||||
uint lastintrs; /* Count as of last watchdog timer */
|
||||
uint pollcnt; /* Count of active polls */
|
||||
uint regfails; /* Count of R_REG failures */
|
||||
uint tx_sderrs; /* Count of tx attempts with sd errors */
|
||||
uint fcqueued; /* Tx packets that got queued */
|
||||
uint rxrtx; /* Count of rtx requests (NAK to dongle) */
|
||||
uint rx_toolong; /* Receive frames too long to receive */
|
||||
uint rxc_errors; /* SDIO errors when reading control frames */
|
||||
uint rx_hdrfail; /* SDIO errors on header reads */
|
||||
uint rx_badhdr; /* Bad received headers (roosync?) */
|
||||
uint rx_badseq; /* Mismatched rx sequence number */
|
||||
uint fc_rcvd; /* Number of flow-control events received */
|
||||
uint fc_xoff; /* Number which turned on flow-control */
|
||||
uint fc_xon; /* Number which turned off flow-control */
|
||||
uint rxglomfail; /* Failed deglom attempts */
|
||||
uint rxglomframes; /* Number of glom frames (superframes) */
|
||||
uint rxglompkts; /* Number of packets from glom frames */
|
||||
uint f2rxhdrs; /* Number of header reads */
|
||||
uint f2rxdata; /* Number of frame data reads */
|
||||
uint f2txdata; /* Number of f2 frame writes */
|
||||
uint f1regdata; /* Number of f1 register accesses */
|
||||
uint tickcnt; /* Number of watchdog been schedule */
|
||||
ulong tx_ctlerrs; /* Err of sending ctrl frames */
|
||||
ulong tx_ctlpkts; /* Ctrl frames sent to dongle */
|
||||
ulong rx_ctlerrs; /* Err of processing rx ctrl frames */
|
||||
ulong rx_ctlpkts; /* Ctrl frames processed from dongle */
|
||||
ulong rx_readahead_cnt; /* packets where header read-ahead was used */
|
||||
};
|
||||
|
||||
struct brcmf_fws_stats {
|
||||
u32 tlv_parse_failed;
|
||||
u32 tlv_invalid_type;
|
||||
u32 header_only_pkt;
|
||||
u32 header_pulls;
|
||||
u32 pkt2bus;
|
||||
u32 send_pkts[5];
|
||||
u32 requested_sent[5];
|
||||
u32 generic_error;
|
||||
u32 mac_update_failed;
|
||||
u32 mac_ps_update_failed;
|
||||
u32 if_update_failed;
|
||||
u32 packet_request_failed;
|
||||
u32 credit_request_failed;
|
||||
u32 rollback_success;
|
||||
u32 rollback_failed;
|
||||
u32 delayq_full_error;
|
||||
u32 supprq_full_error;
|
||||
u32 txs_indicate;
|
||||
u32 txs_discard;
|
||||
u32 txs_supp_core;
|
||||
u32 txs_supp_ps;
|
||||
u32 txs_tossed;
|
||||
u32 txs_host_tossed;
|
||||
u32 bus_flow_block;
|
||||
u32 fws_flow_block;
|
||||
};
|
||||
|
||||
struct brcmf_pub;
|
||||
#ifdef DEBUG
|
||||
void brcmf_debugfs_init(void);
|
||||
|
@ -169,10 +107,8 @@ void brcmf_debugfs_exit(void);
|
|||
int brcmf_debugfs_attach(struct brcmf_pub *drvr);
|
||||
void brcmf_debugfs_detach(struct brcmf_pub *drvr);
|
||||
struct dentry *brcmf_debugfs_get_devdir(struct brcmf_pub *drvr);
|
||||
void brcmf_debugfs_create_sdio_count(struct brcmf_pub *drvr,
|
||||
struct brcmf_sdio_count *sdcnt);
|
||||
void brcmf_debugfs_create_fws_stats(struct brcmf_pub *drvr,
|
||||
struct brcmf_fws_stats *stats);
|
||||
int brcmf_debugfs_add_entry(struct brcmf_pub *drvr, const char *fn,
|
||||
int (*read_fn)(struct seq_file *seq, void *data));
|
||||
#else
|
||||
static inline void brcmf_debugfs_init(void)
|
||||
{
|
||||
|
@ -187,9 +123,11 @@ static inline int brcmf_debugfs_attach(struct brcmf_pub *drvr)
|
|||
static inline void brcmf_debugfs_detach(struct brcmf_pub *drvr)
|
||||
{
|
||||
}
|
||||
static inline void brcmf_debugfs_create_fws_stats(struct brcmf_pub *drvr,
|
||||
struct brcmf_fws_stats *stats)
|
||||
static inline
|
||||
int brcmf_debugfs_add_entry(struct brcmf_pub *drvr, const char *fn,
|
||||
int (*read_fn)(struct seq_file *seq, void *data))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "wl_cfg80211.h"
|
||||
#include "fwil.h"
|
||||
#include "fwsignal.h"
|
||||
#include "feature.h"
|
||||
#include "proto.h"
|
||||
|
||||
MODULE_AUTHOR("Broadcom Corporation");
|
||||
|
@ -936,6 +937,8 @@ int brcmf_bus_start(struct device *dev)
|
|||
if (ret < 0)
|
||||
goto fail;
|
||||
|
||||
brcmf_feat_attach(drvr);
|
||||
|
||||
ret = brcmf_fws_init(drvr);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
|
@ -1073,16 +1076,6 @@ int brcmf_netdev_wait_pend8021x(struct net_device *ndev)
|
|||
return !err;
|
||||
}
|
||||
|
||||
/*
|
||||
* return chip id and rev of the device encoded in u32.
|
||||
*/
|
||||
u32 brcmf_get_chip_info(struct brcmf_if *ifp)
|
||||
{
|
||||
struct brcmf_bus *bus = ifp->drvr->bus_if;
|
||||
|
||||
return bus->chip << 4 | bus->chiprev;
|
||||
}
|
||||
|
||||
static void brcmf_driver_register(struct work_struct *work)
|
||||
{
|
||||
#ifdef CONFIG_BRCMFMAC_SDIO
|
||||
|
|
|
@ -391,6 +391,40 @@ struct brcmf_sdio_hdrinfo {
|
|||
u16 tail_pad;
|
||||
};
|
||||
|
||||
/*
|
||||
* hold counter variables
|
||||
*/
|
||||
struct brcmf_sdio_count {
|
||||
uint intrcount; /* Count of device interrupt callbacks */
|
||||
uint lastintrs; /* Count as of last watchdog timer */
|
||||
uint pollcnt; /* Count of active polls */
|
||||
uint regfails; /* Count of R_REG failures */
|
||||
uint tx_sderrs; /* Count of tx attempts with sd errors */
|
||||
uint fcqueued; /* Tx packets that got queued */
|
||||
uint rxrtx; /* Count of rtx requests (NAK to dongle) */
|
||||
uint rx_toolong; /* Receive frames too long to receive */
|
||||
uint rxc_errors; /* SDIO errors when reading control frames */
|
||||
uint rx_hdrfail; /* SDIO errors on header reads */
|
||||
uint rx_badhdr; /* Bad received headers (roosync?) */
|
||||
uint rx_badseq; /* Mismatched rx sequence number */
|
||||
uint fc_rcvd; /* Number of flow-control events received */
|
||||
uint fc_xoff; /* Number which turned on flow-control */
|
||||
uint fc_xon; /* Number which turned off flow-control */
|
||||
uint rxglomfail; /* Failed deglom attempts */
|
||||
uint rxglomframes; /* Number of glom frames (superframes) */
|
||||
uint rxglompkts; /* Number of packets from glom frames */
|
||||
uint f2rxhdrs; /* Number of header reads */
|
||||
uint f2rxdata; /* Number of frame data reads */
|
||||
uint f2txdata; /* Number of f2 frame writes */
|
||||
uint f1regdata; /* Number of f1 register accesses */
|
||||
uint tickcnt; /* Number of watchdog been schedule */
|
||||
ulong tx_ctlerrs; /* Err of sending ctrl frames */
|
||||
ulong tx_ctlpkts; /* Ctrl frames sent to dongle */
|
||||
ulong rx_ctlerrs; /* Err of processing rx ctrl frames */
|
||||
ulong rx_ctlpkts; /* Ctrl frames processed from dongle */
|
||||
ulong rx_readahead_cnt; /* packets where header read-ahead was used */
|
||||
};
|
||||
|
||||
/* misc chip info needed by some of the routines */
|
||||
/* Private data for SDIO bus interaction */
|
||||
struct brcmf_sdio {
|
||||
|
@ -620,40 +654,46 @@ enum brcmf_firmware_type {
|
|||
name ## _FIRMWARE_NAME, name ## _NVRAM_NAME
|
||||
|
||||
static const struct brcmf_firmware_names brcmf_fwname_data[] = {
|
||||
{ BCM43143_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM43143) },
|
||||
{ BCM43241_CHIP_ID, 0x0000001F, BRCMF_FIRMWARE_NVRAM(BCM43241B0) },
|
||||
{ BCM43241_CHIP_ID, 0xFFFFFFE0, BRCMF_FIRMWARE_NVRAM(BCM43241B4) },
|
||||
{ BCM4329_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4329) },
|
||||
{ BCM4330_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4330) },
|
||||
{ BCM4334_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4334) },
|
||||
{ BCM4335_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4335) },
|
||||
{ BCM43362_CHIP_ID, 0xFFFFFFFE, BRCMF_FIRMWARE_NVRAM(BCM43362) },
|
||||
{ BCM4339_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4339) },
|
||||
{ BCM4354_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4354) }
|
||||
{ BRCM_CC_43143_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM43143) },
|
||||
{ BRCM_CC_43241_CHIP_ID, 0x0000001F, BRCMF_FIRMWARE_NVRAM(BCM43241B0) },
|
||||
{ BRCM_CC_43241_CHIP_ID, 0xFFFFFFE0, BRCMF_FIRMWARE_NVRAM(BCM43241B4) },
|
||||
{ BRCM_CC_4329_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4329) },
|
||||
{ BRCM_CC_4330_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4330) },
|
||||
{ BRCM_CC_4334_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4334) },
|
||||
{ BRCM_CC_4335_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4335) },
|
||||
{ BRCM_CC_43362_CHIP_ID, 0xFFFFFFFE, BRCMF_FIRMWARE_NVRAM(BCM43362) },
|
||||
{ BRCM_CC_4339_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4339) },
|
||||
{ BRCM_CC_4354_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4354) }
|
||||
};
|
||||
|
||||
static const char *brcmf_sdio_get_fwname(struct brcmf_chip *ci,
|
||||
enum brcmf_firmware_type type)
|
||||
static int brcmf_sdio_get_fwnames(struct brcmf_chip *ci,
|
||||
struct brcmf_sdio_dev *sdiodev)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(brcmf_fwname_data); i++) {
|
||||
if (brcmf_fwname_data[i].chipid == ci->chip &&
|
||||
brcmf_fwname_data[i].revmsk & BIT(ci->chiprev)) {
|
||||
switch (type) {
|
||||
case BRCMF_FIRMWARE_BIN:
|
||||
return brcmf_fwname_data[i].bin;
|
||||
case BRCMF_FIRMWARE_NVRAM:
|
||||
return brcmf_fwname_data[i].nv;
|
||||
default:
|
||||
brcmf_err("invalid firmware type (%d)\n", type);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
brcmf_fwname_data[i].revmsk & BIT(ci->chiprev))
|
||||
break;
|
||||
}
|
||||
brcmf_err("Unknown chipid %d [%d]\n",
|
||||
ci->chip, ci->chiprev);
|
||||
return NULL;
|
||||
|
||||
if (i == ARRAY_SIZE(brcmf_fwname_data)) {
|
||||
brcmf_err("Unknown chipid %d [%d]\n", ci->chip, ci->chiprev);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* check if firmware path is provided by module parameter */
|
||||
if (brcmf_firmware_path[0] != '\0') {
|
||||
if (brcmf_firmware_path[strlen(brcmf_firmware_path) - 1] != '/')
|
||||
strcat(brcmf_firmware_path, "/");
|
||||
|
||||
strcpy(sdiodev->fw_name, brcmf_firmware_path);
|
||||
strcpy(sdiodev->nvram_name, brcmf_firmware_path);
|
||||
}
|
||||
strcat(sdiodev->fw_name, brcmf_fwname_data[i].bin);
|
||||
strcat(sdiodev->nvram_name, brcmf_fwname_data[i].nv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pkt_align(struct sk_buff *p, int len, int align)
|
||||
|
@ -2898,16 +2938,13 @@ brcmf_sdio_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
|
|||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
static int brcmf_sdio_dump_console(struct brcmf_sdio *bus,
|
||||
struct sdpcm_shared *sh, char __user *data,
|
||||
size_t count)
|
||||
static int brcmf_sdio_dump_console(struct seq_file *seq, struct brcmf_sdio *bus,
|
||||
struct sdpcm_shared *sh)
|
||||
{
|
||||
u32 addr, console_ptr, console_size, console_index;
|
||||
char *conbuf = NULL;
|
||||
__le32 sh_val;
|
||||
int rv;
|
||||
loff_t pos = 0;
|
||||
int nbytes = 0;
|
||||
|
||||
/* obtain console information from device memory */
|
||||
addr = sh->console_addr + offsetof(struct rte_console, log_le);
|
||||
|
@ -2945,33 +2982,24 @@ static int brcmf_sdio_dump_console(struct brcmf_sdio *bus,
|
|||
if (rv < 0)
|
||||
goto done;
|
||||
|
||||
rv = simple_read_from_buffer(data, count, &pos,
|
||||
conbuf + console_index,
|
||||
console_size - console_index);
|
||||
rv = seq_write(seq, conbuf + console_index,
|
||||
console_size - console_index);
|
||||
if (rv < 0)
|
||||
goto done;
|
||||
|
||||
nbytes = rv;
|
||||
if (console_index > 0) {
|
||||
pos = 0;
|
||||
rv = simple_read_from_buffer(data+nbytes, count, &pos,
|
||||
conbuf, console_index - 1);
|
||||
if (rv < 0)
|
||||
goto done;
|
||||
rv += nbytes;
|
||||
}
|
||||
if (console_index > 0)
|
||||
rv = seq_write(seq, conbuf, console_index - 1);
|
||||
|
||||
done:
|
||||
vfree(conbuf);
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int brcmf_sdio_trap_info(struct brcmf_sdio *bus, struct sdpcm_shared *sh,
|
||||
char __user *data, size_t count)
|
||||
static int brcmf_sdio_trap_info(struct seq_file *seq, struct brcmf_sdio *bus,
|
||||
struct sdpcm_shared *sh)
|
||||
{
|
||||
int error, res;
|
||||
char buf[350];
|
||||
int error;
|
||||
struct brcmf_trap_info tr;
|
||||
loff_t pos = 0;
|
||||
|
||||
if ((sh->flags & SDPCM_SHARED_TRAP) == 0) {
|
||||
brcmf_dbg(INFO, "no trap in firmware\n");
|
||||
|
@ -2983,34 +3011,30 @@ static int brcmf_sdio_trap_info(struct brcmf_sdio *bus, struct sdpcm_shared *sh,
|
|||
if (error < 0)
|
||||
return error;
|
||||
|
||||
res = scnprintf(buf, sizeof(buf),
|
||||
"dongle trap info: type 0x%x @ epc 0x%08x\n"
|
||||
" cpsr 0x%08x spsr 0x%08x sp 0x%08x\n"
|
||||
" lr 0x%08x pc 0x%08x offset 0x%x\n"
|
||||
" r0 0x%08x r1 0x%08x r2 0x%08x r3 0x%08x\n"
|
||||
" r4 0x%08x r5 0x%08x r6 0x%08x r7 0x%08x\n",
|
||||
le32_to_cpu(tr.type), le32_to_cpu(tr.epc),
|
||||
le32_to_cpu(tr.cpsr), le32_to_cpu(tr.spsr),
|
||||
le32_to_cpu(tr.r13), le32_to_cpu(tr.r14),
|
||||
le32_to_cpu(tr.pc), sh->trap_addr,
|
||||
le32_to_cpu(tr.r0), le32_to_cpu(tr.r1),
|
||||
le32_to_cpu(tr.r2), le32_to_cpu(tr.r3),
|
||||
le32_to_cpu(tr.r4), le32_to_cpu(tr.r5),
|
||||
le32_to_cpu(tr.r6), le32_to_cpu(tr.r7));
|
||||
seq_printf(seq,
|
||||
"dongle trap info: type 0x%x @ epc 0x%08x\n"
|
||||
" cpsr 0x%08x spsr 0x%08x sp 0x%08x\n"
|
||||
" lr 0x%08x pc 0x%08x offset 0x%x\n"
|
||||
" r0 0x%08x r1 0x%08x r2 0x%08x r3 0x%08x\n"
|
||||
" r4 0x%08x r5 0x%08x r6 0x%08x r7 0x%08x\n",
|
||||
le32_to_cpu(tr.type), le32_to_cpu(tr.epc),
|
||||
le32_to_cpu(tr.cpsr), le32_to_cpu(tr.spsr),
|
||||
le32_to_cpu(tr.r13), le32_to_cpu(tr.r14),
|
||||
le32_to_cpu(tr.pc), sh->trap_addr,
|
||||
le32_to_cpu(tr.r0), le32_to_cpu(tr.r1),
|
||||
le32_to_cpu(tr.r2), le32_to_cpu(tr.r3),
|
||||
le32_to_cpu(tr.r4), le32_to_cpu(tr.r5),
|
||||
le32_to_cpu(tr.r6), le32_to_cpu(tr.r7));
|
||||
|
||||
return simple_read_from_buffer(data, count, &pos, buf, res);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int brcmf_sdio_assert_info(struct brcmf_sdio *bus,
|
||||
struct sdpcm_shared *sh, char __user *data,
|
||||
size_t count)
|
||||
static int brcmf_sdio_assert_info(struct seq_file *seq, struct brcmf_sdio *bus,
|
||||
struct sdpcm_shared *sh)
|
||||
{
|
||||
int error = 0;
|
||||
char buf[200];
|
||||
char file[80] = "?";
|
||||
char expr[80] = "<???>";
|
||||
int res;
|
||||
loff_t pos = 0;
|
||||
|
||||
if ((sh->flags & SDPCM_SHARED_ASSERT_BUILT) == 0) {
|
||||
brcmf_dbg(INFO, "firmware not built with -assert\n");
|
||||
|
@ -3035,10 +3059,9 @@ static int brcmf_sdio_assert_info(struct brcmf_sdio *bus,
|
|||
}
|
||||
sdio_release_host(bus->sdiodev->func[1]);
|
||||
|
||||
res = scnprintf(buf, sizeof(buf),
|
||||
"dongle assert: %s:%d: assert(%s)\n",
|
||||
file, sh->assert_line, expr);
|
||||
return simple_read_from_buffer(data, count, &pos, buf, res);
|
||||
seq_printf(seq, "dongle assert: %s:%d: assert(%s)\n",
|
||||
file, sh->assert_line, expr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int brcmf_sdio_checkdied(struct brcmf_sdio *bus)
|
||||
|
@ -3062,59 +3085,75 @@ static int brcmf_sdio_checkdied(struct brcmf_sdio *bus)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int brcmf_sdio_died_dump(struct brcmf_sdio *bus, char __user *data,
|
||||
size_t count, loff_t *ppos)
|
||||
static int brcmf_sdio_died_dump(struct seq_file *seq, struct brcmf_sdio *bus)
|
||||
{
|
||||
int error = 0;
|
||||
struct sdpcm_shared sh;
|
||||
int nbytes = 0;
|
||||
loff_t pos = *ppos;
|
||||
|
||||
if (pos != 0)
|
||||
return 0;
|
||||
|
||||
error = brcmf_sdio_readshared(bus, &sh);
|
||||
if (error < 0)
|
||||
goto done;
|
||||
|
||||
error = brcmf_sdio_assert_info(bus, &sh, data, count);
|
||||
error = brcmf_sdio_assert_info(seq, bus, &sh);
|
||||
if (error < 0)
|
||||
goto done;
|
||||
nbytes = error;
|
||||
|
||||
error = brcmf_sdio_trap_info(bus, &sh, data+nbytes, count);
|
||||
error = brcmf_sdio_trap_info(seq, bus, &sh);
|
||||
if (error < 0)
|
||||
goto done;
|
||||
nbytes += error;
|
||||
|
||||
error = brcmf_sdio_dump_console(bus, &sh, data+nbytes, count);
|
||||
if (error < 0)
|
||||
goto done;
|
||||
nbytes += error;
|
||||
error = brcmf_sdio_dump_console(seq, bus, &sh);
|
||||
|
||||
error = nbytes;
|
||||
*ppos += nbytes;
|
||||
done:
|
||||
return error;
|
||||
}
|
||||
|
||||
static ssize_t brcmf_sdio_forensic_read(struct file *f, char __user *data,
|
||||
size_t count, loff_t *ppos)
|
||||
static int brcmf_sdio_forensic_read(struct seq_file *seq, void *data)
|
||||
{
|
||||
struct brcmf_sdio *bus = f->private_data;
|
||||
int res;
|
||||
struct brcmf_bus *bus_if = dev_get_drvdata(seq->private);
|
||||
struct brcmf_sdio *bus = bus_if->bus_priv.sdio->bus;
|
||||
|
||||
res = brcmf_sdio_died_dump(bus, data, count, ppos);
|
||||
if (res > 0)
|
||||
*ppos += res;
|
||||
return (ssize_t)res;
|
||||
return brcmf_sdio_died_dump(seq, bus);
|
||||
}
|
||||
|
||||
static const struct file_operations brcmf_sdio_forensic_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = simple_open,
|
||||
.read = brcmf_sdio_forensic_read
|
||||
};
|
||||
static int brcmf_debugfs_sdio_count_read(struct seq_file *seq, void *data)
|
||||
{
|
||||
struct brcmf_bus *bus_if = dev_get_drvdata(seq->private);
|
||||
struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
|
||||
struct brcmf_sdio_count *sdcnt = &sdiodev->bus->sdcnt;
|
||||
|
||||
seq_printf(seq,
|
||||
"intrcount: %u\nlastintrs: %u\n"
|
||||
"pollcnt: %u\nregfails: %u\n"
|
||||
"tx_sderrs: %u\nfcqueued: %u\n"
|
||||
"rxrtx: %u\nrx_toolong: %u\n"
|
||||
"rxc_errors: %u\nrx_hdrfail: %u\n"
|
||||
"rx_badhdr: %u\nrx_badseq: %u\n"
|
||||
"fc_rcvd: %u\nfc_xoff: %u\n"
|
||||
"fc_xon: %u\nrxglomfail: %u\n"
|
||||
"rxglomframes: %u\nrxglompkts: %u\n"
|
||||
"f2rxhdrs: %u\nf2rxdata: %u\n"
|
||||
"f2txdata: %u\nf1regdata: %u\n"
|
||||
"tickcnt: %u\ntx_ctlerrs: %lu\n"
|
||||
"tx_ctlpkts: %lu\nrx_ctlerrs: %lu\n"
|
||||
"rx_ctlpkts: %lu\nrx_readahead: %lu\n",
|
||||
sdcnt->intrcount, sdcnt->lastintrs,
|
||||
sdcnt->pollcnt, sdcnt->regfails,
|
||||
sdcnt->tx_sderrs, sdcnt->fcqueued,
|
||||
sdcnt->rxrtx, sdcnt->rx_toolong,
|
||||
sdcnt->rxc_errors, sdcnt->rx_hdrfail,
|
||||
sdcnt->rx_badhdr, sdcnt->rx_badseq,
|
||||
sdcnt->fc_rcvd, sdcnt->fc_xoff,
|
||||
sdcnt->fc_xon, sdcnt->rxglomfail,
|
||||
sdcnt->rxglomframes, sdcnt->rxglompkts,
|
||||
sdcnt->f2rxhdrs, sdcnt->f2rxdata,
|
||||
sdcnt->f2txdata, sdcnt->f1regdata,
|
||||
sdcnt->tickcnt, sdcnt->tx_ctlerrs,
|
||||
sdcnt->tx_ctlpkts, sdcnt->rx_ctlerrs,
|
||||
sdcnt->rx_ctlpkts, sdcnt->rx_readahead_cnt);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void brcmf_sdio_debugfs_create(struct brcmf_sdio *bus)
|
||||
{
|
||||
|
@ -3124,9 +3163,9 @@ static void brcmf_sdio_debugfs_create(struct brcmf_sdio *bus)
|
|||
if (IS_ERR_OR_NULL(dentry))
|
||||
return;
|
||||
|
||||
debugfs_create_file("forensics", S_IRUGO, dentry, bus,
|
||||
&brcmf_sdio_forensic_ops);
|
||||
brcmf_debugfs_create_sdio_count(drvr, &bus->sdcnt);
|
||||
brcmf_debugfs_add_entry(drvr, "forensics", brcmf_sdio_forensic_read);
|
||||
brcmf_debugfs_add_entry(drvr, "counters",
|
||||
brcmf_debugfs_sdio_count_read);
|
||||
debugfs_create_u32("console_interval", 0644, dentry,
|
||||
&bus->console_interval);
|
||||
}
|
||||
|
@ -3598,17 +3637,17 @@ brcmf_sdio_drivestrengthinit(struct brcmf_sdio_dev *sdiodev,
|
|||
return;
|
||||
|
||||
switch (SDIOD_DRVSTR_KEY(ci->chip, ci->pmurev)) {
|
||||
case SDIOD_DRVSTR_KEY(BCM4330_CHIP_ID, 12):
|
||||
case SDIOD_DRVSTR_KEY(BRCM_CC_4330_CHIP_ID, 12):
|
||||
str_tab = sdiod_drvstr_tab1_1v8;
|
||||
str_mask = 0x00003800;
|
||||
str_shift = 11;
|
||||
break;
|
||||
case SDIOD_DRVSTR_KEY(BCM4334_CHIP_ID, 17):
|
||||
case SDIOD_DRVSTR_KEY(BRCM_CC_4334_CHIP_ID, 17):
|
||||
str_tab = sdiod_drvstr_tab6_1v8;
|
||||
str_mask = 0x00001800;
|
||||
str_shift = 11;
|
||||
break;
|
||||
case SDIOD_DRVSTR_KEY(BCM43143_CHIP_ID, 17):
|
||||
case SDIOD_DRVSTR_KEY(BRCM_CC_43143_CHIP_ID, 17):
|
||||
/* note: 43143 does not support tristate */
|
||||
i = ARRAY_SIZE(sdiod_drvstr_tab2_3v3) - 1;
|
||||
if (drivestrength >= sdiod_drvstr_tab2_3v3[i].strength) {
|
||||
|
@ -3619,7 +3658,7 @@ brcmf_sdio_drivestrengthinit(struct brcmf_sdio_dev *sdiodev,
|
|||
brcmf_err("Invalid SDIO Drive strength for chip %s, strength=%d\n",
|
||||
ci->name, drivestrength);
|
||||
break;
|
||||
case SDIOD_DRVSTR_KEY(BCM43362_CHIP_ID, 13):
|
||||
case SDIOD_DRVSTR_KEY(BRCM_CC_43362_CHIP_ID, 13):
|
||||
str_tab = sdiod_drive_strength_tab5_1v8;
|
||||
str_mask = 0x00003800;
|
||||
str_shift = 11;
|
||||
|
@ -3720,12 +3759,12 @@ static u32 brcmf_sdio_buscore_read32(void *ctx, u32 addr)
|
|||
u32 val, rev;
|
||||
|
||||
val = brcmf_sdiod_regrl(sdiodev, addr, NULL);
|
||||
if (sdiodev->func[0]->device == SDIO_DEVICE_ID_BROADCOM_4335_4339 &&
|
||||
if (sdiodev->func[0]->device == BRCM_SDIO_4335_4339_DEVICE_ID &&
|
||||
addr == CORE_CC_REG(SI_ENUM_BASE, chipid)) {
|
||||
rev = (val & CID_REV_MASK) >> CID_REV_SHIFT;
|
||||
if (rev >= 2) {
|
||||
val &= ~CID_ID_MASK;
|
||||
val |= BCM4339_CHIP_ID;
|
||||
val |= BRCM_CC_4339_CHIP_ID;
|
||||
}
|
||||
}
|
||||
return val;
|
||||
|
@ -4127,11 +4166,12 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
|
|||
brcmf_sdio_debugfs_create(bus);
|
||||
brcmf_dbg(INFO, "completed!!\n");
|
||||
|
||||
ret = brcmf_sdio_get_fwnames(bus->ci, sdiodev);
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
ret = brcmf_fw_get_firmwares(sdiodev->dev, BRCMF_FW_REQUEST_NVRAM,
|
||||
brcmf_sdio_get_fwname(bus->ci,
|
||||
BRCMF_FIRMWARE_BIN),
|
||||
brcmf_sdio_get_fwname(bus->ci,
|
||||
BRCMF_FIRMWARE_NVRAM),
|
||||
sdiodev->fw_name, sdiodev->nvram_name,
|
||||
brcmf_sdio_firmware_callback);
|
||||
if (ret != 0) {
|
||||
brcmf_err("async firmware request failed: %d\n", ret);
|
||||
|
|
|
@ -0,0 +1,136 @@
|
|||
/*
|
||||
* Copyright (c) 2014 Broadcom Corporation
|
||||
*
|
||||
* 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/netdevice.h>
|
||||
|
||||
#include <brcm_hw_ids.h>
|
||||
#include "dhd.h"
|
||||
#include "dhd_bus.h"
|
||||
#include "dhd_dbg.h"
|
||||
#include "fwil.h"
|
||||
#include "feature.h"
|
||||
|
||||
/*
|
||||
* firmware error code received if iovar is unsupported.
|
||||
*/
|
||||
#define EBRCMF_FEAT_UNSUPPORTED 23
|
||||
|
||||
/*
|
||||
* expand feature list to array of feature strings.
|
||||
*/
|
||||
#define BRCMF_FEAT_DEF(_f) \
|
||||
#_f,
|
||||
static const char *brcmf_feat_names[] = {
|
||||
BRCMF_FEAT_LIST
|
||||
};
|
||||
#undef BRCMF_FEAT_DEF
|
||||
|
||||
#ifdef DEBUG
|
||||
/*
|
||||
* expand quirk list to array of quirk strings.
|
||||
*/
|
||||
#define BRCMF_QUIRK_DEF(_q) \
|
||||
#_q,
|
||||
static const char * const brcmf_quirk_names[] = {
|
||||
BRCMF_QUIRK_LIST
|
||||
};
|
||||
#undef BRCMF_QUIRK_DEF
|
||||
|
||||
/**
|
||||
* brcmf_feat_debugfs_read() - expose feature info to debugfs.
|
||||
*
|
||||
* @seq: sequence for debugfs entry.
|
||||
* @data: raw data pointer.
|
||||
*/
|
||||
static int brcmf_feat_debugfs_read(struct seq_file *seq, void *data)
|
||||
{
|
||||
struct brcmf_bus *bus_if = dev_get_drvdata(seq->private);
|
||||
u32 feats = bus_if->drvr->feat_flags;
|
||||
u32 quirks = bus_if->drvr->chip_quirks;
|
||||
int id;
|
||||
|
||||
seq_printf(seq, "Features: %08x\n", feats);
|
||||
for (id = 0; id < BRCMF_FEAT_LAST; id++)
|
||||
if (feats & BIT(id))
|
||||
seq_printf(seq, "\t%s\n", brcmf_feat_names[id]);
|
||||
seq_printf(seq, "\nQuirks: %08x\n", quirks);
|
||||
for (id = 0; id < BRCMF_FEAT_QUIRK_LAST; id++)
|
||||
if (quirks & BIT(id))
|
||||
seq_printf(seq, "\t%s\n", brcmf_quirk_names[id]);
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
static int brcmf_feat_debugfs_read(struct seq_file *seq, void *data)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
|
||||
/**
|
||||
* brcmf_feat_iovar_int_get() - determine feature through iovar query.
|
||||
*
|
||||
* @ifp: interface to query.
|
||||
* @id: feature id.
|
||||
* @name: iovar name.
|
||||
*/
|
||||
static void brcmf_feat_iovar_int_get(struct brcmf_if *ifp,
|
||||
enum brcmf_feat_id id, char *name)
|
||||
{
|
||||
u32 data;
|
||||
int err;
|
||||
|
||||
err = brcmf_fil_iovar_int_get(ifp, name, &data);
|
||||
if (err == 0) {
|
||||
brcmf_dbg(INFO, "enabling feature: %s\n", brcmf_feat_names[id]);
|
||||
ifp->drvr->feat_flags |= BIT(id);
|
||||
} else {
|
||||
brcmf_dbg(TRACE, "%s feature check failed: %d\n",
|
||||
brcmf_feat_names[id], err);
|
||||
}
|
||||
}
|
||||
|
||||
void brcmf_feat_attach(struct brcmf_pub *drvr)
|
||||
{
|
||||
struct brcmf_if *ifp = drvr->iflist[0];
|
||||
|
||||
brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_MCHAN, "mchan");
|
||||
|
||||
/* set chip related quirks */
|
||||
switch (drvr->bus_if->chip) {
|
||||
case BRCM_CC_43236_CHIP_ID:
|
||||
drvr->chip_quirks |= BIT(BRCMF_FEAT_QUIRK_AUTO_AUTH);
|
||||
break;
|
||||
case BRCM_CC_4329_CHIP_ID:
|
||||
drvr->chip_quirks |= BIT(BRCMF_FEAT_QUIRK_NEED_MPC);
|
||||
break;
|
||||
default:
|
||||
/* no quirks */
|
||||
break;
|
||||
}
|
||||
|
||||
brcmf_debugfs_add_entry(drvr, "features", brcmf_feat_debugfs_read);
|
||||
}
|
||||
|
||||
bool brcmf_feat_is_enabled(struct brcmf_if *ifp, enum brcmf_feat_id id)
|
||||
{
|
||||
return (ifp->drvr->feat_flags & BIT(id));
|
||||
}
|
||||
|
||||
bool brcmf_feat_is_quirk_enabled(struct brcmf_if *ifp,
|
||||
enum brcmf_feat_quirk quirk)
|
||||
{
|
||||
return (ifp->drvr->chip_quirks & BIT(quirk));
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* Copyright (c) 2014 Broadcom Corporation
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef _BRCMF_FEATURE_H
|
||||
#define _BRCMF_FEATURE_H
|
||||
|
||||
/*
|
||||
* Features:
|
||||
*
|
||||
* MCHAN: multi-channel for concurrent P2P.
|
||||
*/
|
||||
#define BRCMF_FEAT_LIST \
|
||||
BRCMF_FEAT_DEF(MCHAN)
|
||||
/*
|
||||
* Quirks:
|
||||
*
|
||||
* AUTO_AUTH: workaround needed for automatic authentication type.
|
||||
* NEED_MPC: driver needs to disable MPC during scanning operation.
|
||||
*/
|
||||
#define BRCMF_QUIRK_LIST \
|
||||
BRCMF_QUIRK_DEF(AUTO_AUTH) \
|
||||
BRCMF_QUIRK_DEF(NEED_MPC)
|
||||
|
||||
#define BRCMF_FEAT_DEF(_f) \
|
||||
BRCMF_FEAT_ ## _f,
|
||||
/*
|
||||
* expand feature list to enumeration.
|
||||
*/
|
||||
enum brcmf_feat_id {
|
||||
BRCMF_FEAT_LIST
|
||||
BRCMF_FEAT_LAST
|
||||
};
|
||||
#undef BRCMF_FEAT_DEF
|
||||
|
||||
#define BRCMF_QUIRK_DEF(_q) \
|
||||
BRCMF_FEAT_QUIRK_ ## _q,
|
||||
/*
|
||||
* expand quirk list to enumeration.
|
||||
*/
|
||||
enum brcmf_feat_quirk {
|
||||
BRCMF_QUIRK_LIST
|
||||
BRCMF_FEAT_QUIRK_LAST
|
||||
};
|
||||
#undef BRCMF_QUIRK_DEF
|
||||
|
||||
/**
|
||||
* brcmf_feat_attach() - determine features and quirks.
|
||||
*
|
||||
* @drvr: driver instance.
|
||||
*/
|
||||
void brcmf_feat_attach(struct brcmf_pub *drvr);
|
||||
|
||||
/**
|
||||
* brcmf_feat_is_enabled() - query feature.
|
||||
*
|
||||
* @ifp: interface instance.
|
||||
* @id: feature id to check.
|
||||
*
|
||||
* Return: true is feature is enabled; otherwise false.
|
||||
*/
|
||||
bool brcmf_feat_is_enabled(struct brcmf_if *ifp, enum brcmf_feat_id id);
|
||||
|
||||
/**
|
||||
* brcmf_feat_is_quirk_enabled() - query chip quirk.
|
||||
*
|
||||
* @ifp: interface instance.
|
||||
* @quirk: quirk id to check.
|
||||
*
|
||||
* Return: true is quirk is enabled; otherwise false.
|
||||
*/
|
||||
bool brcmf_feat_is_quirk_enabled(struct brcmf_if *ifp,
|
||||
enum brcmf_feat_quirk quirk);
|
||||
|
||||
#endif /* _BRCMF_FEATURE_H */
|
|
@ -18,10 +18,15 @@
|
|||
#include <linux/slab.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include "dhd_dbg.h"
|
||||
#include "firmware.h"
|
||||
|
||||
char brcmf_firmware_path[BRCMF_FW_PATH_LEN];
|
||||
module_param_string(firmware_path, brcmf_firmware_path,
|
||||
BRCMF_FW_PATH_LEN, 0440);
|
||||
|
||||
enum nvram_parser_state {
|
||||
IDLE,
|
||||
KEY,
|
||||
|
|
|
@ -21,6 +21,11 @@
|
|||
#define BRCMF_FW_REQ_FLAGS 0x00F0
|
||||
#define BRCMF_FW_REQ_NV_OPTIONAL 0x0010
|
||||
|
||||
#define BRCMF_FW_PATH_LEN 256
|
||||
#define BRCMF_FW_NAME_LEN 32
|
||||
|
||||
extern char brcmf_firmware_path[];
|
||||
|
||||
void brcmf_fw_nvram_free(void *nvram);
|
||||
/*
|
||||
* Request firmware(s) asynchronously. When the asynchronous request
|
||||
|
|
|
@ -454,6 +454,34 @@ struct brcmf_fws_macdesc_table {
|
|||
struct brcmf_fws_mac_descriptor other;
|
||||
};
|
||||
|
||||
struct brcmf_fws_stats {
|
||||
u32 tlv_parse_failed;
|
||||
u32 tlv_invalid_type;
|
||||
u32 header_only_pkt;
|
||||
u32 header_pulls;
|
||||
u32 pkt2bus;
|
||||
u32 send_pkts[5];
|
||||
u32 requested_sent[5];
|
||||
u32 generic_error;
|
||||
u32 mac_update_failed;
|
||||
u32 mac_ps_update_failed;
|
||||
u32 if_update_failed;
|
||||
u32 packet_request_failed;
|
||||
u32 credit_request_failed;
|
||||
u32 rollback_success;
|
||||
u32 rollback_failed;
|
||||
u32 delayq_full_error;
|
||||
u32 supprq_full_error;
|
||||
u32 txs_indicate;
|
||||
u32 txs_discard;
|
||||
u32 txs_supp_core;
|
||||
u32 txs_supp_ps;
|
||||
u32 txs_tossed;
|
||||
u32 txs_host_tossed;
|
||||
u32 bus_flow_block;
|
||||
u32 fws_flow_block;
|
||||
};
|
||||
|
||||
struct brcmf_fws_info {
|
||||
struct brcmf_pub *drvr;
|
||||
spinlock_t spinlock;
|
||||
|
@ -2017,6 +2045,75 @@ static void brcmf_fws_dequeue_worker(struct work_struct *worker)
|
|||
brcmf_fws_unlock(fws);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
static int brcmf_debugfs_fws_stats_read(struct seq_file *seq, void *data)
|
||||
{
|
||||
struct brcmf_bus *bus_if = dev_get_drvdata(seq->private);
|
||||
struct brcmf_fws_stats *fwstats = &bus_if->drvr->fws->stats;
|
||||
|
||||
seq_printf(seq,
|
||||
"header_pulls: %u\n"
|
||||
"header_only_pkt: %u\n"
|
||||
"tlv_parse_failed: %u\n"
|
||||
"tlv_invalid_type: %u\n"
|
||||
"mac_update_fails: %u\n"
|
||||
"ps_update_fails: %u\n"
|
||||
"if_update_fails: %u\n"
|
||||
"pkt2bus: %u\n"
|
||||
"generic_error: %u\n"
|
||||
"rollback_success: %u\n"
|
||||
"rollback_failed: %u\n"
|
||||
"delayq_full: %u\n"
|
||||
"supprq_full: %u\n"
|
||||
"txs_indicate: %u\n"
|
||||
"txs_discard: %u\n"
|
||||
"txs_suppr_core: %u\n"
|
||||
"txs_suppr_ps: %u\n"
|
||||
"txs_tossed: %u\n"
|
||||
"txs_host_tossed: %u\n"
|
||||
"bus_flow_block: %u\n"
|
||||
"fws_flow_block: %u\n"
|
||||
"send_pkts: BK:%u BE:%u VO:%u VI:%u BCMC:%u\n"
|
||||
"requested_sent: BK:%u BE:%u VO:%u VI:%u BCMC:%u\n",
|
||||
fwstats->header_pulls,
|
||||
fwstats->header_only_pkt,
|
||||
fwstats->tlv_parse_failed,
|
||||
fwstats->tlv_invalid_type,
|
||||
fwstats->mac_update_failed,
|
||||
fwstats->mac_ps_update_failed,
|
||||
fwstats->if_update_failed,
|
||||
fwstats->pkt2bus,
|
||||
fwstats->generic_error,
|
||||
fwstats->rollback_success,
|
||||
fwstats->rollback_failed,
|
||||
fwstats->delayq_full_error,
|
||||
fwstats->supprq_full_error,
|
||||
fwstats->txs_indicate,
|
||||
fwstats->txs_discard,
|
||||
fwstats->txs_supp_core,
|
||||
fwstats->txs_supp_ps,
|
||||
fwstats->txs_tossed,
|
||||
fwstats->txs_host_tossed,
|
||||
fwstats->bus_flow_block,
|
||||
fwstats->fws_flow_block,
|
||||
fwstats->send_pkts[0], fwstats->send_pkts[1],
|
||||
fwstats->send_pkts[2], fwstats->send_pkts[3],
|
||||
fwstats->send_pkts[4],
|
||||
fwstats->requested_sent[0],
|
||||
fwstats->requested_sent[1],
|
||||
fwstats->requested_sent[2],
|
||||
fwstats->requested_sent[3],
|
||||
fwstats->requested_sent[4]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
static int brcmf_debugfs_fws_stats_read(struct seq_file *seq, void *data)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int brcmf_fws_init(struct brcmf_pub *drvr)
|
||||
{
|
||||
struct brcmf_fws_info *fws;
|
||||
|
@ -2107,7 +2204,8 @@ int brcmf_fws_init(struct brcmf_pub *drvr)
|
|||
BRCMF_FWS_PSQ_LEN);
|
||||
|
||||
/* create debugfs file for statistics */
|
||||
brcmf_debugfs_create_fws_stats(drvr, &fws->stats);
|
||||
brcmf_debugfs_add_entry(drvr, "fws_stats",
|
||||
brcmf_debugfs_fws_stats_read);
|
||||
|
||||
brcmf_dbg(INFO, "%s bdcv2 tlv signaling [%x]\n",
|
||||
fws->fw_signals ? "enabled" : "disabled", tlv);
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
#define _BRCM_SDH_H_
|
||||
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/firmware.h>
|
||||
#include "firmware.h"
|
||||
|
||||
#define SDIO_FUNC_0 0
|
||||
#define SDIO_FUNC_1 1
|
||||
|
@ -182,6 +184,8 @@ struct brcmf_sdio_dev {
|
|||
uint max_segment_size;
|
||||
uint txglomsz;
|
||||
struct sg_table sgtable;
|
||||
char fw_name[BRCMF_FW_PATH_LEN + BRCMF_FW_NAME_LEN];
|
||||
char nvram_name[BRCMF_FW_PATH_LEN + BRCMF_FW_NAME_LEN];
|
||||
};
|
||||
|
||||
/* sdio core registers */
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include <linux/vmalloc.h>
|
||||
|
||||
#include <brcmu_utils.h>
|
||||
#include <brcm_hw_ids.h>
|
||||
#include <brcmu_wifi.h>
|
||||
#include <dhd_bus.h>
|
||||
#include <dhd_dbg.h>
|
||||
|
@ -913,16 +914,16 @@ static int brcmf_usb_dlrun(struct brcmf_usbdev_info *devinfo)
|
|||
static bool brcmf_usb_chip_support(int chipid, int chiprev)
|
||||
{
|
||||
switch(chipid) {
|
||||
case 43143:
|
||||
case BRCM_CC_43143_CHIP_ID:
|
||||
return true;
|
||||
case 43235:
|
||||
case 43236:
|
||||
case 43238:
|
||||
case BRCM_CC_43235_CHIP_ID:
|
||||
case BRCM_CC_43236_CHIP_ID:
|
||||
case BRCM_CC_43238_CHIP_ID:
|
||||
return (chiprev == 3);
|
||||
case 43242:
|
||||
case BRCM_CC_43242_CHIP_ID:
|
||||
return true;
|
||||
case 43566:
|
||||
case 43569:
|
||||
case BRCM_CC_43566_CHIP_ID:
|
||||
case BRCM_CC_43569_CHIP_ID:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
|
@ -1016,16 +1017,16 @@ static int check_file(const u8 *headers)
|
|||
static const char *brcmf_usb_get_fwname(struct brcmf_usbdev_info *devinfo)
|
||||
{
|
||||
switch (devinfo->bus_pub.devid) {
|
||||
case 43143:
|
||||
case BRCM_CC_43143_CHIP_ID:
|
||||
return BRCMF_USB_43143_FW_NAME;
|
||||
case 43235:
|
||||
case 43236:
|
||||
case 43238:
|
||||
case BRCM_CC_43235_CHIP_ID:
|
||||
case BRCM_CC_43236_CHIP_ID:
|
||||
case BRCM_CC_43238_CHIP_ID:
|
||||
return BRCMF_USB_43236_FW_NAME;
|
||||
case 43242:
|
||||
case BRCM_CC_43242_CHIP_ID:
|
||||
return BRCMF_USB_43242_FW_NAME;
|
||||
case 43566:
|
||||
case 43569:
|
||||
case BRCM_CC_43566_CHIP_ID:
|
||||
case BRCM_CC_43569_CHIP_ID:
|
||||
return BRCMF_USB_43569_FW_NAME;
|
||||
default:
|
||||
return NULL;
|
||||
|
@ -1183,8 +1184,6 @@ static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo)
|
|||
bus->bus_priv.usb = bus_pub;
|
||||
dev_set_drvdata(dev, bus);
|
||||
bus->ops = &brcmf_usb_bus_ops;
|
||||
bus->chip = bus_pub->devid;
|
||||
bus->chiprev = bus_pub->chiprev;
|
||||
bus->proto_type = BRCMF_PROTO_BCDC;
|
||||
bus->always_use_fws_queue = true;
|
||||
|
||||
|
@ -1193,6 +1192,9 @@ static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo)
|
|||
if (ret)
|
||||
goto fail;
|
||||
}
|
||||
bus->chip = bus_pub->devid;
|
||||
bus->chiprev = bus_pub->chiprev;
|
||||
|
||||
/* request firmware here */
|
||||
brcmf_fw_get_firmwares(dev, 0, brcmf_usb_get_fwname(devinfo), NULL,
|
||||
brcmf_usb_probe_phase2);
|
||||
|
@ -1365,21 +1367,17 @@ static int brcmf_usb_reset_resume(struct usb_interface *intf)
|
|||
brcmf_usb_probe_phase2);
|
||||
}
|
||||
|
||||
#define BRCMF_USB_VENDOR_ID_BROADCOM 0x0a5c
|
||||
#define BRCMF_USB_DEVICE_ID_43143 0xbd1e
|
||||
#define BRCMF_USB_DEVICE_ID_43236 0xbd17
|
||||
#define BRCMF_USB_DEVICE_ID_43242 0xbd1f
|
||||
#define BRCMF_USB_DEVICE_ID_43569 0xbd27
|
||||
#define BRCMF_USB_DEVICE_ID_BCMFW 0x0bdc
|
||||
#define BRCMF_USB_DEVICE(dev_id) \
|
||||
{ USB_DEVICE(BRCM_USB_VENDOR_ID_BROADCOM, dev_id) }
|
||||
|
||||
static struct usb_device_id brcmf_usb_devid_table[] = {
|
||||
{ USB_DEVICE(BRCMF_USB_VENDOR_ID_BROADCOM, BRCMF_USB_DEVICE_ID_43143) },
|
||||
{ USB_DEVICE(BRCMF_USB_VENDOR_ID_BROADCOM, BRCMF_USB_DEVICE_ID_43236) },
|
||||
{ USB_DEVICE(BRCMF_USB_VENDOR_ID_BROADCOM, BRCMF_USB_DEVICE_ID_43242) },
|
||||
{ USB_DEVICE(BRCMF_USB_VENDOR_ID_BROADCOM, BRCMF_USB_DEVICE_ID_43569) },
|
||||
BRCMF_USB_DEVICE(BRCM_USB_43143_DEVICE_ID),
|
||||
BRCMF_USB_DEVICE(BRCM_USB_43236_DEVICE_ID),
|
||||
BRCMF_USB_DEVICE(BRCM_USB_43242_DEVICE_ID),
|
||||
BRCMF_USB_DEVICE(BRCM_USB_43569_DEVICE_ID),
|
||||
/* special entry for device with firmware loaded and running */
|
||||
{ USB_DEVICE(BRCMF_USB_VENDOR_ID_BROADCOM, BRCMF_USB_DEVICE_ID_BCMFW) },
|
||||
{ }
|
||||
BRCMF_USB_DEVICE(BRCM_USB_BCMFW_DEVICE_ID),
|
||||
{ /* end: all zeroes */ }
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(usb, brcmf_usb_devid_table);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -4707,41 +4707,6 @@ static int brcms_b_attach(struct brcms_c_info *wlc, struct bcma_device *core,
|
|||
return err;
|
||||
}
|
||||
|
||||
static void brcms_c_attach_antgain_init(struct brcms_c_info *wlc)
|
||||
{
|
||||
uint unit;
|
||||
unit = wlc->pub->unit;
|
||||
|
||||
if ((wlc->band->antgain == -1) && (wlc->pub->sromrev == 1)) {
|
||||
/* default antenna gain for srom rev 1 is 2 dBm (8 qdbm) */
|
||||
wlc->band->antgain = 8;
|
||||
} else if (wlc->band->antgain == -1) {
|
||||
wiphy_err(wlc->wiphy, "wl%d: %s: Invalid antennas available in"
|
||||
" srom, using 2dB\n", unit, __func__);
|
||||
wlc->band->antgain = 8;
|
||||
} else {
|
||||
s8 gain, fract;
|
||||
/* Older sroms specified gain in whole dbm only. In order
|
||||
* be able to specify qdbm granularity and remain backward
|
||||
* compatible the whole dbms are now encoded in only
|
||||
* low 6 bits and remaining qdbms are encoded in the hi 2 bits.
|
||||
* 6 bit signed number ranges from -32 - 31.
|
||||
*
|
||||
* Examples:
|
||||
* 0x1 = 1 db,
|
||||
* 0xc1 = 1.75 db (1 + 3 quarters),
|
||||
* 0x3f = -1 (-1 + 0 quarters),
|
||||
* 0x7f = -.75 (-1 + 1 quarters) = -3 qdbm.
|
||||
* 0xbf = -.50 (-1 + 2 quarters) = -2 qdbm.
|
||||
*/
|
||||
gain = wlc->band->antgain & 0x3f;
|
||||
gain <<= 2; /* Sign extend */
|
||||
gain >>= 2;
|
||||
fract = (wlc->band->antgain & 0xc0) >> 6;
|
||||
wlc->band->antgain = 4 * gain + fract;
|
||||
}
|
||||
}
|
||||
|
||||
static bool brcms_c_attach_stf_ant_init(struct brcms_c_info *wlc)
|
||||
{
|
||||
int aa;
|
||||
|
@ -4780,8 +4745,6 @@ static bool brcms_c_attach_stf_ant_init(struct brcms_c_info *wlc)
|
|||
else
|
||||
wlc->band->antgain = sprom->antenna_gain.a0;
|
||||
|
||||
brcms_c_attach_antgain_init(wlc);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,32 +17,56 @@
|
|||
#ifndef _BRCM_HW_IDS_H_
|
||||
#define _BRCM_HW_IDS_H_
|
||||
|
||||
#define BCM4313_D11N2G_ID 0x4727 /* 4313 802.11n 2.4G device */
|
||||
#include <linux/pci_ids.h>
|
||||
#include <linux/mmc/sdio_ids.h>
|
||||
|
||||
#define BRCM_USB_VENDOR_ID_BROADCOM 0x0a5c
|
||||
#define BRCM_PCIE_VENDOR_ID_BROADCOM PCI_VENDOR_ID_BROADCOM
|
||||
#define BRCM_SDIO_VENDOR_ID_BROADCOM SDIO_VENDOR_ID_BROADCOM
|
||||
|
||||
/* Chipcommon Core Chip IDs */
|
||||
#define BRCM_CC_43143_CHIP_ID 43143
|
||||
#define BRCM_CC_43235_CHIP_ID 43235
|
||||
#define BRCM_CC_43236_CHIP_ID 43236
|
||||
#define BRCM_CC_43238_CHIP_ID 43238
|
||||
#define BRCM_CC_43241_CHIP_ID 0x4324
|
||||
#define BRCM_CC_43242_CHIP_ID 43242
|
||||
#define BRCM_CC_4329_CHIP_ID 0x4329
|
||||
#define BRCM_CC_4330_CHIP_ID 0x4330
|
||||
#define BRCM_CC_4334_CHIP_ID 0x4334
|
||||
#define BRCM_CC_43362_CHIP_ID 43362
|
||||
#define BRCM_CC_4335_CHIP_ID 0x4335
|
||||
#define BRCM_CC_4339_CHIP_ID 0x4339
|
||||
#define BRCM_CC_4354_CHIP_ID 0x4354
|
||||
#define BRCM_CC_43566_CHIP_ID 43566
|
||||
#define BRCM_CC_43569_CHIP_ID 43569
|
||||
|
||||
/* SDIO Device IDs */
|
||||
#define BRCM_SDIO_43143_DEVICE_ID BRCM_CC_43143_CHIP_ID
|
||||
#define BRCM_SDIO_43241_DEVICE_ID BRCM_CC_43241_CHIP_ID
|
||||
#define BRCM_SDIO_4329_DEVICE_ID BRCM_CC_4329_CHIP_ID
|
||||
#define BRCM_SDIO_4330_DEVICE_ID BRCM_CC_4330_CHIP_ID
|
||||
#define BRCM_SDIO_4334_DEVICE_ID BRCM_CC_4334_CHIP_ID
|
||||
#define BRCM_SDIO_43362_DEVICE_ID BRCM_CC_43362_CHIP_ID
|
||||
#define BRCM_SDIO_4335_4339_DEVICE_ID BRCM_CC_4335_CHIP_ID
|
||||
#define BRCM_SDIO_4354_DEVICE_ID BRCM_CC_4354_CHIP_ID
|
||||
|
||||
/* USB Device IDs */
|
||||
#define BRCM_USB_43143_DEVICE_ID 0xbd1e
|
||||
#define BRCM_USB_43236_DEVICE_ID 0xbd17
|
||||
#define BRCM_USB_43242_DEVICE_ID 0xbd1f
|
||||
#define BRCM_USB_43569_DEVICE_ID 0xbd27
|
||||
#define BRCM_USB_BCMFW_DEVICE_ID 0x0bdc
|
||||
|
||||
/* brcmsmac IDs */
|
||||
#define BCM4313_D11N2G_ID 0x4727 /* 4313 802.11n 2.4G device */
|
||||
#define BCM43224_D11N_ID 0x4353 /* 43224 802.11n dualband device */
|
||||
#define BCM43224_D11N_ID_VEN1 0x0576 /* Vendor specific 43224 802.11n db */
|
||||
|
||||
#define BCM43225_D11N2G_ID 0x4357 /* 43225 802.11n 2.4GHz device */
|
||||
|
||||
#define BCM43236_D11N_ID 0x4346 /* 43236 802.11n dualband device */
|
||||
#define BCM43236_D11N2G_ID 0x4347 /* 43236 802.11n 2.4GHz device */
|
||||
|
||||
/* Chipcommon Core Chip IDs */
|
||||
#define BCM4313_CHIP_ID 0x4313
|
||||
#define BCM43143_CHIP_ID 43143
|
||||
#define BCM43224_CHIP_ID 43224
|
||||
#define BCM43225_CHIP_ID 43225
|
||||
#define BCM43235_CHIP_ID 43235
|
||||
#define BCM43236_CHIP_ID 43236
|
||||
#define BCM43238_CHIP_ID 43238
|
||||
#define BCM43241_CHIP_ID 0x4324
|
||||
#define BCM4329_CHIP_ID 0x4329
|
||||
#define BCM4330_CHIP_ID 0x4330
|
||||
#define BCM4331_CHIP_ID 0x4331
|
||||
#define BCM4334_CHIP_ID 0x4334
|
||||
#define BCM4335_CHIP_ID 0x4335
|
||||
#define BCM43362_CHIP_ID 43362
|
||||
#define BCM4339_CHIP_ID 0x4339
|
||||
#define BCM4354_CHIP_ID 0x4354
|
||||
|
||||
#endif /* _BRCM_HW_IDS_H_ */
|
||||
|
|
|
@ -541,7 +541,6 @@ void mwifiex_create_ba_tbl(struct mwifiex_private *priv, u8 *ra, int tid,
|
|||
int mwifiex_send_addba(struct mwifiex_private *priv, int tid, u8 *peer_mac)
|
||||
{
|
||||
struct host_cmd_ds_11n_addba_req add_ba_req;
|
||||
struct mwifiex_sta_node *sta_ptr;
|
||||
u32 tx_win_size = priv->add_ba_param.tx_win_size;
|
||||
static u8 dialog_tok;
|
||||
int ret;
|
||||
|
@ -553,6 +552,8 @@ int mwifiex_send_addba(struct mwifiex_private *priv, int tid, u8 *peer_mac)
|
|||
ISSUPP_TDLS_ENABLED(priv->adapter->fw_cap_info) &&
|
||||
priv->adapter->is_hw_11ac_capable &&
|
||||
memcmp(priv->cfg_bssid, peer_mac, ETH_ALEN)) {
|
||||
struct mwifiex_sta_node *sta_ptr;
|
||||
|
||||
sta_ptr = mwifiex_get_sta_entry(priv, peer_mac);
|
||||
if (!sta_ptr) {
|
||||
dev_warn(priv->adapter->dev,
|
||||
|
|
|
@ -185,6 +185,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
|
|||
skb_reserve(skb_aggr, headroom + sizeof(struct txpd));
|
||||
tx_info_aggr = MWIFIEX_SKB_TXCB(skb_aggr);
|
||||
|
||||
memset(tx_info_aggr, 0, sizeof(*tx_info_aggr));
|
||||
tx_info_aggr->bss_type = tx_info_src->bss_type;
|
||||
tx_info_aggr->bss_num = tx_info_src->bss_num;
|
||||
|
||||
|
|
|
@ -249,13 +249,22 @@ void mwifiex_11n_del_rx_reorder_tbl_by_ta(struct mwifiex_private *priv, u8 *ta)
|
|||
* buffered in Rx reordering table.
|
||||
*/
|
||||
static int
|
||||
mwifiex_11n_find_last_seq_num(struct mwifiex_rx_reorder_tbl *rx_reorder_tbl_ptr)
|
||||
mwifiex_11n_find_last_seq_num(struct reorder_tmr_cnxt *ctx)
|
||||
{
|
||||
struct mwifiex_rx_reorder_tbl *rx_reorder_tbl_ptr = ctx->ptr;
|
||||
struct mwifiex_private *priv = ctx->priv;
|
||||
unsigned long flags;
|
||||
int i;
|
||||
|
||||
for (i = (rx_reorder_tbl_ptr->win_size - 1); i >= 0; --i)
|
||||
if (rx_reorder_tbl_ptr->rx_reorder_ptr[i])
|
||||
spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
|
||||
for (i = rx_reorder_tbl_ptr->win_size - 1; i >= 0; --i) {
|
||||
if (rx_reorder_tbl_ptr->rx_reorder_ptr[i]) {
|
||||
spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock,
|
||||
flags);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
@ -274,7 +283,7 @@ mwifiex_flush_data(unsigned long context)
|
|||
(struct reorder_tmr_cnxt *) context;
|
||||
int start_win, seq_num;
|
||||
|
||||
seq_num = mwifiex_11n_find_last_seq_num(ctx->ptr);
|
||||
seq_num = mwifiex_11n_find_last_seq_num(ctx);
|
||||
|
||||
if (seq_num < 0)
|
||||
return;
|
||||
|
@ -729,9 +738,9 @@ void mwifiex_11n_cleanup_reorder_tbl(struct mwifiex_private *priv)
|
|||
mwifiex_del_rx_reorder_entry(priv, del_tbl_ptr);
|
||||
spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
|
||||
}
|
||||
INIT_LIST_HEAD(&priv->rx_reorder_tbl_ptr);
|
||||
spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
|
||||
|
||||
INIT_LIST_HEAD(&priv->rx_reorder_tbl_ptr);
|
||||
mwifiex_reset_11n_rx_seq_num(priv);
|
||||
}
|
||||
|
||||
|
@ -749,10 +758,14 @@ void mwifiex_update_rxreor_flags(struct mwifiex_adapter *adapter, u8 flags)
|
|||
priv = adapter->priv[i];
|
||||
if (!priv)
|
||||
continue;
|
||||
if (list_empty(&priv->rx_reorder_tbl_ptr))
|
||||
continue;
|
||||
|
||||
spin_lock_irqsave(&priv->rx_reorder_tbl_lock, lock_flags);
|
||||
if (list_empty(&priv->rx_reorder_tbl_ptr)) {
|
||||
spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock,
|
||||
lock_flags);
|
||||
continue;
|
||||
}
|
||||
|
||||
list_for_each_entry(tbl, &priv->rx_reorder_tbl_ptr, list)
|
||||
tbl->flags = flags;
|
||||
spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, lock_flags);
|
||||
|
|
|
@ -188,6 +188,7 @@ mwifiex_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
|
|||
}
|
||||
|
||||
tx_info = MWIFIEX_SKB_TXCB(skb);
|
||||
memset(tx_info, 0, sizeof(*tx_info));
|
||||
tx_info->bss_num = priv->bss_num;
|
||||
tx_info->bss_type = priv->bss_type;
|
||||
tx_info->pkt_len = pkt_len;
|
||||
|
@ -1603,9 +1604,6 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* disconnect before try to associate */
|
||||
mwifiex_deauthenticate(priv, NULL);
|
||||
|
||||
/* As this is new association, clear locally stored
|
||||
* keys and security related flags */
|
||||
priv->sec_info.wpa_enabled = false;
|
||||
|
@ -1743,6 +1741,11 @@ mwifiex_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (priv->wdev && priv->wdev->current_bss) {
|
||||
wiphy_warn(wiphy, "%s: already connected\n", dev->name);
|
||||
return -EALREADY;
|
||||
}
|
||||
|
||||
wiphy_dbg(wiphy, "info: Trying to associate to %s and bssid %pM\n",
|
||||
(char *) sme->ssid, sme->bssid);
|
||||
|
||||
|
|
|
@ -137,7 +137,6 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv,
|
|||
struct host_cmd_ds_command *host_cmd;
|
||||
uint16_t cmd_code;
|
||||
uint16_t cmd_size;
|
||||
struct timeval tstamp;
|
||||
unsigned long flags;
|
||||
__le32 tmp;
|
||||
|
||||
|
@ -198,10 +197,8 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv,
|
|||
*/
|
||||
skb_put(cmd_node->cmd_skb, cmd_size - cmd_node->cmd_skb->len);
|
||||
|
||||
do_gettimeofday(&tstamp);
|
||||
dev_dbg(adapter->dev, "cmd: DNLD_CMD: (%lu.%lu): %#x, act %#x, len %d,"
|
||||
" seqno %#x\n",
|
||||
tstamp.tv_sec, tstamp.tv_usec, cmd_code,
|
||||
dev_dbg(adapter->dev,
|
||||
"cmd: DNLD_CMD: %#x, act %#x, len %d, seqno %#x\n", cmd_code,
|
||||
le16_to_cpu(*(__le16 *) ((u8 *) host_cmd + S_DS_GEN)), cmd_size,
|
||||
le16_to_cpu(host_cmd->seq_num));
|
||||
|
||||
|
@ -273,7 +270,6 @@ static int mwifiex_dnld_sleep_confirm_cmd(struct mwifiex_adapter *adapter)
|
|||
(struct mwifiex_opt_sleep_confirm *)
|
||||
adapter->sleep_cfm->data;
|
||||
struct sk_buff *sleep_cfm_tmp;
|
||||
struct timeval ts;
|
||||
__le32 tmp;
|
||||
|
||||
priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
|
||||
|
@ -284,10 +280,9 @@ static int mwifiex_dnld_sleep_confirm_cmd(struct mwifiex_adapter *adapter)
|
|||
(adapter->seq_num, priv->bss_num,
|
||||
priv->bss_type)));
|
||||
|
||||
do_gettimeofday(&ts);
|
||||
dev_dbg(adapter->dev,
|
||||
"cmd: DNLD_CMD: (%lu.%lu): %#x, act %#x, len %d, seqno %#x\n",
|
||||
ts.tv_sec, ts.tv_usec, le16_to_cpu(sleep_cfm_buf->command),
|
||||
"cmd: DNLD_CMD: %#x, act %#x, len %d, seqno %#x\n",
|
||||
le16_to_cpu(sleep_cfm_buf->command),
|
||||
le16_to_cpu(sleep_cfm_buf->action),
|
||||
le16_to_cpu(sleep_cfm_buf->size),
|
||||
le16_to_cpu(sleep_cfm_buf->seq_num));
|
||||
|
@ -442,7 +437,6 @@ int mwifiex_process_event(struct mwifiex_adapter *adapter)
|
|||
mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
|
||||
struct sk_buff *skb = adapter->event_skb;
|
||||
u32 eventcause = adapter->event_cause;
|
||||
struct timeval tstamp;
|
||||
struct mwifiex_rxinfo *rx_info;
|
||||
|
||||
/* Save the last event to debug log */
|
||||
|
@ -462,13 +456,12 @@ int mwifiex_process_event(struct mwifiex_adapter *adapter)
|
|||
|
||||
if (skb) {
|
||||
rx_info = MWIFIEX_SKB_RXCB(skb);
|
||||
memset(rx_info, 0, sizeof(*rx_info));
|
||||
rx_info->bss_num = priv->bss_num;
|
||||
rx_info->bss_type = priv->bss_type;
|
||||
}
|
||||
|
||||
do_gettimeofday(&tstamp);
|
||||
dev_dbg(adapter->dev, "EVENT: %lu.%lu: cause: %#x\n",
|
||||
tstamp.tv_sec, tstamp.tv_usec, eventcause);
|
||||
dev_dbg(adapter->dev, "EVENT: cause: %#x\n", eventcause);
|
||||
if (eventcause == EVENT_PS_SLEEP || eventcause == EVENT_PS_AWAKE) {
|
||||
/* Handle PS_SLEEP/AWAKE events on STA */
|
||||
priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA);
|
||||
|
@ -780,7 +773,6 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter)
|
|||
uint16_t orig_cmdresp_no;
|
||||
uint16_t cmdresp_no;
|
||||
uint16_t cmdresp_result;
|
||||
struct timeval tstamp;
|
||||
unsigned long flags;
|
||||
|
||||
/* Now we got response from FW, cancel the command timer */
|
||||
|
@ -838,11 +830,10 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter)
|
|||
adapter->dbg.last_cmd_resp_id[adapter->dbg.last_cmd_resp_index] =
|
||||
orig_cmdresp_no;
|
||||
|
||||
do_gettimeofday(&tstamp);
|
||||
dev_dbg(adapter->dev, "cmd: CMD_RESP: (%lu.%lu): 0x%x, result %d,"
|
||||
" len %d, seqno 0x%x\n",
|
||||
tstamp.tv_sec, tstamp.tv_usec, orig_cmdresp_no, cmdresp_result,
|
||||
le16_to_cpu(resp->size), le16_to_cpu(resp->seq_num));
|
||||
dev_dbg(adapter->dev,
|
||||
"cmd: CMD_RESP: 0x%x, result %d, len %d, seqno 0x%x\n",
|
||||
orig_cmdresp_no, cmdresp_result,
|
||||
le16_to_cpu(resp->size), le16_to_cpu(resp->seq_num));
|
||||
|
||||
if (!(orig_cmdresp_no & HostCmd_RET_BIT)) {
|
||||
dev_err(adapter->dev, "CMD_RESP: invalid cmd resp\n");
|
||||
|
@ -902,7 +893,6 @@ mwifiex_cmd_timeout_func(unsigned long function_context)
|
|||
struct mwifiex_adapter *adapter =
|
||||
(struct mwifiex_adapter *) function_context;
|
||||
struct cmd_ctrl_node *cmd_node;
|
||||
struct timeval tstamp;
|
||||
|
||||
adapter->is_cmd_timedout = 1;
|
||||
if (!adapter->curr_cmd) {
|
||||
|
@ -915,10 +905,8 @@ mwifiex_cmd_timeout_func(unsigned long function_context)
|
|||
adapter->dbg.last_cmd_id[adapter->dbg.last_cmd_index];
|
||||
adapter->dbg.timeout_cmd_act =
|
||||
adapter->dbg.last_cmd_act[adapter->dbg.last_cmd_index];
|
||||
do_gettimeofday(&tstamp);
|
||||
dev_err(adapter->dev,
|
||||
"%s: Timeout cmd id (%lu.%lu) = %#x, act = %#x\n",
|
||||
__func__, tstamp.tv_sec, tstamp.tv_usec,
|
||||
"%s: Timeout cmd id = %#x, act = %#x\n", __func__,
|
||||
adapter->dbg.timeout_cmd_id,
|
||||
adapter->dbg.timeout_cmd_act);
|
||||
|
||||
|
@ -1236,18 +1224,15 @@ mwifiex_process_sleep_confirm_resp(struct mwifiex_adapter *adapter,
|
|||
uint16_t result = le16_to_cpu(cmd->result);
|
||||
uint16_t command = le16_to_cpu(cmd->command);
|
||||
uint16_t seq_num = le16_to_cpu(cmd->seq_num);
|
||||
struct timeval ts;
|
||||
|
||||
if (!upld_len) {
|
||||
dev_err(adapter->dev, "%s: cmd size is 0\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
do_gettimeofday(&ts);
|
||||
dev_dbg(adapter->dev,
|
||||
"cmd: CMD_RESP: (%lu.%lu): 0x%x, result %d, len %d, seqno 0x%x\n",
|
||||
ts.tv_sec, ts.tv_usec, command, result, le16_to_cpu(cmd->size),
|
||||
seq_num);
|
||||
"cmd: CMD_RESP: 0x%x, result %d, len %d, seqno 0x%x\n",
|
||||
command, result, le16_to_cpu(cmd->size), seq_num);
|
||||
|
||||
/* Get BSS number and corresponding priv */
|
||||
priv = mwifiex_get_priv_by_id(adapter, HostCmd_GET_BSS_NO(seq_num),
|
||||
|
|
|
@ -713,7 +713,7 @@ struct mwifiex_ie_types_vendor_param_set {
|
|||
u8 ie[MWIFIEX_MAX_VSIE_LEN];
|
||||
};
|
||||
|
||||
#define MWIFIEX_TDLS_IDLE_TIMEOUT 60
|
||||
#define MWIFIEX_TDLS_IDLE_TIMEOUT_IN_SEC 60
|
||||
|
||||
struct mwifiex_ie_types_tdls_idle_timeout {
|
||||
struct mwifiex_ie_types_header header;
|
||||
|
|
|
@ -949,7 +949,7 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv,
|
|||
chan_tlv->chan_scan_param[0].radio_type |=
|
||||
(IEEE80211_HT_PARAM_CHA_SEC_ABOVE << 4);
|
||||
else if (adapter->sec_chan_offset ==
|
||||
IEEE80211_HT_PARAM_CHA_SEC_ABOVE)
|
||||
IEEE80211_HT_PARAM_CHA_SEC_BELOW)
|
||||
chan_tlv->chan_scan_param[0].radio_type |=
|
||||
(IEEE80211_HT_PARAM_CHA_SEC_BELOW << 4);
|
||||
}
|
||||
|
@ -1288,8 +1288,6 @@ int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv,
|
|||
int mwifiex_associate(struct mwifiex_private *priv,
|
||||
struct mwifiex_bssdescriptor *bss_desc)
|
||||
{
|
||||
u8 current_bssid[ETH_ALEN];
|
||||
|
||||
/* Return error if the adapter is not STA role or table entry
|
||||
* is not marked as infra.
|
||||
*/
|
||||
|
@ -1304,10 +1302,6 @@ int mwifiex_associate(struct mwifiex_private *priv,
|
|||
else
|
||||
mwifiex_set_ba_params(priv);
|
||||
|
||||
memcpy(¤t_bssid,
|
||||
&priv->curr_bss_params.bss_descriptor.mac_address,
|
||||
sizeof(current_bssid));
|
||||
|
||||
/* Clear any past association response stored for application
|
||||
retrieval */
|
||||
priv->assoc_rsp_size = 0;
|
||||
|
|
|
@ -33,6 +33,7 @@ static void scan_delay_timer_fn(unsigned long data)
|
|||
struct mwifiex_private *priv = (struct mwifiex_private *)data;
|
||||
struct mwifiex_adapter *adapter = priv->adapter;
|
||||
struct cmd_ctrl_node *cmd_node, *tmp_node;
|
||||
spinlock_t *scan_q_lock = &adapter->scan_pending_q_lock;
|
||||
unsigned long flags;
|
||||
|
||||
if (adapter->surprise_removed)
|
||||
|
@ -44,13 +45,13 @@ static void scan_delay_timer_fn(unsigned long data)
|
|||
* Abort scan operation by cancelling all pending scan
|
||||
* commands
|
||||
*/
|
||||
spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
|
||||
spin_lock_irqsave(scan_q_lock, flags);
|
||||
list_for_each_entry_safe(cmd_node, tmp_node,
|
||||
&adapter->scan_pending_q, list) {
|
||||
list_del(&cmd_node->list);
|
||||
mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
|
||||
}
|
||||
spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
|
||||
spin_unlock_irqrestore(scan_q_lock, flags);
|
||||
|
||||
spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
|
||||
adapter->scan_processing = false;
|
||||
|
@ -79,12 +80,17 @@ static void scan_delay_timer_fn(unsigned long data)
|
|||
*/
|
||||
adapter->scan_delay_cnt = 0;
|
||||
adapter->empty_tx_q_cnt = 0;
|
||||
spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
|
||||
spin_lock_irqsave(scan_q_lock, flags);
|
||||
|
||||
if (list_empty(&adapter->scan_pending_q)) {
|
||||
spin_unlock_irqrestore(scan_q_lock, flags);
|
||||
goto done;
|
||||
}
|
||||
|
||||
cmd_node = list_first_entry(&adapter->scan_pending_q,
|
||||
struct cmd_ctrl_node, list);
|
||||
list_del(&cmd_node->list);
|
||||
spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
|
||||
flags);
|
||||
spin_unlock_irqrestore(scan_q_lock, flags);
|
||||
|
||||
mwifiex_insert_cmd_to_pending_q(adapter, cmd_node,
|
||||
true);
|
||||
|
@ -644,6 +650,7 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
}
|
||||
|
||||
tx_info = MWIFIEX_SKB_TXCB(skb);
|
||||
memset(tx_info, 0, sizeof(*tx_info));
|
||||
tx_info->bss_num = priv->bss_num;
|
||||
tx_info->bss_type = priv->bss_type;
|
||||
tx_info->pkt_len = skb->len;
|
||||
|
|
|
@ -57,7 +57,7 @@ mwifiex_map_pci_memory(struct mwifiex_adapter *adapter, struct sk_buff *skb,
|
|||
return -1;
|
||||
}
|
||||
mapping.len = size;
|
||||
memcpy(skb->cb, &mapping, sizeof(mapping));
|
||||
mwifiex_store_mapping(skb, &mapping);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -67,7 +67,7 @@ static void mwifiex_unmap_pci_memory(struct mwifiex_adapter *adapter,
|
|||
struct pcie_service_card *card = adapter->card;
|
||||
struct mwifiex_dma_mapping mapping;
|
||||
|
||||
MWIFIEX_SKB_PACB(skb, &mapping);
|
||||
mwifiex_get_mapping(skb, &mapping);
|
||||
pci_unmap_single(card->dev, mapping.addr, mapping.len, flags);
|
||||
}
|
||||
|
||||
|
@ -2238,7 +2238,6 @@ static void mwifiex_pcie_fw_dump_work(struct mwifiex_adapter *adapter)
|
|||
struct pcie_service_card *card = adapter->card;
|
||||
const struct mwifiex_pcie_card_reg *creg = card->pcie.reg;
|
||||
unsigned int reg, reg_start, reg_end;
|
||||
struct timeval t;
|
||||
u8 *dbg_ptr, *end_ptr, dump_num, idx, i, read_reg, doneflag = 0;
|
||||
enum rdwr_status stat;
|
||||
u32 memory_size;
|
||||
|
@ -2257,9 +2256,7 @@ static void mwifiex_pcie_fw_dump_work(struct mwifiex_adapter *adapter)
|
|||
entry->mem_size = 0;
|
||||
}
|
||||
|
||||
do_gettimeofday(&t);
|
||||
dev_info(adapter->dev, "== mwifiex firmware dump start: %u.%06u ==\n",
|
||||
(u32)t.tv_sec, (u32)t.tv_usec);
|
||||
dev_info(adapter->dev, "== mwifiex firmware dump start ==\n");
|
||||
|
||||
/* Read the number of the memories which will dump */
|
||||
stat = mwifiex_pcie_rdwr_firmware(adapter, doneflag);
|
||||
|
@ -2303,9 +2300,8 @@ static void mwifiex_pcie_fw_dump_work(struct mwifiex_adapter *adapter)
|
|||
end_ptr = dbg_ptr + memory_size;
|
||||
|
||||
doneflag = entry->done_flag;
|
||||
do_gettimeofday(&t);
|
||||
dev_info(adapter->dev, "Start %s output %u.%06u, please wait...\n",
|
||||
entry->mem_name, (u32)t.tv_sec, (u32)t.tv_usec);
|
||||
dev_info(adapter->dev, "Start %s output, please wait...\n",
|
||||
entry->mem_name);
|
||||
|
||||
do {
|
||||
stat = mwifiex_pcie_rdwr_firmware(adapter, doneflag);
|
||||
|
@ -2331,9 +2327,7 @@ static void mwifiex_pcie_fw_dump_work(struct mwifiex_adapter *adapter)
|
|||
break;
|
||||
} while (true);
|
||||
}
|
||||
do_gettimeofday(&t);
|
||||
dev_info(adapter->dev, "== mwifiex firmware dump end: %u.%06u ==\n",
|
||||
(u32)t.tv_sec, (u32)t.tv_usec);
|
||||
dev_info(adapter->dev, "== mwifiex firmware dump end ==\n");
|
||||
|
||||
kobject_uevent_env(&adapter->wiphy->dev.kobj, KOBJ_CHANGE, env);
|
||||
|
||||
|
|
|
@ -2012,7 +2012,6 @@ static void mwifiex_sdio_fw_dump_work(struct work_struct *work)
|
|||
int ret = 0;
|
||||
unsigned int reg, reg_start, reg_end;
|
||||
u8 *dbg_ptr, *end_ptr, dump_num, idx, i, read_reg, doneflag = 0;
|
||||
struct timeval t;
|
||||
enum rdwr_status stat;
|
||||
u32 memory_size;
|
||||
static char *env[] = { "DRIVER=mwifiex_sdio", "EVENT=fw_dump", NULL };
|
||||
|
@ -2033,9 +2032,7 @@ static void mwifiex_sdio_fw_dump_work(struct work_struct *work)
|
|||
mwifiex_pm_wakeup_card(adapter);
|
||||
sdio_claim_host(card->func);
|
||||
|
||||
do_gettimeofday(&t);
|
||||
dev_info(adapter->dev, "== mwifiex firmware dump start: %u.%06u ==\n",
|
||||
(u32)t.tv_sec, (u32)t.tv_usec);
|
||||
dev_info(adapter->dev, "== mwifiex firmware dump start ==\n");
|
||||
|
||||
stat = mwifiex_sdio_rdwr_firmware(adapter, doneflag);
|
||||
if (stat == RDWR_STATUS_FAILURE)
|
||||
|
@ -2087,9 +2084,8 @@ static void mwifiex_sdio_fw_dump_work(struct work_struct *work)
|
|||
end_ptr = dbg_ptr + memory_size;
|
||||
|
||||
doneflag = entry->done_flag;
|
||||
do_gettimeofday(&t);
|
||||
dev_info(adapter->dev, "Start %s output %u.%06u, please wait...\n",
|
||||
entry->mem_name, (u32)t.tv_sec, (u32)t.tv_usec);
|
||||
dev_info(adapter->dev, "Start %s output, please wait...\n",
|
||||
entry->mem_name);
|
||||
|
||||
do {
|
||||
stat = mwifiex_sdio_rdwr_firmware(adapter, doneflag);
|
||||
|
@ -2120,9 +2116,7 @@ static void mwifiex_sdio_fw_dump_work(struct work_struct *work)
|
|||
break;
|
||||
} while (1);
|
||||
}
|
||||
do_gettimeofday(&t);
|
||||
dev_info(adapter->dev, "== mwifiex firmware dump end: %u.%06u ==\n",
|
||||
(u32)t.tv_sec, (u32)t.tv_usec);
|
||||
dev_info(adapter->dev, "== mwifiex firmware dump end ==\n");
|
||||
|
||||
kobject_uevent_env(&adapter->wiphy->dev.kobj, KOBJ_CHANGE, env);
|
||||
|
||||
|
|
|
@ -1647,7 +1647,7 @@ mwifiex_cmd_tdls_oper(struct mwifiex_private *priv,
|
|||
timeout = (void *)(pos + config_len);
|
||||
timeout->header.type = cpu_to_le16(TLV_TYPE_TDLS_IDLE_TIMEOUT);
|
||||
timeout->header.len = cpu_to_le16(sizeof(timeout->value));
|
||||
timeout->value = cpu_to_le16(MWIFIEX_TDLS_IDLE_TIMEOUT);
|
||||
timeout->value = cpu_to_le16(MWIFIEX_TDLS_IDLE_TIMEOUT_IN_SEC);
|
||||
config_len += sizeof(struct mwifiex_ie_types_tdls_idle_timeout);
|
||||
|
||||
break;
|
||||
|
|
|
@ -908,7 +908,7 @@ static int mwifiex_ret_tdls_oper(struct mwifiex_private *priv,
|
|||
break;
|
||||
default:
|
||||
dev_err(priv->adapter->dev,
|
||||
"Unknown TDLS command action respnse %d", action);
|
||||
"Unknown TDLS command action response %d", action);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
|
@ -283,10 +283,6 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
|
|||
priv->bss_mode == NL80211_IFTYPE_P2P_CLIENT) {
|
||||
u8 config_bands;
|
||||
|
||||
ret = mwifiex_deauthenticate(priv, NULL);
|
||||
if (ret)
|
||||
goto done;
|
||||
|
||||
if (!bss_desc)
|
||||
return -1;
|
||||
|
||||
|
@ -345,12 +341,6 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
|
|||
goto done;
|
||||
}
|
||||
|
||||
/* Exit Adhoc mode first */
|
||||
dev_dbg(adapter->dev, "info: Sending Adhoc Stop\n");
|
||||
ret = mwifiex_deauthenticate(priv, NULL);
|
||||
if (ret)
|
||||
goto done;
|
||||
|
||||
priv->adhoc_is_link_sensed = false;
|
||||
|
||||
ret = mwifiex_check_network_compatibility(priv, bss_desc);
|
||||
|
|
|
@ -150,6 +150,7 @@ int mwifiex_send_null_packet(struct mwifiex_private *priv, u8 flags)
|
|||
return -1;
|
||||
|
||||
tx_info = MWIFIEX_SKB_TXCB(skb);
|
||||
memset(tx_info, 0, sizeof(*tx_info));
|
||||
tx_info->bss_num = priv->bss_num;
|
||||
tx_info->bss_type = priv->bss_type;
|
||||
tx_info->pkt_len = data_len - (sizeof(struct txpd) + INTF_HEADER_LEN);
|
||||
|
|
|
@ -604,6 +604,7 @@ int mwifiex_send_tdls_data_frame(struct mwifiex_private *priv, const u8 *peer,
|
|||
}
|
||||
|
||||
tx_info = MWIFIEX_SKB_TXCB(skb);
|
||||
memset(tx_info, 0, sizeof(*tx_info));
|
||||
tx_info->bss_num = priv->bss_num;
|
||||
tx_info->bss_type = priv->bss_type;
|
||||
|
||||
|
@ -757,6 +758,7 @@ int mwifiex_send_tdls_action_frame(struct mwifiex_private *priv, const u8 *peer,
|
|||
skb->priority = MWIFIEX_PRIO_VI;
|
||||
|
||||
tx_info = MWIFIEX_SKB_TXCB(skb);
|
||||
memset(tx_info, 0, sizeof(*tx_info));
|
||||
tx_info->bss_num = priv->bss_num;
|
||||
tx_info->bss_type = priv->bss_type;
|
||||
tx_info->flags |= MWIFIEX_BUF_FLAG_TDLS_PKT;
|
||||
|
@ -779,6 +781,7 @@ void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv,
|
|||
struct mwifiex_sta_node *sta_ptr;
|
||||
u8 *peer, *pos, *end;
|
||||
u8 i, action, basic;
|
||||
__le16 cap = 0;
|
||||
int ie_len = 0;
|
||||
|
||||
if (len < (sizeof(struct ethhdr) + 3))
|
||||
|
@ -790,18 +793,9 @@ void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv,
|
|||
|
||||
peer = buf + ETH_ALEN;
|
||||
action = *(buf + sizeof(struct ethhdr) + 2);
|
||||
|
||||
/* just handle TDLS setup request/response/confirm */
|
||||
if (action > WLAN_TDLS_SETUP_CONFIRM)
|
||||
return;
|
||||
|
||||
dev_dbg(priv->adapter->dev,
|
||||
"rx:tdls action: peer=%pM, action=%d\n", peer, action);
|
||||
|
||||
sta_ptr = mwifiex_add_sta_entry(priv, peer);
|
||||
if (!sta_ptr)
|
||||
return;
|
||||
|
||||
switch (action) {
|
||||
case WLAN_TDLS_SETUP_REQUEST:
|
||||
if (len < (sizeof(struct ethhdr) + TDLS_REQ_FIX_LEN))
|
||||
|
@ -809,7 +803,7 @@ void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv,
|
|||
|
||||
pos = buf + sizeof(struct ethhdr) + 4;
|
||||
/* payload 1+ category 1 + action 1 + dialog 1 */
|
||||
sta_ptr->tdls_cap.capab = cpu_to_le16(*(u16 *)pos);
|
||||
cap = cpu_to_le16(*(u16 *)pos);
|
||||
ie_len = len - sizeof(struct ethhdr) - TDLS_REQ_FIX_LEN;
|
||||
pos += 2;
|
||||
break;
|
||||
|
@ -819,7 +813,7 @@ void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv,
|
|||
return;
|
||||
/* payload 1+ category 1 + action 1 + dialog 1 + status code 2*/
|
||||
pos = buf + sizeof(struct ethhdr) + 6;
|
||||
sta_ptr->tdls_cap.capab = cpu_to_le16(*(u16 *)pos);
|
||||
cap = cpu_to_le16(*(u16 *)pos);
|
||||
ie_len = len - sizeof(struct ethhdr) - TDLS_RESP_FIX_LEN;
|
||||
pos += 2;
|
||||
break;
|
||||
|
@ -831,10 +825,16 @@ void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv,
|
|||
ie_len = len - sizeof(struct ethhdr) - TDLS_CONFIRM_FIX_LEN;
|
||||
break;
|
||||
default:
|
||||
dev_warn(priv->adapter->dev, "Unknown TDLS frame type.\n");
|
||||
dev_dbg(priv->adapter->dev, "Unknown TDLS frame type.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
sta_ptr = mwifiex_add_sta_entry(priv, peer);
|
||||
if (!sta_ptr)
|
||||
return;
|
||||
|
||||
sta_ptr->tdls_cap.capab = cap;
|
||||
|
||||
for (end = pos + ie_len; pos + 1 < end; pos += 2 + pos[1]) {
|
||||
if (pos + 2 + pos[1] > end)
|
||||
break;
|
||||
|
|
|
@ -55,6 +55,7 @@ int mwifiex_handle_rx_packet(struct mwifiex_adapter *adapter,
|
|||
return -1;
|
||||
}
|
||||
|
||||
memset(rx_info, 0, sizeof(*rx_info));
|
||||
rx_info->bss_num = priv->bss_num;
|
||||
rx_info->bss_type = priv->bss_type;
|
||||
|
||||
|
|
|
@ -174,6 +174,7 @@ static void mwifiex_uap_queue_bridged_pkt(struct mwifiex_private *priv,
|
|||
}
|
||||
|
||||
tx_info = MWIFIEX_SKB_TXCB(skb);
|
||||
memset(tx_info, 0, sizeof(*tx_info));
|
||||
tx_info->bss_num = priv->bss_num;
|
||||
tx_info->bss_type = priv->bss_type;
|
||||
tx_info->flags |= MWIFIEX_BUF_FLAG_BRIDGED_PKT;
|
||||
|
|
|
@ -20,32 +20,55 @@
|
|||
#ifndef _MWIFIEX_UTIL_H_
|
||||
#define _MWIFIEX_UTIL_H_
|
||||
|
||||
static inline struct mwifiex_rxinfo *MWIFIEX_SKB_RXCB(struct sk_buff *skb)
|
||||
{
|
||||
return (struct mwifiex_rxinfo *)(skb->cb + sizeof(dma_addr_t));
|
||||
}
|
||||
|
||||
static inline struct mwifiex_txinfo *MWIFIEX_SKB_TXCB(struct sk_buff *skb)
|
||||
{
|
||||
return (struct mwifiex_txinfo *)(skb->cb + sizeof(dma_addr_t));
|
||||
}
|
||||
|
||||
struct mwifiex_dma_mapping {
|
||||
dma_addr_t addr;
|
||||
size_t len;
|
||||
};
|
||||
|
||||
static inline void MWIFIEX_SKB_PACB(struct sk_buff *skb,
|
||||
struct mwifiex_dma_mapping *mapping)
|
||||
struct mwifiex_cb {
|
||||
struct mwifiex_dma_mapping dma_mapping;
|
||||
union {
|
||||
struct mwifiex_rxinfo rx_info;
|
||||
struct mwifiex_txinfo tx_info;
|
||||
};
|
||||
};
|
||||
|
||||
static inline struct mwifiex_rxinfo *MWIFIEX_SKB_RXCB(struct sk_buff *skb)
|
||||
{
|
||||
memcpy(mapping, skb->cb, sizeof(*mapping));
|
||||
struct mwifiex_cb *cb = (struct mwifiex_cb *)skb->cb;
|
||||
|
||||
BUILD_BUG_ON(sizeof(struct mwifiex_cb) > sizeof(skb->cb));
|
||||
return &cb->rx_info;
|
||||
}
|
||||
|
||||
static inline struct mwifiex_txinfo *MWIFIEX_SKB_TXCB(struct sk_buff *skb)
|
||||
{
|
||||
struct mwifiex_cb *cb = (struct mwifiex_cb *)skb->cb;
|
||||
|
||||
return &cb->tx_info;
|
||||
}
|
||||
|
||||
static inline void mwifiex_store_mapping(struct sk_buff *skb,
|
||||
struct mwifiex_dma_mapping *mapping)
|
||||
{
|
||||
struct mwifiex_cb *cb = (struct mwifiex_cb *)skb->cb;
|
||||
|
||||
memcpy(&cb->dma_mapping, mapping, sizeof(*mapping));
|
||||
}
|
||||
|
||||
static inline void mwifiex_get_mapping(struct sk_buff *skb,
|
||||
struct mwifiex_dma_mapping *mapping)
|
||||
{
|
||||
struct mwifiex_cb *cb = (struct mwifiex_cb *)skb->cb;
|
||||
|
||||
memcpy(mapping, &cb->dma_mapping, sizeof(*mapping));
|
||||
}
|
||||
|
||||
static inline dma_addr_t MWIFIEX_SKB_DMA_ADDR(struct sk_buff *skb)
|
||||
{
|
||||
struct mwifiex_dma_mapping mapping;
|
||||
|
||||
MWIFIEX_SKB_PACB(skb, &mapping);
|
||||
mwifiex_get_mapping(skb, &mapping);
|
||||
|
||||
return mapping.addr;
|
||||
}
|
||||
|
|
|
@ -1681,8 +1681,13 @@ static int rt2500pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
|
|||
/*
|
||||
* Detect if this device has an hardware controlled radio.
|
||||
*/
|
||||
if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO))
|
||||
if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO)) {
|
||||
__set_bit(CAPABILITY_HW_BUTTON, &rt2x00dev->cap_flags);
|
||||
/*
|
||||
* On this device RFKILL initialized during probe does not work.
|
||||
*/
|
||||
__set_bit(REQUIRE_DELAYED_RFKILL, &rt2x00dev->cap_flags);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if the BBP tuning should be enabled.
|
||||
|
|
|
@ -229,6 +229,31 @@ static enum hrtimer_restart rt2800usb_tx_sta_fifo_timeout(struct hrtimer *timer)
|
|||
/*
|
||||
* Firmware functions
|
||||
*/
|
||||
static int rt2800usb_autorun_detect(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
__le32 *reg;
|
||||
u32 fw_mode;
|
||||
|
||||
reg = kmalloc(sizeof(*reg), GFP_KERNEL);
|
||||
if (reg == NULL)
|
||||
return -ENOMEM;
|
||||
/* cannot use rt2x00usb_register_read here as it uses different
|
||||
* mode (MULTI_READ vs. DEVICE_MODE) and does not pass the
|
||||
* magic value USB_MODE_AUTORUN (0x11) to the device, thus the
|
||||
* returned value would be invalid.
|
||||
*/
|
||||
rt2x00usb_vendor_request(rt2x00dev, USB_DEVICE_MODE,
|
||||
USB_VENDOR_REQUEST_IN, 0, USB_MODE_AUTORUN,
|
||||
reg, sizeof(*reg), REGISTER_TIMEOUT_FIRMWARE);
|
||||
fw_mode = le32_to_cpu(*reg);
|
||||
kfree(reg);
|
||||
|
||||
if ((fw_mode & 0x00000003) == 2)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *rt2800usb_get_firmware_name(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
return FIRMWARE_RT2870;
|
||||
|
@ -240,6 +265,7 @@ static int rt2800usb_write_firmware(struct rt2x00_dev *rt2x00dev,
|
|||
int status;
|
||||
u32 offset;
|
||||
u32 length;
|
||||
int retval;
|
||||
|
||||
/*
|
||||
* Check which section of the firmware we need.
|
||||
|
@ -257,8 +283,16 @@ static int rt2800usb_write_firmware(struct rt2x00_dev *rt2x00dev,
|
|||
/*
|
||||
* Write firmware to device.
|
||||
*/
|
||||
rt2x00usb_register_multiwrite(rt2x00dev, FIRMWARE_IMAGE_BASE,
|
||||
data + offset, length);
|
||||
retval = rt2800usb_autorun_detect(rt2x00dev);
|
||||
if (retval < 0)
|
||||
return retval;
|
||||
if (retval) {
|
||||
rt2x00_info(rt2x00dev,
|
||||
"Firmware loading not required - NIC in AutoRun mode\n");
|
||||
} else {
|
||||
rt2x00usb_register_multiwrite(rt2x00dev, FIRMWARE_IMAGE_BASE,
|
||||
data + offset, length);
|
||||
}
|
||||
|
||||
rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
|
||||
rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0);
|
||||
|
@ -735,11 +769,26 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry,
|
|||
/*
|
||||
* Device probe functions.
|
||||
*/
|
||||
static int rt2800usb_efuse_detect(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
int retval;
|
||||
|
||||
retval = rt2800usb_autorun_detect(rt2x00dev);
|
||||
if (retval < 0)
|
||||
return retval;
|
||||
if (retval)
|
||||
return 1;
|
||||
return rt2800_efuse_detect(rt2x00dev);
|
||||
}
|
||||
|
||||
static int rt2800usb_read_eeprom(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
int retval;
|
||||
|
||||
if (rt2800_efuse_detect(rt2x00dev))
|
||||
retval = rt2800usb_efuse_detect(rt2x00dev);
|
||||
if (retval < 0)
|
||||
return retval;
|
||||
if (retval)
|
||||
retval = rt2800_read_eeprom_efuse(rt2x00dev);
|
||||
else
|
||||
retval = rt2x00usb_eeprom_read(rt2x00dev, rt2x00dev->eeprom,
|
||||
|
@ -1235,6 +1284,8 @@ static struct usb_device_id rt2800usb_device_table[] = {
|
|||
/* Arcadyan */
|
||||
{ USB_DEVICE(0x043e, 0x7a12) },
|
||||
{ USB_DEVICE(0x043e, 0x7a32) },
|
||||
/* ASUS */
|
||||
{ USB_DEVICE(0x0b05, 0x17e8) },
|
||||
/* Azurewave */
|
||||
{ USB_DEVICE(0x13d3, 0x3329) },
|
||||
{ USB_DEVICE(0x13d3, 0x3365) },
|
||||
|
@ -1271,6 +1322,7 @@ static struct usb_device_id rt2800usb_device_table[] = {
|
|||
{ USB_DEVICE(0x057c, 0x8501) },
|
||||
/* Buffalo */
|
||||
{ USB_DEVICE(0x0411, 0x0241) },
|
||||
{ USB_DEVICE(0x0411, 0x0253) },
|
||||
/* D-Link */
|
||||
{ USB_DEVICE(0x2001, 0x3c1a) },
|
||||
{ USB_DEVICE(0x2001, 0x3c21) },
|
||||
|
@ -1361,6 +1413,7 @@ static struct usb_device_id rt2800usb_device_table[] = {
|
|||
{ USB_DEVICE(0x0df6, 0x0053) },
|
||||
{ USB_DEVICE(0x0df6, 0x0069) },
|
||||
{ USB_DEVICE(0x0df6, 0x006f) },
|
||||
{ USB_DEVICE(0x0df6, 0x0078) },
|
||||
/* SMC */
|
||||
{ USB_DEVICE(0x083a, 0xa512) },
|
||||
{ USB_DEVICE(0x083a, 0xc522) },
|
||||
|
|
|
@ -693,6 +693,7 @@ enum rt2x00_capability_flags {
|
|||
REQUIRE_SW_SEQNO,
|
||||
REQUIRE_HT_TX_DESC,
|
||||
REQUIRE_PS_AUTOWAKE,
|
||||
REQUIRE_DELAYED_RFKILL,
|
||||
|
||||
/*
|
||||
* Capabilities
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue