Hi John, I already sent these three patches for inclusion into the softmac version of the driver. Here are the devicescape port versions for inclusion in your wireless-dev tree.
-- Greetings Michael.
Index: wireless-dev-ds/drivers/net/wireless/bcm43xx-d80211/bcm43xx.h =================================================================== --- wireless-dev-ds.orig/drivers/net/wireless/bcm43xx-d80211/bcm43xx.h 2006-04-18 16:33:23.000000000 +0200 +++ wireless-dev-ds/drivers/net/wireless/bcm43xx-d80211/bcm43xx.h 2006-04-18 16:38:10.000000000 +0200 @@ -18,7 +18,6 @@ #include "bcm43xx_debugfs.h" #include "bcm43xx_leds.h" -#include "bcm43xx_sysfs.h" #define PFX KBUILD_MODNAME ": " @@ -628,8 +627,6 @@ }; struct bcm43xx_private { - struct bcm43xx_sysfs sysfs; - struct ieee80211_hw *ieee; struct ieee80211_low_level_stats ieee_stats; int iw_mode; @@ -843,6 +840,20 @@ return phy->_lo_pairs + (radio_attenuation + 14 * (baseband_attenuation / 2)); } +struct device; + +static inline +struct bcm43xx_private * dev_to_bcm(struct device *dev) +{ + struct net_device *net_dev; + struct bcm43xx_private *bcm; + + net_dev = dev_get_drvdata(dev); + bcm = bcm43xx_priv(net_dev); + + return bcm; +} + static inline u16 bcm43xx_read16(struct bcm43xx_private *bcm, u16 offset) Index: wireless-dev-ds/drivers/net/wireless/bcm43xx-d80211/bcm43xx_main.c =================================================================== --- wireless-dev-ds.orig/drivers/net/wireless/bcm43xx-d80211/bcm43xx_main.c 2006-04-18 16:33:23.000000000 +0200 +++ wireless-dev-ds/drivers/net/wireless/bcm43xx-d80211/bcm43xx_main.c 2006-04-18 16:37:48.000000000 +0200 @@ -52,6 +52,7 @@ #include "bcm43xx_sysfs.h" #include "bcm43xx_ethtool.h" #include "bcm43xx_xmit.h" +#include "bcm43xx_sysfs.h" MODULE_DESCRIPTION("Broadcom BCM43xx wireless driver"); Index: wireless-dev-ds/drivers/net/wireless/bcm43xx-d80211/bcm43xx_sysfs.c =================================================================== --- wireless-dev-ds.orig/drivers/net/wireless/bcm43xx-d80211/bcm43xx_sysfs.c 2006-04-18 16:33:23.000000000 +0200 +++ wireless-dev-ds/drivers/net/wireless/bcm43xx-d80211/bcm43xx_sysfs.c 2006-04-18 16:37:48.000000000 +0200 @@ -71,14 +71,46 @@ return -EINVAL; } +static int sprom2hex(const u16 *sprom, char *buf, size_t buf_len) +{ + int i, pos = 0; + + for (i = 0; i < BCM43xx_SPROM_SIZE; i++) { + pos += snprintf(buf + pos, buf_len - pos - 1, + "%04X", swab16(sprom[i]) & 0xFFFF); + } + pos += snprintf(buf + pos, buf_len - pos - 1, "\n"); + + return pos + 1; +} + +static int hex2sprom(u16 *sprom, const char *dump, size_t len) +{ + char tmp[5] = { 0 }; + int cnt = 0; + unsigned long parsed; + + if (len < BCM43xx_SPROM_SIZE * sizeof(u16) * 2) + return -EINVAL; + + while (cnt < BCM43xx_SPROM_SIZE) { + memcpy(tmp, dump, 4); + dump += 4; + parsed = simple_strtoul(tmp, NULL, 16); + sprom[cnt++] = swab16((u16)parsed); + } + + return 0; +} + static ssize_t bcm43xx_attr_sprom_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct bcm43xx_private *bcm = devattr_to_bcm(attr, attr_sprom); + struct bcm43xx_private *bcm = dev_to_bcm(dev); u16 *sprom; unsigned long flags; - int i, err; + int err; if (!capable(CAP_NET_ADMIN)) return -EPERM; @@ -91,55 +123,53 @@ bcm43xx_lock_mmio(bcm, flags); assert(bcm->initialized); err = bcm43xx_sprom_read(bcm, sprom); - if (!err) { - for (i = 0; i < BCM43xx_SPROM_SIZE; i++) { - buf[i * 2] = sprom[i] & 0x00FF; - buf[i * 2 + 1] = (sprom[i] & 0xFF00) >> 8; - } - } + if (!err) + err = sprom2hex(sprom, buf, PAGE_SIZE); bcm43xx_unlock_mmio(bcm, flags); kfree(sprom); - return err ? err : BCM43xx_SPROM_SIZE * sizeof(u16); + return err; } static ssize_t bcm43xx_attr_sprom_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct bcm43xx_private *bcm = devattr_to_bcm(attr, attr_sprom); + struct bcm43xx_private *bcm = dev_to_bcm(dev); u16 *sprom; unsigned long flags; - int i, err; + int err; if (!capable(CAP_NET_ADMIN)) return -EPERM; - if (count != BCM43xx_SPROM_SIZE * sizeof(u16)) - return -EINVAL; sprom = kmalloc(BCM43xx_SPROM_SIZE * sizeof(*sprom), GFP_KERNEL); if (!sprom) return -ENOMEM; - for (i = 0; i < BCM43xx_SPROM_SIZE; i++) { - sprom[i] = buf[i * 2] & 0xFF; - sprom[i] |= ((u16)(buf[i * 2 + 1] & 0xFF)) << 8; - } + err = hex2sprom(sprom, buf, count); + if (err) + goto out_kfree; bcm43xx_lock_mmio(bcm, flags); assert(bcm->initialized); err = bcm43xx_sprom_write(bcm, sprom); bcm43xx_unlock_mmio(bcm, flags); +out_kfree: kfree(sprom); return err ? err : count; } +static DEVICE_ATTR(sprom, 0600, + bcm43xx_attr_sprom_show, + bcm43xx_attr_sprom_store); + static ssize_t bcm43xx_attr_interfmode_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct bcm43xx_private *bcm = devattr_to_bcm(attr, attr_interfmode); + struct bcm43xx_private *bcm = dev_to_bcm(dev); unsigned long flags; int err; ssize_t count = 0; @@ -175,7 +205,7 @@ struct device_attribute *attr, const char *buf, size_t count) { - struct bcm43xx_private *bcm = devattr_to_bcm(attr, attr_interfmode); + struct bcm43xx_private *bcm = dev_to_bcm(dev); unsigned long flags; int err; int mode; @@ -215,11 +245,15 @@ return err ? err : count; } +static DEVICE_ATTR(interference, 0644, + bcm43xx_attr_interfmode_show, + bcm43xx_attr_interfmode_store); + static ssize_t bcm43xx_attr_preamble_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct bcm43xx_private *bcm = devattr_to_bcm(attr, attr_preamble); + struct bcm43xx_private *bcm = dev_to_bcm(dev); unsigned long flags; int err; ssize_t count; @@ -245,7 +279,7 @@ struct device_attribute *attr, const char *buf, size_t count) { - struct bcm43xx_private *bcm = devattr_to_bcm(attr, attr_preamble); + struct bcm43xx_private *bcm = dev_to_bcm(dev); unsigned long flags; int err; int value; @@ -267,56 +301,41 @@ return err ? err : count; } +static DEVICE_ATTR(shortpreamble, 0644, + bcm43xx_attr_preamble_show, + bcm43xx_attr_preamble_store); + int bcm43xx_sysfs_register(struct bcm43xx_private *bcm) { struct device *dev = &bcm->pci_dev->dev; - struct bcm43xx_sysfs *sysfs = &bcm->sysfs; int err; assert(bcm->initialized); - sysfs->attr_sprom.attr.name = "sprom"; - sysfs->attr_sprom.attr.owner = THIS_MODULE; - sysfs->attr_sprom.attr.mode = 0600; - sysfs->attr_sprom.show = bcm43xx_attr_sprom_show; - sysfs->attr_sprom.store = bcm43xx_attr_sprom_store; - err = device_create_file(dev, &sysfs->attr_sprom); + err = device_create_file(dev, &dev_attr_sprom); if (err) goto out; - - sysfs->attr_interfmode.attr.name = "interference"; - sysfs->attr_interfmode.attr.owner = THIS_MODULE; - sysfs->attr_interfmode.attr.mode = 0600; - sysfs->attr_interfmode.show = bcm43xx_attr_interfmode_show; - sysfs->attr_interfmode.store = bcm43xx_attr_interfmode_store; - err = device_create_file(dev, &sysfs->attr_interfmode); + err = device_create_file(dev, &dev_attr_interference); if (err) goto err_remove_sprom; - - sysfs->attr_preamble.attr.name = "shortpreamble"; - sysfs->attr_preamble.attr.owner = THIS_MODULE; - sysfs->attr_preamble.attr.mode = 0600; - sysfs->attr_preamble.show = bcm43xx_attr_preamble_show; - sysfs->attr_preamble.store = bcm43xx_attr_preamble_store; - err = device_create_file(dev, &sysfs->attr_preamble); + err = device_create_file(dev, &dev_attr_shortpreamble); if (err) goto err_remove_interfmode; out: return err; err_remove_interfmode: - device_remove_file(dev, &sysfs->attr_interfmode); + device_remove_file(dev, &dev_attr_interference); err_remove_sprom: - device_remove_file(dev, &sysfs->attr_sprom); + device_remove_file(dev, &dev_attr_sprom); goto out; } void bcm43xx_sysfs_unregister(struct bcm43xx_private *bcm) { struct device *dev = &bcm->pci_dev->dev; - struct bcm43xx_sysfs *sysfs = &bcm->sysfs; - device_remove_file(dev, &sysfs->attr_preamble); - device_remove_file(dev, &sysfs->attr_interfmode); - device_remove_file(dev, &sysfs->attr_sprom); + device_remove_file(dev, &dev_attr_shortpreamble); + device_remove_file(dev, &dev_attr_interference); + device_remove_file(dev, &dev_attr_sprom); } Index: wireless-dev-ds/drivers/net/wireless/bcm43xx-d80211/bcm43xx_sysfs.h =================================================================== --- wireless-dev-ds.orig/drivers/net/wireless/bcm43xx-d80211/bcm43xx_sysfs.h 2006-04-18 16:33:23.000000000 +0200 +++ wireless-dev-ds/drivers/net/wireless/bcm43xx-d80211/bcm43xx_sysfs.h 2006-04-18 16:37:48.000000000 +0200 @@ -1,22 +1,6 @@ #ifndef BCM43xx_SYSFS_H_ #define BCM43xx_SYSFS_H_ -#include <linux/device.h> - - -struct bcm43xx_sysfs { - struct device_attribute attr_sprom; - struct device_attribute attr_interfmode; - struct device_attribute attr_preamble; -}; - -#define devattr_to_bcm(attr, attr_name) ({ \ - struct bcm43xx_sysfs *__s; struct bcm43xx_private *__p; \ - __s = container_of((attr), struct bcm43xx_sysfs, attr_name); \ - __p = container_of(__s, struct bcm43xx_private, sysfs); \ - __p; \ - }) - struct bcm43xx_private; int bcm43xx_sysfs_register(struct bcm43xx_private *bcm);
Index: wireless-dev-ds/drivers/net/wireless/bcm43xx-d80211/bcm43xx_power.c =================================================================== --- wireless-dev-ds.orig/drivers/net/wireless/bcm43xx-d80211/bcm43xx_power.c 2006-04-18 16:33:23.000000000 +0200 +++ wireless-dev-ds/drivers/net/wireless/bcm43xx-d80211/bcm43xx_power.c 2006-04-18 16:38:56.000000000 +0200 @@ -35,77 +35,101 @@ #include "bcm43xx_main.h" +/* Get the Slow Clock Source */ +static int bcm43xx_pctl_get_slowclksrc(struct bcm43xx_private *bcm) +{ + u32 tmp; + int err; + + assert(bcm->current_core == &bcm->core_chipcommon); + if (bcm->current_core->rev < 6) { + if (bcm->bustype == BCM43xx_BUSTYPE_PCMCIA || + bcm->bustype == BCM43xx_BUSTYPE_SB) + return BCM43xx_PCTL_CLKSRC_XTALOS; + if (bcm->bustype == BCM43xx_BUSTYPE_PCI) { + err = bcm43xx_pci_read_config32(bcm, BCM43xx_PCTL_OUT, &tmp); + assert(!err); + if (tmp & 0x10) + return BCM43xx_PCTL_CLKSRC_PCI; + return BCM43xx_PCTL_CLKSRC_XTALOS; + } + } + if (bcm->current_core->rev < 10) { + tmp = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_SLOWCLKCTL); + tmp &= 0x7; + if (tmp == 0) + return BCM43xx_PCTL_CLKSRC_LOPWROS; + if (tmp == 1) + return BCM43xx_PCTL_CLKSRC_XTALOS; + if (tmp == 2) + return BCM43xx_PCTL_CLKSRC_PCI; + } + + return BCM43xx_PCTL_CLKSRC_XTALOS; +} + /* Get max/min slowclock frequency * as described in http://bcm-specs.sipsolutions.net/PowerControl */ static int bcm43xx_pctl_clockfreqlimit(struct bcm43xx_private *bcm, int get_max) { - int limit = 0; + int limit; + int clocksrc; int divisor; - int selection; - int err; u32 tmp; - struct bcm43xx_coreinfo *old_core; - if (!(bcm->chipcommon_capabilities & BCM43xx_CAPABILITIES_PCTL)) - goto out; - old_core = bcm->current_core; - err = bcm43xx_switch_core(bcm, &bcm->core_chipcommon); - if (err) - goto out; + assert(bcm->chipcommon_capabilities & BCM43xx_CAPABILITIES_PCTL); + assert(bcm->current_core == &bcm->core_chipcommon); + clocksrc = bcm43xx_pctl_get_slowclksrc(bcm); if (bcm->current_core->rev < 6) { - if ((bcm->bustype == BCM43xx_BUSTYPE_PCMCIA) || - (bcm->bustype == BCM43xx_BUSTYPE_SB)) { - selection = 1; + switch (clocksrc) { + case BCM43xx_PCTL_CLKSRC_PCI: + divisor = 64; + break; + case BCM43xx_PCTL_CLKSRC_XTALOS: divisor = 32; - } else { - err = bcm43xx_pci_read_config32(bcm, BCM43xx_PCTL_OUT, &tmp); - if (err) { - printk(KERN_ERR PFX "clockfreqlimit pcicfg read failure\n"); - goto out_switchback; - } - if (tmp & 0x10) { - /* PCI */ - selection = 2; - divisor = 64; - } else { - /* XTAL */ - selection = 1; - divisor = 32; - } + break; + default: + assert(0); + divisor = 1; } } else if (bcm->current_core->rev < 10) { - selection = (tmp & 0x07); - if (selection) { + switch (clocksrc) { + case BCM43xx_PCTL_CLKSRC_LOPWROS: + divisor = 1; + break; + case BCM43xx_PCTL_CLKSRC_XTALOS: + case BCM43xx_PCTL_CLKSRC_PCI: tmp = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_SLOWCLKCTL); - divisor = 4 * (1 + ((tmp & 0xFFFF0000) >> 16)); - } else + divisor = ((tmp & 0xFFFF0000) >> 16) + 1; + divisor *= 4; + break; + default: + assert(0); divisor = 1; + } } else { tmp = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_SYSCLKCTL); - divisor = 4 * (1 + ((tmp & 0xFFFF0000) >> 16)); - selection = 1; + divisor = ((tmp & 0xFFFF0000) >> 16) + 1; + divisor *= 4; } - - switch (selection) { - case 0: - /* LPO */ + + switch (clocksrc) { + case BCM43xx_PCTL_CLKSRC_LOPWROS: if (get_max) limit = 43000; else limit = 25000; break; - case 1: - /* XTAL */ + case BCM43xx_PCTL_CLKSRC_XTALOS: if (get_max) limit = 20200000; else limit = 19800000; break; - case 2: - /* PCI */ + case BCM43xx_PCTL_CLKSRC_PCI: if (get_max) limit = 34000000; else @@ -113,17 +137,14 @@ break; default: assert(0); + limit = 0; } limit /= divisor; -out_switchback: - err = bcm43xx_switch_core(bcm, old_core); - assert(err == 0); - -out: return limit; } + /* init power control * as described in http://bcm-specs.sipsolutions.net/PowerControl */ Index: wireless-dev-ds/drivers/net/wireless/bcm43xx-d80211/bcm43xx_power.h =================================================================== --- wireless-dev-ds.orig/drivers/net/wireless/bcm43xx-d80211/bcm43xx_power.h 2006-04-18 16:33:23.000000000 +0200 +++ wireless-dev-ds/drivers/net/wireless/bcm43xx-d80211/bcm43xx_power.h 2006-04-18 16:38:56.000000000 +0200 @@ -33,6 +33,15 @@ #include <linux/types.h> +/* Clock sources */ +enum { + /* PCI clock */ + BCM43xx_PCTL_CLKSRC_PCI, + /* Crystal slow clock oscillator */ + BCM43xx_PCTL_CLKSRC_XTALOS, + /* Low power oscillator */ + BCM43xx_PCTL_CLKSRC_LOPWROS, +}; struct bcm43xx_private;
Index: wireless-dev-ds/drivers/net/wireless/bcm43xx-d80211/bcm43xx_phy.c =================================================================== --- wireless-dev-ds/drivers/net/wireless/bcm43xx-d80211/bcm43xx_phy.c 2006-04-13 02:21:39.000000000 +0200 +++ wireless-dev-ds/drivers/net/wireless/bcm43xx-d80211/bcm43xx_phy.c 2006-04-13 02:23:31.000000000 +0200 @@ -2151,6 +2151,7 @@ phy->tssi2dbm = NULL; printk(KERN_ERR PFX "Could not generate " "tssi2dBm table\n"); + kfree(dyn_tssi2dbm); return -ENODEV; } phy->tssi2dbm = dyn_tssi2dbm;
pgpknZtGl48n3.pgp
Description: PGP signature