--- bwn/if_bwn.c 2022-10-25 19:03:32.598598000 +0300
+++ xbwn/if_bwn.c 2022-10-25 19:10:31.697818000 +0300
@@ -97,7 +97,6 @@
#include "bhnd_nvram_map.h"
#include "gpio_if.h"
-
static SYSCTL_NODE(_hw, OID_AUTO, bwn, CTLFLAG_RD | CTLFLAG_MPSAFE, 0,
"Broadcom driver parameters");
@@ -111,6 +110,16 @@
"Broadcom debugging printfs");
#endif
+static int bwn_hacks = 0; /* hack crappy rx on my bcm43228 */
+// bit 8 => set RX antenna using the code for PHY_TYPE_G
+// bit 9 => enable alternative values for retry counters
+// bit 0-3 => alternative value for short retries counter
+// bit 4-7 => alternative value for long retries counter
+SYSCTL_INT(_hw_bwn, OID_AUTO, bwn_hacks, CTLFLAG_RWTUN, &bwn_hacks, 0,
+ "uses hacks around bad RX");
+TUNABLE_INT("hw.bwn.bwn_hacks", &bwn_hacks);
+
+
static int bwn_bfp = 0; /* use "Bad Frames Preemption" */
SYSCTL_INT(_hw_bwn, OID_AUTO, bfp, CTLFLAG_RW, &bwn_bfp, 0,
"uses Bad Frames Preemption");
@@ -375,6 +384,14 @@
{ 2472, 13, 30 }, { 2484, 14, 30 } },
.nchannels = 14
};
+static const struct bwn_channelinfo bwn_chantable_bg_lim = {
+ .channels = {
+ { 2412, 1, 30 }, { 2417, 2, 30 }, { 2422, 3, 30 },
+ { 2427, 4, 30 }, { 2432, 5, 30 }, { 2437, 6, 30 },
+ { 2442, 7, 30 }, { 2447, 8, 30 }, { 2452, 9, 30 },
+ { 2457, 10, 30 }, { 2462, 11, 30 }},
+ .nchannels = 11
+};
static const struct bwn_channelinfo bwn_chantable_a = {
.channels = {
@@ -394,6 +411,15 @@
.nchannels = 37
};
+static const struct bwn_channelinfo bwn_chantable_a_lim = {
+ .channels = {
+ { 5180, 36, 30 }, { 5200, 40, 30 }, { 5220, 44, 30 },
+ { 5240, 48, 30 }, { 5745, 149, 30 }, { 5765, 153, 30 },
+ { 5785, 157, 30 }, { 5805, 161, 30 }, { 5825, 165, 30 }
+ },
+ .nchannels = 9
+};
+
#if 0
static const struct bwn_channelinfo bwn_chantable_n = {
.channels = {
@@ -498,6 +524,7 @@
static const struct bhnd_device bwn_devices[] = {
BWN_DEV(HWREV_RANGE(5, 16)),
BWN_DEV(HWREV_EQ(23)),
+ BWN_DEV(HWREV_EQ(30)),
BHND_DEVICE_END
};
@@ -1355,6 +1382,10 @@
if (error)
goto fail;
+ if(mac->mac_phy.type == BWN_PHYTYPE_LCNXN) {
+ mac->mac_phy.type = BWN_PHYTYPE_N;
+ mac->mac_phy.rev += 16;
+ }
/*
* This is the whitelist of devices which we "believe"
* the SPROM PHY config from. The rest are "guessed".
@@ -1364,7 +1395,9 @@
sc->sc_board_info.board_devid != PCI_DEVID_BCM4318_D11DUAL &&
sc->sc_board_info.board_devid != PCI_DEVID_BCM4306_D11DUAL &&
sc->sc_board_info.board_devid != PCI_DEVID_BCM4321_D11N &&
- sc->sc_board_info.board_devid != PCI_DEVID_BCM4322_D11N) {
+ sc->sc_board_info.board_devid != PCI_DEVID_BCM4322_D11N &&
+ sc->sc_board_info.board_devid != PCI_DEVID_BCM43228_D11N
+ ) {
have_a = have_bg = 0;
if (mac->mac_phy.type == BWN_PHYTYPE_A)
have_a = 1;
@@ -1443,7 +1476,7 @@
mac->mac_phy.switch_analog = bwn_phy_n_switch_analog;
mac->mac_phy.switch_channel = bwn_phy_n_switch_channel;
mac->mac_phy.get_default_chan = bwn_phy_n_get_default_chan;
- mac->mac_phy.set_antenna = bwn_phy_n_set_antenna;
+ mac->mac_phy.set_antenna = (bwn_hacks & 0x100) ? bwn_phy_g_set_antenna : bwn_phy_n_set_antenna;
mac->mac_phy.set_im = bwn_phy_n_im;
mac->mac_phy.recalc_txpwr = bwn_phy_n_recalc_txpwr;
mac->mac_phy.set_txpwr = bwn_phy_n_set_txpwr;
@@ -1574,11 +1607,15 @@
phy->analog = (tmp & BWN_PHYVER_ANALOG) >> 12;
phy->type = (tmp & BWN_PHYVER_TYPE) >> 8;
phy->rev = (tmp & BWN_PHYVER_VERSION);
+ if(phy->type == BWN_PHYTYPE_LCNXN) {
+ phy->type = BWN_PHYTYPE_N;
+ phy->rev += 16;
+ }
if ((phy->type == BWN_PHYTYPE_A && phy->rev >= 4) ||
(phy->type == BWN_PHYTYPE_B && phy->rev != 2 &&
phy->rev != 4 && phy->rev != 6 && phy->rev != 7) ||
(phy->type == BWN_PHYTYPE_G && phy->rev > 9) ||
- (phy->type == BWN_PHYTYPE_N && phy->rev > 6) ||
+ (phy->type == BWN_PHYTYPE_N && phy->rev > 19) ||
(phy->type == BWN_PHYTYPE_LP && phy->rev > 2))
goto unsupphy;
@@ -1605,7 +1642,7 @@
(phy->type == BWN_PHYTYPE_B && (phy->rf_ver & 0xfff0) != 0x2050) ||
(phy->type == BWN_PHYTYPE_G && phy->rf_ver != 0x2050) ||
(phy->type == BWN_PHYTYPE_N &&
- phy->rf_ver != 0x2055 && phy->rf_ver != 0x2056) ||
+ phy->rf_ver != 0x2055 && phy->rf_ver != 0x2056 && phy->rf_ver != 0x2057) ||
(phy->type == BWN_PHYTYPE_LP &&
phy->rf_ver != 0x2062 && phy->rf_ver != 0x2063))
goto unsupradio;
@@ -1672,8 +1709,14 @@
{
struct bwn_softc *sc = mac->mac_sc;
struct ieee80211com *ic = &sc->sc_ic;
- uint8_t bands[IEEE80211_MODE_BYTES];
+ struct bwn_phy *phy = &mac->mac_phy;
+ uint8_t bands[IEEE80211_MODE_BYTES], limited_2g, limited_5g;
+ limited_2g = phy->rf_ver == 0x2057 &&
+ (phy->rf_rev == 9 || phy->rf_rev == 14);
+
+ limited_5g = phy->rf_ver == 0x2057 && phy->rf_rev == 9;
+
memset(ic->ic_channels, 0, sizeof(ic->ic_channels));
ic->ic_nchans = 0;
@@ -1687,14 +1730,18 @@
setbit(bands, IEEE80211_MODE_11B);
setbit(bands, IEEE80211_MODE_11G);
bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
- &ic->ic_nchans, &bwn_chantable_bg, bands);
+ &ic->ic_nchans,
+ limited_2g ? &bwn_chantable_bg_lim : &bwn_chantable_bg,
+ bands);
}
if (have_a) {
memset(bands, 0, sizeof(bands));
setbit(bands, IEEE80211_MODE_11A);
bwn_addchannels(ic->ic_channels, IEEE80211_CHAN_MAX,
- &ic->ic_nchans, &bwn_chantable_a, bands);
+ &ic->ic_nchans,
+ limited_5g ? &bwn_chantable_a_lim : &bwn_chantable_a,
+ bands);
}
mac->mac_phy.supports_2ghz = have_bg;
@@ -1971,7 +2018,8 @@
if (error)
goto fail;
bwn_mac_suspend(mac);
- bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG);
+ bwn_set_txretry(mac, (bwn_hacks & 0x200) ? bwn_hacks & 0xF : BWN_RETRY_SHORT,
+ (bwn_hacks & 0x200) ? (bwn_hacks & 0xF0) >> 4 : BWN_RETRY_LONG);
chan = ieee80211_chan2ieee(ic, ic->ic_curchan);
if (chan != phy->chan)
bwn_switch_channel(mac, chan);
@@ -2287,12 +2335,11 @@
bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_MACHW_H,
(cap >> 16) & 0xffff);
}
-
- bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG);
+ bwn_set_txretry(mac, (bwn_hacks & 0x200) ? bwn_hacks & 0xF : BWN_RETRY_SHORT,
+ (bwn_hacks & 0x200) ? (bwn_hacks & 0xF0) >> 4 : BWN_RETRY_LONG);
bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_SHORT_RETRY_FALLBACK, 3);
bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_LONG_RETRY_FALLBACK, 2);
bwn_shm_write_2(mac, BWN_SHARED, BWN_SHARED_PROBE_RESP_MAXTIME, 1);
-
bwn_rate_init(mac);
bwn_set_phytxctl(mac);
@@ -2414,7 +2461,15 @@
error = bwn_fw_loaducode(mac);
if (error)
return (error);
-
+/*
+ mac->asi = bwn_c_antsel_attach(mac);
+ if (!mac->asi) {
+ device_printf(sc->sc_dev, "Cant figure out antenna\n");
+ return (ENXIO);
+ } else {
+ device_printf(sc->sc_dev, "Antenna attached\n");
+ }
+*/
error = bwn_gpio_init(mac);
if (error)
return (error);
@@ -2481,6 +2536,8 @@
}
BWN_WRITE_2(mac, BWN_POWERUP_DELAY, delay);
+
+
return (0);
}
@@ -2991,6 +3048,7 @@
return (dr);
fail2:
+ device_printf(sc->sc_dev,"F2 DMA RING SETUP CI=%d TX=%d\n",controller_index,for_tx);
if (dr->dr_txhdr_cache != NULL) {
contigfree(dr->dr_txhdr_cache,
(dr->dr_numslots / BWN_TX_SLOTS_PER_FRAME) *
@@ -3009,7 +3067,6 @@
if (dr == NULL)
return;
-
bwn_dma_free_descbufs(*dr);
bwn_dma_free_ringmemory(*dr);
@@ -3230,11 +3287,12 @@
int error;
error = bus_dma_tag_create(dma->parent_dtag,
- BWN_ALIGN, 0,
+ mac->mac_dmatype == BHND_DMA_ADDR_64BIT ? 2 * BWN_ALIGN : BWN_ALIGN,
+ 0,
BUS_SPACE_MAXADDR,
BUS_SPACE_MAXADDR,
NULL, NULL,
- BWN_DMA_RINGMEMSIZE,
+ mac->mac_dmatype == BHND_DMA_ADDR_64BIT ? 2 * BWN_DMA_RINGMEMSIZE : BWN_DMA_RINGMEMSIZE,
1,
BUS_SPACE_MAXSIZE_32BIT,
0,
@@ -3255,7 +3313,8 @@
return (-1);
}
error = bus_dmamap_load(dr->dr_ring_dtag, dr->dr_ring_dmap,
- dr->dr_ring_descbase, BWN_DMA_RINGMEMSIZE,
+ dr->dr_ring_descbase,
+ mac->mac_dmatype == BHND_DMA_ADDR_64BIT ? 2 * BWN_DMA_RINGMEMSIZE : BWN_DMA_RINGMEMSIZE,
bwn_dma_ring_addr, &dr->dr_ring_dmabase, BUS_DMA_NOWAIT);
if (error) {
device_printf(sc->sc_dev,
@@ -3287,7 +3346,7 @@
if (dr->dr_tx) {
dr->dr_curslot = -1;
-
+ dr->dr_usedslot = 0;
if (dr->dr_type == BHND_DMA_ADDR_64BIT) {
value = BWN_DMA64_TXENABLE;
value |= BWN_DMA64_TXPARITY_DISABLE;
@@ -3640,7 +3699,6 @@
bwn_fw_fillinfo(struct bwn_mac *mac)
{
int error;
-
error = bwn_fw_gets(mac, BWN_FWTYPE_DEFAULT);
if (error == 0)
return (0);
@@ -4040,7 +4098,7 @@
{
struct bwn_softc *sc = mac->mac_sc;
struct bwn_fw *fw = &mac->mac_fw;
- const uint8_t rev = bhnd_get_hwrev(sc->sc_dev);
+ uint8_t rev = bhnd_get_hwrev(sc->sc_dev);
const char *filename;
uint16_t iost;
int error;
@@ -5082,7 +5140,6 @@
struct bwn_softc *sc = mac->mac_sc;
uint32_t merged = 0;
int i, tx = 0, rx = 0;
-
BWN_LOCK(sc);
if (mac->mac_status < BWN_MAC_STATUS_STARTED ||
(sc->sc_flags & BWN_FLAG_INVALID)) {
@@ -6148,8 +6205,7 @@
struct bwn_dmadesc_generic *desc;
struct bwn_dmadesc_meta *meta;
struct bwn_softc *sc = mac->mac_sc;
- int slot;
-
+ int slot,firstused;
BWN_ASSERT_LOCKED(sc);
dr = bwn_dma_parse_cookie(mac, status, status->cookie, &slot);
@@ -6157,8 +6213,21 @@
device_printf(sc->sc_dev, "failed to parse cookie\n");
return;
}
+ if (dr->dr_usedslot <= 0) {
+ device_printf(sc->sc_dev, "handle txeof fXXX no slots used\n");
+ goto _dexit;
+ }
KASSERT(dr->dr_tx, ("%s:%d: fail", __func__, __LINE__));
+ firstused = dr->dr_curslot - dr->dr_usedslot + 1;
+ if (firstused < 0)
+ firstused = dr->dr_numslots + firstused;
+ if(firstused != slot) {
+ device_printf(sc->sc_dev,"DMA %s S=%d ring=%d cur=%d used=%d TX=1 F=%d\n",
+ firstused != slot ? "XXX" : " ",
+ slot,dr->dr_index,dr->dr_curslot,dr->dr_usedslot,firstused);
+ }
+
while (1) {
KASSERT(slot >= 0 && slot < dr->dr_numslots,
("%s:%d: fail", __func__, __LINE__));
@@ -6172,7 +6241,12 @@
if (meta->mt_islast) {
KASSERT(meta->mt_m != NULL,
("%s:%d: fail", __func__, __LINE__));
-
+ if(!meta->mt_ni) {
+ device_printf(sc->sc_dev,"TX status unexpected NULL meta->mt_ni "
+ "at slot %d (first=%d) on ring %d\n",
+ slot, firstused, dr->dr_index);
+ break;
+ }
bwn_ratectl_tx_complete(meta->mt_ni, status);
ieee80211_tx_complete(meta->mt_ni, meta->mt_m, 0);
meta->mt_ni = NULL;
@@ -6186,6 +6260,7 @@
break;
slot = bwn_dma_nextslot(dr, slot);
}
+_dexit:
sc->sc_watchdog_timer = 0;
if (dr->dr_stop) {
KASSERT(bwn_dma_freeslot(dr) >= BWN_TX_SLOTS_PER_FRAME,