This patch exports the hardware rfkill bits to sysfs, as Joe Jezak suggested. I tested it on my bcm4318, but it seems that those bits can't be set, so this shouldn't solve any issue with radio buttons. Please tell me if it gives different behaviour on laptops with a radio button switch.
Signed-off-by: Stefano Brivio <[EMAIL PROTECTED]> Index: wireless-dev/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c =================================================================== --- wireless-dev.orig/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c +++ wireless-dev/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c @@ -305,6 +305,83 @@ static DEVICE_ATTR(shortpreamble, 0644, bcm43xx_attr_preamble_show, bcm43xx_attr_preamble_store); +static ssize_t bcm43xx_attr_rfkill_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct bcm43xx_private *bcm = dev_to_bcm(dev); + unsigned long flags; + ssize_t count; + + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + + bcm43xx_lock_mmio(bcm, flags); + assert(bcm->initialized); + + if (bcm->core_80211[0].rev >= 3) { + if (bcm43xx_read32(bcm, 0x0158) & (1 << 16)) + count = snprintf(buf, PAGE_SIZE, "1 (Radio disabled by hardware)\n"); + else + count = snprintf(buf, PAGE_SIZE, "0 (Radio not disabled by hardware)\n"); + } else { + if (bcm43xx_read16(bcm, 0x049A) & (1 << 4)) + count = snprintf(buf, PAGE_SIZE, "0 (Radio not disabled by hardware)\n"); + else + count = snprintf(buf, PAGE_SIZE, "1 (Radio disabled by hardware)\n"); + } + + bcm43xx_unlock_mmio(bcm, flags); + + return count; +} + +static ssize_t bcm43xx_attr_rfkill_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct bcm43xx_private *bcm = dev_to_bcm(dev); + unsigned long flags; + int value; + + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + + value = get_boolean(buf, count); + if (value < 0) + return value; + bcm43xx_lock_mmio(bcm, flags); + assert(bcm->initialized); + + if (value) { + if (bcm->core_80211[0].rev >= 3) + bcm43xx_write32(bcm, BCM43xx_MMIO_RADIO_HWENABLED_HI, + bcm43xx_read32(bcm, BCM43xx_MMIO_RADIO_HWENABLED_HI) + | (1 << 16)); + else + bcm43xx_write16(bcm, BCM43xx_MMIO_RADIO_HWENABLED_LO, + bcm43xx_read16(bcm, BCM43xx_MMIO_RADIO_HWENABLED_LO) + & ~(1 << 4)); + } else { + if (bcm->core_80211[0].rev >= 3) + bcm43xx_write32(bcm, BCM43xx_MMIO_RADIO_HWENABLED_HI, + bcm43xx_read32(bcm, BCM43xx_MMIO_RADIO_HWENABLED_HI) + & ~(1 << 16)); + else + bcm43xx_write16(bcm, BCM43xx_MMIO_RADIO_HWENABLED_LO, + bcm43xx_read16(bcm, BCM43xx_MMIO_RADIO_HWENABLED_LO) + | (1 << 4)); + } + + bcm43xx_unlock_mmio(bcm, flags); + + return count; +} + +static DEVICE_ATTR(rfkill, 0644, + bcm43xx_attr_rfkill_show, + bcm43xx_attr_rfkill_store); + int bcm43xx_sysfs_register(struct bcm43xx_private *bcm) { struct device *dev = &bcm->pci_dev->dev; @@ -321,9 +398,14 @@ int bcm43xx_sysfs_register(struct bcm43x err = device_create_file(dev, &dev_attr_shortpreamble); if (err) goto err_remove_interfmode; + err = device_create_file(dev, &dev_attr_rfkill); + if (err) + goto err_remove_shortpreamble; out: return err; +err_remove_shortpreamble: + device_remove_file(dev, &dev_attr_shortpreamble); err_remove_interfmode: device_remove_file(dev, &dev_attr_interference); err_remove_sprom: @@ -335,6 +417,7 @@ void bcm43xx_sysfs_unregister(struct bcm { struct device *dev = &bcm->pci_dev->dev; + device_remove_file(dev, &dev_attr_rfkill); device_remove_file(dev, &dev_attr_shortpreamble); device_remove_file(dev, &dev_attr_interference); device_remove_file(dev, &dev_attr_sprom); -- Ciao Stefano _______________________________________________ Bcm43xx-dev mailing list Bcm43xx-dev@lists.berlios.de http://lists.berlios.de/mailman/listinfo/bcm43xx-dev