Merge tag 'wireless-drivers-next-for-davem-2016-06-21' of git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next

Kalle Valo says:

====================
wireless-drivers patches for 4.8

Major changes:

ath10k

* enable btcoex support without restarting firmware
* enable ipq4019 support using AHB bus
* add QCA9887 chipset support
* retrieve calibration data from EEPROM, currently only for QCA9887

wil6210

* add pm_notify handling

brcmfmac

* add support for the PCIE devices 43525 and 43465
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller
2016-06-23 15:40:31 -04:00
83 changed files with 1257 additions and 1358 deletions

View File

@@ -1,6 +1,6 @@
b43-y += main.o
b43-y += bus.o
b43-$(CONFIG_B43_PHY_G) += phy_a.o phy_g.o tables.o lo.o wa.o
b43-$(CONFIG_B43_PHY_G) += phy_g.o tables.o lo.o wa.o
b43-$(CONFIG_B43_PHY_N) += tables_nphy.o
b43-$(CONFIG_B43_PHY_N) += radio_2055.o
b43-$(CONFIG_B43_PHY_N) += radio_2056.o

View File

@@ -222,7 +222,7 @@ static void b43_led_get_sprominfo(struct b43_wldev *dev,
sprom[2] = dev->dev->bus_sprom->gpio2;
sprom[3] = dev->dev->bus_sprom->gpio3;
if (sprom[led_index] == 0xFF) {
if ((sprom[0] & sprom[1] & sprom[2] & sprom[3]) == 0xff) {
/* There is no LED information in the SPROM
* for this LED. Hardcode it here. */
*activelow = false;
@@ -250,7 +250,11 @@ static void b43_led_get_sprominfo(struct b43_wldev *dev,
return;
}
} else {
*behaviour = sprom[led_index] & B43_LED_BEHAVIOUR;
/* keep LED disabled if no mapping is defined */
if (sprom[led_index] == 0xff)
*behaviour = B43_LED_OFF;
else
*behaviour = sprom[led_index] & B43_LED_BEHAVIOUR;
*activelow = !!(sprom[led_index] & B43_LED_ACTIVELOW);
}
}

View File

@@ -3180,7 +3180,6 @@ static void b43_rate_memory_write(struct b43_wldev *dev, u16 rate, int is_ofdm)
static void b43_rate_memory_init(struct b43_wldev *dev)
{
switch (dev->phy.type) {
case B43_PHYTYPE_A:
case B43_PHYTYPE_G:
case B43_PHYTYPE_N:
case B43_PHYTYPE_LP:
@@ -3194,8 +3193,6 @@ static void b43_rate_memory_init(struct b43_wldev *dev)
b43_rate_memory_write(dev, B43_OFDM_RATE_36MB, 1);
b43_rate_memory_write(dev, B43_OFDM_RATE_48MB, 1);
b43_rate_memory_write(dev, B43_OFDM_RATE_54MB, 1);
if (dev->phy.type == B43_PHYTYPE_A)
break;
/* fallthrough */
case B43_PHYTYPE_B:
b43_rate_memory_write(dev, B43_CCK_RATE_1MB, 0);
@@ -4604,14 +4601,6 @@ static int b43_phy_versioning(struct b43_wldev *dev)
if (radio_manuf != 0x17F /* Broadcom */)
unsupported = 1;
switch (phy_type) {
case B43_PHYTYPE_A:
if (radio_id != 0x2060)
unsupported = 1;
if (radio_rev != 1)
unsupported = 1;
if (radio_manuf != 0x17F)
unsupported = 1;
break;
case B43_PHYTYPE_B:
if ((radio_id & 0xFFF0) != 0x2050)
unsupported = 1;
@@ -4766,10 +4755,7 @@ static void b43_set_synth_pu_delay(struct b43_wldev *dev, bool idle)
u16 pu_delay;
/* The time value is in microseconds. */
if (dev->phy.type == B43_PHYTYPE_A)
pu_delay = 3700;
else
pu_delay = 1050;
pu_delay = 1050;
if (b43_is_mode(dev->wl, NL80211_IFTYPE_ADHOC) || idle)
pu_delay = 500;
if ((dev->phy.radio_ver == 0x2050) && (dev->phy.radio_rev == 8))
@@ -4784,14 +4770,10 @@ static void b43_set_pretbtt(struct b43_wldev *dev)
u16 pretbtt;
/* The time value is in microseconds. */
if (b43_is_mode(dev->wl, NL80211_IFTYPE_ADHOC)) {
if (b43_is_mode(dev->wl, NL80211_IFTYPE_ADHOC))
pretbtt = 2;
} else {
if (dev->phy.type == B43_PHYTYPE_A)
pretbtt = 120;
else
pretbtt = 250;
}
else
pretbtt = 250;
b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_PRETBTT, pretbtt);
b43_write16(dev, B43_MMIO_TSF_CFP_PRETBTT, pretbtt);
}
@@ -5380,10 +5362,6 @@ static void b43_supported_bands(struct b43_wldev *dev, bool *have_2ghz_phy,
/* As a fallback, try to guess using PHY type */
switch (dev->phy.type) {
case B43_PHYTYPE_A:
*have_2ghz_phy = false;
*have_5ghz_phy = true;
return;
case B43_PHYTYPE_G:
case B43_PHYTYPE_N:
case B43_PHYTYPE_LP:
@@ -5455,7 +5433,6 @@ static int b43_wireless_core_attach(struct b43_wldev *dev)
/* We don't support 5 GHz on some PHYs yet */
if (have_5ghz_phy) {
switch (dev->phy.type) {
case B43_PHYTYPE_A:
case B43_PHYTYPE_G:
case B43_PHYTYPE_LP:
case B43_PHYTYPE_HT:

View File

@@ -1,595 +0,0 @@
/*
Broadcom B43 wireless driver
IEEE 802.11a PHY driver
Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>,
Copyright (c) 2005-2007 Stefano Brivio <stefano.brivio@polimi.it>
Copyright (c) 2005-2008 Michael Buesch <m@bues.ch>
Copyright (c) 2005, 2006 Danny van Dyk <kugelfang@gentoo.org>
Copyright (c) 2005, 2006 Andreas Jaggi <andreas.jaggi@waterwave.ch>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include <linux/slab.h>
#include "b43.h"
#include "phy_a.h"
#include "phy_common.h"
#include "wa.h"
#include "tables.h"
#include "main.h"
/* Get the freq, as it has to be written to the device. */
static inline u16 channel2freq_a(u8 channel)
{
B43_WARN_ON(channel > 200);
return (5000 + 5 * channel);
}
static inline u16 freq_r3A_value(u16 frequency)
{
u16 value;
if (frequency < 5091)
value = 0x0040;
else if (frequency < 5321)
value = 0x0000;
else if (frequency < 5806)
value = 0x0080;
else
value = 0x0040;
return value;
}
#if 0
/* This function converts a TSSI value to dBm in Q5.2 */
static s8 b43_aphy_estimate_power_out(struct b43_wldev *dev, s8 tssi)
{
struct b43_phy *phy = &dev->phy;
struct b43_phy_a *aphy = phy->a;
s8 dbm = 0;
s32 tmp;
tmp = (aphy->tgt_idle_tssi - aphy->cur_idle_tssi + tssi);
tmp += 0x80;
tmp = clamp_val(tmp, 0x00, 0xFF);
dbm = aphy->tssi2dbm[tmp];
//TODO: There's a FIXME on the specs
return dbm;
}
#endif
static void b43_radio_set_tx_iq(struct b43_wldev *dev)
{
static const u8 data_high[5] = { 0x00, 0x40, 0x80, 0x90, 0xD0 };
static const u8 data_low[5] = { 0x00, 0x01, 0x05, 0x06, 0x0A };
u16 tmp = b43_radio_read16(dev, 0x001E);
int i, j;
for (i = 0; i < 5; i++) {
for (j = 0; j < 5; j++) {
if (tmp == (data_high[i] << 4 | data_low[j])) {
b43_phy_write(dev, 0x0069,
(i - j) << 8 | 0x00C0);
return;
}
}
}
}
static void aphy_channel_switch(struct b43_wldev *dev, unsigned int channel)
{
u16 freq, r8, tmp;
freq = channel2freq_a(channel);
r8 = b43_radio_read16(dev, 0x0008);
b43_write16(dev, 0x03F0, freq);
b43_radio_write16(dev, 0x0008, r8);
//TODO: write max channel TX power? to Radio 0x2D
tmp = b43_radio_read16(dev, 0x002E);
tmp &= 0x0080;
//TODO: OR tmp with the Power out estimation for this channel?
b43_radio_write16(dev, 0x002E, tmp);
if (freq >= 4920 && freq <= 5500) {
/*
* r8 = (((freq * 15 * 0xE1FC780F) >> 32) / 29) & 0x0F;
* = (freq * 0.025862069
*/
r8 = 3 * freq / 116; /* is equal to r8 = freq * 0.025862 */
}
b43_radio_write16(dev, 0x0007, (r8 << 4) | r8);
b43_radio_write16(dev, 0x0020, (r8 << 4) | r8);
b43_radio_write16(dev, 0x0021, (r8 << 4) | r8);
b43_radio_maskset(dev, 0x0022, 0x000F, (r8 << 4));
b43_radio_write16(dev, 0x002A, (r8 << 4));
b43_radio_write16(dev, 0x002B, (r8 << 4));
b43_radio_maskset(dev, 0x0008, 0x00F0, (r8 << 4));
b43_radio_maskset(dev, 0x0029, 0xFF0F, 0x00B0);
b43_radio_write16(dev, 0x0035, 0x00AA);
b43_radio_write16(dev, 0x0036, 0x0085);
b43_radio_maskset(dev, 0x003A, 0xFF20, freq_r3A_value(freq));
b43_radio_mask(dev, 0x003D, 0x00FF);
b43_radio_maskset(dev, 0x0081, 0xFF7F, 0x0080);
b43_radio_mask(dev, 0x0035, 0xFFEF);
b43_radio_maskset(dev, 0x0035, 0xFFEF, 0x0010);
b43_radio_set_tx_iq(dev);
//TODO: TSSI2dbm workaround
//FIXME b43_phy_xmitpower(dev);
}
static void b43_radio_init2060(struct b43_wldev *dev)
{
b43_radio_write16(dev, 0x0004, 0x00C0);
b43_radio_write16(dev, 0x0005, 0x0008);
b43_radio_write16(dev, 0x0009, 0x0040);
b43_radio_write16(dev, 0x0005, 0x00AA);
b43_radio_write16(dev, 0x0032, 0x008F);
b43_radio_write16(dev, 0x0006, 0x008F);
b43_radio_write16(dev, 0x0034, 0x008F);
b43_radio_write16(dev, 0x002C, 0x0007);
b43_radio_write16(dev, 0x0082, 0x0080);
b43_radio_write16(dev, 0x0080, 0x0000);
b43_radio_write16(dev, 0x003F, 0x00DA);
b43_radio_mask(dev, 0x0005, ~0x0008);
b43_radio_mask(dev, 0x0081, ~0x0010);
b43_radio_mask(dev, 0x0081, ~0x0020);
b43_radio_mask(dev, 0x0081, ~0x0020);
msleep(1); /* delay 400usec */
b43_radio_maskset(dev, 0x0081, ~0x0020, 0x0010);
msleep(1); /* delay 400usec */
b43_radio_maskset(dev, 0x0005, ~0x0008, 0x0008);
b43_radio_mask(dev, 0x0085, ~0x0010);
b43_radio_mask(dev, 0x0005, ~0x0008);
b43_radio_mask(dev, 0x0081, ~0x0040);
b43_radio_maskset(dev, 0x0081, ~0x0040, 0x0040);
b43_radio_write16(dev, 0x0005,
(b43_radio_read16(dev, 0x0081) & ~0x0008) | 0x0008);
b43_phy_write(dev, 0x0063, 0xDDC6);
b43_phy_write(dev, 0x0069, 0x07BE);
b43_phy_write(dev, 0x006A, 0x0000);
aphy_channel_switch(dev, dev->phy.ops->get_default_chan(dev));
msleep(1);
}
static void b43_phy_rssiagc(struct b43_wldev *dev, u8 enable)
{
int i;
if (dev->phy.rev < 3) {
if (enable)
for (i = 0; i < B43_TAB_RSSIAGC1_SIZE; i++) {
b43_ofdmtab_write16(dev,
B43_OFDMTAB_LNAHPFGAIN1, i, 0xFFF8);
b43_ofdmtab_write16(dev,
B43_OFDMTAB_WRSSI, i, 0xFFF8);
}
else
for (i = 0; i < B43_TAB_RSSIAGC1_SIZE; i++) {
b43_ofdmtab_write16(dev,
B43_OFDMTAB_LNAHPFGAIN1, i, b43_tab_rssiagc1[i]);
b43_ofdmtab_write16(dev,
B43_OFDMTAB_WRSSI, i, b43_tab_rssiagc1[i]);
}
} else {
if (enable)
for (i = 0; i < B43_TAB_RSSIAGC1_SIZE; i++)
b43_ofdmtab_write16(dev,
B43_OFDMTAB_WRSSI, i, 0x0820);
else
for (i = 0; i < B43_TAB_RSSIAGC2_SIZE; i++)
b43_ofdmtab_write16(dev,
B43_OFDMTAB_WRSSI, i, b43_tab_rssiagc2[i]);
}
}
static void b43_phy_ww(struct b43_wldev *dev)
{
u16 b, curr_s, best_s = 0xFFFF;
int i;
b43_phy_mask(dev, B43_PHY_CRS0, ~B43_PHY_CRS0_EN);
b43_phy_set(dev, B43_PHY_OFDM(0x1B), 0x1000);
b43_phy_maskset(dev, B43_PHY_OFDM(0x82), 0xF0FF, 0x0300);
b43_radio_set(dev, 0x0009, 0x0080);
b43_radio_maskset(dev, 0x0012, 0xFFFC, 0x0002);
b43_wa_initgains(dev);
b43_phy_write(dev, B43_PHY_OFDM(0xBA), 0x3ED5);
b = b43_phy_read(dev, B43_PHY_PWRDOWN);
b43_phy_write(dev, B43_PHY_PWRDOWN, (b & 0xFFF8) | 0x0005);
b43_radio_set(dev, 0x0004, 0x0004);
for (i = 0x10; i <= 0x20; i++) {
b43_radio_write16(dev, 0x0013, i);
curr_s = b43_phy_read(dev, B43_PHY_OTABLEQ) & 0x00FF;
if (!curr_s) {
best_s = 0x0000;
break;
} else if (curr_s >= 0x0080)
curr_s = 0x0100 - curr_s;
if (curr_s < best_s)
best_s = curr_s;
}
b43_phy_write(dev, B43_PHY_PWRDOWN, b);
b43_radio_mask(dev, 0x0004, 0xFFFB);
b43_radio_write16(dev, 0x0013, best_s);
b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1_R1, 0, 0xFFEC);
b43_phy_write(dev, B43_PHY_OFDM(0xB7), 0x1E80);
b43_phy_write(dev, B43_PHY_OFDM(0xB6), 0x1C00);
b43_phy_write(dev, B43_PHY_OFDM(0xB5), 0x0EC0);
b43_phy_write(dev, B43_PHY_OFDM(0xB2), 0x00C0);
b43_phy_write(dev, B43_PHY_OFDM(0xB9), 0x1FFF);
b43_phy_maskset(dev, B43_PHY_OFDM(0xBB), 0xF000, 0x0053);
b43_phy_maskset(dev, B43_PHY_OFDM61, 0xFE1F, 0x0120);
b43_phy_maskset(dev, B43_PHY_OFDM(0x13), 0x0FFF, 0x3000);
b43_phy_maskset(dev, B43_PHY_OFDM(0x14), 0x0FFF, 0x3000);
b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 6, 0x0017);
for (i = 0; i < 6; i++)
b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, i, 0x000F);
b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 0x0D, 0x000E);
b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 0x0E, 0x0011);
b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 0x0F, 0x0013);
b43_phy_write(dev, B43_PHY_OFDM(0x33), 0x5030);
b43_phy_set(dev, B43_PHY_CRS0, B43_PHY_CRS0_EN);
}
static void hardware_pctl_init_aphy(struct b43_wldev *dev)
{
//TODO
}
void b43_phy_inita(struct b43_wldev *dev)
{
struct b43_phy *phy = &dev->phy;
/* This lowlevel A-PHY init is also called from G-PHY init.
* So we must not access phy->a, if called from G-PHY code.
*/
B43_WARN_ON((phy->type != B43_PHYTYPE_A) &&
(phy->type != B43_PHYTYPE_G));
might_sleep();
if (phy->rev >= 6) {
if (phy->type == B43_PHYTYPE_A)
b43_phy_mask(dev, B43_PHY_OFDM(0x1B), ~0x1000);
if (b43_phy_read(dev, B43_PHY_ENCORE) & B43_PHY_ENCORE_EN)
b43_phy_set(dev, B43_PHY_ENCORE, 0x0010);
else
b43_phy_mask(dev, B43_PHY_ENCORE, ~0x1010);
}
b43_wa_all(dev);
if (phy->type == B43_PHYTYPE_A) {
if (phy->gmode && (phy->rev < 3))
b43_phy_set(dev, 0x0034, 0x0001);
b43_phy_rssiagc(dev, 0);
b43_phy_set(dev, B43_PHY_CRS0, B43_PHY_CRS0_EN);
b43_radio_init2060(dev);
if ((dev->dev->board_vendor == SSB_BOARDVENDOR_BCM) &&
((dev->dev->board_type == SSB_BOARD_BU4306) ||
(dev->dev->board_type == SSB_BOARD_BU4309))) {
; //TODO: A PHY LO
}
if (phy->rev >= 3)
b43_phy_ww(dev);
hardware_pctl_init_aphy(dev);
//TODO: radar detection
}
if ((phy->type == B43_PHYTYPE_G) &&
(dev->dev->bus_sprom->boardflags_lo & B43_BFL_PACTRL)) {
b43_phy_maskset(dev, B43_PHY_OFDM(0x6E), 0xE000, 0x3CF);
}
}
/* Initialise the TSSI->dBm lookup table */
static int b43_aphy_init_tssi2dbm_table(struct b43_wldev *dev)
{
struct b43_phy *phy = &dev->phy;
struct b43_phy_a *aphy = phy->a;
s16 pab0, pab1, pab2;
pab0 = (s16) (dev->dev->bus_sprom->pa1b0);
pab1 = (s16) (dev->dev->bus_sprom->pa1b1);
pab2 = (s16) (dev->dev->bus_sprom->pa1b2);
if (pab0 != 0 && pab1 != 0 && pab2 != 0 &&
pab0 != -1 && pab1 != -1 && pab2 != -1) {
/* The pabX values are set in SPROM. Use them. */
if ((s8) dev->dev->bus_sprom->itssi_a != 0 &&
(s8) dev->dev->bus_sprom->itssi_a != -1)
aphy->tgt_idle_tssi =
(s8) (dev->dev->bus_sprom->itssi_a);
else
aphy->tgt_idle_tssi = 62;
aphy->tssi2dbm = b43_generate_dyn_tssi2dbm_tab(dev, pab0,
pab1, pab2);
if (!aphy->tssi2dbm)
return -ENOMEM;
} else {
/* pabX values not set in SPROM,
* but APHY needs a generated table. */
aphy->tssi2dbm = NULL;
b43err(dev->wl, "Could not generate tssi2dBm "
"table (wrong SPROM info)!\n");
return -ENODEV;
}
return 0;
}
static int b43_aphy_op_allocate(struct b43_wldev *dev)
{
struct b43_phy_a *aphy;
int err;
aphy = kzalloc(sizeof(*aphy), GFP_KERNEL);
if (!aphy)
return -ENOMEM;
dev->phy.a = aphy;
err = b43_aphy_init_tssi2dbm_table(dev);
if (err)
goto err_free_aphy;
return 0;
err_free_aphy:
kfree(aphy);
dev->phy.a = NULL;
return err;
}
static void b43_aphy_op_prepare_structs(struct b43_wldev *dev)
{
struct b43_phy *phy = &dev->phy;
struct b43_phy_a *aphy = phy->a;
const void *tssi2dbm;
int tgt_idle_tssi;
/* tssi2dbm table is constant, so it is initialized at alloc time.
* Save a copy of the pointer. */
tssi2dbm = aphy->tssi2dbm;
tgt_idle_tssi = aphy->tgt_idle_tssi;
/* Zero out the whole PHY structure. */
memset(aphy, 0, sizeof(*aphy));
aphy->tssi2dbm = tssi2dbm;
aphy->tgt_idle_tssi = tgt_idle_tssi;
//TODO init struct b43_phy_a
}
static void b43_aphy_op_free(struct b43_wldev *dev)
{
struct b43_phy *phy = &dev->phy;
struct b43_phy_a *aphy = phy->a;
kfree(aphy->tssi2dbm);
aphy->tssi2dbm = NULL;
kfree(aphy);
dev->phy.a = NULL;
}
static int b43_aphy_op_init(struct b43_wldev *dev)
{
b43_phy_inita(dev);
return 0;
}
static inline u16 adjust_phyreg(struct b43_wldev *dev, u16 offset)
{
/* OFDM registers are base-registers for the A-PHY. */
if ((offset & B43_PHYROUTE) == B43_PHYROUTE_OFDM_GPHY) {
offset &= ~B43_PHYROUTE;
offset |= B43_PHYROUTE_BASE;
}
#if B43_DEBUG
if ((offset & B43_PHYROUTE) == B43_PHYROUTE_EXT_GPHY) {
/* Ext-G registers are only available on G-PHYs */
b43err(dev->wl, "Invalid EXT-G PHY access at "
"0x%04X on A-PHY\n", offset);
dump_stack();
}
if ((offset & B43_PHYROUTE) == B43_PHYROUTE_N_BMODE) {
/* N-BMODE registers are only available on N-PHYs */
b43err(dev->wl, "Invalid N-BMODE PHY access at "
"0x%04X on A-PHY\n", offset);
dump_stack();
}
#endif /* B43_DEBUG */
return offset;
}
static u16 b43_aphy_op_read(struct b43_wldev *dev, u16 reg)
{
reg = adjust_phyreg(dev, reg);
b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
return b43_read16(dev, B43_MMIO_PHY_DATA);
}
static void b43_aphy_op_write(struct b43_wldev *dev, u16 reg, u16 value)
{
reg = adjust_phyreg(dev, reg);
b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
b43_write16(dev, B43_MMIO_PHY_DATA, value);
}
static u16 b43_aphy_op_radio_read(struct b43_wldev *dev, u16 reg)
{
/* Register 1 is a 32-bit register. */
B43_WARN_ON(reg == 1);
/* A-PHY needs 0x40 for read access */
reg |= 0x40;
b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
return b43_read16(dev, B43_MMIO_RADIO_DATA_LOW);
}
static void b43_aphy_op_radio_write(struct b43_wldev *dev, u16 reg, u16 value)
{
/* Register 1 is a 32-bit register. */
B43_WARN_ON(reg == 1);
b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
b43_write16(dev, B43_MMIO_RADIO_DATA_LOW, value);
}
static bool b43_aphy_op_supports_hwpctl(struct b43_wldev *dev)
{
return (dev->phy.rev >= 5);
}
static void b43_aphy_op_software_rfkill(struct b43_wldev *dev,
bool blocked)
{
struct b43_phy *phy = &dev->phy;
if (!blocked) {
if (phy->radio_on)
return;
b43_radio_write16(dev, 0x0004, 0x00C0);
b43_radio_write16(dev, 0x0005, 0x0008);
b43_phy_mask(dev, 0x0010, 0xFFF7);
b43_phy_mask(dev, 0x0011, 0xFFF7);
b43_radio_init2060(dev);
} else {
b43_radio_write16(dev, 0x0004, 0x00FF);
b43_radio_write16(dev, 0x0005, 0x00FB);
b43_phy_set(dev, 0x0010, 0x0008);
b43_phy_set(dev, 0x0011, 0x0008);
}
}
static int b43_aphy_op_switch_channel(struct b43_wldev *dev,
unsigned int new_channel)
{
if (new_channel > 200)
return -EINVAL;
aphy_channel_switch(dev, new_channel);
return 0;
}
static unsigned int b43_aphy_op_get_default_chan(struct b43_wldev *dev)
{
return 36; /* Default to channel 36 */
}
static void b43_aphy_op_set_rx_antenna(struct b43_wldev *dev, int antenna)
{//TODO
struct b43_phy *phy = &dev->phy;
u16 tmp;
int autodiv = 0;
if (antenna == B43_ANTENNA_AUTO0 || antenna == B43_ANTENNA_AUTO1)
autodiv = 1;
b43_hf_write(dev, b43_hf_read(dev) & ~B43_HF_ANTDIVHELP);
b43_phy_maskset(dev, B43_PHY_BBANDCFG, ~B43_PHY_BBANDCFG_RXANT,
(autodiv ? B43_ANTENNA_AUTO1 : antenna) <<
B43_PHY_BBANDCFG_RXANT_SHIFT);
if (autodiv) {
tmp = b43_phy_read(dev, B43_PHY_ANTDWELL);
if (antenna == B43_ANTENNA_AUTO1)
tmp &= ~B43_PHY_ANTDWELL_AUTODIV1;
else
tmp |= B43_PHY_ANTDWELL_AUTODIV1;
b43_phy_write(dev, B43_PHY_ANTDWELL, tmp);
}
if (phy->rev < 3)
b43_phy_maskset(dev, B43_PHY_ANTDWELL, 0xFF00, 0x24);
else {
b43_phy_set(dev, B43_PHY_OFDM61, 0x10);
if (phy->rev == 3) {
b43_phy_write(dev, B43_PHY_CLIPPWRDOWNT, 0x1D);
b43_phy_write(dev, B43_PHY_ADIVRELATED, 8);
} else {
b43_phy_write(dev, B43_PHY_CLIPPWRDOWNT, 0x3A);
b43_phy_maskset(dev, B43_PHY_ADIVRELATED, 0xFF00, 8);
}
}
b43_hf_write(dev, b43_hf_read(dev) | B43_HF_ANTDIVHELP);
}
static void b43_aphy_op_adjust_txpower(struct b43_wldev *dev)
{//TODO
}
static enum b43_txpwr_result b43_aphy_op_recalc_txpower(struct b43_wldev *dev,
bool ignore_tssi)
{//TODO
return B43_TXPWR_RES_DONE;
}
static void b43_aphy_op_pwork_15sec(struct b43_wldev *dev)
{//TODO
}
static void b43_aphy_op_pwork_60sec(struct b43_wldev *dev)
{//TODO
}
static const struct b43_phy_operations b43_phyops_a = {
.allocate = b43_aphy_op_allocate,
.free = b43_aphy_op_free,
.prepare_structs = b43_aphy_op_prepare_structs,
.init = b43_aphy_op_init,
.phy_read = b43_aphy_op_read,
.phy_write = b43_aphy_op_write,
.radio_read = b43_aphy_op_radio_read,
.radio_write = b43_aphy_op_radio_write,
.supports_hwpctl = b43_aphy_op_supports_hwpctl,
.software_rfkill = b43_aphy_op_software_rfkill,
.switch_analog = b43_phyop_switch_analog_generic,
.switch_channel = b43_aphy_op_switch_channel,
.get_default_chan = b43_aphy_op_get_default_chan,
.set_rx_antenna = b43_aphy_op_set_rx_antenna,
.recalc_txpower = b43_aphy_op_recalc_txpower,
.adjust_txpower = b43_aphy_op_adjust_txpower,
.pwork_15sec = b43_aphy_op_pwork_15sec,
.pwork_60sec = b43_aphy_op_pwork_60sec,
};

