aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/natsemi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/natsemi.c')
-rw-r--r--drivers/net/natsemi.c192
1 files changed, 141 insertions, 51 deletions
diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c
index 9d6d2548c2d3..8d4999837b65 100644
--- a/drivers/net/natsemi.c
+++ b/drivers/net/natsemi.c
@@ -3,6 +3,7 @@
3 Written/copyright 1999-2001 by Donald Becker. 3 Written/copyright 1999-2001 by Donald Becker.
4 Portions copyright (c) 2001,2002 Sun Microsystems (thockin@sun.com) 4 Portions copyright (c) 2001,2002 Sun Microsystems (thockin@sun.com)
5 Portions copyright 2001,2002 Manfred Spraul (manfred@colorfullife.com) 5 Portions copyright 2001,2002 Manfred Spraul (manfred@colorfullife.com)
6 Portions copyright 2004 Harald Welte <laforge@gnumonks.org>
6 7
7 This software may be used and distributed according to the terms of 8 This software may be used and distributed according to the terms of
8 the GNU General Public License (GPL), incorporated herein by reference. 9 the GNU General Public License (GPL), incorporated herein by reference.
@@ -135,8 +136,6 @@
135 136
136 TODO: 137 TODO:
137 * big endian support with CFG:BEM instead of cpu_to_le32 138 * big endian support with CFG:BEM instead of cpu_to_le32
138 * support for an external PHY
139 * NAPI
140*/ 139*/
141 140
142#include <linux/config.h> 141#include <linux/config.h>
@@ -160,6 +159,7 @@
160#include <linux/mii.h> 159#include <linux/mii.h>
161#include <linux/crc32.h> 160#include <linux/crc32.h>
162#include <linux/bitops.h> 161#include <linux/bitops.h>
162#include <linux/prefetch.h>
163#include <asm/processor.h> /* Processor type for cache alignment. */ 163#include <asm/processor.h> /* Processor type for cache alignment. */
164#include <asm/io.h> 164#include <asm/io.h>
165#include <asm/irq.h> 165#include <asm/irq.h>
@@ -183,13 +183,11 @@
183 NETIF_MSG_TX_ERR) 183 NETIF_MSG_TX_ERR)
184static int debug = -1; 184static int debug = -1;
185 185
186/* Maximum events (Rx packets, etc.) to handle at each interrupt. */
187static int max_interrupt_work = 20;
188static int mtu; 186static int mtu;
189 187
190/* Maximum number of multicast addresses to filter (vs. rx-all-multicast). 188/* Maximum number of multicast addresses to filter (vs. rx-all-multicast).
191 This chip uses a 512 element hash table based on the Ethernet CRC. */ 189 This chip uses a 512 element hash table based on the Ethernet CRC. */
192static int multicast_filter_limit = 100; 190static const int multicast_filter_limit = 100;
193 191
194/* Set the copy breakpoint for the copy-only-tiny-frames scheme. 192/* Set the copy breakpoint for the copy-only-tiny-frames scheme.
195 Setting to > 1518 effectively disables this feature. */ 193 Setting to > 1518 effectively disables this feature. */
@@ -251,14 +249,11 @@ MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
251MODULE_DESCRIPTION("National Semiconductor DP8381x series PCI Ethernet driver"); 249MODULE_DESCRIPTION("National Semiconductor DP8381x series PCI Ethernet driver");
252MODULE_LICENSE("GPL"); 250MODULE_LICENSE("GPL");
253 251
254module_param(max_interrupt_work, int, 0);
255module_param(mtu, int, 0); 252module_param(mtu, int, 0);
256module_param(debug, int, 0); 253module_param(debug, int, 0);
257module_param(rx_copybreak, int, 0); 254module_param(rx_copybreak, int, 0);
258module_param_array(options, int, NULL, 0); 255module_param_array(options, int, NULL, 0);
259module_param_array(full_duplex, int, NULL, 0); 256module_param_array(full_duplex, int, NULL, 0);
260MODULE_PARM_DESC(max_interrupt_work,
261 "DP8381x maximum events handled per interrupt");
262MODULE_PARM_DESC(mtu, "DP8381x MTU (all boards)"); 257MODULE_PARM_DESC(mtu, "DP8381x MTU (all boards)");
263MODULE_PARM_DESC(debug, "DP8381x default debug level"); 258MODULE_PARM_DESC(debug, "DP8381x default debug level");
264MODULE_PARM_DESC(rx_copybreak, 259MODULE_PARM_DESC(rx_copybreak,
@@ -374,7 +369,7 @@ enum pcistuff {
374 369
375 370
376/* array of board data directly indexed by pci_tbl[x].driver_data */ 371/* array of board data directly indexed by pci_tbl[x].driver_data */
377static struct { 372static const struct {
378 const char *name; 373 const char *name;
379 unsigned long flags; 374 unsigned long flags;
380} natsemi_pci_info[] __devinitdata = { 375} natsemi_pci_info[] __devinitdata = {
@@ -691,6 +686,8 @@ struct netdev_private {
691 /* Based on MTU+slack. */ 686 /* Based on MTU+slack. */
692 unsigned int rx_buf_sz; 687 unsigned int rx_buf_sz;
693 int oom; 688 int oom;
689 /* Interrupt status */
690 u32 intr_status;
694 /* Do not touch the nic registers */ 691 /* Do not touch the nic registers */
695 int hands_off; 692 int hands_off;
696 /* external phy that is used: only valid if dev->if_port != PORT_TP */ 693 /* external phy that is used: only valid if dev->if_port != PORT_TP */
@@ -748,7 +745,8 @@ static void init_registers(struct net_device *dev);
748static int start_tx(struct sk_buff *skb, struct net_device *dev); 745static int start_tx(struct sk_buff *skb, struct net_device *dev);
749static irqreturn_t intr_handler(int irq, void *dev_instance, struct pt_regs *regs); 746static irqreturn_t intr_handler(int irq, void *dev_instance, struct pt_regs *regs);
750static void netdev_error(struct net_device *dev, int intr_status); 747static void netdev_error(struct net_device *dev, int intr_status);
751static void netdev_rx(struct net_device *dev); 748static int natsemi_poll(struct net_device *dev, int *budget);
749static void netdev_rx(struct net_device *dev, int *work_done, int work_to_do);
752static void netdev_tx_done(struct net_device *dev); 750static void netdev_tx_done(struct net_device *dev);
753static int natsemi_change_mtu(struct net_device *dev, int new_mtu); 751static int natsemi_change_mtu(struct net_device *dev, int new_mtu);
754#ifdef CONFIG_NET_POLL_CONTROLLER 752#ifdef CONFIG_NET_POLL_CONTROLLER
@@ -776,6 +774,18 @@ static inline void __iomem *ns_ioaddr(struct net_device *dev)
776 return (void __iomem *) dev->base_addr; 774 return (void __iomem *) dev->base_addr;
777} 775}
778 776
777static inline void natsemi_irq_enable(struct net_device *dev)
778{
779 writel(1, ns_ioaddr(dev) + IntrEnable);
780 readl(ns_ioaddr(dev) + IntrEnable);
781}
782
783static inline void natsemi_irq_disable(struct net_device *dev)
784{
785 writel(0, ns_ioaddr(dev) + IntrEnable);
786 readl(ns_ioaddr(dev) + IntrEnable);
787}
788
779static void move_int_phy(struct net_device *dev, int addr) 789static void move_int_phy(struct net_device *dev, int addr)
780{ 790{
781 struct netdev_private *np = netdev_priv(dev); 791 struct netdev_private *np = netdev_priv(dev);
@@ -879,6 +889,7 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev,
879 spin_lock_init(&np->lock); 889 spin_lock_init(&np->lock);
880 np->msg_enable = (debug >= 0) ? (1<<debug)-1 : NATSEMI_DEF_MSG; 890 np->msg_enable = (debug >= 0) ? (1<<debug)-1 : NATSEMI_DEF_MSG;
881 np->hands_off = 0; 891 np->hands_off = 0;
892 np->intr_status = 0;
882 893
883 /* Initial port: 894 /* Initial port:
884 * - If the nic was configured to use an external phy and if find_mii 895 * - If the nic was configured to use an external phy and if find_mii
@@ -932,6 +943,9 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev,
932 dev->do_ioctl = &netdev_ioctl; 943 dev->do_ioctl = &netdev_ioctl;
933 dev->tx_timeout = &tx_timeout; 944 dev->tx_timeout = &tx_timeout;
934 dev->watchdog_timeo = TX_TIMEOUT; 945 dev->watchdog_timeo = TX_TIMEOUT;
946 dev->poll = natsemi_poll;
947 dev->weight = 64;
948
935#ifdef CONFIG_NET_POLL_CONTROLLER 949#ifdef CONFIG_NET_POLL_CONTROLLER
936 dev->poll_controller = &natsemi_poll_controller; 950 dev->poll_controller = &natsemi_poll_controller;
937#endif 951#endif
@@ -1484,6 +1498,31 @@ static void natsemi_reset(struct net_device *dev)
1484 writel(rfcr, ioaddr + RxFilterAddr); 1498 writel(rfcr, ioaddr + RxFilterAddr);
1485} 1499}
1486 1500
1501static void reset_rx(struct net_device *dev)
1502{
1503 int i;
1504 struct netdev_private *np = netdev_priv(dev);
1505 void __iomem *ioaddr = ns_ioaddr(dev);
1506
1507 np->intr_status &= ~RxResetDone;
1508
1509 writel(RxReset, ioaddr + ChipCmd);
1510
1511 for (i=0;i<NATSEMI_HW_TIMEOUT;i++) {
1512 np->intr_status |= readl(ioaddr + IntrStatus);
1513 if (np->intr_status & RxResetDone)
1514 break;
1515 udelay(15);
1516 }
1517 if (i==NATSEMI_HW_TIMEOUT) {
1518 printk(KERN_WARNING "%s: RX reset did not complete in %d usec.\n",
1519 dev->name, i*15);
1520 } else if (netif_msg_hw(np)) {
1521 printk(KERN_WARNING "%s: RX reset took %d usec.\n",
1522 dev->name, i*15);
1523 }
1524}
1525
1487static void natsemi_reload_eeprom(struct net_device *dev) 1526static void natsemi_reload_eeprom(struct net_device *dev)
1488{ 1527{
1489 struct netdev_private *np = netdev_priv(dev); 1528 struct netdev_private *np = netdev_priv(dev);
@@ -2158,68 +2197,92 @@ static void netdev_tx_done(struct net_device *dev)
2158 } 2197 }
2159} 2198}
2160 2199
2161/* The interrupt handler does all of the Rx thread work and cleans up 2200/* The interrupt handler doesn't actually handle interrupts itself, it
2162 after the Tx thread. */ 2201 * schedules a NAPI poll if there is anything to do. */
2163static irqreturn_t intr_handler(int irq, void *dev_instance, struct pt_regs *rgs) 2202static irqreturn_t intr_handler(int irq, void *dev_instance, struct pt_regs *rgs)
2164{ 2203{
2165 struct net_device *dev = dev_instance; 2204 struct net_device *dev = dev_instance;
2166 struct netdev_private *np = netdev_priv(dev); 2205 struct netdev_private *np = netdev_priv(dev);
2167 void __iomem * ioaddr = ns_ioaddr(dev); 2206 void __iomem * ioaddr = ns_ioaddr(dev);
2168 int boguscnt = max_interrupt_work;
2169 unsigned int handled = 0;
2170 2207
2171 if (np->hands_off) 2208 if (np->hands_off)
2172 return IRQ_NONE; 2209 return IRQ_NONE;
2173 do { 2210
2174 /* Reading automatically acknowledges all int sources. */ 2211 /* Reading automatically acknowledges. */
2175 u32 intr_status = readl(ioaddr + IntrStatus); 2212 np->intr_status = readl(ioaddr + IntrStatus);
2176 2213
2177 if (netif_msg_intr(np)) 2214 if (netif_msg_intr(np))
2178 printk(KERN_DEBUG 2215 printk(KERN_DEBUG
2179 "%s: Interrupt, status %#08x, mask %#08x.\n", 2216 "%s: Interrupt, status %#08x, mask %#08x.\n",
2180 dev->name, intr_status, 2217 dev->name, np->intr_status,
2181 readl(ioaddr + IntrMask)); 2218 readl(ioaddr + IntrMask));
2182 2219
2183 if (intr_status == 0) 2220 if (!np->intr_status)
2184 break; 2221 return IRQ_NONE;
2185 handled = 1;
2186 2222
2187 if (intr_status & 2223 prefetch(&np->rx_skbuff[np->cur_rx % RX_RING_SIZE]);
2188 (IntrRxDone | IntrRxIntr | RxStatusFIFOOver |
2189 IntrRxErr | IntrRxOverrun)) {
2190 netdev_rx(dev);
2191 }
2192 2224
2193 if (intr_status & 2225 if (netif_rx_schedule_prep(dev)) {
2194 (IntrTxDone | IntrTxIntr | IntrTxIdle | IntrTxErr)) { 2226 /* Disable interrupts and register for poll */
2227 natsemi_irq_disable(dev);
2228 __netif_rx_schedule(dev);
2229 }
2230 return IRQ_HANDLED;
2231}
2232
2233/* This is the NAPI poll routine. As well as the standard RX handling
2234 * it also handles all other interrupts that the chip might raise.
2235 */
2236static int natsemi_poll(struct net_device *dev, int *budget)
2237{
2238 struct netdev_private *np = netdev_priv(dev);
2239 void __iomem * ioaddr = ns_ioaddr(dev);
2240
2241 int work_to_do = min(*budget, dev->quota);
2242 int work_done = 0;
2243
2244 do {
2245 if (np->intr_status &
2246 (IntrTxDone | IntrTxIntr | IntrTxIdle | IntrTxErr)) {
2195 spin_lock(&np->lock); 2247 spin_lock(&np->lock);
2196 netdev_tx_done(dev); 2248 netdev_tx_done(dev);
2197 spin_unlock(&np->lock); 2249 spin_unlock(&np->lock);
2198 } 2250 }
2199 2251
2200 /* Abnormal error summary/uncommon events handlers. */ 2252 /* Abnormal error summary/uncommon events handlers. */
2201 if (intr_status & IntrAbnormalSummary) 2253 if (np->intr_status & IntrAbnormalSummary)
2202 netdev_error(dev, intr_status); 2254 netdev_error(dev, np->intr_status);
2203 2255
2204 if (--boguscnt < 0) { 2256 if (np->intr_status &
2205 if (netif_msg_intr(np)) 2257 (IntrRxDone | IntrRxIntr | RxStatusFIFOOver |
2206 printk(KERN_WARNING 2258 IntrRxErr | IntrRxOverrun)) {
2207 "%s: Too much work at interrupt, " 2259 netdev_rx(dev, &work_done, work_to_do);
2208 "status=%#08x.\n",
2209 dev->name, intr_status);
2210 break;
2211 } 2260 }
2212 } while (1); 2261
2262 *budget -= work_done;
2263 dev->quota -= work_done;
2213 2264
2214 if (netif_msg_intr(np)) 2265 if (work_done >= work_to_do)
2215 printk(KERN_DEBUG "%s: exiting interrupt.\n", dev->name); 2266 return 1;
2267
2268 np->intr_status = readl(ioaddr + IntrStatus);
2269 } while (np->intr_status);
2270
2271 netif_rx_complete(dev);
2216 2272
2217 return IRQ_RETVAL(handled); 2273 /* Reenable interrupts providing nothing is trying to shut
2274 * the chip down. */
2275 spin_lock(&np->lock);
2276 if (!np->hands_off && netif_running(dev))
2277 natsemi_irq_enable(dev);
2278 spin_unlock(&np->lock);
2279
2280 return 0;
2218} 2281}
2219 2282
2220/* This routine is logically part of the interrupt handler, but separated 2283/* This routine is logically part of the interrupt handler, but separated
2221 for clarity and better register allocation. */ 2284 for clarity and better register allocation. */
2222static void netdev_rx(struct net_device *dev) 2285static void netdev_rx(struct net_device *dev, int *work_done, int work_to_do)
2223{ 2286{
2224 struct netdev_private *np = netdev_priv(dev); 2287 struct netdev_private *np = netdev_priv(dev);
2225 int entry = np->cur_rx % RX_RING_SIZE; 2288 int entry = np->cur_rx % RX_RING_SIZE;
@@ -2237,6 +2300,12 @@ static void netdev_rx(struct net_device *dev)
2237 entry, desc_status); 2300 entry, desc_status);
2238 if (--boguscnt < 0) 2301 if (--boguscnt < 0)
2239 break; 2302 break;
2303
2304 if (*work_done >= work_to_do)
2305 break;
2306
2307 (*work_done)++;
2308
2240 pkt_len = (desc_status & DescSizeMask) - 4; 2309 pkt_len = (desc_status & DescSizeMask) - 4;
2241 if ((desc_status&(DescMore|DescPktOK|DescRxLong)) != DescPktOK){ 2310 if ((desc_status&(DescMore|DescPktOK|DescRxLong)) != DescPktOK){
2242 if (desc_status & DescMore) { 2311 if (desc_status & DescMore) {
@@ -2248,6 +2317,23 @@ static void netdev_rx(struct net_device *dev)
2248 "status %#08x.\n", dev->name, 2317 "status %#08x.\n", dev->name,
2249 np->cur_rx, desc_status); 2318 np->cur_rx, desc_status);
2250 np->stats.rx_length_errors++; 2319 np->stats.rx_length_errors++;
2320
2321 /* The RX state machine has probably
2322 * locked up beneath us. Follow the
2323 * reset procedure documented in
2324 * AN-1287. */
2325
2326 spin_lock_irq(&np->lock);
2327 reset_rx(dev);
2328 reinit_rx(dev);
2329 writel(np->ring_dma, ioaddr + RxRingPtr);
2330 check_link(dev);
2331 spin_unlock_irq(&np->lock);
2332
2333 /* We'll enable RX on exit from this
2334 * function. */
2335 break;
2336
2251 } else { 2337 } else {
2252 /* There was an error. */ 2338 /* There was an error. */
2253 np->stats.rx_errors++; 2339 np->stats.rx_errors++;
@@ -2293,7 +2379,7 @@ static void netdev_rx(struct net_device *dev)
2293 np->rx_skbuff[entry] = NULL; 2379 np->rx_skbuff[entry] = NULL;
2294 } 2380 }
2295 skb->protocol = eth_type_trans(skb, dev); 2381 skb->protocol = eth_type_trans(skb, dev);
2296 netif_rx(skb); 2382 netif_receive_skb(skb);
2297 dev->last_rx = jiffies; 2383 dev->last_rx = jiffies;
2298 np->stats.rx_packets++; 2384 np->stats.rx_packets++;
2299 np->stats.rx_bytes += pkt_len; 2385 np->stats.rx_bytes += pkt_len;
@@ -3074,9 +3160,7 @@ static int netdev_close(struct net_device *dev)
3074 del_timer_sync(&np->timer); 3160 del_timer_sync(&np->timer);
3075 disable_irq(dev->irq); 3161 disable_irq(dev->irq);
3076 spin_lock_irq(&np->lock); 3162 spin_lock_irq(&np->lock);
3077 /* Disable interrupts, and flush posted writes */ 3163 natsemi_irq_disable(dev);
3078 writel(0, ioaddr + IntrEnable);
3079 readl(ioaddr + IntrEnable);
3080 np->hands_off = 1; 3164 np->hands_off = 1;
3081 spin_unlock_irq(&np->lock); 3165 spin_unlock_irq(&np->lock);
3082 enable_irq(dev->irq); 3166 enable_irq(dev->irq);
@@ -3158,6 +3242,9 @@ static void __devexit natsemi_remove1 (struct pci_dev *pdev)
3158 * * netdev_timer: timer stopped by natsemi_suspend. 3242 * * netdev_timer: timer stopped by natsemi_suspend.
3159 * * intr_handler: doesn't acquire the spinlock. suspend calls 3243 * * intr_handler: doesn't acquire the spinlock. suspend calls
3160 * disable_irq() to enforce synchronization. 3244 * disable_irq() to enforce synchronization.
3245 * * natsemi_poll: checks before reenabling interrupts. suspend
3246 * sets hands_off, disables interrupts and then waits with
3247 * netif_poll_disable().
3161 * 3248 *
3162 * Interrupts must be disabled, otherwise hands_off can cause irq storms. 3249 * Interrupts must be disabled, otherwise hands_off can cause irq storms.
3163 */ 3250 */
@@ -3183,6 +3270,8 @@ static int natsemi_suspend (struct pci_dev *pdev, pm_message_t state)
3183 spin_unlock_irq(&np->lock); 3270 spin_unlock_irq(&np->lock);
3184 enable_irq(dev->irq); 3271 enable_irq(dev->irq);
3185 3272
3273 netif_poll_disable(dev);
3274
3186 /* Update the error counts. */ 3275 /* Update the error counts. */
3187 __get_stats(dev); 3276 __get_stats(dev);
3188 3277
@@ -3235,6 +3324,7 @@ static int natsemi_resume (struct pci_dev *pdev)
3235 mod_timer(&np->timer, jiffies + 1*HZ); 3324 mod_timer(&np->timer, jiffies + 1*HZ);
3236 } 3325 }
3237 netif_device_attach(dev); 3326 netif_device_attach(dev);
3327 netif_poll_enable(dev);
3238out: 3328out:
3239 rtnl_unlock(); 3329 rtnl_unlock();
3240 return 0; 3330 return 0;