From 7d4b0394bbf5e306ff9d5753163a07187131bfd8 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Mon, 21 Aug 2006 09:43:44 -0500 Subject: [PATCH 01/11] [PATCH] bcm43xx-softmac: Init, shutdown and restart fixes This fixes various bugs in the init and shutdown code that would lead to lockups and crashes. Signed-Off-By: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/bcm43xx/bcm43xx_main.c | 39 +++++++++++--------- drivers/net/wireless/bcm43xx/bcm43xx_main.h | 3 ++ drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c | 3 ++ 3 files changed, 28 insertions(+), 17 deletions(-) diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/bcm43xx/bcm43xx_main.c index 966815be6955..96a5fdec8aad 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c @@ -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); @@ -3150,6 +3151,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); @@ -3158,7 +3160,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 @@ -3172,13 +3173,11 @@ 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(); @@ -3186,12 +3185,12 @@ static void bcm43xx_periodic_work_handler(void *d) 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); @@ -3539,11 +3538,10 @@ 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; + bcm43xx_periodic_tasks_setup(bcm); err = bcm43xx_rng_init(bcm); if (err) goto err_sysfs_unreg; @@ -3969,6 +3967,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; } @@ -4119,11 +4118,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", @@ -4132,11 +4136,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); diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.h b/drivers/net/wireless/bcm43xx/bcm43xx_main.h index 505c86e2007a..f76357178e4d 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_main.h +++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.h @@ -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); diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c b/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c index ece335178f6a..a16400d9ff4b 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c @@ -333,8 +333,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; From 6aeb3dddb7c6697c083582a0757078e163758971 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Mon, 11 Sep 2006 16:46:26 -0400 Subject: [PATCH 02/11] [PATCH] bcm43xx: Correct out of sequence initialization step This patch fixes an out of sequence step in the bcm43xx_init_board routine for bcm43xx-softmac. Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/bcm43xx/bcm43xx_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/bcm43xx/bcm43xx_main.c index 96a5fdec8aad..699b74dfb182 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c @@ -3541,10 +3541,10 @@ static int bcm43xx_init_board(struct bcm43xx_private *bcm) err = bcm43xx_sysfs_register(bcm); if (err) goto err_wlshutdown; - bcm43xx_periodic_tasks_setup(bcm); 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); From fca2714f27376caa04c3127c802a553b295eaa32 Mon Sep 17 00:00:00 2001 From: Daniel Drake Date: Tue, 29 Aug 2006 23:49:32 +0100 Subject: [PATCH 03/11] [PATCH] zd1211rw: Add ID for Siemens Gigaset USB Stick 54 Tested by Martin Dummer. zd1211 chip 0b3b:5630 v4330 high 00-01-e3 RF2959_RF pa0 --- Signed-off-by: Daniel Drake Signed-off-by: John W. Linville --- drivers/net/wireless/zd1211rw/zd_usb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c index 47489fe8ab52..f617fbc613eb 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zd1211rw/zd_usb.c @@ -44,6 +44,7 @@ static struct usb_device_id usb_ids[] = { { USB_DEVICE(0x1740, 0x2000), .driver_info = DEVICE_ZD1211 }, { USB_DEVICE(0x157e, 0x3204), .driver_info = DEVICE_ZD1211 }, { USB_DEVICE(0x0586, 0x3402), .driver_info = DEVICE_ZD1211 }, + { USB_DEVICE(0x0b3b, 0x5630), .driver_info = DEVICE_ZD1211 }, /* ZD1211B */ { USB_DEVICE(0x0ace, 0x1215), .driver_info = DEVICE_ZD1211B }, { USB_DEVICE(0x157e, 0x300d), .driver_info = DEVICE_ZD1211B }, From fc3e39bef9ef5eb594ab2a35206b9b049c36320a Mon Sep 17 00:00:00 2001 From: Daniel Drake Date: Tue, 29 Aug 2006 23:49:53 +0100 Subject: [PATCH 04/11] [PATCH] zd1211rw: Add ID for Asus WL-159g Tested by Vincent TOUCHARD zd1211 chip 0b05:170c v4802 high 00-11-d8 AL2230_RF pa0 g--- Signed-off-by: Daniel Drake Signed-off-by: John W. Linville --- drivers/net/wireless/zd1211rw/zd_usb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c index f617fbc613eb..31027e52b04b 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zd1211rw/zd_usb.c @@ -45,6 +45,7 @@ static struct usb_device_id usb_ids[] = { { USB_DEVICE(0x157e, 0x3204), .driver_info = DEVICE_ZD1211 }, { USB_DEVICE(0x0586, 0x3402), .driver_info = DEVICE_ZD1211 }, { USB_DEVICE(0x0b3b, 0x5630), .driver_info = DEVICE_ZD1211 }, + { USB_DEVICE(0x0b05, 0x170c), .driver_info = DEVICE_ZD1211 }, /* ZD1211B */ { USB_DEVICE(0x0ace, 0x1215), .driver_info = DEVICE_ZD1211B }, { USB_DEVICE(0x157e, 0x300d), .driver_info = DEVICE_ZD1211B }, From 4e1bbd846d00a245dcf78b6b331d8a9afed8e6d7 Mon Sep 17 00:00:00 2001 From: Ulrich Kunitz Date: Tue, 29 Aug 2006 23:51:43 +0100 Subject: [PATCH 05/11] [PATCH] zd1211rw: Removed unneeded packed attributes Inspired by an e-mail by Stephen Hemminger I decided to remove all unneeded packed attributes from the code where the member variables are already aligned. This avoids horrible code being generated on some architectures. Signed-off-by: Ulrich Kunitz Signed-off-by: Daniel Drake Signed-off-by: John W. Linville --- drivers/net/wireless/zd1211rw/zd_ieee80211.h | 2 +- drivers/net/wireless/zd1211rw/zd_mac.c | 2 +- drivers/net/wireless/zd1211rw/zd_mac.h | 4 ++-- drivers/net/wireless/zd1211rw/zd_usb.h | 14 +++++++------- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/zd1211rw/zd_ieee80211.h b/drivers/net/wireless/zd1211rw/zd_ieee80211.h index 36329890dfec..f63245b0d966 100644 --- a/drivers/net/wireless/zd1211rw/zd_ieee80211.h +++ b/drivers/net/wireless/zd1211rw/zd_ieee80211.h @@ -64,7 +64,7 @@ struct cck_plcp_header { u8 service; __le16 length; __le16 crc16; -} __attribute__((packed)); +}; static inline u8 zd_cck_plcp_header_rate(const struct cck_plcp_header *header) { diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 0ddccf893989..1989f1c05fbe 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c @@ -714,7 +714,7 @@ struct zd_rt_hdr { u8 rt_rate; u16 rt_channel; u16 rt_chbitmask; -} __attribute__((packed)); +}; static void fill_rt_header(void *buffer, struct zd_mac *mac, const struct ieee80211_rx_stats *stats, diff --git a/drivers/net/wireless/zd1211rw/zd_mac.h b/drivers/net/wireless/zd1211rw/zd_mac.h index 2b596cc8a41a..29b51fd7d4e5 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.h +++ b/drivers/net/wireless/zd1211rw/zd_mac.h @@ -82,7 +82,7 @@ struct zd_ctrlset { struct rx_length_info { __le16 length[3]; __le16 tag; -} __attribute__((packed)); +}; #define RX_LENGTH_INFO_TAG 0x697e @@ -93,7 +93,7 @@ struct rx_status { u8 signal_quality_ofdm; u8 decryption_type; u8 frame_status; -} __attribute__((packed)); +}; /* rx_status field decryption_type */ #define ZD_RX_NO_WEP 0 diff --git a/drivers/net/wireless/zd1211rw/zd_usb.h b/drivers/net/wireless/zd1211rw/zd_usb.h index 92746f76239a..ded39de5f72d 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.h +++ b/drivers/net/wireless/zd1211rw/zd_usb.h @@ -74,17 +74,17 @@ enum control_requests { struct usb_req_read_regs { __le16 id; __le16 addr[0]; -} __attribute__((packed)); +}; struct reg_data { __le16 addr; __le16 value; -} __attribute__((packed)); +}; struct usb_req_write_regs { __le16 id; struct reg_data reg_writes[0]; -} __attribute__((packed)); +}; enum { RF_IF_LE = 0x02, @@ -101,7 +101,7 @@ struct usb_req_rfwrite { /* RF2595: 24 */ __le16 bit_values[0]; /* (CR203 & ~(RF_IF_LE | RF_CLK | RF_DATA)) | (bit ? RF_DATA : 0) */ -} __attribute__((packed)); +}; /* USB interrupt */ @@ -118,12 +118,12 @@ enum usb_int_flags { struct usb_int_header { u8 type; /* must always be 1 */ u8 id; -} __attribute__((packed)); +}; struct usb_int_regs { struct usb_int_header hdr; struct reg_data regs[0]; -} __attribute__((packed)); +}; struct usb_int_retry_fail { struct usb_int_header hdr; @@ -131,7 +131,7 @@ struct usb_int_retry_fail { u8 _dummy; u8 addr[ETH_ALEN]; u8 ibss_wakeup_dest; -} __attribute__((packed)); +}; struct read_regs_int { struct completion completion; From bd6dd756522f3874b0efe576f9c25f5dee239646 Mon Sep 17 00:00:00 2001 From: Jean Tourrilhes Date: Tue, 29 Aug 2006 18:19:23 -0700 Subject: [PATCH 06/11] [PATCH] Prism54 : add bitrates to scan result This patch adds bitrate information to the scan result in the Prism54 driver, like some/most other driver do. Signed-off-by: Jean Tourrilhes Signed-off-by: John W. Linville --- drivers/net/wireless/prism54/isl_ioctl.c | 30 ++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c index 0c30fe7e8f7f..c09fbf733b3a 100644 --- a/drivers/net/wireless/prism54/isl_ioctl.c +++ b/drivers/net/wireless/prism54/isl_ioctl.c @@ -46,6 +46,10 @@ static size_t prism54_wpa_bss_ie_get(islpci_private *priv, u8 *bssid, u8 *wpa_ie static int prism54_set_wpa(struct net_device *, struct iw_request_info *, __u32 *, char *); +/* In 500 kbps */ +static const unsigned char scan_rate_list[] = { 2, 4, 11, 22, + 12, 18, 24, 36, + 48, 72, 96, 108 }; /** * prism54_mib_mode_helper - MIB change mode helper function @@ -644,6 +648,32 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev, current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, wpa_ie); } + /* Do the bitrates */ + { + char * current_val = current_ev + IW_EV_LCP_LEN; + int i; + int mask; + + iwe.cmd = SIOCGIWRATE; + /* Those two flags are ignored... */ + iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0; + + /* Parse the bitmask */ + mask = 0x1; + for(i = 0; i < sizeof(scan_rate_list); i++) { + if(bss->rates & mask) { + iwe.u.bitrate.value = (scan_rate_list[i] * 500000); + current_val = iwe_stream_add_value(current_ev, current_val, + end_buf, &iwe, + IW_EV_PARAM_LEN); + } + mask <<= 1; + } + /* Check if we added any event */ + if ((current_val - current_ev) > IW_EV_LCP_LEN) + current_ev = current_val; + } + return current_ev; } From 6807b5076373b8a6b6dac3b3b54645c85df91ad6 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Sun, 3 Sep 2006 23:38:56 -0500 Subject: [PATCH 07/11] [PATCH] bcm43xx: remove dead statistics code This patch removes code that was make obsolete when the wireless statistics in bcm43xx-softmac were changed, but was overlooked at that time. The value of bcm->stats.link_quality computed here is never used. Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/bcm43xx/bcm43xx_main.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/bcm43xx/bcm43xx_main.c index 699b74dfb182..c19bd866147e 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c @@ -1546,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; From 1ef4583ee3e1efab83d05b6ccdad378c9caaa95f Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Mon, 4 Sep 2006 17:13:57 -0500 Subject: [PATCH 08/11] [PATCH] bcm43xx: Add firmware version printout This patch prints microcode revision, patchlevel, date and time to KERN_INFO. Also, version 4.xx microcodes (rev>0x128) will be rejected by the driver, because they still do not work. Signed-off-by: Martin Langer Acked-by: Michael Buesch Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/bcm43xx/bcm43xx.h | 6 +++++ drivers/net/wireless/bcm43xx/bcm43xx_main.c | 27 +++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/drivers/net/wireless/bcm43xx/bcm43xx.h b/drivers/net/wireless/bcm43xx/bcm43xx.h index 62fd7e237789..e7d802157803 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx.h +++ b/drivers/net/wireless/bcm43xx/bcm43xx.h @@ -306,6 +306,12 @@ #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 + /* MicrocodeFlagsBitfield (addr + lo-word values?)*/ #define BCM43xx_UCODEFLAGS_OFFSET 0x005E diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/bcm43xx/bcm43xx_main.c index c19bd866147e..cb9a3ae8463a 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c @@ -2384,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; From 87d263271b1bbf344c596ac308417ff692ddc851 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Thu, 7 Sep 2006 10:12:11 -0500 Subject: [PATCH 09/11] [PATCH] bcm43xx: ucode debug status via sysfs This patch prints out the ucode debug status to sysfs. So, users can watch the microcode status of their hardware. Signed-off-by: Martin Langer Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/bcm43xx/bcm43xx.h | 9 +-- drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c | 59 ++++++++++++++++++++ 2 files changed, 64 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/bcm43xx/bcm43xx.h b/drivers/net/wireless/bcm43xx/bcm43xx.h index e7d802157803..6d4ea36bc564 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx.h +++ b/drivers/net/wireless/bcm43xx/bcm43xx.h @@ -307,10 +307,11 @@ #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_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 diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c b/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c index a16400d9ff4b..b2bc5a9b6245 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c @@ -376,6 +376,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; @@ -395,9 +448,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: @@ -411,6 +469,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); From dca762d63a6fd62599f0d5d18525fa347fa1772a Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Thu, 7 Sep 2006 11:17:05 -0500 Subject: [PATCH 10/11] [PATCH] bcm43xx: remove dead code in bcm43xx_sysfs.c Coverity CID 1160 & 1161 Remove some dead code from bcm43xx_sysfs.c in 2.6.18-rc6 Signed-off-by: Darren Jenkins Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c b/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c index b2bc5a9b6245..c71b998a3694 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c @@ -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)) @@ -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; } @@ -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)) @@ -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, @@ -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)) @@ -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, From 884d3a2bad7293e56fe99d9322a1090bfdfd7c4e Mon Sep 17 00:00:00 2001 From: Christian Steineck Date: Fri, 8 Sep 2006 23:51:34 +0200 Subject: [PATCH 11/11] [PATCH] hostap_cs: added support for Proxim Harmony PCI W-Lan card hostap_cs driver - added support for Proxim Harmony PCI W-Lan Card (uses pd6729 based pcmcia2pci bridge) Signed-off-by: Christian Steineck Signed-off-by: John W. Linville --- drivers/net/wireless/hostap/hostap_cs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c index 52e6df5c1a92..686d895116de 100644 --- a/drivers/net/wireless/hostap/hostap_cs.c +++ b/drivers/net/wireless/hostap/hostap_cs.c @@ -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",