View File

@@ -101,26 +101,4 @@ u32 b43_ofdmtab_read32(struct b43_wldev *dev, u16 table, u16 offset);
void b43_ofdmtab_write32(struct b43_wldev *dev, u16 table,
u16 offset, u32 value);
struct b43_phy_a {
/* Pointer to the table used to convert a
* TSSI value to dBm-Q5.2 */
const s8 *tssi2dbm;
/* Target idle TSSI */
int tgt_idle_tssi;
/* Current idle TSSI */
int cur_idle_tssi;//FIXME value currently not set
/* A-PHY TX Power control value. */
u16 txpwr_offset;
//TODO lots of missing stuff
};
/**
* b43_phy_inita - Lowlevel A-PHY init routine.
* This is _only_ used by the G-PHY code.
*/
void b43_phy_inita(struct b43_wldev *dev);
#endif /* LINUX_B43_PHY_A_H_ */

View File

@@ -190,7 +190,6 @@ struct b43_phy_operations {
void (*pwork_60sec)(struct b43_wldev *dev);
};
struct b43_phy_a;
struct b43_phy_g;
struct b43_phy_n;
struct b43_phy_lp;
@@ -210,8 +209,6 @@ struct b43_phy {
#else
union {
#endif
/* A-PHY specific information */
struct b43_phy_a *a;
/* G-PHY specific information */
struct b43_phy_g *g;
/* N-PHY specific information */

View File

@@ -31,6 +31,7 @@
#include "phy_common.h"
#include "lo.h"
#include "main.h"
#include "wa.h"
#include <linux/bitrev.h>
#include <linux/slab.h>
@@ -1987,6 +1988,25 @@ static void b43_phy_init_pctl(struct b43_wldev *dev)
b43_shm_clear_tssi(dev);
}
static void b43_phy_inita(struct b43_wldev *dev)
{
struct b43_phy *phy = &dev->phy;
might_sleep();
if (phy->rev >= 6) {
if (b43_phy_read(dev, B43_PHY_ENCORE) & B43_PHY_ENCORE_EN)
b43_phy_set(dev, B43_PHY_ENCORE, 0x0010);
else
b43_phy_mask(dev, B43_PHY_ENCORE, ~0x1010);
}
b43_wa_all(dev);
if (dev->dev->bus_sprom->boardflags_lo & B43_BFL_PACTRL)
b43_phy_maskset(dev, B43_PHY_OFDM(0x6E), 0xE000, 0x3CF);
}
static void b43_phy_initg(struct b43_wldev *dev)
{
struct b43_phy *phy = &dev->phy;
@@ -2150,11 +2170,6 @@ static void default_radio_attenuation(struct b43_wldev *dev,
}
}
if (phy->type == B43_PHYTYPE_A) {
rf->att = 0x60;
return;
}
switch (phy->radio_ver) {
case 0x2053:
switch (phy->radio_rev) {

View File

@@ -30,33 +30,6 @@
#include "phy_common.h"
#include "wa.h"
static void b43_wa_papd(struct b43_wldev *dev)
{
u16 backup;
backup = b43_ofdmtab_read16(dev, B43_OFDMTAB_PWRDYN2, 0);
b43_ofdmtab_write16(dev, B43_OFDMTAB_PWRDYN2, 0, 7);
b43_ofdmtab_write16(dev, B43_OFDMTAB_UNKNOWN_APHY, 0, 0);
b43_dummy_transmission(dev, true, true);
b43_ofdmtab_write16(dev, B43_OFDMTAB_PWRDYN2, 0, backup);
}
static void b43_wa_auxclipthr(struct b43_wldev *dev)
{
b43_phy_write(dev, B43_PHY_OFDM(0x8E), 0x3800);
}
static void b43_wa_afcdac(struct b43_wldev *dev)
{
b43_phy_write(dev, 0x0035, 0x03FF);
b43_phy_write(dev, 0x0036, 0x0400);
}
static void b43_wa_txdc_offset(struct b43_wldev *dev)
{
b43_ofdmtab_write16(dev, B43_OFDMTAB_DC, 0, 0x0051);
}
void b43_wa_initgains(struct b43_wldev *dev)
{
struct b43_phy *phy = &dev->phy;
@@ -81,41 +54,6 @@ void b43_wa_initgains(struct b43_wldev *dev)
b43_phy_write(dev, 0x00BA, 0x3ED5);
}
static void b43_wa_divider(struct b43_wldev *dev)
{
b43_phy_mask(dev, 0x002B, ~0x0100);
b43_phy_write(dev, 0x008E, 0x58C1);
}
static void b43_wa_gt(struct b43_wldev *dev) /* Gain table. */
{
if (dev->phy.rev <= 2) {
b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN2, 0, 15);
b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN2, 1, 31);
b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN2, 2, 42);
b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN2, 3, 48);
b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN2, 4, 58);
b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 0, 19);
b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 1, 19);
b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 2, 19);
b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 3, 19);
b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 4, 21);
b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 5, 21);
b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 6, 25);
b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN1, 0, 3);
b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN1, 1, 3);
b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN1, 2, 7);
} else {
b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 0, 19);
b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 1, 19);
b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 2, 19);
b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 3, 19);
b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 4, 21);
b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 5, 21);
b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 6, 25);
}
}
static void b43_wa_rssi_lt(struct b43_wldev *dev) /* RSSI lookup table */
{
int i;
@@ -133,15 +71,11 @@ static void b43_wa_rssi_lt(struct b43_wldev *dev) /* RSSI lookup table */
static void b43_wa_analog(struct b43_wldev *dev)
{
struct b43_phy *phy = &dev->phy;
u16 ofdmrev;
ofdmrev = b43_phy_read(dev, B43_PHY_VERSION_OFDM) & B43_PHYVER_VERSION;
if (ofdmrev > 2) {
if (phy->type == B43_PHYTYPE_A)
b43_phy_write(dev, B43_PHY_PWRDOWN, 0x1808);
else
b43_phy_write(dev, B43_PHY_PWRDOWN, 0x1000);
b43_phy_write(dev, B43_PHY_PWRDOWN, 0x1000);
} else {
b43_ofdmtab_write16(dev, B43_OFDMTAB_DAC, 3, 0x1044);
b43_ofdmtab_write16(dev, B43_OFDMTAB_DAC, 4, 0x7201);
@@ -149,26 +83,13 @@ static void b43_wa_analog(struct b43_wldev *dev)
}
}
static void b43_wa_dac(struct b43_wldev *dev)
{
if (dev->phy.analog == 1)
b43_ofdmtab_write16(dev, B43_OFDMTAB_DAC, 1,
(b43_ofdmtab_read16(dev, B43_OFDMTAB_DAC, 1) & ~0x0034) | 0x0008);
else
b43_ofdmtab_write16(dev, B43_OFDMTAB_DAC, 1,
(b43_ofdmtab_read16(dev, B43_OFDMTAB_DAC, 1) & ~0x0078) | 0x0010);
}
static void b43_wa_fft(struct b43_wldev *dev) /* Fine frequency table */
{
int i;
if (dev->phy.type == B43_PHYTYPE_A)
for (i = 0; i < B43_TAB_FINEFREQA_SIZE; i++)
b43_ofdmtab_write16(dev, B43_OFDMTAB_DACRFPABB, i, b43_tab_finefreqa[i]);
else
for (i = 0; i < B43_TAB_FINEFREQG_SIZE; i++)
b43_ofdmtab_write16(dev, B43_OFDMTAB_DACRFPABB, i, b43_tab_finefreqg[i]);
for (i = 0; i < B43_TAB_FINEFREQG_SIZE; i++)
b43_ofdmtab_write16(dev, B43_OFDMTAB_DACRFPABB, i,
b43_tab_finefreqg[i]);
}
static void b43_wa_nft(struct b43_wldev *dev) /* Noise figure table */
@@ -176,21 +97,14 @@ static void b43_wa_nft(struct b43_wldev *dev) /* Noise figure table */
struct b43_phy *phy = &dev->phy;
int i;
if (phy->type == B43_PHYTYPE_A) {
if (phy->rev == 2)
for (i = 0; i < B43_TAB_NOISEA2_SIZE; i++)
b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, i, b43_tab_noisea2[i]);
else
for (i = 0; i < B43_TAB_NOISEA3_SIZE; i++)
b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, i, b43_tab_noisea3[i]);
} else {
if (phy->rev == 1)
for (i = 0; i < B43_TAB_NOISEG1_SIZE; i++)
b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, i, b43_tab_noiseg1[i]);
else
for (i = 0; i < B43_TAB_NOISEG2_SIZE; i++)
b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, i, b43_tab_noiseg2[i]);
}
if (phy->rev == 1)
for (i = 0; i < B43_TAB_NOISEG1_SIZE; i++)
b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, i,
b43_tab_noiseg1[i]);
else
for (i = 0; i < B43_TAB_NOISEG2_SIZE; i++)
b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, i,
b43_tab_noiseg2[i]);
}
static void b43_wa_rt(struct b43_wldev *dev) /* Rotor table */
@@ -201,14 +115,6 @@ static void b43_wa_rt(struct b43_wldev *dev) /* Rotor table */
b43_ofdmtab_write32(dev, B43_OFDMTAB_ROTOR, i, b43_tab_rotor[i]);
}
static void b43_write_null_nst(struct b43_wldev *dev)
{
int i;
for (i = 0; i < B43_TAB_NOISESCALE_SIZE; i++)
b43_ofdmtab_write16(dev, B43_OFDMTAB_NOISESCALE, i, 0);
}
static void b43_write_nst(struct b43_wldev *dev, const u16 *nst)
{
int i;
@@ -221,24 +127,13 @@ static void b43_wa_nst(struct b43_wldev *dev) /* Noise scale table */
{
struct b43_phy *phy = &dev->phy;
if (phy->type == B43_PHYTYPE_A) {
if (phy->rev <= 1)
b43_write_null_nst(dev);
else if (phy->rev == 2)
b43_write_nst(dev, b43_tab_noisescalea2);
else if (phy->rev == 3)
b43_write_nst(dev, b43_tab_noisescalea3);
else
if (phy->rev >= 6) {
if (b43_phy_read(dev, B43_PHY_ENCORE) & B43_PHY_ENCORE_EN)
b43_write_nst(dev, b43_tab_noisescaleg3);
else
b43_write_nst(dev, b43_tab_noisescaleg2);
} else {
if (phy->rev >= 6) {
if (b43_phy_read(dev, B43_PHY_ENCORE) & B43_PHY_ENCORE_EN)
b43_write_nst(dev, b43_tab_noisescaleg3);
else
b43_write_nst(dev, b43_tab_noisescaleg2);
} else {
b43_write_nst(dev, b43_tab_noisescaleg1);
}
b43_write_nst(dev, b43_tab_noisescaleg1);
}
}
@@ -251,41 +146,13 @@ static void b43_wa_art(struct b43_wldev *dev) /* ADV retard table */
i, b43_tab_retard[i]);
}
static void b43_wa_txlna_gain(struct b43_wldev *dev)
{
b43_ofdmtab_write16(dev, B43_OFDMTAB_DC, 13, 0x0000);
}
static void b43_wa_crs_reset(struct b43_wldev *dev)
{
b43_phy_write(dev, 0x002C, 0x0064);
}
static void b43_wa_2060txlna_gain(struct b43_wldev *dev)
{
b43_hf_write(dev, b43_hf_read(dev) |
B43_HF_2060W);
}
static void b43_wa_lms(struct b43_wldev *dev)
{
b43_phy_maskset(dev, 0x0055, 0xFFC0, 0x0004);
}
static void b43_wa_mixedsignal(struct b43_wldev *dev)
{
b43_ofdmtab_write16(dev, B43_OFDMTAB_DAC, 1, 3);
}
static void b43_wa_msst(struct b43_wldev *dev) /* Min sigma square table */
{
struct b43_phy *phy = &dev->phy;
int i;
const u16 *tab;
if (phy->type == B43_PHYTYPE_A) {
tab = b43_tab_sigmasqr1;
} else if (phy->type == B43_PHYTYPE_G) {
if (phy->type == B43_PHYTYPE_G) {
tab = b43_tab_sigmasqr2;
} else {
B43_WARN_ON(1);
@@ -298,13 +165,6 @@ static void b43_wa_msst(struct b43_wldev *dev) /* Min sigma square table */
}
}
static void b43_wa_iqadc(struct b43_wldev *dev)
{
if (dev->phy.analog == 4)
b43_ofdmtab_write16(dev, B43_OFDMTAB_DAC, 0,
b43_ofdmtab_read16(dev, B43_OFDMTAB_DAC, 0) & ~0xF000);
}
static void b43_wa_crs_ed(struct b43_wldev *dev)
{
struct b43_phy *phy = &dev->phy;
@@ -450,38 +310,6 @@ static void b43_wa_cpll_nonpilot(struct b43_wldev *dev)
b43_ofdmtab_write16(dev, B43_OFDMTAB_UNKNOWN_11, 1, 0);
}
static void b43_wa_rssi_adc(struct b43_wldev *dev)
{
if (dev->phy.analog == 4)
b43_phy_write(dev, 0x00DC, 0x7454);
}
static void b43_wa_boards_a(struct b43_wldev *dev)
{
if (dev->dev->board_vendor == SSB_BOARDVENDOR_BCM &&
dev->dev->board_type == SSB_BOARD_BU4306 &&
dev->dev->board_rev < 0x30) {
b43_phy_write(dev, 0x0010, 0xE000);
b43_phy_write(dev, 0x0013, 0x0140);
b43_phy_write(dev, 0x0014, 0x0280);
} else {
if (dev->dev->board_type == SSB_BOARD_MP4318 &&
dev->dev->board_rev < 0x20) {
b43_phy_write(dev, 0x0013, 0x0210);
b43_phy_write(dev, 0x0014, 0x0840);
} else {
b43_phy_write(dev, 0x0013, 0x0140);
b43_phy_write(dev, 0x0014, 0x0280);
}
if (dev->phy.rev <= 4)
b43_phy_write(dev, 0x0010, 0xE000);
else
b43_phy_write(dev, 0x0010, 0x2000);
b43_ofdmtab_write16(dev, B43_OFDMTAB_DC, 1, 0x0039);
b43_ofdmtab_write16(dev, B43_OFDMTAB_UNKNOWN_APHY, 7, 0x0040);
}
}
static void b43_wa_boards_g(struct b43_wldev *dev)
{
struct ssb_sprom *sprom = dev->dev->bus_sprom;
@@ -518,80 +346,7 @@ void b43_wa_all(struct b43_wldev *dev)
{
struct b43_phy *phy = &dev->phy;
if (phy->type == B43_PHYTYPE_A) {
switch (phy->rev) {
case 2:
b43_wa_papd(dev);
b43_wa_auxclipthr(dev);
b43_wa_afcdac(dev);
b43_wa_txdc_offset(dev);
b43_wa_initgains(dev);
b43_wa_divider(dev);
b43_wa_gt(dev);
b43_wa_rssi_lt(dev);
b43_wa_analog(dev);
b43_wa_dac(dev);
b43_wa_fft(dev);
b43_wa_nft(dev);
b43_wa_rt(dev);
b43_wa_nst(dev);
b43_wa_art(dev);
b43_wa_txlna_gain(dev);
b43_wa_crs_reset(dev);
b43_wa_2060txlna_gain(dev);
b43_wa_lms(dev);
break;
case 3:
b43_wa_papd(dev);
b43_wa_mixedsignal(dev);
b43_wa_rssi_lt(dev);
b43_wa_txdc_offset(dev);
b43_wa_initgains(dev);
b43_wa_dac(dev);
b43_wa_nft(dev);
b43_wa_nst(dev);
b43_wa_msst(dev);
b43_wa_analog(dev);
b43_wa_gt(dev);
b43_wa_txpuoff_rxpuon(dev);
b43_wa_txlna_gain(dev);
break;
case 5:
b43_wa_iqadc(dev);
case 6:
b43_wa_papd(dev);
b43_wa_rssi_lt(dev);
b43_wa_txdc_offset(dev);
b43_wa_initgains(dev);
b43_wa_dac(dev);
b43_wa_nft(dev);
b43_wa_nst(dev);
b43_wa_msst(dev);
b43_wa_analog(dev);
b43_wa_gt(dev);
b43_wa_txpuoff_rxpuon(dev);
b43_wa_txlna_gain(dev);
break;
case 7:
b43_wa_iqadc(dev);
b43_wa_papd(dev);
b43_wa_rssi_lt(dev);
b43_wa_txdc_offset(dev);
b43_wa_initgains(dev);
b43_wa_dac(dev);
b43_wa_nft(dev);
b43_wa_nst(dev);
b43_wa_msst(dev);
b43_wa_analog(dev);
b43_wa_gt(dev);
b43_wa_txpuoff_rxpuon(dev);
b43_wa_txlna_gain(dev);
b43_wa_rssi_adc(dev);
default:
B43_WARN_ON(1);
}
b43_wa_boards_a(dev);
} else if (phy->type == B43_PHYTYPE_G) {
if (phy->type == B43_PHYTYPE_G) {
switch (phy->rev) {
case 1://XXX review rev1
b43_wa_crs_ed(dev);

View File

@@ -205,7 +205,7 @@ static u16 b43_generate_tx_phy_ctl1(struct b43_wldev *dev, u8 bitrate)
return control;
}
static u8 b43_calc_fallback_rate(u8 bitrate)
static u8 b43_calc_fallback_rate(u8 bitrate, int gmode)
{
switch (bitrate) {
case B43_CCK_RATE_1MB:
@@ -216,8 +216,15 @@ static u8 b43_calc_fallback_rate(u8 bitrate)
return B43_CCK_RATE_2MB;
case B43_CCK_RATE_11MB:
return B43_CCK_RATE_5MB;
/*
* Don't just fallback to CCK; it may be in 5GHz operation
* and falling back to CCK won't work out very well.
*/
case B43_OFDM_RATE_6MB:
return B43_CCK_RATE_5MB;
if (gmode)
return B43_CCK_RATE_5MB;
else
return B43_OFDM_RATE_6MB;
case B43_OFDM_RATE_9MB:
return B43_OFDM_RATE_6MB;
case B43_OFDM_RATE_12MB:
@@ -438,7 +445,7 @@ int b43_generate_txhdr(struct b43_wldev *dev,
rts_rate = rts_cts_rate ? rts_cts_rate->hw_value : B43_CCK_RATE_1MB;
rts_rate_ofdm = b43_is_ofdm_rate(rts_rate);
rts_rate_fb = b43_calc_fallback_rate(rts_rate);
rts_rate_fb = b43_calc_fallback_rate(rts_rate, phy->gmode);
rts_rate_fb_ofdm = b43_is_ofdm_rate(rts_rate_fb);
if (rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
@@ -642,11 +649,7 @@ static s8 b43_rssinoise_postprocess(struct b43_wldev *dev, u8 in_rssi)
struct b43_phy *phy = &dev->phy;
s8 ret;
if (phy->type == B43_PHYTYPE_A) {
//TODO: Incomplete specs.
ret = 0;
} else
ret = b43_rssi_postprocess(dev, in_rssi, 0, 1, 1);
ret = b43_rssi_postprocess(dev, in_rssi, 0, 1, 1);
return ret;
}
@@ -663,7 +666,6 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
u16 uninitialized_var(chanstat), uninitialized_var(mactime);
u32 uninitialized_var(macstat);
u16 chanid;
u16 phytype;
int padding, rate_idx;
memset(&status, 0, sizeof(status));
@@ -684,7 +686,6 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
chanstat = le16_to_cpu(rxhdr->format_351.channel);
break;
}
phytype = chanstat & B43_RX_CHAN_PHYTYPE;
if (unlikely(macstat & B43_RX_MAC_FCSERR)) {
dev->wl->ieee_stats.dot11FCSErrorCount++;
@@ -755,7 +756,6 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
else
status.signal = max(rxhdr->power0, rxhdr->power1);
break;
case B43_PHYTYPE_A:
case B43_PHYTYPE_B:
case B43_PHYTYPE_G:
case B43_PHYTYPE_LP:
@@ -802,14 +802,6 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
chanid = (chanstat & B43_RX_CHAN_ID) >> B43_RX_CHAN_ID_SHIFT;
switch (chanstat & B43_RX_CHAN_PHYTYPE) {
case B43_PHYTYPE_A:
status.band = NL80211_BAND_5GHZ;
B43_WARN_ON(1);
/* FIXME: We don't really know which value the "chanid" contains.
* So the following assignment might be wrong. */
status.freq =
ieee80211_channel_to_frequency(chanid, status.band);
break;
case B43_PHYTYPE_G:
status.band = NL80211_BAND_2GHZ;
/* Somewhere between 478.104 and 508.1084 firmware for G-PHY

View File

@@ -166,41 +166,45 @@ int brcmf_sdiod_intr_register(struct brcmf_sdio_dev *sdiodev)
sdio_claim_irq(sdiodev->func[1], brcmf_sdiod_ib_irqhandler);
sdio_claim_irq(sdiodev->func[2], brcmf_sdiod_dummy_irqhandler);
sdio_release_host(sdiodev->func[1]);
sdiodev->sd_irq_requested = true;
}
return 0;
}
int brcmf_sdiod_intr_unregister(struct brcmf_sdio_dev *sdiodev)
void brcmf_sdiod_intr_unregister(struct brcmf_sdio_dev *sdiodev)
{
struct brcmfmac_sdio_pd *pdata;
brcmf_dbg(SDIO, "Entering\n");
brcmf_dbg(SDIO, "Entering oob=%d sd=%d\n",
sdiodev->oob_irq_requested,
sdiodev->sd_irq_requested);
pdata = &sdiodev->settings->bus.sdio;
if (pdata->oob_irq_supported) {
if (sdiodev->oob_irq_requested) {
struct brcmfmac_sdio_pd *pdata;
pdata = &sdiodev->settings->bus.sdio;
sdio_claim_host(sdiodev->func[1]);
brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, 0, NULL);
brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_IENx, 0, NULL);
sdio_release_host(sdiodev->func[1]);
if (sdiodev->oob_irq_requested) {
sdiodev->oob_irq_requested = false;
if (sdiodev->irq_wake) {
disable_irq_wake(pdata->oob_irq_nr);
sdiodev->irq_wake = false;
}
free_irq(pdata->oob_irq_nr, &sdiodev->func[1]->dev);
sdiodev->irq_en = false;
sdiodev->oob_irq_requested = false;
if (sdiodev->irq_wake) {
disable_irq_wake(pdata->oob_irq_nr);
sdiodev->irq_wake = false;
}
} else {
free_irq(pdata->oob_irq_nr, &sdiodev->func[1]->dev);
sdiodev->irq_en = false;
sdiodev->oob_irq_requested = false;
}
if (sdiodev->sd_irq_requested) {
sdio_claim_host(sdiodev->func[1]);
sdio_release_irq(sdiodev->func[2]);
sdio_release_irq(sdiodev->func[1]);
sdio_release_host(sdiodev->func[1]);
sdiodev->sd_irq_requested = false;
}
return 0;
}
void brcmf_sdiod_change_state(struct brcmf_sdio_dev *sdiodev,
@@ -1197,12 +1201,17 @@ static void brcmf_ops_sdio_remove(struct sdio_func *func)
brcmf_dbg(SDIO, "sdio device ID: 0x%04x\n", func->device);
brcmf_dbg(SDIO, "Function: %d\n", func->num);
if (func->num != 1)
return;
bus_if = dev_get_drvdata(&func->dev);
if (bus_if) {
sdiodev = bus_if->bus_priv.sdio;
/* start by unregistering irqs */
brcmf_sdiod_intr_unregister(sdiodev);
if (func->num != 1)
return;
/* only proceed with rest of cleanup if func 1 */
brcmf_sdiod_remove(sdiodev);
dev_set_drvdata(&sdiodev->func[1]->dev, NULL);

View File

@@ -541,6 +541,21 @@ brcmf_cfg80211_update_proto_addr_mode(struct wireless_dev *wdev)
ADDR_INDIRECT);
}
static int brcmf_get_first_free_bsscfgidx(struct brcmf_pub *drvr)
{
int bsscfgidx;
for (bsscfgidx = 0; bsscfgidx < BRCMF_MAX_IFS; bsscfgidx++) {
/* bsscfgidx 1 is reserved for legacy P2P */
if (bsscfgidx == 1)
continue;
if (!drvr->iflist[bsscfgidx])
return bsscfgidx;
}
return -ENOMEM;
}
static int brcmf_cfg80211_request_ap_if(struct brcmf_if *ifp)
{
struct brcmf_mbss_ssid_le mbss_ssid_le;
@@ -548,7 +563,7 @@ static int brcmf_cfg80211_request_ap_if(struct brcmf_if *ifp)
int err;
memset(&mbss_ssid_le, 0, sizeof(mbss_ssid_le));
bsscfgidx = brcmf_get_next_free_bsscfgidx(ifp->drvr);
bsscfgidx = brcmf_get_first_free_bsscfgidx(ifp->drvr);
if (bsscfgidx < 0)
return bsscfgidx;
@@ -586,7 +601,7 @@ struct wireless_dev *brcmf_ap_add_vif(struct wiphy *wiphy, const char *name,
brcmf_dbg(INFO, "Adding vif \"%s\"\n", name);
vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_AP, false);
vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_AP);
if (IS_ERR(vif))
return (struct wireless_dev *)vif;
@@ -669,20 +684,24 @@ static struct wireless_dev *brcmf_cfg80211_add_iface(struct wiphy *wiphy,
return ERR_PTR(-EOPNOTSUPP);
case NL80211_IFTYPE_AP:
wdev = brcmf_ap_add_vif(wiphy, name, flags, params);
if (!IS_ERR(wdev))
brcmf_cfg80211_update_proto_addr_mode(wdev);
return wdev;
break;
case NL80211_IFTYPE_P2P_CLIENT:
case NL80211_IFTYPE_P2P_GO:
case NL80211_IFTYPE_P2P_DEVICE:
wdev = brcmf_p2p_add_vif(wiphy, name, name_assign_type, type, flags, params);
if (!IS_ERR(wdev))
brcmf_cfg80211_update_proto_addr_mode(wdev);
return wdev;
break;
case NL80211_IFTYPE_UNSPECIFIED:
default:
return ERR_PTR(-EINVAL);
}
if (IS_ERR(wdev))
brcmf_err("add iface %s type %d failed: err=%d\n",
name, type, (int)PTR_ERR(wdev));
else
brcmf_cfg80211_update_proto_addr_mode(wdev);
return wdev;
}
static void brcmf_scan_config_mpc(struct brcmf_if *ifp, int mpc)
@@ -2750,7 +2769,7 @@ static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_info *cfg,
if (!bi->ctl_ch) {
ch.chspec = le16_to_cpu(bi->chanspec);
cfg->d11inf.decchspec(&ch);
bi->ctl_ch = ch.chnum;
bi->ctl_ch = ch.control_ch_num;
}
channel = bi->ctl_ch;
@@ -2868,7 +2887,7 @@ static s32 brcmf_inform_ibss(struct brcmf_cfg80211_info *cfg,
else
band = wiphy->bands[NL80211_BAND_5GHZ];
freq = ieee80211_channel_to_frequency(ch.chnum, band->band);
freq = ieee80211_channel_to_frequency(ch.control_ch_num, band->band);
cfg->channel = freq;
notify_channel = ieee80211_get_channel(wiphy, freq);
@@ -2878,7 +2897,7 @@ static s32 brcmf_inform_ibss(struct brcmf_cfg80211_info *cfg,
notify_ielen = le32_to_cpu(bi->ie_length);
notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
brcmf_dbg(CONN, "channel: %d(%d)\n", ch.chnum, freq);
brcmf_dbg(CONN, "channel: %d(%d)\n", ch.control_ch_num, freq);
brcmf_dbg(CONN, "capability: %X\n", notify_capability);
brcmf_dbg(CONN, "beacon interval: %d\n", notify_interval);
brcmf_dbg(CONN, "signal: %d\n", notify_signal);
@@ -4439,7 +4458,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
struct brcmf_join_params join_params;
enum nl80211_iftype dev_role;
struct brcmf_fil_bss_enable_le bss_enable;
u16 chanspec;
u16 chanspec = chandef_to_chanspec(&cfg->d11inf, &settings->chandef);
bool mbss;
int is_11d;
@@ -4515,16 +4534,8 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
brcmf_config_ap_mgmt_ie(ifp->vif, &settings->beacon);
/* Parameters shared by all radio interfaces */
if (!mbss) {
chanspec = chandef_to_chanspec(&cfg->d11inf,
&settings->chandef);
err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec);
if (err < 0) {
brcmf_err("Set Channel failed: chspec=%d, %d\n",
chanspec, err);
goto exit;
}
if (is_11d != ifp->vif->is_11d) {
err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_REGULATORY,
is_11d);
@@ -4572,6 +4583,8 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
err = -EINVAL;
goto exit;
}
/* Interface specific setup */
if (dev_role == NL80211_IFTYPE_AP) {
if ((brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS)) && (!mbss))
brcmf_fil_iovar_int_set(ifp, "mbss", 1);
@@ -4581,6 +4594,17 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
brcmf_err("setting AP mode failed %d\n", err);
goto exit;
}
if (!mbss) {
/* Firmware 10.x requires setting channel after enabling
* AP and before bringing interface up.
*/
err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec);
if (err < 0) {
brcmf_err("Set Channel failed: chspec=%d, %d\n",
chanspec, err);
goto exit;
}
}
err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
if (err < 0) {
brcmf_err("BRCMF_C_UP error (%d)\n", err);
@@ -4602,7 +4626,13 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
goto exit;
}
brcmf_dbg(TRACE, "AP mode configuration complete\n");
} else {
} else if (dev_role == NL80211_IFTYPE_P2P_GO) {
err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec);
if (err < 0) {
brcmf_err("Set Channel failed: chspec=%d, %d\n",
chanspec, err);
goto exit;
}
err = brcmf_fil_bsscfg_data_set(ifp, "ssid", &ssid_le,
sizeof(ssid_le));
if (err < 0) {
@@ -4619,7 +4649,10 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
}
brcmf_dbg(TRACE, "GO mode configuration complete\n");
} else {
WARN_ON(1);
}
set_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
brcmf_net_setcarrier(ifp, true);
@@ -4908,6 +4941,68 @@ exit:
return err;
}
static int brcmf_cfg80211_get_channel(struct wiphy *wiphy,
struct wireless_dev *wdev,
struct cfg80211_chan_def *chandef)
{
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
struct net_device *ndev = wdev->netdev;
struct brcmf_if *ifp;
struct brcmu_chan ch;
enum nl80211_band band = 0;
enum nl80211_chan_width width = 0;
u32 chanspec;
int freq, err;
if (!ndev)
return -ENODEV;
ifp = netdev_priv(ndev);
err = brcmf_fil_iovar_int_get(ifp, "chanspec", &chanspec);
if (err) {
brcmf_err("chanspec failed (%d)\n", err);
return err;
}
ch.chspec = chanspec;
cfg->d11inf.decchspec(&ch);
switch (ch.band) {
case BRCMU_CHAN_BAND_2G:
band = NL80211_BAND_2GHZ;
break;
case BRCMU_CHAN_BAND_5G:
band = NL80211_BAND_5GHZ;
break;
}
switch (ch.bw) {
case BRCMU_CHAN_BW_80:
width = NL80211_CHAN_WIDTH_80;
break;
case BRCMU_CHAN_BW_40:
width = NL80211_CHAN_WIDTH_40;
break;
case BRCMU_CHAN_BW_20:
width = NL80211_CHAN_WIDTH_20;
break;
case BRCMU_CHAN_BW_80P80:
width = NL80211_CHAN_WIDTH_80P80;
break;
case BRCMU_CHAN_BW_160:
width = NL80211_CHAN_WIDTH_160;
break;
}
freq = ieee80211_channel_to_frequency(ch.control_ch_num, band);
chandef->chan = ieee80211_get_channel(wiphy, freq);
chandef->width = width;
chandef->center_freq1 = ieee80211_channel_to_frequency(ch.chnum, band);
chandef->center_freq2 = 0;
return 0;
}
static int brcmf_cfg80211_crit_proto_start(struct wiphy *wiphy,
struct wireless_dev *wdev,
enum nl80211_crit_proto_id proto,
@@ -5070,6 +5165,7 @@ static struct cfg80211_ops brcmf_cfg80211_ops = {
.mgmt_tx = brcmf_cfg80211_mgmt_tx,
.remain_on_channel = brcmf_p2p_remain_on_channel,
.cancel_remain_on_channel = brcmf_cfg80211_cancel_remain_on_channel,
.get_channel = brcmf_cfg80211_get_channel,
.start_p2p_device = brcmf_p2p_start_device,
.stop_p2p_device = brcmf_p2p_stop_device,
.crit_proto_start = brcmf_cfg80211_crit_proto_start,
@@ -5078,8 +5174,7 @@ static struct cfg80211_ops brcmf_cfg80211_ops = {
};
struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
enum nl80211_iftype type,
bool pm_block)
enum nl80211_iftype type)
{
struct brcmf_cfg80211_vif *vif_walk;
struct brcmf_cfg80211_vif *vif;
@@ -5094,8 +5189,6 @@ struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
vif->wdev.wiphy = cfg->wiphy;
vif->wdev.iftype = type;
vif->pm_block = pm_block;
brcmf_init_prof(&vif->profile);
if (type == NL80211_IFTYPE_AP) {
@@ -5296,7 +5389,7 @@ brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg,
else
band = wiphy->bands[NL80211_BAND_5GHZ];
freq = ieee80211_channel_to_frequency(ch.chnum, band->band);
freq = ieee80211_channel_to_frequency(ch.control_ch_num, band->band);
notify_channel = ieee80211_get_channel(wiphy, freq);
done:
@@ -5352,7 +5445,6 @@ brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info *cfg,
struct net_device *ndev,
const struct brcmf_event_msg *e, void *data)
{
struct brcmf_if *ifp = netdev_priv(ndev);
static int generation;
u32 event = e->event_code;
u32 reason = e->reason;
@@ -5363,8 +5455,6 @@ brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info *cfg,
ndev != cfg_to_ndev(cfg)) {
brcmf_dbg(CONN, "AP mode link down\n");
complete(&cfg->vif_disabled);
if (ifp->vif->mbss)
brcmf_remove_interface(ifp);
return 0;
}
@@ -5818,14 +5908,15 @@ static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg,
channel = band->channels;
index = band->n_channels;
for (j = 0; j < band->n_channels; j++) {
if (channel[j].hw_value == ch.chnum) {
if (channel[j].hw_value == ch.control_ch_num) {
index = j;
break;
}
}
channel[index].center_freq =
ieee80211_channel_to_frequency(ch.chnum, band->band);
channel[index].hw_value = ch.chnum;
ieee80211_channel_to_frequency(ch.control_ch_num,
band->band);
channel[index].hw_value = ch.control_ch_num;
/* assuming the chanspecs order is HT20,
* HT40 upper, HT40 lower, and VHT80.
@@ -5927,7 +6018,7 @@ static int brcmf_enable_bw40_2g(struct brcmf_cfg80211_info *cfg)
if (WARN_ON(ch.bw != BRCMU_CHAN_BW_40))
continue;
for (j = 0; j < band->n_channels; j++) {
if (band->channels[j].hw_value == ch.chnum)
if (band->channels[j].hw_value == ch.control_ch_num)
break;
}
if (WARN_ON(j == band->n_channels))
@@ -6715,11 +6806,10 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
return NULL;
}
ops = kzalloc(sizeof(*ops), GFP_KERNEL);
ops = kmemdup(&brcmf_cfg80211_ops, sizeof(*ops), GFP_KERNEL);
if (!ops)
return NULL;
memcpy(ops, &brcmf_cfg80211_ops, sizeof(*ops));
ifp = netdev_priv(ndev);
#ifdef CONFIG_PM
if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_GTK))
@@ -6740,7 +6830,7 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
init_vif_event(&cfg->vif_event);
INIT_LIST_HEAD(&cfg->vif_list);
vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_STATION, false);
vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_STATION);
if (IS_ERR(vif))
goto wiphy_out;

View File

@@ -20,6 +20,9 @@
/* for brcmu_d11inf */
#include <brcmu_d11.h>
#include "fwil_types.h"
#include "p2p.h"
#define WL_NUM_SCAN_MAX 10
#define WL_TLV_INFO_MAX 1024
#define WL_BSS_INFO_MAX 2048
@@ -167,7 +170,6 @@ struct vif_saved_ie {
* @wdev: wireless device.
* @profile: profile information.
* @sme_state: SME state using enum brcmf_vif_status bits.
* @pm_block: power-management blocked.
* @list: linked list.
* @mgmt_rx_reg: registered rx mgmt frame types.
* @mbss: Multiple BSS type, set if not first AP (not relevant for P2P).
@@ -177,7 +179,6 @@ struct brcmf_cfg80211_vif {
struct wireless_dev wdev;
struct brcmf_cfg80211_profile profile;
unsigned long sme_state;
bool pm_block;
struct vif_saved_ie saved_ie;
struct list_head list;
u16 mgmt_rx_reg;
@@ -388,8 +389,7 @@ s32 brcmf_cfg80211_down(struct net_device *ndev);
enum nl80211_iftype brcmf_cfg80211_get_iftype(struct brcmf_if *ifp);
struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
enum nl80211_iftype type,
bool pm_block);
enum nl80211_iftype type);
void brcmf_free_vif(struct brcmf_cfg80211_vif *vif);
s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,

View File

@@ -685,6 +685,8 @@ static u32 brcmf_chip_tcm_rambase(struct brcmf_chip_priv *ci)
case BRCM_CC_43602_CHIP_ID:
case BRCM_CC_4371_CHIP_ID:
return 0x180000;
case BRCM_CC_43465_CHIP_ID:
case BRCM_CC_43525_CHIP_ID:
case BRCM_CC_4365_CHIP_ID:
case BRCM_CC_4366_CHIP_ID:
return 0x200000;

View File

@@ -516,7 +516,7 @@ int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked)
/* set appropriate operations */
ndev->netdev_ops = &brcmf_netdev_ops_pri;
ndev->hard_header_len += drvr->hdrlen;
ndev->needed_headroom += drvr->hdrlen;
ndev->ethtool_ops = &brcmf_ethtool_ops;
drvr->rxsz = ndev->mtu + ndev->hard_header_len +
@@ -753,30 +753,6 @@ void brcmf_remove_interface(struct brcmf_if *ifp)
brcmf_del_if(ifp->drvr, ifp->bsscfgidx);
}
int brcmf_get_next_free_bsscfgidx(struct brcmf_pub *drvr)
{
int ifidx;
int bsscfgidx;
bool available;
int highest;
available = false;
bsscfgidx = 2;
highest = 2;
for (ifidx = 0; ifidx < BRCMF_MAX_IFS; ifidx++) {
if (drvr->iflist[ifidx]) {
if (drvr->iflist[ifidx]->bsscfgidx == bsscfgidx)
bsscfgidx = highest + 1;
else if (drvr->iflist[ifidx]->bsscfgidx > highest)
highest = drvr->iflist[ifidx]->bsscfgidx;
} else {
available = true;
}
}
return available ? bsscfgidx : -ENOMEM;
}
#ifdef CONFIG_INET
#define ARPOL_MAX_ENTRIES 8
static int brcmf_inetaddr_changed(struct notifier_block *nb,

View File

@@ -217,7 +217,6 @@ int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked);
struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bsscfgidx, s32 ifidx,
bool is_p2pdev, char *name, u8 *mac_addr);
void brcmf_remove_interface(struct brcmf_if *ifp);
int brcmf_get_next_free_bsscfgidx(struct brcmf_pub *drvr);
void brcmf_txflowblock_if(struct brcmf_if *ifp,
enum brcmf_netif_stop_reason reason, bool state);
void brcmf_txfinalize(struct brcmf_if *ifp, struct sk_buff *txp, bool success);

View File

@@ -2101,7 +2101,7 @@ int brcmf_fws_process_skb(struct brcmf_if *ifp, struct sk_buff *skb)
brcmf_dbg(DATA, "tx proto=0x%X\n", ntohs(eh->h_proto));
/* determine the priority */
if (!skb->priority)
if ((skb->priority == 0) || (skb->priority > 7))
skb->priority = cfg80211_classify8021d(skb, NULL);
drvr->tx_multicast += !!multicast;

View File

@@ -1246,7 +1246,7 @@ bool brcmf_p2p_scan_finding_common_channel(struct brcmf_cfg80211_info *cfg,
if (!bi->ctl_ch) {
ch.chspec = le16_to_cpu(bi->chanspec);
cfg->d11inf.decchspec(&ch);
bi->ctl_ch = ch.chnum;
bi->ctl_ch = ch.control_ch_num;
}
afx_hdl->peer_chan = bi->ctl_ch;
brcmf_dbg(TRACE, "ACTION FRAME SCAN : Peer %pM found, channel : %d\n",
@@ -1385,7 +1385,7 @@ int brcmf_p2p_notify_action_frame_rx(struct brcmf_if *ifp,
if (test_bit(BRCMF_P2P_STATUS_FINDING_COMMON_CHANNEL,
&p2p->status) &&
(ether_addr_equal(afx_hdl->tx_dst_addr, e->addr))) {
afx_hdl->peer_chan = ch.chnum;
afx_hdl->peer_chan = ch.control_ch_num;
brcmf_dbg(INFO, "GON request: Peer found, channel=%d\n",
afx_hdl->peer_chan);
complete(&afx_hdl->act_frm_scan);
@@ -1428,7 +1428,7 @@ int brcmf_p2p_notify_action_frame_rx(struct brcmf_if *ifp,
memcpy(&mgmt_frame->u, frame, mgmt_frame_len);
mgmt_frame_len += offsetof(struct ieee80211_mgmt, u);
freq = ieee80211_channel_to_frequency(ch.chnum,
freq = ieee80211_channel_to_frequency(ch.control_ch_num,
ch.band == BRCMU_CHAN_BAND_2G ?
NL80211_BAND_2GHZ :
NL80211_BAND_5GHZ);
@@ -1873,7 +1873,7 @@ s32 brcmf_p2p_notify_rx_mgmt_p2p_probereq(struct brcmf_if *ifp,
if (test_bit(BRCMF_P2P_STATUS_FINDING_COMMON_CHANNEL, &p2p->status) &&
(ether_addr_equal(afx_hdl->tx_dst_addr, e->addr))) {
afx_hdl->peer_chan = ch.chnum;
afx_hdl->peer_chan = ch.control_ch_num;
brcmf_dbg(INFO, "PROBE REQUEST: Peer found, channel=%d\n",
afx_hdl->peer_chan);
complete(&afx_hdl->act_frm_scan);
@@ -1898,7 +1898,7 @@ s32 brcmf_p2p_notify_rx_mgmt_p2p_probereq(struct brcmf_if *ifp,
mgmt_frame = (u8 *)(rxframe + 1);
mgmt_frame_len = e->datalen - sizeof(*rxframe);
freq = ieee80211_channel_to_frequency(ch.chnum,
freq = ieee80211_channel_to_frequency(ch.control_ch_num,
ch.band == BRCMU_CHAN_BAND_2G ?
NL80211_BAND_2GHZ :
NL80211_BAND_5GHZ);
@@ -2030,8 +2030,6 @@ static int brcmf_p2p_request_p2p_if(struct brcmf_p2p_info *p2p,
err = brcmf_fil_iovar_data_set(ifp, "p2p_ifadd", &if_request,
sizeof(if_request));
if (err)
return err;
return err;
}
@@ -2076,8 +2074,7 @@ static struct wireless_dev *brcmf_p2p_create_p2pdev(struct brcmf_p2p_info *p2p,
if (p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif)
return ERR_PTR(-ENOSPC);
p2p_vif = brcmf_alloc_vif(p2p->cfg, NL80211_IFTYPE_P2P_DEVICE,
false);
p2p_vif = brcmf_alloc_vif(p2p->cfg, NL80211_IFTYPE_P2P_DEVICE);
if (IS_ERR(p2p_vif)) {
brcmf_err("could not create discovery vif\n");
return (struct wireless_dev *)p2p_vif;
@@ -2177,7 +2174,7 @@ struct wireless_dev *brcmf_p2p_add_vif(struct wiphy *wiphy, const char *name,
return ERR_PTR(-EOPNOTSUPP);
}
vif = brcmf_alloc_vif(cfg, type, false);
vif = brcmf_alloc_vif(cfg, type);
if (IS_ERR(vif))
return (struct wireless_dev *)vif;
brcmf_cfg80211_arm_vif_event(cfg, vif);

View File

@@ -54,21 +54,25 @@ BRCMF_FW_NVRAM_DEF(43570, "brcmfmac43570-pcie.bin", "brcmfmac43570-pcie.txt");
BRCMF_FW_NVRAM_DEF(4358, "brcmfmac4358-pcie.bin", "brcmfmac4358-pcie.txt");
BRCMF_FW_NVRAM_DEF(4359, "brcmfmac4359-pcie.bin", "brcmfmac4359-pcie.txt");
BRCMF_FW_NVRAM_DEF(4365B, "brcmfmac4365b-pcie.bin", "brcmfmac4365b-pcie.txt");
BRCMF_FW_NVRAM_DEF(4365C, "brcmfmac4365c-pcie.bin", "brcmfmac4365c-pcie.txt");
BRCMF_FW_NVRAM_DEF(4366B, "brcmfmac4366b-pcie.bin", "brcmfmac4366b-pcie.txt");
BRCMF_FW_NVRAM_DEF(4366C, "brcmfmac4366c-pcie.bin", "brcmfmac4366c-pcie.txt");
BRCMF_FW_NVRAM_DEF(4371, "brcmfmac4371-pcie.bin", "brcmfmac4371-pcie.txt");
static struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = {
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43602_CHIP_ID, 0xFFFFFFFF, 43602),
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43465_CHIP_ID, 0xFFFFFFF0, 4366C),
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4350_CHIP_ID, 0x000000FF, 4350C),
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4350_CHIP_ID, 0xFFFFFF00, 4350),
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43525_CHIP_ID, 0xFFFFFFF0, 4365C),
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4356_CHIP_ID, 0xFFFFFFFF, 4356),
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43567_CHIP_ID, 0xFFFFFFFF, 43570),
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43569_CHIP_ID, 0xFFFFFFFF, 43570),
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43570_CHIP_ID, 0xFFFFFFFF, 43570),
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4358_CHIP_ID, 0xFFFFFFFF, 4358),
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4359_CHIP_ID, 0xFFFFFFFF, 4359),
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4365_CHIP_ID, 0xFFFFFFFF, 4365B),
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4365_CHIP_ID, 0x0000000F, 4365B),
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4365_CHIP_ID, 0xFFFFFFF0, 4365C),
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4366_CHIP_ID, 0x0000000F, 4366B),
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4366_CHIP_ID, 0xFFFFFFF0, 4366C),
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4371_CHIP_ID, 0xFFFFFFFF, 4371),

