Contents of /trunk/kernel26-alx/patches-2.6.21-r14/0302-2.6.21-natsemi-wyse-hack.patch
Parent Directory | Revision Log
Revision 447 -
(show annotations)
(download)
Tue Jan 22 17:55:52 2008 UTC (16 years, 8 months ago) by niro
File size: 5811 byte(s)
Tue Jan 22 17:55:52 2008 UTC (16 years, 8 months ago) by niro
File size: 5811 byte(s)
-2.6.21-alx-r14 - fixed some natsemi errors on wys terminals
1 | Date Wed, 2 May 2007 22:41:29 +0100 |
2 | From Mark Brown <> |
3 | Subject Re: Natsemi DP83815 driver spaming |
4 | |
5 | |
6 | On Wed, May 02, 2007 at 10:05:31PM +0200, Rafal Bilski wrote: |
7 | |
8 | > What about module option? |
9 | |
10 | That would work, though you crossed in the post with me writing a patch |
11 | adding a sysfs file; I merged the two for overkill (below). I also have |
12 | a patch which changes the log message for the workaround so that it is |
13 | displayed by default in order to make this easier to diagnose. |
14 | |
15 | diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c |
16 | index 109e802..b9f3ab3 100644 |
17 | --- a/drivers/net/natsemi.c |
18 | +++ b/drivers/net/natsemi.c |
19 | @@ -81,6 +81,8 @@ static const int multicast_filter_limit = 100; |
20 | Setting to > 1518 effectively disables this feature. */ |
21 | static int rx_copybreak; |
22 | |
23 | +static int dspcfg_workaround = 1; |
24 | + |
25 | /* Used to pass the media type, etc. |
26 | Both 'options[]' and 'full_duplex[]' should exist for driver |
27 | interoperability. |
28 | @@ -139,12 +141,14 @@ MODULE_LICENSE("GPL"); |
29 | module_param(mtu, int, 0); |
30 | module_param(debug, int, 0); |
31 | module_param(rx_copybreak, int, 0); |
32 | +module_param(dspcfg_workaround, int, 1); |
33 | module_param_array(options, int, NULL, 0); |
34 | module_param_array(full_duplex, int, NULL, 0); |
35 | MODULE_PARM_DESC(mtu, "DP8381x MTU (all boards)"); |
36 | MODULE_PARM_DESC(debug, "DP8381x default debug level"); |
37 | MODULE_PARM_DESC(rx_copybreak, |
38 | "DP8381x copy breakpoint for copy-only-tiny-frames"); |
39 | +MODULE_PARM_DESC(dspcfg_workaround, "DP8381x: control DspCfg workaround"); |
40 | MODULE_PARM_DESC(options, |
41 | "DP8381x: Bits 0-3: media type, bit 17: full duplex"); |
42 | MODULE_PARM_DESC(full_duplex, "DP8381x full duplex setting(s) (1)"); |
43 | @@ -590,6 +594,7 @@ struct netdev_private { |
44 | u32 srr; |
45 | /* expected DSPCFG value */ |
46 | u16 dspcfg; |
47 | + int dspcfg_workaround; |
48 | /* parms saved in ethtool format */ |
49 | u16 speed; /* The forced speed, 10Mb, 100Mb, gigabit */ |
50 | u8 duplex; /* Duplex, half or full */ |
51 | @@ -656,6 +661,56 @@ static int netdev_get_regs(struct net_device *dev, u8 *buf); |
52 | static int netdev_get_eeprom(struct net_device *dev, u8 *buf); |
53 | static const struct ethtool_ops ethtool_ops; |
54 | |
55 | +#define NATSEMI_ATTR(_name) \ |
56 | +static ssize_t natsemi_show_##_name(struct device *dev, \ |
57 | + struct device_attribute *attr, char *buf); \ |
58 | + static ssize_t natsemi_set_##_name(struct device *dev, \ |
59 | + struct device_attribute *attr, \ |
60 | + const char *buf, size_t count); \ |
61 | + static DEVICE_ATTR(_name, 0644, natsemi_show_##_name, natsemi_set_##_name) |
62 | + |
63 | +#define NATSEMI_CREATE_FILE(_dev, _name) \ |
64 | + device_create_file(&_dev->dev, &dev_attr_##_name) |
65 | +#define NATSEMI_REMOVE_FILE(_dev, _name) \ |
66 | + device_create_file(&_dev->dev, &dev_attr_##_name) |
67 | + |
68 | +NATSEMI_ATTR(dspcfg_workaround); |
69 | + |
70 | +static ssize_t natsemi_show_dspcfg_workaround(struct device *dev, |
71 | + struct device_attribute *attr, |
72 | + char *buf) |
73 | +{ |
74 | + struct netdev_private *np = netdev_priv(to_net_dev(dev)); |
75 | + |
76 | + return sprintf(buf, "%s\n", np->dspcfg_workaround ? "on" : "off"); |
77 | +} |
78 | + |
79 | +static ssize_t natsemi_set_dspcfg_workaround(struct device *dev, |
80 | + struct device_attribute *attr, |
81 | + const char *buf, size_t count) |
82 | +{ |
83 | + struct netdev_private *np = netdev_priv(to_net_dev(dev)); |
84 | + int new_setting; |
85 | + u32 flags; |
86 | + |
87 | + /* Find out the new setting */ |
88 | + if (!strncmp("on", buf, count - 1) || !strncmp("1", buf, count - 1)) |
89 | + new_setting = 1; |
90 | + else if (!strncmp("off", buf, count - 1) |
91 | + || !strncmp("0", buf, count - 1)) |
92 | + new_setting = 0; |
93 | + else |
94 | + return count; |
95 | + |
96 | + spin_lock_irqsave(&np->lock, flags); |
97 | + |
98 | + np->dspcfg_workaround = new_setting; |
99 | + |
100 | + spin_unlock_irqrestore(&np->lock, flags); |
101 | + |
102 | + return count; |
103 | +} |
104 | + |
105 | static inline void __iomem *ns_ioaddr(struct net_device *dev) |
106 | { |
107 | return (void __iomem *) dev->base_addr; |
108 | @@ -820,6 +875,7 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev, |
109 | np->ignore_phy = 1; |
110 | else |
111 | np->ignore_phy = 0; |
112 | + np->dspcfg_workaround = dspcfg_workaround; |
113 | |
114 | /* Initial port: |
115 | * - If configured to ignore the PHY set up for external. |
116 | @@ -899,6 +955,9 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev, |
117 | if (i) |
118 | goto err_register_netdev; |
119 | |
120 | + if (!NATSEMI_CREATE_FILE(pdev, dspcfg_workaround)) |
121 | + goto err_create_file; |
122 | + |
123 | if (netif_msg_drv(np)) { |
124 | printk(KERN_INFO "natsemi %s: %s at %#08lx (%s), ", |
125 | dev->name, natsemi_pci_info[chip_idx].name, iostart, |
126 | @@ -915,6 +974,9 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev, |
127 | } |
128 | return 0; |
129 | |
130 | + err_create_file: |
131 | + unregister_netdev(dev); |
132 | + |
133 | err_register_netdev: |
134 | iounmap(ioaddr); |
135 | |
136 | @@ -1727,7 +1789,8 @@ static void init_registers(struct net_device *dev) |
137 | * It seems that a reference set for this chip went out with incorrect info, |
138 | * and there exist boards that aren't quite right. An unexpected voltage |
139 | * drop can cause the PHY to get itself in a weird state (basically reset). |
140 | - * NOTE: this only seems to affect revC chips. |
141 | + * NOTE: this only seems to affect revC chips. The user can disable |
142 | + * this check via dspcfg_workaround sysfs option. |
143 | * 3) check of death of the RX path due to OOM |
144 | */ |
145 | static void netdev_timer(unsigned long data) |
146 | @@ -1753,7 +1816,7 @@ static void netdev_timer(unsigned long data) |
147 | writew(1, ioaddr+PGSEL); |
148 | dspcfg = readw(ioaddr+DSPCFG); |
149 | writew(0, ioaddr+PGSEL); |
150 | - if (dspcfg != np->dspcfg) { |
151 | + if (np->dspcfg_workaround && dspcfg != np->dspcfg) { |
152 | if (!netif_queue_stopped(dev)) { |
153 | spin_unlock_irq(&np->lock); |
154 | if (netif_msg_hw(np)) |
155 | @@ -3157,6 +3220,7 @@ static void __devexit natsemi_remove1 (struct pci_dev *pdev) |
156 | struct net_device *dev = pci_get_drvdata(pdev); |
157 | void __iomem * ioaddr = ns_ioaddr(dev); |
158 | |
159 | + NATSEMI_REMOVE_FILE(pdev, dspcfg_workaround); |
160 | unregister_netdev (dev); |
161 | pci_release_regions (pdev); |
162 | iounmap(ioaddr); |