* [PATCH 1/4] sky2: set VPD size
2008-09-04 20:56 ` [PATCH 0/4] PCI VPD changes Stephen Hemminger
@ 2008-09-04 20:56 ` Stephen Hemminger
2008-09-04 20:56 ` [PATCH 2/4] sky2: add more generic ethtool hooks Stephen Hemminger
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Stephen Hemminger @ 2008-09-04 20:56 UTC (permalink / raw)
To: Jesse Barnes, Ben Hutchings; +Cc: linux-pci, netdev
[-- Attachment #1: sky2-vpd-size.patch --]
[-- Type: text/plain, Size: 2069 bytes --]
Read configuration register during probe and use it to size the
available VPD. Move existing code using same register slightly
earlier in probe handling.
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
--- a/drivers/net/sky2.c 2008-09-04 11:27:34.000000000 -0700
+++ b/drivers/net/sky2.c 2008-09-04 11:44:49.000000000 -0700
@@ -4281,6 +4281,7 @@ static int __devinit sky2_probe(struct p
struct net_device *dev;
struct sky2_hw *hw;
int err, using_dac = 0, wol_default;
+ u32 reg;
char buf1[16];
err = pci_enable_device(pdev);
@@ -4314,6 +4315,34 @@ static int __devinit sky2_probe(struct p
}
}
+ /* Get configuration information
+ * Note: only regular PCI config access once to test for HW issues
+ * other PCI access through shared memory for speed and to
+ * avoid MMCONFIG problems.
+ */
+ err = pci_read_config_dword(pdev, PCI_DEV_REG2, ®);
+ if (err) {
+ dev_err(&pdev->dev, "PCI read config failed\n");
+ goto err_out_free_regions;
+ }
+
+ /* size of available VPD, only impact sysfs */
+ err = pci_vpd_size(pdev, 1ul << (((reg & PCI_VPD_ROM_SZ) >> 14) + 8));
+ if (err)
+ dev_warn(&pdev->dev, "Can't set VPD size\n");
+
+#ifdef __BIG_ENDIAN
+ /* The sk98lin vendor driver uses hardware byte swapping but
+ * this driver uses software swapping.
+ */
+ reg &= ~PCI_REV_DESC;
+ err = pci_write_config_dword(pdev,PCI_DEV_REG2, reg);
+ if (err) {
+ dev_err(&pdev->dev, "PCI write config failed\n");
+ goto err_out_free_regions;
+ }
+#endif
+
wol_default = pci_wake_enabled(pdev) ? WAKE_MAGIC : 0;
err = -ENOMEM;
@@ -4331,18 +4360,6 @@ static int __devinit sky2_probe(struct p
goto err_out_free_hw;
}
-#ifdef __BIG_ENDIAN
- /* The sk98lin vendor driver uses hardware byte swapping but
- * this driver uses software swapping.
- */
- {
- u32 reg;
- reg = sky2_pci_read32(hw, PCI_DEV_REG2);
- reg &= ~PCI_REV_DESC;
- sky2_pci_write32(hw, PCI_DEV_REG2, reg);
- }
-#endif
-
/* ring for status responses */
hw->st_le = pci_alloc_consistent(pdev, STATUS_LE_BYTES, &hw->st_dma);
if (!hw->st_le)
--
^ permalink raw reply [flat|nested] 5+ messages in thread* [PATCH 2/4] sky2: add more generic ethtool hooks
2008-09-04 20:56 ` [PATCH 0/4] PCI VPD changes Stephen Hemminger
2008-09-04 20:56 ` [PATCH 1/4] sky2: set VPD size Stephen Hemminger
@ 2008-09-04 20:56 ` Stephen Hemminger
2008-09-04 20:56 ` [PATCH 3/4] sky2: move VPD display into debug interface Stephen Hemminger
2008-09-04 20:56 ` [PATCH 4/4] sky2: remove VPD eeprom Stephen Hemminger
3 siblings, 0 replies; 5+ messages in thread
From: Stephen Hemminger @ 2008-09-04 20:56 UTC (permalink / raw)
To: Jesse Barnes, Ben Hutchings; +Cc: linux-pci, netdev
[-- Attachment #1: sky2-ethtool-ops.patch --]
[-- Type: text/plain, Size: 889 bytes --]
Add support for some missing status queries.
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
--- a/drivers/net/sky2.c 2008-09-04 11:48:30.000000000 -0700
+++ b/drivers/net/sky2.c 2008-09-04 11:48:31.000000000 -0700
@@ -3840,7 +3840,9 @@ static const struct ethtool_ops sky2_eth
.get_eeprom_len = sky2_get_eeprom_len,
.get_eeprom = sky2_get_eeprom,
.set_eeprom = sky2_set_eeprom,
+ .get_sg = ethtool_op_get_sg,
.set_sg = ethtool_op_set_sg,
+ .get_tx_csum = ethtool_op_get_tx_csum,
.set_tx_csum = sky2_set_tx_csum,
.set_tso = sky2_set_tso,
.get_rx_csum = sky2_get_rx_csum,
@@ -3855,6 +3857,8 @@ static const struct ethtool_ops sky2_eth
.phys_id = sky2_phys_id,
.get_sset_count = sky2_get_sset_count,
.get_ethtool_stats = sky2_get_ethtool_stats,
+ .get_flags = ethtool_op_get_flags,
+ .get_ufo = ethtool_op_get_ufo,
};
#ifdef CONFIG_SKY2_DEBUG
--
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 3/4] sky2: move VPD display into debug interface
2008-09-04 20:56 ` [PATCH 0/4] PCI VPD changes Stephen Hemminger
2008-09-04 20:56 ` [PATCH 1/4] sky2: set VPD size Stephen Hemminger
2008-09-04 20:56 ` [PATCH 2/4] sky2: add more generic ethtool hooks Stephen Hemminger
@ 2008-09-04 20:56 ` Stephen Hemminger
2008-09-04 20:56 ` [PATCH 4/4] sky2: remove VPD eeprom Stephen Hemminger
3 siblings, 0 replies; 5+ messages in thread
From: Stephen Hemminger @ 2008-09-04 20:56 UTC (permalink / raw)
To: Jesse Barnes, Ben Hutchings; +Cc: linux-pci, netdev
[-- Attachment #1: sky2-vpd-debug.patch --]
[-- Type: text/plain, Size: 4504 bytes --]
The VPD stuff has more data and isn't generally that useful, so move
it into the existing debugfs display and use the new PCI VPD
accessor routines.
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
--- a/drivers/net/sky2.c 2008-09-04 13:47:04.000000000 -0700
+++ b/drivers/net/sky2.c 2008-09-04 13:47:24.000000000 -0700
@@ -3865,6 +3865,86 @@ static const struct ethtool_ops sky2_eth
static struct dentry *sky2_debug;
+
+/*
+ * Read and parse the first part of Vital Product Data
+ */
+#define VPD_SIZE 128
+#define VPD_MAGIC 0x82
+
+static const struct vpd_tag {
+ char tag[2];
+ char *label;
+} vpd_tags[] = {
+ { "PN", "Part Number" },
+ { "EC", "Engineering Level" },
+ { "MN", "Manufacturer" },
+ { "SN", "Serial Number" },
+ { "YA", "Asset Tag" },
+ { "VL", "First Error Log Message" },
+ { "VF", "Second Error Log Message" },
+ { "VB", "Boot Agent ROM Configuration" },
+ { "VE", "EFI UNDI Configuration" },
+};
+
+static void sky2_show_vpd(struct seq_file *seq, struct sky2_hw *hw)
+{
+ size_t vpd_size;
+ loff_t offs;
+ u8 len;
+ unsigned char *buf;
+ u16 reg2;
+
+ reg2 = sky2_pci_read16(hw, PCI_DEV_REG2);
+ vpd_size = 1 << ( ((reg2 & PCI_VPD_ROM_SZ) >> 14) + 8);
+
+ seq_printf(seq, "%s Product Data\n", pci_name(hw->pdev));
+ buf = kmalloc(vpd_size, GFP_KERNEL);
+ if (!buf) {
+ seq_puts(seq, "no memory!\n");
+ return;
+ }
+
+ if (pci_read_vpd(hw->pdev, 0, vpd_size, buf) < 0) {
+ seq_puts(seq, "VPD read failed\n");
+ goto out;
+ }
+
+ if (buf[0] != VPD_MAGIC) {
+ seq_printf(seq, "VPD tag mismatch: %#x\n", buf[0]);
+ goto out;
+ }
+ len = buf[1];
+ if (len == 0 || len > vpd_size - 4) {
+ seq_printf(seq, "Invalid id length: %d\n", len);
+ goto out;
+ }
+
+ seq_printf(seq, "%.*s\n", len, buf + 3);
+ offs = len + 3;
+
+ while (offs < vpd_size - 4) {
+ int i;
+
+ if (!memcmp("RW", buf + offs, 2)) /* end marker */
+ break;
+ len = buf[offs + 2];
+ if (offs + len + 3 >= vpd_size)
+ break;
+
+ for (i = 0; i < ARRAY_SIZE(vpd_tags); i++) {
+ if (!memcmp(vpd_tags[i].tag, buf + offs, 2)) {
+ seq_printf(seq, " %s: %.*s\n",
+ vpd_tags[i].label, len, buf + offs + 3);
+ break;
+ }
+ }
+ offs += len + 3;
+ }
+out:
+ kfree(buf);
+}
+
static int sky2_debug_show(struct seq_file *seq, void *v)
{
struct net_device *dev = seq->private;
@@ -3874,14 +3954,18 @@ static int sky2_debug_show(struct seq_fi
unsigned idx, last;
int sop;
- if (!netif_running(dev))
- return -ENETDOWN;
+ sky2_show_vpd(seq, hw);
- seq_printf(seq, "IRQ src=%x mask=%x control=%x\n",
+ seq_printf(seq, "\nIRQ src=%x mask=%x control=%x\n",
sky2_read32(hw, B0_ISRC),
sky2_read32(hw, B0_IMSK),
sky2_read32(hw, B0_Y2_SP_ICR));
+ if (!netif_running(dev)) {
+ seq_printf(seq, "network not running\n");
+ return 0;
+ }
+
napi_disable(&hw->napi);
last = sky2_read16(hw, STAT_PUT_IDX);
@@ -4195,69 +4279,6 @@ static int __devinit pci_wake_enabled(st
return value & PCI_PM_CTRL_PME_ENABLE;
}
-/*
- * Read and parse the first part of Vital Product Data
- */
-#define VPD_SIZE 128
-#define VPD_MAGIC 0x82
-
-static void __devinit sky2_vpd_info(struct sky2_hw *hw)
-{
- int cap = pci_find_capability(hw->pdev, PCI_CAP_ID_VPD);
- const u8 *p;
- u8 *vpd_buf = NULL;
- u16 len;
- static struct vpd_tag {
- char tag[2];
- char *label;
- } vpd_tags[] = {
- { "PN", "Part Number" },
- { "EC", "Engineering Level" },
- { "MN", "Manufacturer" },
- };
-
- if (!cap)
- goto out;
-
- vpd_buf = kmalloc(VPD_SIZE, GFP_KERNEL);
- if (!vpd_buf)
- goto out;
-
- if (sky2_vpd_read(hw, cap, vpd_buf, 0, VPD_SIZE))
- goto out;
-
- if (vpd_buf[0] != VPD_MAGIC)
- goto out;
- len = vpd_buf[1];
- if (len == 0 || len > VPD_SIZE - 4)
- goto out;
- p = vpd_buf + 3;
- dev_info(&hw->pdev->dev, "%.*s\n", len, p);
- p += len;
-
- while (p < vpd_buf + VPD_SIZE - 4) {
- int i;
-
- if (!memcmp("RW", p, 2)) /* end marker */
- break;
-
- len = p[2];
- if (len > (p - vpd_buf) - 4)
- break;
-
- for (i = 0; i < ARRAY_SIZE(vpd_tags); i++) {
- if (!memcmp(vpd_tags[i].tag, p, 2)) {
- printk(KERN_DEBUG " %s: %.*s\n",
- vpd_tags[i].label, len, p + 3);
- break;
- }
- }
- p += len + 3;
- }
-out:
- kfree(vpd_buf);
-}
-
/* This driver supports yukon2 chipset only */
static const char *sky2_name(u8 chipid, char *buf, int sz)
{
@@ -4378,8 +4399,6 @@ static int __devinit sky2_probe(struct p
sky2_reset(hw);
- sky2_vpd_info(hw);
-
dev = sky2_init_netdev(hw, 0, using_dac, wol_default);
if (!dev) {
err = -ENOMEM;
--
^ permalink raw reply [flat|nested] 5+ messages in thread* [PATCH 4/4] sky2: remove VPD eeprom
2008-09-04 20:56 ` [PATCH 0/4] PCI VPD changes Stephen Hemminger
` (2 preceding siblings ...)
2008-09-04 20:56 ` [PATCH 3/4] sky2: move VPD display into debug interface Stephen Hemminger
@ 2008-09-04 20:56 ` Stephen Hemminger
3 siblings, 0 replies; 5+ messages in thread
From: Stephen Hemminger @ 2008-09-04 20:56 UTC (permalink / raw)
To: Jesse Barnes, Ben Hutchings; +Cc: linux-pci, netdev
[-- Attachment #1: sky2-no-eeprom.patch --]
[-- Type: text/plain, Size: 3752 bytes --]
The VPD is not really the firmware EEPROM. The real EEPROM is behind
an SPI interface, that maybe supported in later version.
Programming the VPD through the ethtool interface doesn't work
(doesn't really change firmware). Now that the interesting bits are
available through the debug interface and raw data is available through sysfs,
the old interface can go.
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
--- a/drivers/net/sky2.c 2008-09-04 11:49:12.000000000 -0700
+++ b/drivers/net/sky2.c 2008-09-04 11:49:28.000000000 -0700
@@ -75,8 +75,6 @@
#define NAPI_WEIGHT 64
#define PHY_RETRIES 1000
-#define SKY2_EEPROM_MAGIC 0x9955aabb
-
#define RING_NEXT(x,s) (((x)+1) & ((s)-1))
@@ -3722,109 +3720,6 @@ static int sky2_set_tso(struct net_devic
return ethtool_op_set_tso(dev, data);
}
-static int sky2_get_eeprom_len(struct net_device *dev)
-{
- struct sky2_port *sky2 = netdev_priv(dev);
- struct sky2_hw *hw = sky2->hw;
- u16 reg2;
-
- reg2 = sky2_pci_read16(hw, PCI_DEV_REG2);
- return 1 << ( ((reg2 & PCI_VPD_ROM_SZ) >> 14) + 8);
-}
-
-static int sky2_vpd_wait(const struct sky2_hw *hw, int cap, u16 busy)
-{
- unsigned long start = jiffies;
-
- while ( (sky2_pci_read16(hw, cap + PCI_VPD_ADDR) & PCI_VPD_ADDR_F) == busy) {
- /* Can take up to 10.6 ms for write */
- if (time_after(jiffies, start + HZ/4)) {
- dev_err(&hw->pdev->dev, PFX "VPD cycle timed out");
- return -ETIMEDOUT;
- }
- mdelay(1);
- }
-
- return 0;
-}
-
-static int sky2_vpd_read(struct sky2_hw *hw, int cap, void *data,
- u16 offset, size_t length)
-{
- int rc = 0;
-
- while (length > 0) {
- u32 val;
-
- sky2_pci_write16(hw, cap + PCI_VPD_ADDR, offset);
- rc = sky2_vpd_wait(hw, cap, 0);
- if (rc)
- break;
-
- val = sky2_pci_read32(hw, cap + PCI_VPD_DATA);
-
- memcpy(data, &val, min(sizeof(val), length));
- offset += sizeof(u32);
- data += sizeof(u32);
- length -= sizeof(u32);
- }
-
- return rc;
-}
-
-static int sky2_vpd_write(struct sky2_hw *hw, int cap, const void *data,
- u16 offset, unsigned int length)
-{
- unsigned int i;
- int rc = 0;
-
- for (i = 0; i < length; i += sizeof(u32)) {
- u32 val = *(u32 *)(data + i);
-
- sky2_pci_write32(hw, cap + PCI_VPD_DATA, val);
- sky2_pci_write32(hw, cap + PCI_VPD_ADDR, offset | PCI_VPD_ADDR_F);
-
- rc = sky2_vpd_wait(hw, cap, PCI_VPD_ADDR_F);
- if (rc)
- break;
- }
- return rc;
-}
-
-static int sky2_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
- u8 *data)
-{
- struct sky2_port *sky2 = netdev_priv(dev);
- int cap = pci_find_capability(sky2->hw->pdev, PCI_CAP_ID_VPD);
-
- if (!cap)
- return -EINVAL;
-
- eeprom->magic = SKY2_EEPROM_MAGIC;
-
- return sky2_vpd_read(sky2->hw, cap, data, eeprom->offset, eeprom->len);
-}
-
-static int sky2_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
- u8 *data)
-{
- struct sky2_port *sky2 = netdev_priv(dev);
- int cap = pci_find_capability(sky2->hw->pdev, PCI_CAP_ID_VPD);
-
- if (!cap)
- return -EINVAL;
-
- if (eeprom->magic != SKY2_EEPROM_MAGIC)
- return -EINVAL;
-
- /* Partial writes not supported */
- if ((eeprom->offset & 3) || (eeprom->len & 3))
- return -EINVAL;
-
- return sky2_vpd_write(sky2->hw, cap, data, eeprom->offset, eeprom->len);
-}
-
-
static const struct ethtool_ops sky2_ethtool_ops = {
.get_settings = sky2_get_settings,
.set_settings = sky2_set_settings,
@@ -3837,9 +3732,6 @@ static const struct ethtool_ops sky2_eth
.get_regs_len = sky2_get_regs_len,
.get_regs = sky2_get_regs,
.get_link = ethtool_op_get_link,
- .get_eeprom_len = sky2_get_eeprom_len,
- .get_eeprom = sky2_get_eeprom,
- .set_eeprom = sky2_set_eeprom,
.get_sg = ethtool_op_get_sg,
.set_sg = ethtool_op_set_sg,
.get_tx_csum = ethtool_op_get_tx_csum,
--
^ permalink raw reply [flat|nested] 5+ messages in thread