Commit 87d26327 authored by Larry Finger's avatar Larry Finger Committed by John W. Linville
Browse files

[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: default avatarMartin Langer <martin-langer@gmx.de>
Signed-off-by: default avatarLarry Finger <Larry.Finger@lwfinger.net>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 1ef4583e
Loading
Loading
Loading
Loading
+5 −4
Original line number Diff line number Diff line
@@ -311,6 +311,7 @@
#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
+59 −0
Original line number Diff line number Diff line
@@ -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);