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:
@@ -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
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
|
@@ -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:
|
||||
|
@@ -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,
|
||||
};
|
@@ -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_ */
|
||||
|
@@ -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 */
|
||||
|
@@ -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) {
|
||||
|
@@ -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);
|
||||
|
@@ -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
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -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,
|
||||
|
@@ -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;
|
||||
|
@@ -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,
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
|
@@ -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),
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
|
@@ -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
|
||||
|
@@ -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;
|
||||
|
||||
|
Reference in New Issue
Block a user