X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fnet%2Fwireless%2Fbcm43xx%2Fbcm43xx_sysfs.c;h=c71b998a3694a2ed26b6d46ae5bb98f4c1c40ef4;hb=97bf2856c6014879bd04983a3e9dfcdac1e7fe85;hp=f41d9e7d099171313be91076f3e8451bc8e9fed5;hpb=76828883507a47dae78837ab5dec5a5b4513c667;p=linux-2.6.git diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c b/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c index f41d9e7d0..c71b998a3 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c @@ -303,6 +303,126 @@ static DEVICE_ATTR(shortpreamble, 0644, bcm43xx_attr_preamble_show, bcm43xx_attr_preamble_store); +static ssize_t bcm43xx_attr_phymode_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct bcm43xx_private *bcm = dev_to_bcm(dev); + int phytype; + int err = -EINVAL; + + if (count < 1) + goto out; + switch (buf[0]) { + case 'a': case 'A': + phytype = BCM43xx_PHYTYPE_A; + break; + case 'b': case 'B': + phytype = BCM43xx_PHYTYPE_B; + break; + case 'g': case 'G': + phytype = BCM43xx_PHYTYPE_G; + break; + default: + 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; + +out: + return err ? err : count; +} + +static ssize_t bcm43xx_attr_phymode_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct bcm43xx_private *bcm = dev_to_bcm(dev); + ssize_t count = 0; + + mutex_lock(&(bcm)->mutex); + switch (bcm43xx_current_phy(bcm)->type) { + case BCM43xx_PHYTYPE_A: + snprintf(buf, PAGE_SIZE, "A"); + break; + case BCM43xx_PHYTYPE_B: + snprintf(buf, PAGE_SIZE, "B"); + break; + case BCM43xx_PHYTYPE_G: + snprintf(buf, PAGE_SIZE, "G"); + break; + default: + assert(0); + } + mutex_unlock(&(bcm)->mutex); + + return count; +} + +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; @@ -319,9 +439,19 @@ int bcm43xx_sysfs_register(struct bcm43xx_private *bcm) err = device_create_file(dev, &dev_attr_shortpreamble); if (err) goto err_remove_interfmode; + 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: device_remove_file(dev, &dev_attr_interference); err_remove_sprom: @@ -333,6 +463,8 @@ 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); device_remove_file(dev, &dev_attr_sprom);