#include <linux/wireless.h>
#include <linux/workqueue.h>
#include <linux/skbuff.h>
+#include <linux/dma-mapping.h>
#include <net/iw_handler.h>
#include "bcm43xx.h"
#include "bcm43xx_wx.h"
#include "bcm43xx_ethtool.h"
#include "bcm43xx_xmit.h"
+#include "bcm43xx_sysfs.h"
MODULE_DESCRIPTION("Broadcom BCM43xx wireless driver");
static struct pci_device_id bcm43xx_pci_tbl[] = {
/* Broadcom 4303 802.11b */
{ PCI_VENDOR_ID_BROADCOM, 0x4301, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- /* Broadcom 4307 802.11b */
+ /* Broadcom 4307 802.11b */
{ PCI_VENDOR_ID_BROADCOM, 0x4307, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- /* Broadcom 4318 802.11b/g */
+ /* Broadcom 4318 802.11b/g */
{ PCI_VENDOR_ID_BROADCOM, 0x4318, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+ /* Broadcom 4319 802.11a/b/g */
+ { PCI_VENDOR_ID_BROADCOM, 0x4319, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
/* Broadcom 4306 802.11b/g */
{ PCI_VENDOR_ID_BROADCOM, 0x4320, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- /* Broadcom 4306 802.11a */
+ /* Broadcom 4306 802.11a */
// { PCI_VENDOR_ID_BROADCOM, 0x4321, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
/* Broadcom 4309 802.11a/b/g */
{ PCI_VENDOR_ID_BROADCOM, 0x4324, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
bcm43xx_ram_write(bcm, 0x478 + i, *((u32 *)(mac_bssid + i)));
}
+//FIXME: Well, we should probably call them from somewhere.
+#if 0
static void bcm43xx_set_slot_time(struct bcm43xx_private *bcm, u16 slot_time)
{
/* slot_time is in usec. */
{
bcm43xx_set_slot_time(bcm, 20);
}
+#endif
-//FIXME: rename this func?
+/* FIXME: To get the MAC-filter working, we need to implement the
+ * following functions (and rename them :)
+ */
+#if 0
static void bcm43xx_disassociate(struct bcm43xx_private *bcm)
{
bcm43xx_mac_suspend(bcm);
bcm43xx_mac_enable(bcm);
}
-//FIXME: rename this func?
static void bcm43xx_associate(struct bcm43xx_private *bcm,
const u8 *mac)
{
bcm43xx_write_mac_bssid_templates(bcm);
bcm43xx_mac_enable(bcm);
}
+#endif
/* Enable a Generic IRQ. "mask" is the mask of which IRQs to enable.
* Returns the _previously_ enabled IRQ mask.
radio->revision = revision;
/* Set default attenuation values. */
- radio->txpower[0] = 2;
- radio->txpower[1] = 2;
- if (revision == 1)
- radio->txpower[2] = 3;
- else
- radio->txpower[2] = 0;
+ radio->baseband_atten = bcm43xx_default_baseband_attenuation(bcm);
+ radio->radio_atten = bcm43xx_default_radio_attenuation(bcm);
+ radio->txctl1 = bcm43xx_default_txctl1(bcm);
+ radio->txctl2 = 0xFFFF;
if (phy->type == BCM43xx_PHYTYPE_A)
radio->txpower_desired = bcm->sprom.maxpower_aphy;
else
return 0;
}
-static void bcm43xx_geo_init(struct bcm43xx_private *bcm)
+static int bcm43xx_geo_init(struct bcm43xx_private *bcm)
{
- struct ieee80211_geo geo;
+ struct ieee80211_geo *geo;
struct ieee80211_channel *chan;
int have_a = 0, have_bg = 0;
int i;
struct bcm43xx_phyinfo *phy;
const char *iso_country;
- memset(&geo, 0, sizeof(geo));
+ geo = kzalloc(sizeof(*geo), GFP_KERNEL);
+ if (!geo)
+ return -ENOMEM;
+
for (i = 0; i < bcm->nr_80211_available; i++) {
phy = &(bcm->core_80211_ext[i].phy);
switch (phy->type) {
iso_country = bcm43xx_locale_iso(bcm->sprom.locale);
if (have_a) {
- for (i = 0, channel = 0; channel < 201; channel++) {
- chan = &geo.a[i++];
+ for (i = 0, channel = IEEE80211_52GHZ_MIN_CHANNEL;
+ channel <= IEEE80211_52GHZ_MAX_CHANNEL; channel++) {
+ chan = &geo->a[i++];
chan->freq = bcm43xx_channel_to_freq_a(channel);
chan->channel = channel;
}
- geo.a_channels = i;
+ geo->a_channels = i;
}
if (have_bg) {
- for (i = 0, channel = 1; channel < 15; channel++) {
- chan = &geo.bg[i++];
+ for (i = 0, channel = IEEE80211_24GHZ_MIN_CHANNEL;
+ channel <= IEEE80211_24GHZ_MAX_CHANNEL; channel++) {
+ chan = &geo->bg[i++];
chan->freq = bcm43xx_channel_to_freq_bg(channel);
chan->channel = channel;
}
- geo.bg_channels = i;
+ geo->bg_channels = i;
}
- memcpy(geo.name, iso_country, 2);
+ memcpy(geo->name, iso_country, 2);
if (0 /*TODO: Outdoor use only */)
- geo.name[2] = 'O';
+ geo->name[2] = 'O';
else if (0 /*TODO: Indoor use only */)
- geo.name[2] = 'I';
+ geo->name[2] = 'I';
else
- geo.name[2] = ' ';
- geo.name[3] = '\0';
+ geo->name[2] = ' ';
+ geo->name[3] = '\0';
+
+ ieee80211_set_geo(bcm->ieee, geo);
+ kfree(geo);
- ieee80211_set_geo(bcm->ieee, &geo);
+ return 0;
}
/* DummyTransmission function, as documented on
average *= 125;
average += 64;
average /= 128;
+
tmp = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, 0x40C);
tmp = (tmp / 128) & 0x1F;
if (tmp >= 8)
else
average -= 48;
+/* FIXME: This is wrong, but people want fancy stats. well... */
+bcm->stats.noise = average;
if (average > -65)
bcm->stats.link_quality = 0;
else if (average > -75)
bcmirq_handled(BCM43xx_IRQ_XMIT_STATUS);
}
- /* We get spurious IRQs, althought they are masked.
- * Assume they are void and ignore them.
- */
- bcmirq_handled(~(bcm->irq_savedstate));
/* IRQ_PIO_WORKAROUND is handled in the top-half. */
bcmirq_handled(BCM43xx_IRQ_PIO_WORKAROUND);
#ifdef CONFIG_BCM43XX_DEBUG
bcm43xx_unlock_mmio(bcm, flags);
}
-static void bcm43xx_interrupt_ack(struct bcm43xx_private *bcm,
- u32 reason, u32 mask)
+static void pio_irq_workaround(struct bcm43xx_private *bcm,
+ u16 base, int queueidx)
{
- bcm->dma_reason[0] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA1_REASON)
- & 0x0001dc00;
- bcm->dma_reason[1] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA2_REASON)
- & 0x0000dc00;
- bcm->dma_reason[2] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA3_REASON)
- & 0x0000dc00;
- bcm->dma_reason[3] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA4_REASON)
- & 0x0001dc00;
+ u16 rxctl;
+
+ rxctl = bcm43xx_read16(bcm, base + BCM43xx_PIO_RXCTL);
+ if (rxctl & BCM43xx_PIO_RXCTL_DATAAVAILABLE)
+ bcm->dma_reason[queueidx] |= BCM43xx_DMAIRQ_RX_DONE;
+ else
+ bcm->dma_reason[queueidx] &= ~BCM43xx_DMAIRQ_RX_DONE;
+}
+static void bcm43xx_interrupt_ack(struct bcm43xx_private *bcm, u32 reason)
+{
if (bcm43xx_using_pio(bcm) &&
(bcm->current_core->rev < 3) &&
(!(reason & BCM43xx_IRQ_PIO_WORKAROUND))) {
/* Apply a PIO specific workaround to the dma_reasons */
-
-#define apply_pio_workaround(BASE, QNUM) \
- do { \
- if (bcm43xx_read16(bcm, BASE + BCM43xx_PIO_RXCTL) & BCM43xx_PIO_RXCTL_DATAAVAILABLE) \
- bcm->dma_reason[QNUM] |= 0x00010000; \
- else \
- bcm->dma_reason[QNUM] &= ~0x00010000; \
- } while (0)
-
- apply_pio_workaround(BCM43xx_MMIO_PIO1_BASE, 0);
- apply_pio_workaround(BCM43xx_MMIO_PIO2_BASE, 1);
- apply_pio_workaround(BCM43xx_MMIO_PIO3_BASE, 2);
- apply_pio_workaround(BCM43xx_MMIO_PIO4_BASE, 3);
-
-#undef apply_pio_workaround
+ pio_irq_workaround(bcm, BCM43xx_MMIO_PIO1_BASE, 0);
+ pio_irq_workaround(bcm, BCM43xx_MMIO_PIO2_BASE, 1);
+ pio_irq_workaround(bcm, BCM43xx_MMIO_PIO3_BASE, 2);
+ pio_irq_workaround(bcm, BCM43xx_MMIO_PIO4_BASE, 3);
}
- bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON,
- reason & mask);
+ bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, reason);
bcm43xx_write32(bcm, BCM43xx_MMIO_DMA1_REASON,
bcm->dma_reason[0]);
{
irqreturn_t ret = IRQ_HANDLED;
struct bcm43xx_private *bcm = dev_id;
- u32 reason, mask;
+ u32 reason;
if (!bcm)
return IRQ_NONE;
ret = IRQ_NONE;
goto out;
}
- mask = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_MASK);
- if (!(reason & mask))
+ reason &= bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_MASK);
+ if (!reason)
goto out;
- bcm43xx_interrupt_ack(bcm, reason, mask);
+ bcm->dma_reason[0] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA1_REASON)
+ & 0x0001dc00;
+ bcm->dma_reason[1] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA2_REASON)
+ & 0x0000dc00;
+ bcm->dma_reason[2] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA3_REASON)
+ & 0x0000dc00;
+ bcm->dma_reason[3] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA4_REASON)
+ & 0x0001dc00;
+
+ bcm43xx_interrupt_ack(bcm, reason);
/* Only accept IRQs, if we are initialized properly.
* This avoids an RX race while initializing.
if (unlikely(err == -ENODEV)) {
printk(KERN_ERR PFX "gpio error: "
"Neither ChipCommon nor PCI core available!\n");
- return -ENODEV;
- } else if (unlikely(err != 0))
- return -ENODEV;
- } else if (unlikely(err != 0))
- return -ENODEV;
+ }
+ }
- return 0;
+ return err;
}
/* Initialize the GPIOs
{
struct bcm43xx_coreinfo *old_core;
int err;
- u32 mask, value;
+ u32 mask, set;
- value = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
- value &= ~0xc000;
- bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, value);
+ bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD,
+ bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD)
+ & 0xFFFF3FFF);
- mask = 0x0000001F;
- value = 0x0000000F;
- bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_CONTROL,
- bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL) & 0xFFF0);
+ bcm43xx_leds_switch_all(bcm, 0);
bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_MASK,
bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_MASK) | 0x000F);
- old_core = bcm->current_core;
-
- err = switch_to_gpio_core(bcm);
- if (err)
- return err;
-
- if (bcm->current_core->rev >= 2){
- mask |= 0x10;
- value |= 0x10;
- }
+ mask = 0x0000001F;
+ set = 0x0000000F;
if (bcm->chip_id == 0x4301) {
- mask |= 0x60;
- value |= 0x60;
+ mask |= 0x0060;
+ set |= 0x0060;
+ }
+ if (0 /* FIXME: conditional unknown */) {
+ bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_MASK,
+ bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_MASK)
+ | 0x0100);
+ mask |= 0x0180;
+ set |= 0x0180;
}
if (bcm->sprom.boardflags & BCM43xx_BFL_PACTRL) {
- mask |= 0x200;
- value |= 0x200;
+ bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_MASK,
+ bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_MASK)
+ | 0x0200);
+ mask |= 0x0200;
+ set |= 0x0200;
}
+ if (bcm->current_core->rev >= 2)
+ mask |= 0x0010; /* FIXME: This is redundant. */
+ old_core = bcm->current_core;
+ err = switch_to_gpio_core(bcm);
+ if (err)
+ goto out;
bcm43xx_write32(bcm, BCM43xx_GPIO_CONTROL,
- (bcm43xx_read32(bcm, BCM43xx_GPIO_CONTROL) & mask) | value);
-
+ (bcm43xx_read32(bcm, BCM43xx_GPIO_CONTROL) & mask) | set);
err = bcm43xx_switch_core(bcm, old_core);
- assert(err == 0);
-
- return 0;
+out:
+ return err;
}
/* Turn off all GPIO stuff. Call this on module unload, for example. */
int iw_mode)
{
unsigned long flags;
+ struct net_device *net_dev = bcm->net_dev;
u32 status;
+ u16 value;
spin_lock_irqsave(&bcm->ieee->lock, flags);
bcm->ieee->iw_mode = iw_mode;
spin_unlock_irqrestore(&bcm->ieee->lock, flags);
if (iw_mode == IW_MODE_MONITOR)
- bcm->net_dev->type = ARPHRD_IEEE80211;
+ net_dev->type = ARPHRD_IEEE80211;
else
- bcm->net_dev->type = ARPHRD_ETHER;
+ net_dev->type = ARPHRD_ETHER;
- if (!bcm->initialized)
- return;
-
- bcm43xx_mac_suspend(bcm);
status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
/* Reset status to infrastructured mode */
status &= ~(BCM43xx_SBF_MODE_AP | BCM43xx_SBF_MODE_MONITOR);
- /*FIXME: We actually set promiscuous mode as well, until we don't
- * get the HW mac filter working */
- status |= BCM43xx_SBF_MODE_NOTADHOC | BCM43xx_SBF_MODE_PROMISC;
+ status &= ~BCM43xx_SBF_MODE_PROMISC;
+ status |= BCM43xx_SBF_MODE_NOTADHOC;
+
+/* FIXME: Always enable promisc mode, until we get the MAC filters working correctly. */
+status |= BCM43xx_SBF_MODE_PROMISC;
switch (iw_mode) {
case IW_MODE_MONITOR:
- status |= (BCM43xx_SBF_MODE_PROMISC |
- BCM43xx_SBF_MODE_MONITOR);
+ status |= BCM43xx_SBF_MODE_MONITOR;
+ status |= BCM43xx_SBF_MODE_PROMISC;
break;
case IW_MODE_ADHOC:
status &= ~BCM43xx_SBF_MODE_NOTADHOC;
break;
case IW_MODE_MASTER:
+ status |= BCM43xx_SBF_MODE_AP;
+ break;
case IW_MODE_SECOND:
case IW_MODE_REPEAT:
- /* TODO: No AP/Repeater mode for now :-/ */
- TODO();
+ TODO(); /* TODO */
break;
case IW_MODE_INFRA:
/* nothing to be done here... */
break;
default:
- printk(KERN_ERR PFX "Unknown iwmode %d\n", iw_mode);
+ dprintk(KERN_ERR PFX "Unknown mode in set_iwmode: %d\n", iw_mode);
}
-
+ if (net_dev->flags & IFF_PROMISC)
+ status |= BCM43xx_SBF_MODE_PROMISC;
bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, status);
- bcm43xx_mac_enable(bcm);
+
+ value = 0x0002;
+ if (iw_mode != IW_MODE_ADHOC && iw_mode != IW_MODE_MASTER) {
+ if (bcm->chip_id == 0x4306 && bcm->chip_rev == 3)
+ value = 0x0064;
+ else
+ value = 0x0032;
+ }
+ bcm43xx_write16(bcm, 0x0612, value);
}
/* This is the opposite of bcm43xx_chip_init() */
struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
int err;
- int iw_mode = bcm->ieee->iw_mode;
int tmp;
u32 value32;
u16 value16;
goto err_gpio_cleanup;
bcm43xx_radio_turn_on(bcm);
- if (modparam_noleds)
- bcm43xx_leds_turn_off(bcm);
- else
- bcm43xx_leds_update(bcm, 0);
-
bcm43xx_write16(bcm, 0x03E6, 0x0000);
err = bcm43xx_phy_init(bcm);
if (err)
value32 = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
value32 |= BCM43xx_SBF_MODE_NOTADHOC;
bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, value32);
- /*FIXME: For now, use promiscuous mode at all times; otherwise we don't
- get broadcast or multicast packets */
- value32 = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
- value32 |= BCM43xx_SBF_MODE_PROMISC;
- bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, value32);
- if (iw_mode == IW_MODE_MONITOR) {
- value32 = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
- value32 |= BCM43xx_SBF_MODE_PROMISC;
- value32 |= BCM43xx_SBF_MODE_MONITOR;
- bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, value32);
- }
value32 = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
- value32 |= 0x100000; //FIXME: What's this? Is this correct?
+ value32 |= 0x100000;
bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, value32);
if (bcm43xx_using_pio(bcm)) {
/* FIXME: Default to 0, has to be set by ioctl probably... :-/ */
bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0074, 0x0000);
- if (iw_mode != IW_MODE_ADHOC && iw_mode != IW_MODE_MASTER) {
- if ((bcm->chip_id == 0x4306) && (bcm->chip_rev == 3))
- bcm43xx_write16(bcm, 0x0612, 0x0064);
- else
- bcm43xx_write16(bcm, 0x0612, 0x0032);
- } else
- bcm43xx_write16(bcm, 0x0612, 0x0002);
+ /* Initially set the wireless operation mode. */
+ bcm43xx_set_iwmode(bcm, bcm->ieee->iw_mode);
if (bcm->current_core->rev < 3) {
bcm43xx_write16(bcm, 0x060E, 0x0000);
return -ENODEV;
}
-void bcm43xx_init_struct_phyinfo(struct bcm43xx_phyinfo *phy)
+static void bcm43xx_init_struct_phyinfo(struct bcm43xx_phyinfo *phy)
{
/* Initialize a "phyinfo" structure. The structure is already
* zeroed out.
spin_lock_init(&phy->lock);
}
-void bcm43xx_init_struct_radioinfo(struct bcm43xx_radioinfo *radio)
+static void bcm43xx_init_struct_radioinfo(struct bcm43xx_radioinfo *radio)
{
/* Initialize a "radioinfo" structure. The structure is already
* zeroed out.
}
bcm->chip_id = chip_id_16;
- bcm->chip_rev = (chip_id_32 & 0x000f0000) >> 16;
+ bcm->chip_rev = (chip_id_32 & 0x000F0000) >> 16;
+ bcm->chip_package = (chip_id_32 & 0x00F00000) >> 20;
dprintk(KERN_INFO PFX "Chip ID 0x%x, rev 0x%x\n",
bcm->chip_id, bcm->chip_rev);
bcm43xx_sysfs_register(bcm);
//FIXME: check for bcm43xx_sysfs_register failure. This function is a bit messy regarding unwinding, though...
+ /*FIXME: This should be handled by softmac instead. */
+ schedule_work(&bcm->softmac->associnfo.work);
+
assert(err == 0);
out:
return err;
bcm43xx_chipset_detach(bcm);
/* Do _not_ access the chip, after it is detached. */
- iounmap(bcm->mmio_addr);
-
+ pci_iounmap(pci_dev, bcm->mmio_addr);
pci_release_regions(pci_dev);
pci_disable_device(pci_dev);
struct net_device *net_dev = bcm->net_dev;
int err;
int i;
- unsigned long mmio_start, mmio_flags, mmio_len;
u32 coremask;
err = pci_enable_device(pci_dev);
if (err) {
- printk(KERN_ERR PFX "unable to wake up pci device (%i)\n", err);
+ printk(KERN_ERR PFX "pci_enable_device() failed\n");
goto out;
}
- mmio_start = pci_resource_start(pci_dev, 0);
- mmio_flags = pci_resource_flags(pci_dev, 0);
- mmio_len = pci_resource_len(pci_dev, 0);
- if (!(mmio_flags & IORESOURCE_MEM)) {
- printk(KERN_ERR PFX
- "%s, region #0 not an MMIO resource, aborting\n",
- pci_name(pci_dev));
- err = -ENODEV;
- goto err_pci_disable;
- }
err = pci_request_regions(pci_dev, KBUILD_MODNAME);
if (err) {
- printk(KERN_ERR PFX
- "could not access PCI resources (%i)\n", err);
+ printk(KERN_ERR PFX "pci_request_regions() failed\n");
goto err_pci_disable;
}
/* enable PCI bus-mastering */
pci_set_master(pci_dev);
- bcm->mmio_addr = ioremap(mmio_start, mmio_len);
+ bcm->mmio_addr = pci_iomap(pci_dev, 0, ~0UL);
if (!bcm->mmio_addr) {
- printk(KERN_ERR PFX "%s: cannot remap MMIO, aborting\n",
- pci_name(pci_dev));
+ printk(KERN_ERR PFX "pci_iomap() failed\n");
err = -EIO;
goto err_pci_release;
}
- bcm->mmio_len = mmio_len;
net_dev->base_addr = (unsigned long)bcm->mmio_addr;
bcm43xx_pci_read_config16(bcm, PCI_SUBSYSTEM_VENDOR_ID,
goto err_80211_unwind;
bcm43xx_wireless_core_disable(bcm);
}
+ err = bcm43xx_geo_init(bcm);
+ if (err)
+ goto err_80211_unwind;
bcm43xx_pctl_set_crystal(bcm, 0);
/* Set the MAC address in the networking subsystem */
- if (bcm43xx_current_phy(bcm)->type == BCM43xx_PHYTYPE_A)
+ if (is_valid_ether_addr(bcm->sprom.et1macaddr))
memcpy(bcm->net_dev->dev_addr, bcm->sprom.et1macaddr, 6);
else
memcpy(bcm->net_dev->dev_addr, bcm->sprom.il0macaddr, 6);
- bcm43xx_geo_init(bcm);
-
snprintf(bcm->nick, IW_ESSID_MAX_SIZE,
"Broadcom %04X", bcm->chip_id);
err_chipset_detach:
bcm43xx_chipset_detach(bcm);
err_iounmap:
- iounmap(bcm->mmio_addr);
+ pci_iounmap(pci_dev, bcm->mmio_addr);
err_pci_release:
pci_release_regions(pci_dev);
err_pci_disable:
err = bcm43xx_pio_tx(bcm, txb);
else
err = bcm43xx_dma_tx(bcm, txb);
+ bcm->net_dev->trans_start = jiffies;
return err;
}
u8 channel)
{
struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
+ struct bcm43xx_radioinfo *radio;
unsigned long flags;
bcm43xx_lock_mmio(bcm, flags);
- bcm43xx_mac_suspend(bcm);
- bcm43xx_radio_selectchannel(bcm, channel, 0);
- bcm43xx_mac_enable(bcm);
+ if (bcm->initialized) {
+ bcm43xx_mac_suspend(bcm);
+ bcm43xx_radio_selectchannel(bcm, channel, 0);
+ bcm43xx_mac_enable(bcm);
+ } else {
+ radio = bcm43xx_current_radio(bcm);
+ radio->initial_channel = channel;
+ }
bcm43xx_unlock_mmio(bcm, flags);
}
unsigned long flags;
int keyidx;
- dprintk(KERN_INFO PFX "set security called\n");
+ dprintk(KERN_INFO PFX "set security called");
bcm43xx_lock_mmio(bcm, flags);
if (sec->flags & SEC_ACTIVE_KEY) {
secinfo->active_key = sec->active_key;
- dprintk(KERN_INFO PFX " .active_key = %d\n", sec->active_key);
+ dprintk(", .active_key = %d", sec->active_key);
}
if (sec->flags & SEC_UNICAST_GROUP) {
secinfo->unicast_uses_group = sec->unicast_uses_group;
- dprintk(KERN_INFO PFX " .unicast_uses_group = %d\n", sec->unicast_uses_group);
+ dprintk(", .unicast_uses_group = %d", sec->unicast_uses_group);
}
if (sec->flags & SEC_LEVEL) {
secinfo->level = sec->level;
- dprintk(KERN_INFO PFX " .level = %d\n", sec->level);
+ dprintk(", .level = %d", sec->level);
}
if (sec->flags & SEC_ENABLED) {
secinfo->enabled = sec->enabled;
- dprintk(KERN_INFO PFX " .enabled = %d\n", sec->enabled);
+ dprintk(", .enabled = %d", sec->enabled);
}
if (sec->flags & SEC_ENCRYPT) {
secinfo->encrypt = sec->encrypt;
- dprintk(KERN_INFO PFX " .encrypt = %d\n", sec->encrypt);
+ dprintk(", .encrypt = %d", sec->encrypt);
}
+ dprintk("\n");
if (bcm->initialized && !bcm->ieee->host_encrypt) {
if (secinfo->enabled) {
/* upload WEP keys to hardware */
netif_device_attach(net_dev);
- /*FIXME: This should be handled by softmac instead. */
- schedule_work(&bcm->softmac->associnfo.work);
-
dprintk(KERN_INFO PFX "Device resumed.\n");
return 0;
module_init(bcm43xx_init)
module_exit(bcm43xx_exit)
-
-/* vim: set ts=8 sw=8 sts=8: */