Skip to content

Commit

Permalink
Merge branch 'upstream' of git://git.kernel.org/pub/scm/linux/kernel/…
Browse files Browse the repository at this point in the history
…git/linville/wireless-2.6 into upstream
  • Loading branch information
Jeff Garzik committed Sep 12, 2006
2 parents 8083e16 + 884d3a2 commit c925f1e
Show file tree
Hide file tree
Showing 11 changed files with 169 additions and 48 deletions.
7 changes: 7 additions & 0 deletions drivers/net/wireless/bcm43xx/bcm43xx.h
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,13 @@
#define BCM43xx_SBF_TIME_UPDATE 0x10000000
#define BCM43xx_SBF_80000000 0x80000000 /*FIXME: fix name*/

/* Microcode */
#define BCM43xx_UCODE_REVISION 0x0000
#define BCM43xx_UCODE_PATCHLEVEL 0x0002
#define BCM43xx_UCODE_DATE 0x0004
#define BCM43xx_UCODE_TIME 0x0006
#define BCM43xx_UCODE_STATUS 0x0040

/* MicrocodeFlagsBitfield (addr + lo-word values?)*/
#define BCM43xx_UCODEFLAGS_OFFSET 0x005E

Expand Down
78 changes: 50 additions & 28 deletions drivers/net/wireless/bcm43xx/bcm43xx_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,7 @@ static int bcm43xx_disable_interrupts_sync(struct bcm43xx_private *bcm)
return -EBUSY;
}
bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_MASK); /* flush */
spin_unlock_irqrestore(&bcm->irq_lock, flags);
bcm43xx_synchronize_irq(bcm);

Expand Down Expand Up @@ -1545,17 +1546,7 @@ static void handle_irq_noise(struct bcm43xx_private *bcm)
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)
bcm->stats.link_quality = 1;
else if (average > -85)
bcm->stats.link_quality = 2;
else
bcm->stats.link_quality = 3;
// dprintk(KERN_INFO PFX "Link Quality: %u (avg was %d)\n", bcm->stats.link_quality, average);
bcm->stats.noise = average;
drop_calculation:
bcm->noisecalc.calculation_running = 0;
return;
Expand Down Expand Up @@ -2393,6 +2384,33 @@ static int bcm43xx_chip_init(struct bcm43xx_private *bcm)
}
bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); /* dummy read */

value16 = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED,
BCM43xx_UCODE_REVISION);

dprintk(KERN_INFO PFX "Microcode rev 0x%x, pl 0x%x "
"(20%.2i-%.2i-%.2i %.2i:%.2i:%.2i)\n", value16,
bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED,
BCM43xx_UCODE_PATCHLEVEL),
(bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED,
BCM43xx_UCODE_DATE) >> 12) & 0xf,
(bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED,
BCM43xx_UCODE_DATE) >> 8) & 0xf,
bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED,
BCM43xx_UCODE_DATE) & 0xff,
(bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED,
BCM43xx_UCODE_TIME) >> 11) & 0x1f,
(bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED,
BCM43xx_UCODE_TIME) >> 5) & 0x3f,
bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED,
BCM43xx_UCODE_TIME) & 0x1f);

if ( value16 > 0x128 ) {
dprintk(KERN_ERR PFX
"Firmware: no support for microcode rev > 0x128\n");
err = -1;
goto err_release_fw;
}

