#include "debugfs.h"
#include "phy.h"
#include "dma.h"
-#include "pio.h"
#include "sysfs.h"
#include "xmit.h"
#include "lo.h"
MODULE_AUTHOR("Michael Buesch");
MODULE_LICENSE("GPL");
-extern char *nvram_get(char *name);
-
-#if defined(CONFIG_B43_DMA) && defined(CONFIG_B43_PIO)
-static int modparam_pio;
-module_param_named(pio, modparam_pio, int, 0444);
-MODULE_PARM_DESC(pio, "enable(1) / disable(0) PIO mode");
-#elif defined(CONFIG_B43_DMA)
-# define modparam_pio 0
-#elif defined(CONFIG_B43_PIO)
-# define modparam_pio 1
-#endif
static int modparam_bad_frames_preempt;
module_param_named(bad_frames_preempt, modparam_bad_frames_preempt, int, 0444);
SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 7),
SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 9),
SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 10),
+ SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 11),
SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 13),
SSB_DEVTABLE_END
};
.power_level = 0xFF, \
.antenna_max = 0xFF, \
}
-static struct ieee80211_channel b43_bg_chantable[] = {
+static struct ieee80211_channel b43_2ghz_chantable[] = {
CHANTAB_ENT(1, 2412),
CHANTAB_ENT(2, 2417),
CHANTAB_ENT(3, 2422),
CHANTAB_ENT(13, 2472),
CHANTAB_ENT(14, 2484),
};
+#define b43_2ghz_chantable_size ARRAY_SIZE(b43_2ghz_chantable)
-#define b43_bg_chantable_size ARRAY_SIZE(b43_bg_chantable)
-static struct ieee80211_channel b43_a_chantable[] = {
+#if 0
+static struct ieee80211_channel b43_5ghz_chantable[] = {
CHANTAB_ENT(36, 5180),
CHANTAB_ENT(40, 5200),
CHANTAB_ENT(44, 5220),
CHANTAB_ENT(161, 5805),
CHANTAB_ENT(165, 5825),
};
-
-#define b43_a_chantable_size ARRAY_SIZE(b43_a_chantable)
+#define b43_5ghz_chantable_size ARRAY_SIZE(b43_5ghz_chantable)
+#endif
static void b43_wireless_core_exit(struct b43_wldev *dev);
static int b43_wireless_core_init(struct b43_wldev *dev);
static void b43_generate_noise_sample(struct b43_wldev *dev)
{
b43_jssi_write(dev, 0x7F7F7F7F);
- b43_write32(dev, B43_MMIO_STATUS2_BITFIELD,
- b43_read32(dev, B43_MMIO_STATUS2_BITFIELD)
- | (1 << 4));
+ b43_write32(dev, B43_MMIO_MACCMD,
+ b43_read32(dev, B43_MMIO_MACCMD) | B43_MACCMD_BGNOISE);
B43_WARN_ON(dev->noisecalc.channel_at_start != dev->phy.channel);
}
if (1 /*FIXME: the last PSpoll frame was sent successfully */ )
b43_power_saving_ctl_bits(dev, 0);
}
- dev->reg124_set_0x4 = 0;
if (b43_is_mode(dev->wl, IEEE80211_IF_TYPE_IBSS))
- dev->reg124_set_0x4 = 1;
+ dev->dfq_valid = 1;
}
static void handle_irq_atim_end(struct b43_wldev *dev)
{
- if (!dev->reg124_set_0x4 /*FIXME rename this variable */ )
- return;
- b43_write32(dev, B43_MMIO_STATUS2_BITFIELD,
- b43_read32(dev, B43_MMIO_STATUS2_BITFIELD)
- | 0x4);
+ if (dev->dfq_valid) {
+ b43_write32(dev, B43_MMIO_MACCMD,
+ b43_read32(dev, B43_MMIO_MACCMD)
+ | B43_MACCMD_DFQ_VALID);
+ dev->dfq_valid = 0;
+ }
}
static void handle_irq_pmq(struct b43_wldev *dev)
static void b43_update_templates(struct b43_wldev *dev)
{
- u32 status;
+ u32 cmd;
B43_WARN_ON(!dev->cached_beacon);
b43_write_beacon_template(dev, 0x468, 0x1A, B43_CCK_RATE_1MB);
b43_write_probe_resp_template(dev, 0x268, 0x4A, B43_CCK_RATE_11MB);
- status = b43_read32(dev, B43_MMIO_STATUS2_BITFIELD);
- status |= 0x03;
- b43_write32(dev, B43_MMIO_STATUS2_BITFIELD, status);
+ cmd = b43_read32(dev, B43_MMIO_MACCMD);
+ cmd |= B43_MACCMD_BEACON0_VALID | B43_MACCMD_BEACON1_VALID;
+ b43_write32(dev, B43_MMIO_MACCMD, cmd);
}
static void b43_refresh_templates(struct b43_wldev *dev, struct sk_buff *beacon)
return;
dev->irq_savedstate &= ~B43_IRQ_BEACON;
- status = b43_read32(dev, B43_MMIO_STATUS2_BITFIELD);
+ status = b43_read32(dev, B43_MMIO_MACCMD);
if (!dev->cached_beacon || ((status & 0x1) && (status & 0x2))) {
/* ACK beacon IRQ. */
if (!(status & 0x1)) {
b43_write_beacon_template(dev, 0x68, 0x18, B43_CCK_RATE_1MB);
status |= 0x1;
- b43_write32(dev, B43_MMIO_STATUS2_BITFIELD, status);
+ b43_write32(dev, B43_MMIO_MACCMD, status);
}
if (!(status & 0x2)) {
b43_write_beacon_template(dev, 0x468, 0x1A, B43_CCK_RATE_1MB);
status |= 0x2;
- b43_write32(dev, B43_MMIO_STATUS2_BITFIELD, status);
+ b43_write32(dev, B43_MMIO_MACCMD, status);
}
}
handle_irq_noise(dev);
/* Check the DMA reason registers for received data. */
- if (dma_reason[0] & B43_DMAIRQ_RX_DONE) {
- if (b43_using_pio(dev))
- b43_pio_rx(dev->pio.queue0);
- else
- b43_dma_rx(dev->dma.rx_ring0);
- }
+ if (dma_reason[0] & B43_DMAIRQ_RX_DONE)
+ b43_dma_rx(dev->dma.rx_ring0);
+ if (dma_reason[3] & B43_DMAIRQ_RX_DONE)
+ b43_dma_rx(dev->dma.rx_ring3);
B43_WARN_ON(dma_reason[1] & B43_DMAIRQ_RX_DONE);
B43_WARN_ON(dma_reason[2] & B43_DMAIRQ_RX_DONE);
- if (dma_reason[3] & B43_DMAIRQ_RX_DONE) {
- if (b43_using_pio(dev))
- b43_pio_rx(dev->pio.queue3);
- else
- b43_dma_rx(dev->dma.rx_ring3);
- }
B43_WARN_ON(dma_reason[4] & B43_DMAIRQ_RX_DONE);
B43_WARN_ON(dma_reason[5] & B43_DMAIRQ_RX_DONE);
spin_unlock_irqrestore(&dev->wl->irq_lock, flags);
}
-static void pio_irq_workaround(struct b43_wldev *dev, u16 base, int queueidx)
-{
- u16 rxctl;
-
- rxctl = b43_read16(dev, base + B43_PIO_RXCTL);
- if (rxctl & B43_PIO_RXCTL_DATAAVAILABLE)
- dev->dma_reason[queueidx] |= B43_DMAIRQ_RX_DONE;
- else
- dev->dma_reason[queueidx] &= ~B43_DMAIRQ_RX_DONE;
-}
-
static void b43_interrupt_ack(struct b43_wldev *dev, u32 reason)
{
- if (b43_using_pio(dev) &&
- (dev->dev->id.revision < 3) &&
- (!(reason & B43_IRQ_PIO_WORKAROUND))) {
- /* Apply a PIO specific workaround to the dma_reasons */
- pio_irq_workaround(dev, B43_MMIO_PIO1_BASE, 0);
- pio_irq_workaround(dev, B43_MMIO_PIO2_BASE, 1);
- pio_irq_workaround(dev, B43_MMIO_PIO3_BASE, 2);
- pio_irq_workaround(dev, B43_MMIO_PIO4_BASE, 3);
- }
-
b43_write32(dev, B43_MMIO_GEN_IRQ_REASON, reason);
b43_write32(dev, B43_MMIO_DMA0_REASON, dev->dma_reason[0]);
switch (dev->phy.type) {
case B43_PHYTYPE_A:
if ((rev >= 5) && (rev <= 10)) {
- if (tmshigh & B43_TMSHIGH_GPHY)
+ if (tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY)
filename = "a0g1initvals5";
else
filename = "a0g0initvals5";
switch (dev->phy.type) {
case B43_PHYTYPE_A:
if ((rev >= 5) && (rev <= 10)) {
- if (tmshigh & B43_TMSHIGH_GPHY)
+ if (tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY)
filename = "a0g1bsinitvals5";
else
filename = "a0g0bsinitvals5";
b43_write32(dev, B43_MMIO_MACCTL, b43_read32(dev, B43_MMIO_MACCTL)
| B43_MACCTL_INFRA);
- if (b43_using_pio(dev)) {
- b43_write32(dev, 0x0210, 0x00000100);
- b43_write32(dev, 0x0230, 0x00000100);
- b43_write32(dev, 0x0250, 0x00000100);
- b43_write32(dev, 0x0270, 0x00000100);
- b43_shm_write16(dev, B43_SHM_SHARED, 0x0034, 0x0000);
- }
-
/* Probe Response Timeout value */
/* FIXME: Default to 0, has to be set by ioctl probably... :-/ */
b43_shm_write16(dev, B43_SHM_SHARED, 0x0074, 0x0000);
struct b43_wl *wl = hw_to_b43_wl(hw);
struct b43_wldev *dev = wl->current_dev;
int err = -ENODEV;
- unsigned long flags;
if (unlikely(!dev))
goto out;
if (unlikely(b43_status(dev) < B43_STAT_STARTED))
goto out;
/* DMA-TX is done without a global lock. */
- if (b43_using_pio(dev)) {
- spin_lock_irqsave(&wl->irq_lock, flags);
- err = b43_pio_tx(dev, skb, ctl);
- spin_unlock_irqrestore(&wl->irq_lock, flags);
- } else
- err = b43_dma_tx(dev, skb, ctl);
+ err = b43_dma_tx(dev, skb, ctl);
out:
if (unlikely(err))
return NETDEV_TX_BUSY;
goto out;
spin_lock_irqsave(&wl->irq_lock, flags);
if (likely(b43_status(dev) >= B43_STAT_STARTED)) {
- if (b43_using_pio(dev))
- b43_pio_get_tx_stats(dev, stats);
- else
- b43_dma_get_tx_stats(dev, stats);
+ b43_dma_get_tx_stats(dev, stats);
err = 0;
}
spin_unlock_irqrestore(&wl->irq_lock, flags);
if (phy_rev > 9)
unsupported = 1;
break;
+#ifdef CONFIG_B43_NPHY
+ case B43_PHYTYPE_N:
+ if (phy_rev > 1)
+ unsupported = 1;
+ break;
+#endif
default:
unsupported = 1;
};
radio_manuf = (tmp & 0x00000FFF);
radio_ver = (tmp & 0x0FFFF000) >> 12;
radio_rev = (tmp & 0xF0000000) >> 28;
+ if (radio_manuf != 0x17F /* Broadcom */)
+ unsupported = 1;
switch (phy_type) {
case B43_PHYTYPE_A:
if (radio_ver != 0x2060)
if (radio_ver != 0x2050)
unsupported = 1;
break;
+ case B43_PHYTYPE_N:
+ if (radio_ver != 5)
+ unsupported = 1;
+ break;
default:
B43_WARN_ON(1);
}
memset(phy->minlowsig, 0xFF, sizeof(phy->minlowsig));
memset(phy->minlowsigpos, 0, sizeof(phy->minlowsigpos));
- /* Flags */
- phy->locked = 0;
-
phy->aci_enable = 0;
phy->aci_wlan_automatic = 0;
phy->aci_hw_rssi = 0;
phy->lofcal = 0xFFFF;
phy->initval = 0xFFFF;
- spin_lock_init(&phy->lock);
phy->interfmode = B43_INTERFMODE_NONE;
phy->channel = 0xFF;
static void setup_struct_wldev_for_init(struct b43_wldev *dev)
{
- /* Flags */
- dev->reg124_set_0x4 = 0;
+ dev->dfq_valid = 0;
+
/* Assume the radio is enabled. If it's not enabled, the state will
* immediately get fixed on the first periodic work run. */
dev->radio_hw_enable = 1;
b43_leds_exit(dev);
b43_rng_exit(dev->wl);
- b43_pio_free(dev);
b43_dma_free(dev);
b43_chip_exit(dev);
b43_radio_turn_off(dev, 1);
/* Maximum Contention Window */
b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_MAXCONT, 0x3FF);
- do {
- if (b43_using_pio(dev)) {
- err = b43_pio_init(dev);
- } else {
- err = b43_dma_init(dev);
- if (!err)
- b43_qos_init(dev);
- }
- } while (err == -EAGAIN);
+ err = b43_dma_init(dev);
if (err)
goto err_chip_exit;
+ b43_qos_init(dev);
//FIXME
#if 1
}
static int b43_setup_modes(struct b43_wldev *dev,
- int have_aphy, int have_bphy, int have_gphy)
+ bool have_2ghz_phy, bool have_5ghz_phy)
{
struct ieee80211_hw *hw = dev->wl->hw;
struct ieee80211_hw_mode *mode;
struct b43_phy *phy = &dev->phy;
- int cnt = 0;
int err;
-/*FIXME: Don't tell ieee80211 about an A-PHY, because we currently don't support A-PHY. */
- have_aphy = 0;
-
- phy->possible_phymodes = 0;
- for (; 1; cnt++) {
- if (have_aphy) {
- B43_WARN_ON(cnt >= B43_MAX_PHYHWMODES);
- mode = &phy->hwmodes[cnt];
-
- mode->mode = MODE_IEEE80211A;
- mode->num_channels = b43_a_chantable_size;
- mode->channels = b43_a_chantable;
- mode->num_rates = b43_a_ratetable_size;
- mode->rates = b43_a_ratetable;
- err = ieee80211_register_hwmode(hw, mode);
- if (err)
- return err;
-
- phy->possible_phymodes |= B43_PHYMODE_A;
- have_aphy = 0;
- continue;
- }
- if (have_bphy) {
- B43_WARN_ON(cnt >= B43_MAX_PHYHWMODES);
- mode = &phy->hwmodes[cnt];
-
- mode->mode = MODE_IEEE80211B;
- mode->num_channels = b43_bg_chantable_size;
- mode->channels = b43_bg_chantable;
- mode->num_rates = b43_b_ratetable_size;
- mode->rates = b43_b_ratetable;
- err = ieee80211_register_hwmode(hw, mode);
- if (err)
- return err;
-
- phy->possible_phymodes |= B43_PHYMODE_B;
- have_bphy = 0;
- continue;
- }
- if (have_gphy) {
- B43_WARN_ON(cnt >= B43_MAX_PHYHWMODES);
- mode = &phy->hwmodes[cnt];
-
- mode->mode = MODE_IEEE80211G;
- mode->num_channels = b43_bg_chantable_size;
- mode->channels = b43_bg_chantable;
- mode->num_rates = b43_g_ratetable_size;
- mode->rates = b43_g_ratetable;
- err = ieee80211_register_hwmode(hw, mode);
- if (err)
- return err;
-
- phy->possible_phymodes |= B43_PHYMODE_G;
- have_gphy = 0;
- continue;
- }
- break;
- }
+ /* XXX: This function will go away soon, when mac80211
+ * band stuff is rewritten. So this is just a hack.
+ * For now we always claim GPHY mode, as there is no
+ * support for NPHY and APHY in the device, yet.
+ * This assumption is OK, as any B, N or A PHY will already
+ * have died a horrible sanity check death earlier. */
+
+ mode = &phy->hwmodes[0];
+ mode->mode = MODE_IEEE80211G;
+ mode->num_channels = b43_2ghz_chantable_size;
+ mode->channels = b43_2ghz_chantable;
+ mode->num_rates = b43_g_ratetable_size;
+ mode->rates = b43_g_ratetable;
+ err = ieee80211_register_hwmode(hw, mode);
+ if (err)
+ return err;
+ phy->possible_phymodes |= B43_PHYMODE_G;
return 0;
}
struct ssb_bus *bus = dev->dev->bus;
struct pci_dev *pdev = bus->host_pci;
int err;
- int have_aphy = 0, have_bphy = 0, have_gphy = 0;
+ bool have_2ghz_phy = 0, have_5ghz_phy = 0;
u32 tmp;
/* Do NOT do any device initialization here.
u32 tmshigh;
tmshigh = ssb_read32(dev->dev, SSB_TMSHIGH);
- have_aphy = !!(tmshigh & B43_TMSHIGH_APHY);
- have_gphy = !!(tmshigh & B43_TMSHIGH_GPHY);
- if (!have_aphy && !have_gphy)
- have_bphy = 1;
- } else if (dev->dev->id.revision == 4) {
- have_gphy = 1;
- have_aphy = 1;
+ have_2ghz_phy = !!(tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY);
+ have_5ghz_phy = !!(tmshigh & B43_TMSHIGH_HAVE_5GHZ_PHY);
} else
- have_bphy = 1;
+ B43_WARN_ON(1);
- dev->phy.gmode = (have_gphy || have_bphy);
+ dev->phy.gmode = have_2ghz_phy;
tmp = dev->phy.gmode ? B43_TMSLOW_GMODE : 0;
b43_wireless_core_reset(dev, tmp);
(pdev->device != 0x4312 &&
pdev->device != 0x4319 && pdev->device != 0x4324)) {
/* No multiband support. */
- have_aphy = 0;
- have_bphy = 0;
- have_gphy = 0;
+ have_2ghz_phy = 0;
+ have_5ghz_phy = 0;
switch (dev->phy.type) {
case B43_PHYTYPE_A:
- have_aphy = 1;
- break;
- case B43_PHYTYPE_B:
- have_bphy = 1;
+ have_5ghz_phy = 1;
break;
case B43_PHYTYPE_G:
- have_gphy = 1;
+ case B43_PHYTYPE_N:
+ have_2ghz_phy = 1;
break;
default:
B43_WARN_ON(1);
}
}
- dev->phy.gmode = (have_gphy || have_bphy);
+ if (dev->phy.type == B43_PHYTYPE_A) {
+ /* FIXME */
+ b43err(wl, "IEEE 802.11a devices are unsupported\n");
+ err = -EOPNOTSUPP;
+ goto err_powerdown;
+ }
+ dev->phy.gmode = have_2ghz_phy;
tmp = dev->phy.gmode ? B43_TMSLOW_GMODE : 0;
b43_wireless_core_reset(dev, tmp);
err = b43_validate_chipaccess(dev);
if (err)
goto err_powerdown;
- err = b43_setup_modes(dev, have_aphy, have_bphy, have_gphy);
+ err = b43_setup_modes(dev, have_2ghz_phy, have_5ghz_phy);
if (err)
goto err_powerdown;
tasklet_init(&wldev->isr_tasklet,
(void (*)(unsigned long))b43_interrupt_tasklet,
(unsigned long)wldev);
- if (modparam_pio)
- wldev->__using_pio = 1;
INIT_LIST_HEAD(&wldev->list);
err = b43_wireless_core_attach(wldev);