Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 55097
b: refs/heads/master
c: 1a14780
h: refs/heads/master
i:
  55095: fcbff64
v: v3
  • Loading branch information
Mark Brown authored and Jeff Garzik committed May 8, 2007
1 parent 6a8b797 commit 9ae652f
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 3 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: d0ed48640e746a5537d0e7c49d5029949b15ee88
refs/heads/master: 1a14780960888c97371a9918f42c4dbe6957efb4
68 changes: 66 additions & 2 deletions trunk/drivers/net/natsemi.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ static const int multicast_filter_limit = 100;
Setting to > 1518 effectively disables this feature. */
static int rx_copybreak;

static int dspcfg_workaround = 1;

/* Used to pass the media type, etc.
Both 'options[]' and 'full_duplex[]' should exist for driver
interoperability.
Expand Down Expand Up @@ -139,12 +141,14 @@ MODULE_LICENSE("GPL");
module_param(mtu, int, 0);
module_param(debug, int, 0);
module_param(rx_copybreak, int, 0);
module_param(dspcfg_workaround, int, 1);
module_param_array(options, int, NULL, 0);
module_param_array(full_duplex, int, NULL, 0);
MODULE_PARM_DESC(mtu, "DP8381x MTU (all boards)");
MODULE_PARM_DESC(debug, "DP8381x default debug level");
MODULE_PARM_DESC(rx_copybreak,
"DP8381x copy breakpoint for copy-only-tiny-frames");
MODULE_PARM_DESC(dspcfg_workaround, "DP8381x: control DspCfg workaround");
MODULE_PARM_DESC(options,
"DP8381x: Bits 0-3: media type, bit 17: full duplex");
MODULE_PARM_DESC(full_duplex, "DP8381x full duplex setting(s) (1)");
Expand Down Expand Up @@ -590,6 +594,7 @@ struct netdev_private {
u32 srr;
/* expected DSPCFG value */
u16 dspcfg;
int dspcfg_workaround;
/* parms saved in ethtool format */
u16 speed; /* The forced speed, 10Mb, 100Mb, gigabit */
u8 duplex; /* Duplex, half or full */
Expand Down Expand Up @@ -656,6 +661,56 @@ static int netdev_get_regs(struct net_device *dev, u8 *buf);
static int netdev_get_eeprom(struct net_device *dev, u8 *buf);
static const struct ethtool_ops ethtool_ops;

#define NATSEMI_ATTR(_name) \
static ssize_t natsemi_show_##_name(struct device *dev, \
struct device_attribute *attr, char *buf); \
static ssize_t natsemi_set_##_name(struct device *dev, \
struct device_attribute *attr, \
const char *buf, size_t count); \
static DEVICE_ATTR(_name, 0644, natsemi_show_##_name, natsemi_set_##_name)

#define NATSEMI_CREATE_FILE(_dev, _name) \
device_create_file(&_dev->dev, &dev_attr_##_name)
#define NATSEMI_REMOVE_FILE(_dev, _name) \
device_create_file(&_dev->dev, &dev_attr_##_name)

NATSEMI_ATTR(dspcfg_workaround);

static ssize_t natsemi_show_dspcfg_workaround(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct netdev_private *np = netdev_priv(to_net_dev(dev));

return sprintf(buf, "%s\n", np->dspcfg_workaround ? "on" : "off");
}

static ssize_t natsemi_set_dspcfg_workaround(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct netdev_private *np = netdev_priv(to_net_dev(dev));
int new_setting;
u32 flags;

/* Find out the new setting */
if (!strncmp("on", buf, count - 1) || !strncmp("1", buf, count - 1))
new_setting = 1;
else if (!strncmp("off", buf, count - 1)
|| !strncmp("0", buf, count - 1))
new_setting = 0;
else
return count;

spin_lock_irqsave(&np->lock, flags);

np->dspcfg_workaround = new_setting;

spin_unlock_irqrestore(&np->lock, flags);

return count;
}

static inline void __iomem *ns_ioaddr(struct net_device *dev)
{
return (void __iomem *) dev->base_addr;
Expand Down Expand Up @@ -820,6 +875,7 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev,
np->ignore_phy = 1;
else
np->ignore_phy = 0;
np->dspcfg_workaround = dspcfg_workaround;

/* Initial port:
* - If configured to ignore the PHY set up for external.
Expand Down Expand Up @@ -899,6 +955,9 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev,
if (i)
goto err_register_netdev;

if (NATSEMI_CREATE_FILE(pdev, dspcfg_workaround))
goto err_create_file;

if (netif_msg_drv(np)) {
printk(KERN_INFO "natsemi %s: %s at %#08lx (%s), ",
dev->name, natsemi_pci_info[chip_idx].name, iostart,
Expand All @@ -915,6 +974,9 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev,
}
return 0;

err_create_file:
unregister_netdev(dev);

err_register_netdev:
iounmap(ioaddr);

Expand Down Expand Up @@ -1727,7 +1789,8 @@ static void init_registers(struct net_device *dev)
* It seems that a reference set for this chip went out with incorrect info,
* and there exist boards that aren't quite right. An unexpected voltage
* drop can cause the PHY to get itself in a weird state (basically reset).
* NOTE: this only seems to affect revC chips.
* NOTE: this only seems to affect revC chips. The user can disable
* this check via dspcfg_workaround sysfs option.
* 3) check of death of the RX path due to OOM
*/
static void netdev_timer(unsigned long data)
Expand All @@ -1753,7 +1816,7 @@ static void netdev_timer(unsigned long data)
writew(1, ioaddr+PGSEL);
dspcfg = readw(ioaddr+DSPCFG);
writew(0, ioaddr+PGSEL);
if (dspcfg != np->dspcfg) {
if (np->dspcfg_workaround && dspcfg != np->dspcfg) {
if (!netif_queue_stopped(dev)) {
spin_unlock_irq(&np->lock);
if (netif_msg_drv(np))
Expand Down Expand Up @@ -3157,6 +3220,7 @@ static void __devexit natsemi_remove1 (struct pci_dev *pdev)
struct net_device *dev = pci_get_drvdata(pdev);
void __iomem * ioaddr = ns_ioaddr(dev);

NATSEMI_REMOVE_FILE(pdev, dspcfg_workaround);
unregister_netdev (dev);
pci_release_regions (pdev);
iounmap(ioaddr);
Expand Down

0 comments on commit 9ae652f

Please sign in to comment.