err = bcm43xx_gpio_init(bcm);
if (err)
goto err_release_fw;
Expand Down Expand Up @@ -3150,6 +3168,7 @@ static void bcm43xx_periodic_work_handler(void *d)
/* Periodic work will take a long time, so we want it to
* be preemtible.
*/
mutex_lock(&bcm->mutex);
netif_stop_queue(bcm->net_dev);
synchronize_net();
spin_lock_irqsave(&bcm->irq_lock, flags);
Expand All @@ -3158,7 +3177,6 @@ static void bcm43xx_periodic_work_handler(void *d)
bcm43xx_pio_freeze_txqueues(bcm);
savedirqs = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
spin_unlock_irqrestore(&bcm->irq_lock, flags);
mutex_lock(&bcm->mutex);
bcm43xx_synchronize_irq(bcm);
} else {
/* Periodic work should take short time, so we want low
Expand All @@ -3172,26 +3190,24 @@ static void bcm43xx_periodic_work_handler(void *d)

if (badness > BADNESS_LIMIT) {
spin_lock_irqsave(&bcm->irq_lock, flags);
if (likely(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED)) {
tasklet_enable(&bcm->isr_tasklet);
bcm43xx_interrupt_enable(bcm, savedirqs);
if (bcm43xx_using_pio(bcm))
bcm43xx_pio_thaw_txqueues(bcm);
bcm43xx_mac_enable(bcm);
}
tasklet_enable(&bcm->isr_tasklet);
bcm43xx_interrupt_enable(bcm, savedirqs);
if (bcm43xx_using_pio(bcm))
bcm43xx_pio_thaw_txqueues(bcm);
bcm43xx_mac_enable(bcm);
netif_wake_queue(bcm->net_dev);
}
mmiowb();
spin_unlock_irqrestore(&bcm->irq_lock, flags);
mutex_unlock(&bcm->mutex);
}

static void bcm43xx_periodic_tasks_delete(struct bcm43xx_private *bcm)
void bcm43xx_periodic_tasks_delete(struct bcm43xx_private *bcm)
{
cancel_rearming_delayed_work(&bcm->periodic_work);
}

static void bcm43xx_periodic_tasks_setup(struct bcm43xx_private *bcm)
void bcm43xx_periodic_tasks_setup(struct bcm43xx_private *bcm)
{
struct work_struct *work = &(bcm->periodic_work);

Expand Down Expand Up @@ -3539,14 +3555,13 @@ static int bcm43xx_init_board(struct bcm43xx_private *bcm)
err = bcm43xx_select_wireless_core(bcm, -1);
if (err)
goto err_crystal_off;

bcm43xx_periodic_tasks_setup(bcm);
err = bcm43xx_sysfs_register(bcm);
if (err)
goto err_wlshutdown;
err = bcm43xx_rng_init(bcm);
if (err)
goto err_sysfs_unreg;
bcm43xx_periodic_tasks_setup(bcm);

/*FIXME: This should be handled by softmac instead. */
schedule_work(&bcm->softmac->associnfo.work);
Expand Down Expand Up @@ -3969,6 +3984,7 @@ static int bcm43xx_net_stop(struct net_device *net_dev)
err = bcm43xx_disable_interrupts_sync(bcm);
assert(!err);
bcm43xx_free_board(bcm);
flush_scheduled_work();

return 0;
}
Expand Down Expand Up @@ -4119,11 +4135,16 @@ static void bcm43xx_chip_reset(void *_bcm)
{
struct bcm43xx_private *bcm = _bcm;
struct bcm43xx_phyinfo *phy;
int err;
int err = -ENODEV;

mutex_lock(&(bcm)->mutex);
phy = bcm43xx_current_phy(bcm);
err = bcm43xx_select_wireless_core(bcm, phy->type);
if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) {
bcm43xx_periodic_tasks_delete(bcm);
phy = bcm43xx_current_phy(bcm);
err = bcm43xx_select_wireless_core(bcm, phy->type);
if (!err)
bcm43xx_periodic_tasks_setup(bcm);
}
mutex_unlock(&(bcm)->mutex);