View File

@@ -1384,8 +1384,7 @@ static int brcmf_sdio_hdparse(struct brcmf_sdio *bus, u8 *header,
return -ENXIO;
}
if (rd->seq_num != rx_seq) {
brcmf_err("seq %d: sequence number error, expect %d\n",
rx_seq, rd->seq_num);
brcmf_dbg(SDIO, "seq %d, expected %d\n", rx_seq, rd->seq_num);
bus->sdcnt.rx_badseq++;
rd->seq_num = rx_seq;
}
@@ -3666,7 +3665,7 @@ brcmf_sdio_drivestrengthinit(struct brcmf_sdio_dev *sdiodev,
str_shift = 11;
break;
default:
brcmf_err("No SDIO Drive strength init done for chip %s rev %d pmurev %d\n",
brcmf_dbg(INFO, "No SDIO driver strength init needed for chip %s rev %d pmurev %d\n",
ci->name, ci->chiprev, ci->pmurev);
break;
}

View File

@@ -186,6 +186,7 @@ struct brcmf_sdio_dev {
struct brcmf_bus *bus_if;
struct brcmf_mp_device *settings;
bool oob_irq_requested;
bool sd_irq_requested;
bool irq_en; /* irq enable flags */
spinlock_t irq_en_lock;
bool irq_wake; /* irq wake enable flags */
@@ -293,7 +294,7 @@ struct sdpcmd_regs {
/* Register/deregister interrupt handler. */
int brcmf_sdiod_intr_register(struct brcmf_sdio_dev *sdiodev);
int brcmf_sdiod_intr_unregister(struct brcmf_sdio_dev *sdiodev);
void brcmf_sdiod_intr_unregister(struct brcmf_sdio_dev *sdiodev);
/* sdio device register access interface */
u8 brcmf_sdiod_regrb(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret);

View File

@@ -27017,7 +27017,7 @@ wlc_phy_rxcal_gainctrl_nphy_rev5(struct brcms_phy *pi, u8 rx_core,
tx_core = 1 - rx_core;
num_samps = 1024;
desired_log2_pwr = (cal_type == 0) ? 13 : 13;
desired_log2_pwr = 13;
wlc_phy_rx_iq_coeffs_nphy(pi, 0, &save_comp);
zero_comp.a0 = zero_comp.b0 = zero_comp.a1 = zero_comp.b1 = 0x0;

View File

@@ -107,6 +107,7 @@ static void brcmu_d11n_decchspec(struct brcmu_chan *ch)
u16 val;
ch->chnum = (u8)(ch->chspec & BRCMU_CHSPEC_CH_MASK);
ch->control_ch_num = ch->chnum;
switch (ch->chspec & BRCMU_CHSPEC_D11N_BW_MASK) {
case BRCMU_CHSPEC_D11N_BW_20:
@@ -118,10 +119,10 @@ static void brcmu_d11n_decchspec(struct brcmu_chan *ch)
val = ch->chspec & BRCMU_CHSPEC_D11N_SB_MASK;
if (val == BRCMU_CHSPEC_D11N_SB_L) {
ch->sb = BRCMU_CHAN_SB_L;
ch->chnum -= CH_10MHZ_APART;
ch->control_ch_num -= CH_10MHZ_APART;
} else {
ch->sb = BRCMU_CHAN_SB_U;
ch->chnum += CH_10MHZ_APART;
ch->control_ch_num += CH_10MHZ_APART;
}
break;
default:
@@ -147,6 +148,7 @@ static void brcmu_d11ac_decchspec(struct brcmu_chan *ch)
u16 val;
ch->chnum = (u8)(ch->chspec & BRCMU_CHSPEC_CH_MASK);
ch->control_ch_num = ch->chnum;
switch (ch->chspec & BRCMU_CHSPEC_D11AC_BW_MASK) {
case BRCMU_CHSPEC_D11AC_BW_20:
@@ -158,10 +160,10 @@ static void brcmu_d11ac_decchspec(struct brcmu_chan *ch)
val = ch->chspec & BRCMU_CHSPEC_D11AC_SB_MASK;
if (val == BRCMU_CHSPEC_D11AC_SB_L) {
ch->sb = BRCMU_CHAN_SB_L;
ch->chnum -= CH_10MHZ_APART;
ch->control_ch_num -= CH_10MHZ_APART;
} else if (val == BRCMU_CHSPEC_D11AC_SB_U) {
ch->sb = BRCMU_CHAN_SB_U;
ch->chnum += CH_10MHZ_APART;
ch->control_ch_num += CH_10MHZ_APART;
} else {
WARN_ON_ONCE(1);
}
@@ -172,16 +174,16 @@ static void brcmu_d11ac_decchspec(struct brcmu_chan *ch)
BRCMU_CHSPEC_D11AC_SB_SHIFT);
switch (ch->sb) {
case BRCMU_CHAN_SB_LL:
ch->chnum -= CH_30MHZ_APART;
ch->control_ch_num -= CH_30MHZ_APART;
break;
case BRCMU_CHAN_SB_LU:
ch->chnum -= CH_10MHZ_APART;
ch->control_ch_num -= CH_10MHZ_APART;
break;
case BRCMU_CHAN_SB_UL:
ch->chnum += CH_10MHZ_APART;
ch->control_ch_num += CH_10MHZ_APART;
break;
case BRCMU_CHAN_SB_UU:
ch->chnum += CH_30MHZ_APART;
ch->control_ch_num += CH_30MHZ_APART;
break;
default:
WARN_ON_ONCE(1);

View File

@@ -40,7 +40,9 @@
#define BRCM_CC_4339_CHIP_ID 0x4339
#define BRCM_CC_43430_CHIP_ID 43430
#define BRCM_CC_4345_CHIP_ID 0x4345
#define BRCM_CC_43465_CHIP_ID 43465
#define BRCM_CC_4350_CHIP_ID 0x4350
#define BRCM_CC_43525_CHIP_ID 43525
#define BRCM_CC_4354_CHIP_ID 0x4354
#define BRCM_CC_4356_CHIP_ID 0x4356
#define BRCM_CC_43566_CHIP_ID 43566

View File

@@ -125,14 +125,36 @@ enum brcmu_chan_sb {
BRCMU_CHAN_SB_UU = BRCMU_CHAN_SB_LUU,
};
/**
* struct brcmu_chan - stores channel formats
*
* This structure can be used with functions translating chanspec into generic
* channel info and the other way.
*
* @chspec: firmware specific format
* @chnum: center channel number
* @control_ch_num: control channel number
* @band: frequency band
* @bw: channel width
* @sb: control sideband (location of control channel against the center one)
*/
struct brcmu_chan {
u16 chspec;
u8 chnum;
u8 control_ch_num;
u8 band;
enum brcmu_chan_bw bw;
enum brcmu_chan_sb sb;
};
/**
* struct brcmu_d11inf - provides functions translating channel format
*
* @io_type: determines version of channel format used by firmware
* @encchspec: encodes channel info into a chanspec, requires center channel
* number, ignores control one
* @decchspec: decodes chanspec into generic info
*/
struct brcmu_d11inf {
u8 io_type;