ia64/linux-2.6.18-xen.hg

annotate drivers/net/au1000_eth.c @ 897:329ea0ccb344

balloon: try harder to balloon up under memory pressure.

Currently if the balloon driver is unable to increase the guest's
reservation it assumes the failure was due to reaching its full
allocation, gives up on the ballooning operation and records the limit
it reached as the "hard limit". The driver will not try again until
the target is set again (even to the same value).

However it is possible that ballooning has in fact failed due to
memory pressure in the host and therefore it is desirable to keep
attempting to reach the target in case memory becomes available. The
most likely scenario is that some guests are ballooning down while
others are ballooning up and therefore there is temporary memory
pressure while things stabilise. You would not expect a well behaved
toolstack to ask a domain to balloon to more than its allocation nor
would you expect it to deliberately over-commit memory by setting
balloon targets which exceed the total host memory.

This patch drops the concept of a hard limit and causes the balloon
driver to retry increasing the reservation on a timer in the same
manner as when decreasing the reservation.

Also if we partially succeed in increasing the reservation
(i.e. receive less pages than we asked for) then we may as well keep
those pages rather than returning them to Xen.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Fri Jun 05 14:01:20 2009 +0100 (2009-06-05)
parents 831230e53067
children
rev   line source
ian@0 1 /*
ian@0 2 *
ian@0 3 * Alchemy Au1x00 ethernet driver
ian@0 4 *
ian@0 5 * Copyright 2001-2003, 2006 MontaVista Software Inc.
ian@0 6 * Copyright 2002 TimeSys Corp.
ian@0 7 * Added ethtool/mii-tool support,
ian@0 8 * Copyright 2004 Matt Porter <mporter@kernel.crashing.org>
ian@0 9 * Update: 2004 Bjoern Riemer, riemer@fokus.fraunhofer.de
ian@0 10 * or riemer@riemer-nt.de: fixed the link beat detection with
ian@0 11 * ioctls (SIOCGMIIPHY)
ian@0 12 * Copyright 2006 Herbert Valerio Riedel <hvr@gnu.org>
ian@0 13 * converted to use linux-2.6.x's PHY framework
ian@0 14 *
ian@0 15 * Author: MontaVista Software, Inc.
ian@0 16 * ppopov@mvista.com or source@mvista.com
ian@0 17 *
ian@0 18 * ########################################################################
ian@0 19 *
ian@0 20 * This program is free software; you can distribute it and/or modify it
ian@0 21 * under the terms of the GNU General Public License (Version 2) as
ian@0 22 * published by the Free Software Foundation.
ian@0 23 *
ian@0 24 * This program is distributed in the hope it will be useful, but WITHOUT
ian@0 25 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
ian@0 26 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
ian@0 27 * for more details.
ian@0 28 *
ian@0 29 * You should have received a copy of the GNU General Public License along
ian@0 30 * with this program; if not, write to the Free Software Foundation, Inc.,
ian@0 31 * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
ian@0 32 *
ian@0 33 * ########################################################################
ian@0 34 *
ian@0 35 *
ian@0 36 */
ian@0 37
ian@0 38 #include <linux/module.h>
ian@0 39 #include <linux/kernel.h>
ian@0 40 #include <linux/sched.h>
ian@0 41 #include <linux/string.h>
ian@0 42 #include <linux/timer.h>
ian@0 43 #include <linux/errno.h>
ian@0 44 #include <linux/in.h>
ian@0 45 #include <linux/ioport.h>
ian@0 46 #include <linux/bitops.h>
ian@0 47 #include <linux/slab.h>
ian@0 48 #include <linux/interrupt.h>
ian@0 49 #include <linux/pci.h>
ian@0 50 #include <linux/init.h>
ian@0 51 #include <linux/netdevice.h>
ian@0 52 #include <linux/etherdevice.h>
ian@0 53 #include <linux/ethtool.h>
ian@0 54 #include <linux/mii.h>
ian@0 55 #include <linux/skbuff.h>
ian@0 56 #include <linux/delay.h>
ian@0 57 #include <linux/crc32.h>
ian@0 58 #include <linux/phy.h>
ian@0 59 #include <asm/mipsregs.h>
ian@0 60 #include <asm/irq.h>
ian@0 61 #include <asm/io.h>
ian@0 62 #include <asm/processor.h>
ian@0 63
ian@0 64 #include <asm/mach-au1x00/au1000.h>
ian@0 65 #include <asm/cpu.h>
ian@0 66 #include "au1000_eth.h"
ian@0 67
ian@0 68 #ifdef AU1000_ETH_DEBUG
ian@0 69 static int au1000_debug = 5;
ian@0 70 #else
ian@0 71 static int au1000_debug = 3;
ian@0 72 #endif
ian@0 73
ian@0 74 #define DRV_NAME "au1000_eth"
ian@0 75 #define DRV_VERSION "1.5"
ian@0 76 #define DRV_AUTHOR "Pete Popov <ppopov@embeddedalley.com>"
ian@0 77 #define DRV_DESC "Au1xxx on-chip Ethernet driver"
ian@0 78
ian@0 79 MODULE_AUTHOR(DRV_AUTHOR);
ian@0 80 MODULE_DESCRIPTION(DRV_DESC);
ian@0 81 MODULE_LICENSE("GPL");
ian@0 82
ian@0 83 // prototypes
ian@0 84 static void hard_stop(struct net_device *);
ian@0 85 static void enable_rx_tx(struct net_device *dev);
ian@0 86 static struct net_device * au1000_probe(int port_num);
ian@0 87 static int au1000_init(struct net_device *);
ian@0 88 static int au1000_open(struct net_device *);
ian@0 89 static int au1000_close(struct net_device *);
ian@0 90 static int au1000_tx(struct sk_buff *, struct net_device *);
ian@0 91 static int au1000_rx(struct net_device *);
ian@0 92 static irqreturn_t au1000_interrupt(int, void *, struct pt_regs *);
ian@0 93 static void au1000_tx_timeout(struct net_device *);
ian@0 94 static void set_rx_mode(struct net_device *);
ian@0 95 static struct net_device_stats *au1000_get_stats(struct net_device *);
ian@0 96 static int au1000_ioctl(struct net_device *, struct ifreq *, int);
ian@0 97 static int mdio_read(struct net_device *, int, int);
ian@0 98 static void mdio_write(struct net_device *, int, int, u16);
ian@0 99 static void au1000_adjust_link(struct net_device *);
ian@0 100 static void enable_mac(struct net_device *, int);
ian@0 101
ian@0 102 // externs
ian@0 103 extern int get_ethernet_addr(char *ethernet_addr);
ian@0 104 extern void str2eaddr(unsigned char *ea, unsigned char *str);
ian@0 105 extern char * __init prom_getcmdline(void);
ian@0 106
ian@0 107 /*
ian@0 108 * Theory of operation
ian@0 109 *
ian@0 110 * The Au1000 MACs use a simple rx and tx descriptor ring scheme.
ian@0 111 * There are four receive and four transmit descriptors. These
ian@0 112 * descriptors are not in memory; rather, they are just a set of
ian@0 113 * hardware registers.
ian@0 114 *
ian@0 115 * Since the Au1000 has a coherent data cache, the receive and
ian@0 116 * transmit buffers are allocated from the KSEG0 segment. The
ian@0 117 * hardware registers, however, are still mapped at KSEG1 to
ian@0 118 * make sure there's no out-of-order writes, and that all writes
ian@0 119 * complete immediately.
ian@0 120 */
ian@0 121
ian@0 122 /* These addresses are only used if yamon doesn't tell us what
ian@0 123 * the mac address is, and the mac address is not passed on the
ian@0 124 * command line.
ian@0 125 */
ian@0 126 static unsigned char au1000_mac_addr[6] __devinitdata = {
ian@0 127 0x00, 0x50, 0xc2, 0x0c, 0x30, 0x00
ian@0 128 };
ian@0 129
ian@0 130 struct au1000_private *au_macs[NUM_ETH_INTERFACES];
ian@0 131
ian@0 132 /*
ian@0 133 * board-specific configurations
ian@0 134 *
ian@0 135 * PHY detection algorithm
ian@0 136 *
ian@0 137 * If AU1XXX_PHY_STATIC_CONFIG is undefined, the PHY setup is
ian@0 138 * autodetected:
ian@0 139 *
ian@0 140 * mii_probe() first searches the current MAC's MII bus for a PHY,
ian@0 141 * selecting the first (or last, if AU1XXX_PHY_SEARCH_HIGHEST_ADDR is
ian@0 142 * defined) PHY address not already claimed by another netdev.
ian@0 143 *
ian@0 144 * If nothing was found that way when searching for the 2nd ethernet
ian@0 145 * controller's PHY and AU1XXX_PHY1_SEARCH_ON_MAC0 is defined, then
ian@0 146 * the first MII bus is searched as well for an unclaimed PHY; this is
ian@0 147 * needed in case of a dual-PHY accessible only through the MAC0's MII
ian@0 148 * bus.
ian@0 149 *
ian@0 150 * Finally, if no PHY is found, then the corresponding ethernet
ian@0 151 * controller is not registered to the network subsystem.
ian@0 152 */
ian@0 153
ian@0 154 /* autodetection defaults */
ian@0 155 #undef AU1XXX_PHY_SEARCH_HIGHEST_ADDR
ian@0 156 #define AU1XXX_PHY1_SEARCH_ON_MAC0
ian@0 157
ian@0 158 /* static PHY setup
ian@0 159 *
ian@0 160 * most boards PHY setup should be detectable properly with the
ian@0 161 * autodetection algorithm in mii_probe(), but in some cases (e.g. if
ian@0 162 * you have a switch attached, or want to use the PHY's interrupt
ian@0 163 * notification capabilities) you can provide a static PHY
ian@0 164 * configuration here
ian@0 165 *
ian@0 166 * IRQs may only be set, if a PHY address was configured
ian@0 167 * If a PHY address is given, also a bus id is required to be set
ian@0 168 *
ian@0 169 * ps: make sure the used irqs are configured properly in the board
ian@0 170 * specific irq-map
ian@0 171 */
ian@0 172
ian@0 173 #if defined(CONFIG_MIPS_BOSPORUS)
ian@0 174 /*
ian@0 175 * Micrel/Kendin 5 port switch attached to MAC0,
ian@0 176 * MAC0 is associated with PHY address 5 (== WAN port)
ian@0 177 * MAC1 is not associated with any PHY, since it's connected directly
ian@0 178 * to the switch.
ian@0 179 * no interrupts are used
ian@0 180 */
ian@0 181 # define AU1XXX_PHY_STATIC_CONFIG
ian@0 182
ian@0 183 # define AU1XXX_PHY0_ADDR 5
ian@0 184 # define AU1XXX_PHY0_BUSID 0
ian@0 185 # undef AU1XXX_PHY0_IRQ
ian@0 186
ian@0 187 # undef AU1XXX_PHY1_ADDR
ian@0 188 # undef AU1XXX_PHY1_BUSID
ian@0 189 # undef AU1XXX_PHY1_IRQ
ian@0 190 #endif
ian@0 191
ian@0 192 #if defined(AU1XXX_PHY0_BUSID) && (AU1XXX_PHY0_BUSID > 0)
ian@0 193 # error MAC0-associated PHY attached 2nd MACs MII bus not supported yet
ian@0 194 #endif
ian@0 195
ian@0 196 /*
ian@0 197 * MII operations
ian@0 198 */
ian@0 199 static int mdio_read(struct net_device *dev, int phy_addr, int reg)
ian@0 200 {
ian@0 201 struct au1000_private *aup = (struct au1000_private *) dev->priv;
ian@0 202 volatile u32 *const mii_control_reg = &aup->mac->mii_control;
ian@0 203 volatile u32 *const mii_data_reg = &aup->mac->mii_data;
ian@0 204 u32 timedout = 20;
ian@0 205 u32 mii_control;
ian@0 206
ian@0 207 while (*mii_control_reg & MAC_MII_BUSY) {
ian@0 208 mdelay(1);
ian@0 209 if (--timedout == 0) {
ian@0 210 printk(KERN_ERR "%s: read_MII busy timeout!!\n",
ian@0 211 dev->name);
ian@0 212 return -1;
ian@0 213 }
ian@0 214 }
ian@0 215
ian@0 216 mii_control = MAC_SET_MII_SELECT_REG(reg) |
ian@0 217 MAC_SET_MII_SELECT_PHY(phy_addr) | MAC_MII_READ;
ian@0 218
ian@0 219 *mii_control_reg = mii_control;
ian@0 220
ian@0 221 timedout = 20;
ian@0 222 while (*mii_control_reg & MAC_MII_BUSY) {
ian@0 223 mdelay(1);
ian@0 224 if (--timedout == 0) {
ian@0 225 printk(KERN_ERR "%s: mdio_read busy timeout!!\n",
ian@0 226 dev->name);
ian@0 227 return -1;
ian@0 228 }
ian@0 229 }
ian@0 230 return (int)*mii_data_reg;
ian@0 231 }
ian@0 232
ian@0 233 static void mdio_write(struct net_device *dev, int phy_addr, int reg, u16 value)
ian@0 234 {
ian@0 235 struct au1000_private *aup = (struct au1000_private *) dev->priv;
ian@0 236 volatile u32 *const mii_control_reg = &aup->mac->mii_control;
ian@0 237 volatile u32 *const mii_data_reg = &aup->mac->mii_data;
ian@0 238 u32 timedout = 20;
ian@0 239 u32 mii_control;
ian@0 240
ian@0 241 while (*mii_control_reg & MAC_MII_BUSY) {
ian@0 242 mdelay(1);
ian@0 243 if (--timedout == 0) {
ian@0 244 printk(KERN_ERR "%s: mdio_write busy timeout!!\n",
ian@0 245 dev->name);
ian@0 246 return;
ian@0 247 }
ian@0 248 }
ian@0 249
ian@0 250 mii_control = MAC_SET_MII_SELECT_REG(reg) |
ian@0 251 MAC_SET_MII_SELECT_PHY(phy_addr) | MAC_MII_WRITE;
ian@0 252
ian@0 253 *mii_data_reg = value;
ian@0 254 *mii_control_reg = mii_control;
ian@0 255 }
ian@0 256
ian@0 257 static int mdiobus_read(struct mii_bus *bus, int phy_addr, int regnum)
ian@0 258 {
ian@0 259 /* WARNING: bus->phy_map[phy_addr].attached_dev == dev does
ian@0 260 * _NOT_ hold (e.g. when PHY is accessed through other MAC's MII bus) */
ian@0 261 struct net_device *const dev = bus->priv;
ian@0 262
ian@0 263 enable_mac(dev, 0); /* make sure the MAC associated with this
ian@0 264 * mii_bus is enabled */
ian@0 265 return mdio_read(dev, phy_addr, regnum);
ian@0 266 }
ian@0 267
ian@0 268 static int mdiobus_write(struct mii_bus *bus, int phy_addr, int regnum,
ian@0 269 u16 value)
ian@0 270 {
ian@0 271 struct net_device *const dev = bus->priv;
ian@0 272
ian@0 273 enable_mac(dev, 0); /* make sure the MAC associated with this
ian@0 274 * mii_bus is enabled */
ian@0 275 mdio_write(dev, phy_addr, regnum, value);
ian@0 276 return 0;
ian@0 277 }
ian@0 278
ian@0 279 static int mdiobus_reset(struct mii_bus *bus)
ian@0 280 {
ian@0 281 struct net_device *const dev = bus->priv;
ian@0 282
ian@0 283 enable_mac(dev, 0); /* make sure the MAC associated with this
ian@0 284 * mii_bus is enabled */
ian@0 285 return 0;
ian@0 286 }
ian@0 287
ian@0 288 static int mii_probe (struct net_device *dev)
ian@0 289 {
ian@0 290 struct au1000_private *const aup = (struct au1000_private *) dev->priv;
ian@0 291 struct phy_device *phydev = NULL;
ian@0 292
ian@0 293 #if defined(AU1XXX_PHY_STATIC_CONFIG)
ian@0 294 BUG_ON(aup->mac_id < 0 || aup->mac_id > 1);
ian@0 295
ian@0 296 if(aup->mac_id == 0) { /* get PHY0 */
ian@0 297 # if defined(AU1XXX_PHY0_ADDR)
ian@0 298 phydev = au_macs[AU1XXX_PHY0_BUSID]->mii_bus.phy_map[AU1XXX_PHY0_ADDR];
ian@0 299 # else
ian@0 300 printk (KERN_INFO DRV_NAME ":%s: using PHY-less setup\n",
ian@0 301 dev->name);
ian@0 302 return 0;
ian@0 303 # endif /* defined(AU1XXX_PHY0_ADDR) */
ian@0 304 } else if (aup->mac_id == 1) { /* get PHY1 */
ian@0 305 # if defined(AU1XXX_PHY1_ADDR)
ian@0 306 phydev = au_macs[AU1XXX_PHY1_BUSID]->mii_bus.phy_map[AU1XXX_PHY1_ADDR];
ian@0 307 # else
ian@0 308 printk (KERN_INFO DRV_NAME ":%s: using PHY-less setup\n",
ian@0 309 dev->name);
ian@0 310 return 0;
ian@0 311 # endif /* defined(AU1XXX_PHY1_ADDR) */
ian@0 312 }
ian@0 313
ian@0 314 #else /* defined(AU1XXX_PHY_STATIC_CONFIG) */
ian@0 315 int phy_addr;
ian@0 316
ian@0 317 /* find the first (lowest address) PHY on the current MAC's MII bus */
ian@0 318 for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++)
ian@0 319 if (aup->mii_bus.phy_map[phy_addr]) {
ian@0 320 phydev = aup->mii_bus.phy_map[phy_addr];
ian@0 321 # if !defined(AU1XXX_PHY_SEARCH_HIGHEST_ADDR)
ian@0 322 break; /* break out with first one found */
ian@0 323 # endif
ian@0 324 }
ian@0 325
ian@0 326 # if defined(AU1XXX_PHY1_SEARCH_ON_MAC0)
ian@0 327 /* try harder to find a PHY */
ian@0 328 if (!phydev && (aup->mac_id == 1)) {
ian@0 329 /* no PHY found, maybe we have a dual PHY? */
ian@0 330 printk (KERN_INFO DRV_NAME ": no PHY found on MAC1, "
ian@0 331 "let's see if it's attached to MAC0...\n");
ian@0 332
ian@0 333 BUG_ON(!au_macs[0]);
ian@0 334
ian@0 335 /* find the first (lowest address) non-attached PHY on
ian@0 336 * the MAC0 MII bus */
ian@0 337 for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) {
ian@0 338 struct phy_device *const tmp_phydev =
ian@0 339 au_macs[0]->mii_bus.phy_map[phy_addr];
ian@0 340
ian@0 341 if (!tmp_phydev)
ian@0 342 continue; /* no PHY here... */
ian@0 343
ian@0 344 if (tmp_phydev->attached_dev)
ian@0 345 continue; /* already claimed by MAC0 */
ian@0 346
ian@0 347 phydev = tmp_phydev;
ian@0 348 break; /* found it */
ian@0 349 }
ian@0 350 }
ian@0 351 # endif /* defined(AU1XXX_PHY1_SEARCH_OTHER_BUS) */
ian@0 352
ian@0 353 #endif /* defined(AU1XXX_PHY_STATIC_CONFIG) */
ian@0 354 if (!phydev) {
ian@0 355 printk (KERN_ERR DRV_NAME ":%s: no PHY found\n", dev->name);
ian@0 356 return -1;
ian@0 357 }
ian@0 358
ian@0 359 /* now we are supposed to have a proper phydev, to attach to... */
ian@0 360 BUG_ON(!phydev);
ian@0 361 BUG_ON(phydev->attached_dev);
ian@0 362
ian@0 363 phydev = phy_connect(dev, phydev->dev.bus_id, &au1000_adjust_link, 0);
ian@0 364
ian@0 365 if (IS_ERR(phydev)) {
ian@0 366 printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name);
ian@0 367 return PTR_ERR(phydev);
ian@0 368 }
ian@0 369
ian@0 370 /* mask with MAC supported features */
ian@0 371 phydev->supported &= (SUPPORTED_10baseT_Half
ian@0 372 | SUPPORTED_10baseT_Full
ian@0 373 | SUPPORTED_100baseT_Half
ian@0 374 | SUPPORTED_100baseT_Full
ian@0 375 | SUPPORTED_Autoneg
ian@0 376 /* | SUPPORTED_Pause | SUPPORTED_Asym_Pause */
ian@0 377 | SUPPORTED_MII
ian@0 378 | SUPPORTED_TP);
ian@0 379
ian@0 380 phydev->advertising = phydev->supported;
ian@0 381
ian@0 382 aup->old_link = 0;
ian@0 383 aup->old_speed = 0;
ian@0 384 aup->old_duplex = -1;
ian@0 385 aup->phy_dev = phydev;
ian@0 386
ian@0 387 printk(KERN_INFO "%s: attached PHY driver [%s] "
ian@0 388 "(mii_bus:phy_addr=%s, irq=%d)\n",
ian@0 389 dev->name, phydev->drv->name, phydev->dev.bus_id, phydev->irq);
ian@0 390
ian@0 391 return 0;
ian@0 392 }
ian@0 393
ian@0 394
ian@0 395 /*
ian@0 396 * Buffer allocation/deallocation routines. The buffer descriptor returned
ian@0 397 * has the virtual and dma address of a buffer suitable for
ian@0 398 * both, receive and transmit operations.
ian@0 399 */
ian@0 400 static db_dest_t *GetFreeDB(struct au1000_private *aup)
ian@0 401 {
ian@0 402 db_dest_t *pDB;
ian@0 403 pDB = aup->pDBfree;
ian@0 404
ian@0 405 if (pDB) {
ian@0 406 aup->pDBfree = pDB->pnext;
ian@0 407 }
ian@0 408 return pDB;
ian@0 409 }
ian@0 410
ian@0 411 void ReleaseDB(struct au1000_private *aup, db_dest_t *pDB)
ian@0 412 {
ian@0 413 db_dest_t *pDBfree = aup->pDBfree;
ian@0 414 if (pDBfree)
ian@0 415 pDBfree->pnext = pDB;
ian@0 416 aup->pDBfree = pDB;
ian@0 417 }
ian@0 418
ian@0 419 static void enable_rx_tx(struct net_device *dev)
ian@0 420 {
ian@0 421 struct au1000_private *aup = (struct au1000_private *) dev->priv;
ian@0 422
ian@0 423 if (au1000_debug > 4)
ian@0 424 printk(KERN_INFO "%s: enable_rx_tx\n", dev->name);
ian@0 425
ian@0 426 aup->mac->control |= (MAC_RX_ENABLE | MAC_TX_ENABLE);
ian@0 427 au_sync_delay(10);
ian@0 428 }
ian@0 429
ian@0 430 static void hard_stop(struct net_device *dev)
ian@0 431 {
ian@0 432 struct au1000_private *aup = (struct au1000_private *) dev->priv;
ian@0 433
ian@0 434 if (au1000_debug > 4)
ian@0 435 printk(KERN_INFO "%s: hard stop\n", dev->name);
ian@0 436
ian@0 437 aup->mac->control &= ~(MAC_RX_ENABLE | MAC_TX_ENABLE);
ian@0 438 au_sync_delay(10);
ian@0 439 }
ian@0 440
ian@0 441 static void enable_mac(struct net_device *dev, int force_reset)
ian@0 442 {
ian@0 443 unsigned long flags;
ian@0 444 struct au1000_private *aup = (struct au1000_private *) dev->priv;
ian@0 445
ian@0 446 spin_lock_irqsave(&aup->lock, flags);
ian@0 447
ian@0 448 if(force_reset || (!aup->mac_enabled)) {
ian@0 449 *aup->enable = MAC_EN_CLOCK_ENABLE;
ian@0 450 au_sync_delay(2);
ian@0 451 *aup->enable = (MAC_EN_RESET0 | MAC_EN_RESET1 | MAC_EN_RESET2
ian@0 452 | MAC_EN_CLOCK_ENABLE);
ian@0 453 au_sync_delay(2);
ian@0 454
ian@0 455 aup->mac_enabled = 1;
ian@0 456 }
ian@0 457
ian@0 458 spin_unlock_irqrestore(&aup->lock, flags);
ian@0 459 }
ian@0 460
ian@0 461 static void reset_mac_unlocked(struct net_device *dev)
ian@0 462 {
ian@0 463 struct au1000_private *const aup = (struct au1000_private *) dev->priv;
ian@0 464 int i;
ian@0 465
ian@0 466 hard_stop(dev);
ian@0 467
ian@0 468 *aup->enable = MAC_EN_CLOCK_ENABLE;
ian@0 469 au_sync_delay(2);
ian@0 470 *aup->enable = 0;
ian@0 471 au_sync_delay(2);
ian@0 472
ian@0 473 aup->tx_full = 0;
ian@0 474 for (i = 0; i < NUM_RX_DMA; i++) {
ian@0 475 /* reset control bits */
ian@0 476 aup->rx_dma_ring[i]->buff_stat &= ~0xf;
ian@0 477 }
ian@0 478 for (i = 0; i < NUM_TX_DMA; i++) {
ian@0 479 /* reset control bits */
ian@0 480 aup->tx_dma_ring[i]->buff_stat &= ~0xf;
ian@0 481 }
ian@0 482
ian@0 483 aup->mac_enabled = 0;
ian@0 484
ian@0 485 }
ian@0 486
ian@0 487 static void reset_mac(struct net_device *dev)
ian@0 488 {
ian@0 489 struct au1000_private *const aup = (struct au1000_private *) dev->priv;
ian@0 490 unsigned long flags;
ian@0 491
ian@0 492 if (au1000_debug > 4)
ian@0 493 printk(KERN_INFO "%s: reset mac, aup %x\n",
ian@0 494 dev->name, (unsigned)aup);
ian@0 495
ian@0 496 spin_lock_irqsave(&aup->lock, flags);
ian@0 497
ian@0 498 reset_mac_unlocked (dev);
ian@0 499
ian@0 500 spin_unlock_irqrestore(&aup->lock, flags);
ian@0 501 }
ian@0 502
ian@0 503 /*
ian@0 504 * Setup the receive and transmit "rings". These pointers are the addresses
ian@0 505 * of the rx and tx MAC DMA registers so they are fixed by the hardware --
ian@0 506 * these are not descriptors sitting in memory.
ian@0 507 */
ian@0 508 static void
ian@0 509 setup_hw_rings(struct au1000_private *aup, u32 rx_base, u32 tx_base)
ian@0 510 {
ian@0 511 int i;
ian@0 512
ian@0 513 for (i = 0; i < NUM_RX_DMA; i++) {
ian@0 514 aup->rx_dma_ring[i] =
ian@0 515 (volatile rx_dma_t *) (rx_base + sizeof(rx_dma_t)*i);
ian@0 516 }
ian@0 517 for (i = 0; i < NUM_TX_DMA; i++) {
ian@0 518 aup->tx_dma_ring[i] =
ian@0 519 (volatile tx_dma_t *) (tx_base + sizeof(tx_dma_t)*i);
ian@0 520 }
ian@0 521 }
ian@0 522
ian@0 523 static struct {
ian@0 524 u32 base_addr;
ian@0 525 u32 macen_addr;
ian@0 526 int irq;
ian@0 527 struct net_device *dev;
ian@0 528 } iflist[2] = {
ian@0 529 #ifdef CONFIG_SOC_AU1000
ian@0 530 {AU1000_ETH0_BASE, AU1000_MAC0_ENABLE, AU1000_MAC0_DMA_INT},
ian@0 531 {AU1000_ETH1_BASE, AU1000_MAC1_ENABLE, AU1000_MAC1_DMA_INT}
ian@0 532 #endif
ian@0 533 #ifdef CONFIG_SOC_AU1100
ian@0 534 {AU1100_ETH0_BASE, AU1100_MAC0_ENABLE, AU1100_MAC0_DMA_INT}
ian@0 535 #endif
ian@0 536 #ifdef CONFIG_SOC_AU1500
ian@0 537 {AU1500_ETH0_BASE, AU1500_MAC0_ENABLE, AU1500_MAC0_DMA_INT},
ian@0 538 {AU1500_ETH1_BASE, AU1500_MAC1_ENABLE, AU1500_MAC1_DMA_INT}
ian@0 539 #endif
ian@0 540 #ifdef CONFIG_SOC_AU1550
ian@0 541 {AU1550_ETH0_BASE, AU1550_MAC0_ENABLE, AU1550_MAC0_DMA_INT},
ian@0 542 {AU1550_ETH1_BASE, AU1550_MAC1_ENABLE, AU1550_MAC1_DMA_INT}
ian@0 543 #endif
ian@0 544 };
ian@0 545
ian@0 546 static int num_ifs;
ian@0 547
ian@0 548 /*
ian@0 549 * Setup the base address and interupt of the Au1xxx ethernet macs
ian@0 550 * based on cpu type and whether the interface is enabled in sys_pinfunc
ian@0 551 * register. The last interface is enabled if SYS_PF_NI2 (bit 4) is 0.
ian@0 552 */
ian@0 553 static int __init au1000_init_module(void)
ian@0 554 {
ian@0 555 int ni = (int)((au_readl(SYS_PINFUNC) & (u32)(SYS_PF_NI2)) >> 4);
ian@0 556 struct net_device *dev;
ian@0 557 int i, found_one = 0;
ian@0 558
ian@0 559 num_ifs = NUM_ETH_INTERFACES - ni;
ian@0 560
ian@0 561 for(i = 0; i < num_ifs; i++) {
ian@0 562 dev = au1000_probe(i);
ian@0 563 iflist[i].dev = dev;
ian@0 564 if (dev)
ian@0 565 found_one++;
ian@0 566 }
ian@0 567 if (!found_one)
ian@0 568 return -ENODEV;
ian@0 569 return 0;
ian@0 570 }
ian@0 571
ian@0 572 /*
ian@0 573 * ethtool operations
ian@0 574 */
ian@0 575
ian@0 576 static int au1000_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
ian@0 577 {
ian@0 578 struct au1000_private *aup = (struct au1000_private *)dev->priv;
ian@0 579
ian@0 580 if (aup->phy_dev)
ian@0 581 return phy_ethtool_gset(aup->phy_dev, cmd);
ian@0 582
ian@0 583 return -EINVAL;
ian@0 584 }
ian@0 585
ian@0 586 static int au1000_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
ian@0 587 {
ian@0 588 struct au1000_private *aup = (struct au1000_private *)dev->priv;
ian@0 589
ian@0 590 if (!capable(CAP_NET_ADMIN))
ian@0 591 return -EPERM;
ian@0 592
ian@0 593 if (aup->phy_dev)
ian@0 594 return phy_ethtool_sset(aup->phy_dev, cmd);
ian@0 595
ian@0 596 return -EINVAL;
ian@0 597 }
ian@0 598
ian@0 599 static void
ian@0 600 au1000_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
ian@0 601 {
ian@0 602 struct au1000_private *aup = (struct au1000_private *)dev->priv;
ian@0 603
ian@0 604 strcpy(info->driver, DRV_NAME);
ian@0 605 strcpy(info->version, DRV_VERSION);
ian@0 606 info->fw_version[0] = '\0';
ian@0 607 sprintf(info->bus_info, "%s %d", DRV_NAME, aup->mac_id);
ian@0 608 info->regdump_len = 0;
ian@0 609 }
ian@0 610
ian@0 611 static struct ethtool_ops au1000_ethtool_ops = {
ian@0 612 .get_settings = au1000_get_settings,
ian@0 613 .set_settings = au1000_set_settings,
ian@0 614 .get_drvinfo = au1000_get_drvinfo,
ian@0 615 .get_link = ethtool_op_get_link,
ian@0 616 };
ian@0 617
ian@0 618 static struct net_device * au1000_probe(int port_num)
ian@0 619 {
ian@0 620 static unsigned version_printed = 0;
ian@0 621 struct au1000_private *aup = NULL;
ian@0 622 struct net_device *dev = NULL;
ian@0 623 db_dest_t *pDB, *pDBfree;
ian@0 624 char *pmac, *argptr;
ian@0 625 char ethaddr[6];
ian@0 626 int irq, i, err;
ian@0 627 u32 base, macen;
ian@0 628
ian@0 629 if (port_num >= NUM_ETH_INTERFACES)
ian@0 630 return NULL;
ian@0 631
ian@0 632 base = CPHYSADDR(iflist[port_num].base_addr );
ian@0 633 macen = CPHYSADDR(iflist[port_num].macen_addr);
ian@0 634 irq = iflist[port_num].irq;
ian@0 635
ian@0 636 if (!request_mem_region( base, MAC_IOSIZE, "Au1x00 ENET") ||
ian@0 637 !request_mem_region(macen, 4, "Au1x00 ENET"))
ian@0 638 return NULL;
ian@0 639
ian@0 640 if (version_printed++ == 0)
ian@0 641 printk("%s version %s %s\n", DRV_NAME, DRV_VERSION, DRV_AUTHOR);
ian@0 642
ian@0 643 dev = alloc_etherdev(sizeof(struct au1000_private));
ian@0 644 if (!dev) {
ian@0 645 printk(KERN_ERR "%s: alloc_etherdev failed\n", DRV_NAME);
ian@0 646 return NULL;
ian@0 647 }
ian@0 648
ian@0 649 if ((err = register_netdev(dev)) != 0) {
ian@0 650 printk(KERN_ERR "%s: Cannot register net device, error %d\n",
ian@0 651 DRV_NAME, err);
ian@0 652 free_netdev(dev);
ian@0 653 return NULL;
ian@0 654 }
ian@0 655
ian@0 656 printk("%s: Au1xx0 Ethernet found at 0x%x, irq %d\n",
ian@0 657 dev->name, base, irq);
ian@0 658
ian@0 659 aup = dev->priv;
ian@0 660
ian@0 661 /* Allocate the data buffers */
ian@0 662 /* Snooping works fine with eth on all au1xxx */
ian@0 663 aup->vaddr = (u32)dma_alloc_noncoherent(NULL, MAX_BUF_SIZE *
ian@0 664 (NUM_TX_BUFFS + NUM_RX_BUFFS),
ian@0 665 &aup->dma_addr, 0);
ian@0 666 if (!aup->vaddr) {
ian@0 667 free_netdev(dev);
ian@0 668 release_mem_region( base, MAC_IOSIZE);
ian@0 669 release_mem_region(macen, 4);
ian@0 670 return NULL;
ian@0 671 }
ian@0 672
ian@0 673 /* aup->mac is the base address of the MAC's registers */
ian@0 674 aup->mac = (volatile mac_reg_t *)iflist[port_num].base_addr;
ian@0 675
ian@0 676 /* Setup some variables for quick register address access */
ian@0 677 aup->enable = (volatile u32 *)iflist[port_num].macen_addr;
ian@0 678 aup->mac_id = port_num;
ian@0 679 au_macs[port_num] = aup;
ian@0 680
ian@0 681 if (port_num == 0) {
ian@0 682 /* Check the environment variables first */
ian@0 683 if (get_ethernet_addr(ethaddr) == 0)
ian@0 684 memcpy(au1000_mac_addr, ethaddr, sizeof(au1000_mac_addr));
ian@0 685 else {
ian@0 686 /* Check command line */
ian@0 687 argptr = prom_getcmdline();
ian@0 688 if ((pmac = strstr(argptr, "ethaddr=")) == NULL)
ian@0 689 printk(KERN_INFO "%s: No MAC address found\n",
ian@0 690 dev->name);
ian@0 691 /* Use the hard coded MAC addresses */
ian@0 692 else {
ian@0 693 str2eaddr(ethaddr, pmac + strlen("ethaddr="));
ian@0 694 memcpy(au1000_mac_addr, ethaddr,
ian@0 695 sizeof(au1000_mac_addr));
ian@0 696 }
ian@0 697 }
ian@0 698
ian@0 699 setup_hw_rings(aup, MAC0_RX_DMA_ADDR, MAC0_TX_DMA_ADDR);
ian@0 700 } else if (port_num == 1)
ian@0 701 setup_hw_rings(aup, MAC1_RX_DMA_ADDR, MAC1_TX_DMA_ADDR);
ian@0 702
ian@0 703 /*
ian@0 704 * Assign to the Ethernet ports two consecutive MAC addresses
ian@0 705 * to match those that are printed on their stickers
ian@0 706 */
ian@0 707 memcpy(dev->dev_addr, au1000_mac_addr, sizeof(au1000_mac_addr));
ian@0 708 dev->dev_addr[5] += port_num;
ian@0 709
ian@0 710 *aup->enable = 0;
ian@0 711 aup->mac_enabled = 0;
ian@0 712
ian@0 713 aup->mii_bus.priv = dev;
ian@0 714 aup->mii_bus.read = mdiobus_read;
ian@0 715 aup->mii_bus.write = mdiobus_write;
ian@0 716 aup->mii_bus.reset = mdiobus_reset;
ian@0 717 aup->mii_bus.name = "au1000_eth_mii";
ian@0 718 aup->mii_bus.id = aup->mac_id;
ian@0 719 aup->mii_bus.irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL);
ian@0 720 for(i = 0; i < PHY_MAX_ADDR; ++i)
ian@0 721 aup->mii_bus.irq[i] = PHY_POLL;
ian@0 722
ian@0 723 /* if known, set corresponding PHY IRQs */
ian@0 724 #if defined(AU1XXX_PHY_STATIC_CONFIG)
ian@0 725 # if defined(AU1XXX_PHY0_IRQ)
ian@0 726 if (AU1XXX_PHY0_BUSID == aup->mii_bus.id)
ian@0 727 aup->mii_bus.irq[AU1XXX_PHY0_ADDR] = AU1XXX_PHY0_IRQ;
ian@0 728 # endif
ian@0 729 # if defined(AU1XXX_PHY1_IRQ)
ian@0 730 if (AU1XXX_PHY1_BUSID == aup->mii_bus.id)
ian@0 731 aup->mii_bus.irq[AU1XXX_PHY1_ADDR] = AU1XXX_PHY1_IRQ;
ian@0 732 # endif
ian@0 733 #endif
ian@0 734 mdiobus_register(&aup->mii_bus);
ian@0 735
ian@0 736 if (mii_probe(dev) != 0) {
ian@0 737 goto err_out;
ian@0 738 }
ian@0 739
ian@0 740 pDBfree = NULL;
ian@0 741 /* setup the data buffer descriptors and attach a buffer to each one */
ian@0 742 pDB = aup->db;
ian@0 743 for (i = 0; i < (NUM_TX_BUFFS+NUM_RX_BUFFS); i++) {
ian@0 744 pDB->pnext = pDBfree;
ian@0 745 pDBfree = pDB;
ian@0 746 pDB->vaddr = (u32 *)((unsigned)aup->vaddr + MAX_BUF_SIZE*i);
ian@0 747 pDB->dma_addr = (dma_addr_t)virt_to_bus(pDB->vaddr);
ian@0 748 pDB++;
ian@0 749 }
ian@0 750 aup->pDBfree = pDBfree;
ian@0 751
ian@0 752 for (i = 0; i < NUM_RX_DMA; i++) {
ian@0 753 pDB = GetFreeDB(aup);
ian@0 754 if (!pDB) {
ian@0 755 goto err_out;
ian@0 756 }
ian@0 757 aup->rx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr;
ian@0 758 aup->rx_db_inuse[i] = pDB;
ian@0 759 }
ian@0 760 for (i = 0; i < NUM_TX_DMA; i++) {
ian@0 761 pDB = GetFreeDB(aup);
ian@0 762 if (!pDB) {
ian@0 763 goto err_out;
ian@0 764 }
ian@0 765 aup->tx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr;
ian@0 766 aup->tx_dma_ring[i]->len = 0;
ian@0 767 aup->tx_db_inuse[i] = pDB;
ian@0 768 }
ian@0 769
ian@0 770 spin_lock_init(&aup->lock);
ian@0 771 dev->base_addr = base;
ian@0 772 dev->irq = irq;
ian@0 773 dev->open = au1000_open;
ian@0 774 dev->hard_start_xmit = au1000_tx;
ian@0 775 dev->stop = au1000_close;
ian@0 776 dev->get_stats = au1000_get_stats;
ian@0 777 dev->set_multicast_list = &set_rx_mode;
ian@0 778 dev->do_ioctl = &au1000_ioctl;
ian@0 779 SET_ETHTOOL_OPS(dev, &au1000_ethtool_ops);
ian@0 780 dev->tx_timeout = au1000_tx_timeout;
ian@0 781 dev->watchdog_timeo = ETH_TX_TIMEOUT;
ian@0 782
ian@0 783 /*
ian@0 784 * The boot code uses the ethernet controller, so reset it to start
ian@0 785 * fresh. au1000_init() expects that the device is in reset state.
ian@0 786 */
ian@0 787 reset_mac(dev);
ian@0 788
ian@0 789 return dev;
ian@0 790
ian@0 791 err_out:
ian@0 792 /* here we should have a valid dev plus aup-> register addresses
ian@0 793 * so we can reset the mac properly.*/
ian@0 794 reset_mac(dev);
ian@0 795
ian@0 796 for (i = 0; i < NUM_RX_DMA; i++) {
ian@0 797 if (aup->rx_db_inuse[i])
ian@0 798 ReleaseDB(aup, aup->rx_db_inuse[i]);
ian@0 799 }
ian@0 800 for (i = 0; i < NUM_TX_DMA; i++) {
ian@0 801 if (aup->tx_db_inuse[i])
ian@0 802 ReleaseDB(aup, aup->tx_db_inuse[i]);
ian@0 803 }
ian@0 804 dma_free_noncoherent(NULL, MAX_BUF_SIZE * (NUM_TX_BUFFS + NUM_RX_BUFFS),
ian@0 805 (void *)aup->vaddr, aup->dma_addr);
ian@0 806 unregister_netdev(dev);
ian@0 807 free_netdev(dev);
ian@0 808 release_mem_region( base, MAC_IOSIZE);
ian@0 809 release_mem_region(macen, 4);
ian@0 810 return NULL;
ian@0 811 }
ian@0 812
ian@0 813 /*
ian@0 814 * Initialize the interface.
ian@0 815 *
ian@0 816 * When the device powers up, the clocks are disabled and the
ian@0 817 * mac is in reset state. When the interface is closed, we
ian@0 818 * do the same -- reset the device and disable the clocks to
ian@0 819 * conserve power. Thus, whenever au1000_init() is called,
ian@0 820 * the device should already be in reset state.
ian@0 821 */
ian@0 822 static int au1000_init(struct net_device *dev)
ian@0 823 {
ian@0 824 struct au1000_private *aup = (struct au1000_private *) dev->priv;
ian@0 825 u32 flags;
ian@0 826 int i;
ian@0 827 u32 control;
ian@0 828
ian@0 829 if (au1000_debug > 4)
ian@0 830 printk("%s: au1000_init\n", dev->name);
ian@0 831
ian@0 832 /* bring the device out of reset */
ian@0 833 enable_mac(dev, 1);
ian@0 834
ian@0 835 spin_lock_irqsave(&aup->lock, flags);
ian@0 836
ian@0 837 aup->mac->control = 0;
ian@0 838 aup->tx_head = (aup->tx_dma_ring[0]->buff_stat & 0xC) >> 2;
ian@0 839 aup->tx_tail = aup->tx_head;
ian@0 840 aup->rx_head = (aup->rx_dma_ring[0]->buff_stat & 0xC) >> 2;
ian@0 841
ian@0 842 aup->mac->mac_addr_high = dev->dev_addr[5]<<8 | dev->dev_addr[4];
ian@0 843 aup->mac->mac_addr_low = dev->dev_addr[3]<<24 | dev->dev_addr[2]<<16 |
ian@0 844 dev->dev_addr[1]<<8 | dev->dev_addr[0];
ian@0 845
ian@0 846 for (i = 0; i < NUM_RX_DMA; i++) {
ian@0 847 aup->rx_dma_ring[i]->buff_stat |= RX_DMA_ENABLE;
ian@0 848 }
ian@0 849 au_sync();
ian@0 850
ian@0 851 control = MAC_RX_ENABLE | MAC_TX_ENABLE;
ian@0 852 #ifndef CONFIG_CPU_LITTLE_ENDIAN
ian@0 853 control |= MAC_BIG_ENDIAN;
ian@0 854 #endif
ian@0 855 if (aup->phy_dev) {
ian@0 856 if (aup->phy_dev->link && (DUPLEX_FULL == aup->phy_dev->duplex))
ian@0 857 control |= MAC_FULL_DUPLEX;
ian@0 858 else
ian@0 859 control |= MAC_DISABLE_RX_OWN;
ian@0 860 } else { /* PHY-less op, assume full-duplex */
ian@0 861 control |= MAC_FULL_DUPLEX;
ian@0 862 }
ian@0 863
ian@0 864 aup->mac->control = control;
ian@0 865 aup->mac->vlan1_tag = 0x8100; /* activate vlan support */
ian@0 866 au_sync();
ian@0 867
ian@0 868 spin_unlock_irqrestore(&aup->lock, flags);
ian@0 869 return 0;
ian@0 870 }
ian@0 871
ian@0 872 static void
ian@0 873 au1000_adjust_link(struct net_device *dev)
ian@0 874 {
ian@0 875 struct au1000_private *aup = (struct au1000_private *) dev->priv;
ian@0 876 struct phy_device *phydev = aup->phy_dev;
ian@0 877 unsigned long flags;
ian@0 878
ian@0 879 int status_change = 0;
ian@0 880
ian@0 881 BUG_ON(!aup->phy_dev);
ian@0 882
ian@0 883 spin_lock_irqsave(&aup->lock, flags);
ian@0 884
ian@0 885 if (phydev->link && (aup->old_speed != phydev->speed)) {
ian@0 886 // speed changed
ian@0 887
ian@0 888 switch(phydev->speed) {
ian@0 889 case SPEED_10:
ian@0 890 case SPEED_100:
ian@0 891 break;
ian@0 892 default:
ian@0 893 printk(KERN_WARNING
ian@0 894 "%s: Speed (%d) is not 10/100 ???\n",
ian@0 895 dev->name, phydev->speed);
ian@0 896 break;
ian@0 897 }
ian@0 898
ian@0 899 aup->old_speed = phydev->speed;
ian@0 900
ian@0 901 status_change = 1;
ian@0 902 }
ian@0 903
ian@0 904 if (phydev->link && (aup->old_duplex != phydev->duplex)) {
ian@0 905 // duplex mode changed
ian@0 906
ian@0 907 /* switching duplex mode requires to disable rx and tx! */
ian@0 908 hard_stop(dev);
ian@0 909
ian@0 910 if (DUPLEX_FULL == phydev->duplex)
ian@0 911 aup->mac->control = ((aup->mac->control
ian@0 912 | MAC_FULL_DUPLEX)
ian@0 913 & ~MAC_DISABLE_RX_OWN);
ian@0 914 else
ian@0 915 aup->mac->control = ((aup->mac->control
ian@0 916 & ~MAC_FULL_DUPLEX)
ian@0 917 | MAC_DISABLE_RX_OWN);
ian@0 918 au_sync_delay(1);
ian@0 919
ian@0 920 enable_rx_tx(dev);
ian@0 921 aup->old_duplex = phydev->duplex;
ian@0 922
ian@0 923 status_change = 1;
ian@0 924 }
ian@0 925
ian@0 926 if(phydev->link != aup->old_link) {
ian@0 927 // link state changed
ian@0 928
ian@0 929 if (phydev->link) // link went up
ian@0 930 netif_schedule(dev);
ian@0 931 else { // link went down
ian@0 932 aup->old_speed = 0;
ian@0 933 aup->old_duplex = -1;
ian@0 934 }
ian@0 935
ian@0 936 aup->old_link = phydev->link;
ian@0 937 status_change = 1;
ian@0 938 }
ian@0 939
ian@0 940 spin_unlock_irqrestore(&aup->lock, flags);
ian@0 941
ian@0 942 if (status_change) {
ian@0 943 if (phydev->link)
ian@0 944 printk(KERN_INFO "%s: link up (%d/%s)\n",
ian@0 945 dev->name, phydev->speed,
ian@0 946 DUPLEX_FULL == phydev->duplex ? "Full" : "Half");
ian@0 947 else
ian@0 948 printk(KERN_INFO "%s: link down\n", dev->name);
ian@0 949 }
ian@0 950 }
ian@0 951
ian@0 952 static int au1000_open(struct net_device *dev)
ian@0 953 {
ian@0 954 int retval;
ian@0 955 struct au1000_private *aup = (struct au1000_private *) dev->priv;
ian@0 956
ian@0 957 if (au1000_debug > 4)
ian@0 958 printk("%s: open: dev=%p\n", dev->name, dev);
ian@0 959
ian@0 960 if ((retval = request_irq(dev->irq, &au1000_interrupt, 0,
ian@0 961 dev->name, dev))) {
ian@0 962 printk(KERN_ERR "%s: unable to get IRQ %d\n",
ian@0 963 dev->name, dev->irq);
ian@0 964 return retval;
ian@0 965 }
ian@0 966
ian@0 967 if ((retval = au1000_init(dev))) {
ian@0 968 printk(KERN_ERR "%s: error in au1000_init\n", dev->name);
ian@0 969 free_irq(dev->irq, dev);
ian@0 970 return retval;
ian@0 971 }
ian@0 972
ian@0 973 if (aup->phy_dev) {
ian@0 974 /* cause the PHY state machine to schedule a link state check */
ian@0 975 aup->phy_dev->state = PHY_CHANGELINK;
ian@0 976 phy_start(aup->phy_dev);
ian@0 977 }
ian@0 978
ian@0 979 netif_start_queue(dev);
ian@0 980
ian@0 981 if (au1000_debug > 4)
ian@0 982 printk("%s: open: Initialization done.\n", dev->name);
ian@0 983
ian@0 984 return 0;
ian@0 985 }
ian@0 986
ian@0 987 static int au1000_close(struct net_device *dev)
ian@0 988 {
ian@0 989 unsigned long flags;
ian@0 990 struct au1000_private *const aup = (struct au1000_private *) dev->priv;
ian@0 991
ian@0 992 if (au1000_debug > 4)
ian@0 993 printk("%s: close: dev=%p\n", dev->name, dev);
ian@0 994
ian@0 995 if (aup->phy_dev)
ian@0 996 phy_stop(aup->phy_dev);
ian@0 997
ian@0 998 spin_lock_irqsave(&aup->lock, flags);
ian@0 999
ian@0 1000 reset_mac_unlocked (dev);
ian@0 1001
ian@0 1002 /* stop the device */
ian@0 1003 netif_stop_queue(dev);
ian@0 1004
ian@0 1005 /* disable the interrupt */
ian@0 1006 free_irq(dev->irq, dev);
ian@0 1007 spin_unlock_irqrestore(&aup->lock, flags);
ian@0 1008
ian@0 1009 return 0;
ian@0 1010 }
ian@0 1011
ian@0 1012 static void __exit au1000_cleanup_module(void)
ian@0 1013 {
ian@0 1014 int i, j;
ian@0 1015 struct net_device *dev;
ian@0 1016 struct au1000_private *aup;
ian@0 1017
ian@0 1018 for (i = 0; i < num_ifs; i++) {
ian@0 1019 dev = iflist[i].dev;
ian@0 1020 if (dev) {
ian@0 1021 aup = (struct au1000_private *) dev->priv;
ian@0 1022 unregister_netdev(dev);
ian@0 1023 for (j = 0; j < NUM_RX_DMA; j++)
ian@0 1024 if (aup->rx_db_inuse[j])
ian@0 1025 ReleaseDB(aup, aup->rx_db_inuse[j]);
ian@0 1026 for (j = 0; j < NUM_TX_DMA; j++)
ian@0 1027 if (aup->tx_db_inuse[j])
ian@0 1028 ReleaseDB(aup, aup->tx_db_inuse[j]);
ian@0 1029 dma_free_noncoherent(NULL, MAX_BUF_SIZE *
ian@0 1030 (NUM_TX_BUFFS + NUM_RX_BUFFS),
ian@0 1031 (void *)aup->vaddr, aup->dma_addr);
ian@0 1032 release_mem_region(dev->base_addr, MAC_IOSIZE);
ian@0 1033 release_mem_region(CPHYSADDR(iflist[i].macen_addr), 4);
ian@0 1034 free_netdev(dev);
ian@0 1035 }
ian@0 1036 }
ian@0 1037 }
ian@0 1038
ian@0 1039 static void update_tx_stats(struct net_device *dev, u32 status)
ian@0 1040 {
ian@0 1041 struct au1000_private *aup = (struct au1000_private *) dev->priv;
ian@0 1042 struct net_device_stats *ps = &aup->stats;
ian@0 1043
ian@0 1044 if (status & TX_FRAME_ABORTED) {
ian@0 1045 if (!aup->phy_dev || (DUPLEX_FULL == aup->phy_dev->duplex)) {
ian@0 1046 if (status & (TX_JAB_TIMEOUT | TX_UNDERRUN)) {
ian@0 1047 /* any other tx errors are only valid
ian@0 1048 * in half duplex mode */
ian@0 1049 ps->tx_errors++;
ian@0 1050 ps->tx_aborted_errors++;
ian@0 1051 }
ian@0 1052 }
ian@0 1053 else {
ian@0 1054 ps->tx_errors++;
ian@0 1055 ps->tx_aborted_errors++;
ian@0 1056 if (status & (TX_NO_CARRIER | TX_LOSS_CARRIER))
ian@0 1057 ps->tx_carrier_errors++;
ian@0 1058 }
ian@0 1059 }
ian@0 1060 }
ian@0 1061
ian@0 1062
ian@0 1063 /*
ian@0 1064 * Called from the interrupt service routine to acknowledge
ian@0 1065 * the TX DONE bits. This is a must if the irq is setup as
ian@0 1066 * edge triggered.
ian@0 1067 */
ian@0 1068 static void au1000_tx_ack(struct net_device *dev)
ian@0 1069 {
ian@0 1070 struct au1000_private *aup = (struct au1000_private *) dev->priv;
ian@0 1071 volatile tx_dma_t *ptxd;
ian@0 1072
ian@0 1073 ptxd = aup->tx_dma_ring[aup->tx_tail];
ian@0 1074
ian@0 1075 while (ptxd->buff_stat & TX_T_DONE) {
ian@0 1076 update_tx_stats(dev, ptxd->status);
ian@0 1077 ptxd->buff_stat &= ~TX_T_DONE;
ian@0 1078 ptxd->len = 0;
ian@0 1079 au_sync();
ian@0 1080
ian@0 1081 aup->tx_tail = (aup->tx_tail + 1) & (NUM_TX_DMA - 1);
ian@0 1082 ptxd = aup->tx_dma_ring[aup->tx_tail];
ian@0 1083
ian@0 1084 if (aup->tx_full) {
ian@0 1085 aup->tx_full = 0;
ian@0 1086 netif_wake_queue(dev);
ian@0 1087 }
ian@0 1088 }
ian@0 1089 }
ian@0 1090
ian@0 1091
ian@0 1092 /*
ian@0 1093 * Au1000 transmit routine.
ian@0 1094 */
ian@0 1095 static int au1000_tx(struct sk_buff *skb, struct net_device *dev)
ian@0 1096 {
ian@0 1097 struct au1000_private *aup = (struct au1000_private *) dev->priv;
ian@0 1098 struct net_device_stats *ps = &aup->stats;
ian@0 1099 volatile tx_dma_t *ptxd;
ian@0 1100 u32 buff_stat;
ian@0 1101 db_dest_t *pDB;
ian@0 1102 int i;
ian@0 1103
ian@0 1104 if (au1000_debug > 5)
ian@0 1105 printk("%s: tx: aup %x len=%d, data=%p, head %d\n",
ian@0 1106 dev->name, (unsigned)aup, skb->len,
ian@0 1107 skb->data, aup->tx_head);
ian@0 1108
ian@0 1109 ptxd = aup->tx_dma_ring[aup->tx_head];
ian@0 1110 buff_stat = ptxd->buff_stat;
ian@0 1111 if (buff_stat & TX_DMA_ENABLE) {
ian@0 1112 /* We've wrapped around and the transmitter is still busy */
ian@0 1113 netif_stop_queue(dev);
ian@0 1114 aup->tx_full = 1;
ian@0 1115 return 1;
ian@0 1116 }
ian@0 1117 else if (buff_stat & TX_T_DONE) {
ian@0 1118 update_tx_stats(dev, ptxd->status);
ian@0 1119 ptxd->len = 0;
ian@0 1120 }
ian@0 1121
ian@0 1122 if (aup->tx_full) {
ian@0 1123 aup->tx_full = 0;
ian@0 1124 netif_wake_queue(dev);
ian@0 1125 }
ian@0 1126
ian@0 1127 pDB = aup->tx_db_inuse[aup->tx_head];
ian@0 1128 memcpy((void *)pDB->vaddr, skb->data, skb->len);
ian@0 1129 if (skb->len < ETH_ZLEN) {
ian@0 1130 for (i=skb->len; i<ETH_ZLEN; i++) {
ian@0 1131 ((char *)pDB->vaddr)[i] = 0;
ian@0 1132 }
ian@0 1133 ptxd->len = ETH_ZLEN;
ian@0 1134 }
ian@0 1135 else
ian@0 1136 ptxd->len = skb->len;
ian@0 1137
ian@0 1138 ps->tx_packets++;
ian@0 1139 ps->tx_bytes += ptxd->len;
ian@0 1140
ian@0 1141 ptxd->buff_stat = pDB->dma_addr | TX_DMA_ENABLE;
ian@0 1142 au_sync();
ian@0 1143 dev_kfree_skb(skb);
ian@0 1144 aup->tx_head = (aup->tx_head + 1) & (NUM_TX_DMA - 1);
ian@0 1145 dev->trans_start = jiffies;
ian@0 1146 return 0;
ian@0 1147 }
ian@0 1148
ian@0 1149 static inline void update_rx_stats(struct net_device *dev, u32 status)
ian@0 1150 {
ian@0 1151 struct au1000_private *aup = (struct au1000_private *) dev->priv;
ian@0 1152 struct net_device_stats *ps = &aup->stats;
ian@0 1153
ian@0 1154 ps->rx_packets++;
ian@0 1155 if (status & RX_MCAST_FRAME)
ian@0 1156 ps->multicast++;
ian@0 1157
ian@0 1158 if (status & RX_ERROR) {
ian@0 1159 ps->rx_errors++;
ian@0 1160 if (status & RX_MISSED_FRAME)
ian@0 1161 ps->rx_missed_errors++;
ian@0 1162 if (status & (RX_OVERLEN | RX_OVERLEN | RX_LEN_ERROR))
ian@0 1163 ps->rx_length_errors++;
ian@0 1164 if (status & RX_CRC_ERROR)
ian@0 1165 ps->rx_crc_errors++;
ian@0 1166 if (status & RX_COLL)
ian@0 1167 ps->collisions++;
ian@0 1168 }
ian@0 1169 else
ian@0 1170 ps->rx_bytes += status & RX_FRAME_LEN_MASK;
ian@0 1171
ian@0 1172 }
ian@0 1173
ian@0 1174 /*
ian@0 1175 * Au1000 receive routine.
ian@0 1176 */
ian@0 1177 static int au1000_rx(struct net_device *dev)
ian@0 1178 {
ian@0 1179 struct au1000_private *aup = (struct au1000_private *) dev->priv;
ian@0 1180 struct sk_buff *skb;
ian@0 1181 volatile rx_dma_t *prxd;
ian@0 1182 u32 buff_stat, status;
ian@0 1183 db_dest_t *pDB;
ian@0 1184 u32 frmlen;
ian@0 1185
ian@0 1186 if (au1000_debug > 5)
ian@0 1187 printk("%s: au1000_rx head %d\n", dev->name, aup->rx_head);
ian@0 1188
ian@0 1189 prxd = aup->rx_dma_ring[aup->rx_head];
ian@0 1190 buff_stat = prxd->buff_stat;
ian@0 1191 while (buff_stat & RX_T_DONE) {
ian@0 1192 status = prxd->status;
ian@0 1193 pDB = aup->rx_db_inuse[aup->rx_head];
ian@0 1194 update_rx_stats(dev, status);
ian@0 1195 if (!(status & RX_ERROR)) {
ian@0 1196
ian@0 1197 /* good frame */
ian@0 1198 frmlen = (status & RX_FRAME_LEN_MASK);
ian@0 1199 frmlen -= 4; /* Remove FCS */
ian@0 1200 skb = dev_alloc_skb(frmlen + 2);
ian@0 1201 if (skb == NULL) {
ian@0 1202 printk(KERN_ERR
ian@0 1203 "%s: Memory squeeze, dropping packet.\n",
ian@0 1204 dev->name);
ian@0 1205 aup->stats.rx_dropped++;
ian@0 1206 continue;
ian@0 1207 }
ian@0 1208 skb->dev = dev;
ian@0 1209 skb_reserve(skb, 2); /* 16 byte IP header align */
ian@0 1210 eth_copy_and_sum(skb,
ian@0 1211 (unsigned char *)pDB->vaddr, frmlen, 0);
ian@0 1212 skb_put(skb, frmlen);
ian@0 1213 skb->protocol = eth_type_trans(skb, dev);
ian@0 1214 netif_rx(skb); /* pass the packet to upper layers */
ian@0 1215 }
ian@0 1216 else {
ian@0 1217 if (au1000_debug > 4) {
ian@0 1218 if (status & RX_MISSED_FRAME)
ian@0 1219 printk("rx miss\n");
ian@0 1220 if (status & RX_WDOG_TIMER)
ian@0 1221 printk("rx wdog\n");
ian@0 1222 if (status & RX_RUNT)
ian@0 1223 printk("rx runt\n");
ian@0 1224 if (status & RX_OVERLEN)
ian@0 1225 printk("rx overlen\n");
ian@0 1226 if (status & RX_COLL)
ian@0 1227 printk("rx coll\n");
ian@0 1228 if (status & RX_MII_ERROR)
ian@0 1229 printk("rx mii error\n");
ian@0 1230 if (status & RX_CRC_ERROR)
ian@0 1231 printk("rx crc error\n");
ian@0 1232 if (status & RX_LEN_ERROR)
ian@0 1233 printk("rx len error\n");
ian@0 1234 if (status & RX_U_CNTRL_FRAME)
ian@0 1235 printk("rx u control frame\n");
ian@0 1236 if (status & RX_MISSED_FRAME)
ian@0 1237 printk("rx miss\n");
ian@0 1238 }
ian@0 1239 }
ian@0 1240 prxd->buff_stat = (u32)(pDB->dma_addr | RX_DMA_ENABLE);
ian@0 1241 aup->rx_head = (aup->rx_head + 1) & (NUM_RX_DMA - 1);
ian@0 1242 au_sync();
ian@0 1243
ian@0 1244 /* next descriptor */
ian@0 1245 prxd = aup->rx_dma_ring[aup->rx_head];
ian@0 1246 buff_stat = prxd->buff_stat;
ian@0 1247 dev->last_rx = jiffies;
ian@0 1248 }
ian@0 1249 return 0;
ian@0 1250 }
ian@0 1251
ian@0 1252
ian@0 1253 /*
ian@0 1254 * Au1000 interrupt service routine.
ian@0 1255 */
ian@0 1256 static irqreturn_t au1000_interrupt(int irq, void *dev_id, struct pt_regs *regs)
ian@0 1257 {
ian@0 1258 struct net_device *dev = (struct net_device *) dev_id;
ian@0 1259
ian@0 1260 if (dev == NULL) {
ian@0 1261 printk(KERN_ERR "%s: isr: null dev ptr\n", dev->name);
ian@0 1262 return IRQ_RETVAL(1);
ian@0 1263 }
ian@0 1264
ian@0 1265 /* Handle RX interrupts first to minimize chance of overrun */
ian@0 1266
ian@0 1267 au1000_rx(dev);
ian@0 1268 au1000_tx_ack(dev);
ian@0 1269 return IRQ_RETVAL(1);
ian@0 1270 }
ian@0 1271
ian@0 1272
ian@0 1273 /*
ian@0 1274 * The Tx ring has been full longer than the watchdog timeout
ian@0 1275 * value. The transmitter must be hung?
ian@0 1276 */
ian@0 1277 static void au1000_tx_timeout(struct net_device *dev)
ian@0 1278 {
ian@0 1279 printk(KERN_ERR "%s: au1000_tx_timeout: dev=%p\n", dev->name, dev);
ian@0 1280 reset_mac(dev);
ian@0 1281 au1000_init(dev);
ian@0 1282 dev->trans_start = jiffies;
ian@0 1283 netif_wake_queue(dev);
ian@0 1284 }
ian@0 1285
ian@0 1286 static void set_rx_mode(struct net_device *dev)
ian@0 1287 {
ian@0 1288 struct au1000_private *aup = (struct au1000_private *) dev->priv;
ian@0 1289
ian@0 1290 if (au1000_debug > 4)
ian@0 1291 printk("%s: set_rx_mode: flags=%x\n", dev->name, dev->flags);
ian@0 1292
ian@0 1293 if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */
ian@0 1294 aup->mac->control |= MAC_PROMISCUOUS;
ian@0 1295 printk(KERN_INFO "%s: Promiscuous mode enabled.\n", dev->name);
ian@0 1296 } else if ((dev->flags & IFF_ALLMULTI) ||
ian@0 1297 dev->mc_count > MULTICAST_FILTER_LIMIT) {
ian@0 1298 aup->mac->control |= MAC_PASS_ALL_MULTI;
ian@0 1299 aup->mac->control &= ~MAC_PROMISCUOUS;
ian@0 1300 printk(KERN_INFO "%s: Pass all multicast\n", dev->name);
ian@0 1301 } else {
ian@0 1302 int i;
ian@0 1303 struct dev_mc_list *mclist;
ian@0 1304 u32 mc_filter[2]; /* Multicast hash filter */
ian@0 1305
ian@0 1306 mc_filter[1] = mc_filter[0] = 0;
ian@0 1307 for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
ian@0 1308 i++, mclist = mclist->next) {
ian@0 1309 set_bit(ether_crc(ETH_ALEN, mclist->dmi_addr)>>26,
ian@0 1310 (long *)mc_filter);
ian@0 1311 }
ian@0 1312 aup->mac->multi_hash_high = mc_filter[1];
ian@0 1313 aup->mac->multi_hash_low = mc_filter[0];
ian@0 1314 aup->mac->control &= ~MAC_PROMISCUOUS;
ian@0 1315 aup->mac->control |= MAC_HASH_MODE;
ian@0 1316 }
ian@0 1317 }
ian@0 1318
ian@0 1319 static int au1000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
ian@0 1320 {
ian@0 1321 struct au1000_private *aup = (struct au1000_private *)dev->priv;
ian@0 1322
ian@0 1323 if (!netif_running(dev)) return -EINVAL;
ian@0 1324
ian@0 1325 if (!aup->phy_dev) return -EINVAL; // PHY not controllable
ian@0 1326
ian@0 1327 return phy_mii_ioctl(aup->phy_dev, if_mii(rq), cmd);
ian@0 1328 }
ian@0 1329
ian@0 1330 static struct net_device_stats *au1000_get_stats(struct net_device *dev)
ian@0 1331 {
ian@0 1332 struct au1000_private *aup = (struct au1000_private *) dev->priv;
ian@0 1333
ian@0 1334 if (au1000_debug > 4)
ian@0 1335 printk("%s: au1000_get_stats: dev=%p\n", dev->name, dev);
ian@0 1336
ian@0 1337 if (netif_device_present(dev)) {
ian@0 1338 return &aup->stats;
ian@0 1339 }
ian@0 1340 return 0;
ian@0 1341 }
ian@0 1342
ian@0 1343 module_init(au1000_init_module);
ian@0 1344 module_exit(au1000_cleanup_module);