printk(KERN_ERR PFX "Controller restart%s\n",
Expand All @@ -4132,11 +4153,12 @@ static void bcm43xx_chip_reset(void *_bcm)

/* Hard-reset the chip.
* This can be called from interrupt or process context.
* bcm->irq_lock must be locked.
*/
void bcm43xx_controller_restart(struct bcm43xx_private *bcm, const char *reason)
{
assert(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED);
bcm43xx_set_status(bcm, BCM43xx_STAT_RESTARTING);
if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED)
return;
printk(KERN_ERR PFX "Controller RESET (%s) ...\n", reason);
INIT_WORK(&bcm->restart_work, bcm43xx_chip_reset, bcm);
schedule_work(&bcm->restart_work);
Expand Down
3 changes: 3 additions & 0 deletions drivers/net/wireless/bcm43xx/bcm43xx_main.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,9 @@ void bcm43xx_wireless_core_reset(struct bcm43xx_private *bcm, int connect_phy);
void bcm43xx_mac_suspend(struct bcm43xx_private *bcm);
void bcm43xx_mac_enable(struct bcm43xx_private *bcm);

void bcm43xx_periodic_tasks_delete(struct bcm43xx_private *bcm);
void bcm43xx_periodic_tasks_setup(struct bcm43xx_private *bcm);

void bcm43xx_controller_restart(struct bcm43xx_private *bcm, const char *reason);

int bcm43xx_sprom_read(struct bcm43xx_private *bcm, u16 *sprom);
Expand Down
74 changes: 65 additions & 9 deletions drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,6 @@ static ssize_t bcm43xx_attr_interfmode_show(struct device *dev,
char *buf)
{
struct bcm43xx_private *bcm = dev_to_bcm(dev);
int err;
ssize_t count = 0;

if (!capable(CAP_NET_ADMIN))
Expand All @@ -197,11 +196,10 @@ static ssize_t bcm43xx_attr_interfmode_show(struct device *dev,
default:
assert(0);
}
err = 0;

mutex_unlock(&bcm->mutex);

return err ? err : count;
return count;

}

Expand Down Expand Up @@ -259,7 +257,6 @@ static ssize_t bcm43xx_attr_preamble_show(struct device *dev,
char *buf)
{
struct bcm43xx_private *bcm = dev_to_bcm(dev);
int err;
ssize_t count;

if (!capable(CAP_NET_ADMIN))
Expand All @@ -272,10 +269,9 @@ static ssize_t bcm43xx_attr_preamble_show(struct device *dev,
else
count = snprintf(buf, PAGE_SIZE, "0 (Short Preamble disabled)\n");

err = 0;
mutex_unlock(&bcm->mutex);

return err ? err : count;
return count;
}

static ssize_t bcm43xx_attr_preamble_store(struct device *dev,
Expand All @@ -284,7 +280,6 @@ static ssize_t bcm43xx_attr_preamble_store(struct device *dev,
{
struct bcm43xx_private *bcm = dev_to_bcm(dev);
unsigned long flags;
int err;
int value;

if (!capable(CAP_NET_ADMIN))
Expand All @@ -298,11 +293,10 @@ static ssize_t bcm43xx_attr_preamble_store(struct device *dev,

bcm->short_preamble = !!value;

err = 0;
spin_unlock_irqrestore(&bcm->irq_lock, flags);
mutex_unlock(&bcm->mutex);

return err ? err : count;
return count;
}

static DEVICE_ATTR(shortpreamble, 0644,
Expand Down Expand Up @@ -333,8 +327,11 @@ static ssize_t bcm43xx_attr_phymode_store(struct device *dev,
goto out;
}

bcm43xx_periodic_tasks_delete(bcm);
mutex_lock(&(bcm)->mutex);
err = bcm43xx_select_wireless_core(bcm, phytype);
if (!err)
bcm43xx_periodic_tasks_setup(bcm);
mutex_unlock(&(bcm)->mutex);
if (err == -ESRCH)
err = -ENODEV;
Expand Down Expand Up @@ -373,6 +370,59 @@ static DEVICE_ATTR(phymode, 0644,
bcm43xx_attr_phymode_show,
bcm43xx_attr_phymode_store);

static ssize_t bcm43xx_attr_microcode_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
unsigned long flags;
struct bcm43xx_private *bcm = dev_to_bcm(dev);
ssize_t count = 0;
u16 status;

if (!capable(CAP_NET_ADMIN))
return -EPERM;

mutex_lock(&(bcm)->mutex);
spin_lock_irqsave(&bcm->irq_lock, flags);
status = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED,
BCM43xx_UCODE_STATUS);

spin_unlock_irqrestore(&bcm->irq_lock, flags);
mutex_unlock(&(bcm)->mutex);
switch (status) {
case 0x0000:
count = snprintf(buf, PAGE_SIZE, "0x%.4x (invalid)\n",
status);
break;
case 0x0001:
count = snprintf(buf, PAGE_SIZE, "0x%.4x (init)\n",
status);
break;
case 0x0002:
count = snprintf(buf, PAGE_SIZE, "0x%.4x (active)\n",
status);
break;
case 0x0003:
count = snprintf(buf, PAGE_SIZE, "0x%.4x (suspended)\n",
status);
break;
case 0x0004:
count = snprintf(buf, PAGE_SIZE, "0x%.4x (asleep)\n",
status);
break;
default:
count = snprintf(buf, PAGE_SIZE, "0x%.4x (unknown)\n",
status);
break;
}

return count;
}

static DEVICE_ATTR(microcodestatus, 0444,
bcm43xx_attr_microcode_show,
NULL);

int bcm43xx_sysfs_register(struct bcm43xx_private *bcm)
{
struct device *dev = &bcm->pci_dev->dev;
Expand All @@ -392,9 +442,14 @@ int bcm43xx_sysfs_register(struct bcm43xx_private *bcm)
err = device_create_file(dev, &dev_attr_phymode);
if (err)
goto err_remove_shortpreamble;
err = device_create_file(dev, &dev_attr_microcodestatus);
if (err)
goto err_remove_phymode;

out:
return err;
err_remove_phymode:
device_remove_file(dev, &dev_attr_phymode);
err_remove_shortpreamble:
device_remove_file(dev, &dev_attr_shortpreamble);
err_remove_interfmode:
Expand All @@ -408,6 +463,7 @@ void bcm43xx_sysfs_unregister(struct bcm43xx_private *bcm)
{
struct device *dev = &bcm->pci_dev->dev;

device_remove_file(dev, &dev_attr_microcodestatus);
device_remove_file(dev, &dev_attr_phymode);
device_remove_file(dev, &dev_attr_shortpreamble);
device_remove_file(dev, &dev_attr_interference);
Expand Down
1 change: 1 addition & 0 deletions drivers/net/wireless/hostap/hostap_cs.c
Original file line number Diff line number Diff line change
Expand Up @@ -847,6 +847,7 @@ static struct pcmcia_device_id hostap_cs_ids[] = {
PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0002),
PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0005),
PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0010),
PCMCIA_DEVICE_MANF_CARD(0x0126, 0x0002),
PCMCIA_DEVICE_MANF_CARD_PROD_ID1(0x0156, 0x0002, "INTERSIL",
0x74c5e40d),
PCMCIA_DEVICE_MANF_CARD_PROD_ID1(0x0156, 0x0002, "Intersil",
Expand Down
Loading

0 comments on commit c925f1e

Please sign in to comment.