dm9000.c 31.2 KB
Newer Older
S
Sascha Hauer 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
/*
 *   dm9000.c: Version 1.2 03/18/2003
 *
 *         A Davicom DM9000 ISA NIC fast Ethernet driver for Linux.
 * 	Copyright (C) 1997  Sten Wang
 *
 * 	This program is free software; you can redistribute it and/or
 * 	modify it under the terms of the GNU General Public License
 * 	as published by the Free Software Foundation; either version 2
 * 	of the License, or (at your option) any later version.
 *
 * 	This program is distributed in the hope that it will be useful,
 * 	but WITHOUT ANY WARRANTY; without even the implied warranty of
 * 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * 	GNU General Public License for more details.
 *
 *   (C)Copyright 1997-1998 DAVICOM Semiconductor,Inc. All Rights Reserved.
 *
 * V0.11	06/20/2001	REG_0A bit3=1, default enable BP with DA match
 * 	06/22/2001 	Support DM9801 progrmming
 * 	 	 	E3: R25 = ((R24 + NF) & 0x00ff) | 0xf000
 * 		 	E4: R25 = ((R24 + NF) & 0x00ff) | 0xc200
 * 		     		R17 = (R17 & 0xfff0) | NF + 3
 * 		 	E5: R25 = ((R24 + NF - 3) & 0x00ff) | 0xc200
 * 		     		R17 = (R17 & 0xfff0) | NF
 *
 * v1.00               	modify by simon 2001.9.5
 *                         change for kernel 2.4.x
 *
 * v1.1   11/09/2001      	fix force mode bug
 *
 * v1.2   03/18/2003       Weilun Huang <weilun_huang@davicom.com.tw>:
 * 			Fixed phy reset.
 * 			Added tx/rx 32 bit mode.
 * 			Cleaned up for kernel merge.
 *
 *        03/03/2004    Sascha Hauer <s.hauer@pengutronix.de>
 *                      Port to 2.6 kernel
 *
 *	  24-Sep-2004   Ben Dooks <ben@simtec.co.uk>
 *			Cleanup of code to remove ifdefs
 *			Allowed platform device data to influence access width
 *			Reformatting areas of code
 *
 *        17-Mar-2005   Sascha Hauer <s.hauer@pengutronix.de>
 *                      * removed 2.4 style module parameters
 *                      * removed removed unused stat counter and fixed
 *                        net_device_stats
 *                      * introduced tx_timeout function
 *                      * reworked locking
B
Ben Dooks 已提交
51 52 53 54
 *
 *	  01-Jul-2005   Ben Dooks <ben@simtec.co.uk>
 *			* fixed spinlock call without pointer
 *			* ensure spinlock is initialised
S
Sascha Hauer 已提交
55 56 57 58 59 60 61 62 63 64 65
 */

#include <linux/module.h>
#include <linux/ioport.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/init.h>
#include <linux/skbuff.h>
#include <linux/spinlock.h>
#include <linux/crc32.h>
#include <linux/mii.h>
B
Ben Dooks 已提交
66
#include <linux/ethtool.h>
S
Sascha Hauer 已提交
67 68
#include <linux/dm9000.h>
#include <linux/delay.h>
69
#include <linux/platform_device.h>
70
#include <linux/irq.h>
S
Sascha Hauer 已提交
71 72 73 74 75 76 77 78 79 80 81 82 83

#include <asm/delay.h>
#include <asm/irq.h>
#include <asm/io.h>

#include "dm9000.h"

/* Board/System/Debug information/definition ---------------- */

#define DM9000_PHY		0x40	/* PHY address 0x01 */

#define CARDNAME "dm9000"
#define PFX CARDNAME ": "
B
Ben Dooks 已提交
84
#define DRV_VERSION	"1.30"
S
Sascha Hauer 已提交
85

86 87 88 89 90 91 92
#ifdef CONFIG_BLACKFIN
#define readsb	insb
#define readsw	insw
#define readsl	insl
#define writesb	outsb
#define writesw	outsw
#define writesl	outsl
93
#define DEFAULT_TRIGGER IRQF_TRIGGER_HIGH
94
#else
95
#define DEFAULT_TRIGGER (0)
96 97
#endif

S
Sascha Hauer 已提交
98 99 100 101 102 103 104
/*
 * Transmit timeout, default 5 seconds.
 */
static int watchdog = 5000;
module_param(watchdog, int, 0400);
MODULE_PARM_DESC(watchdog, "transmit timeout in milliseconds");

B
Ben Dooks 已提交
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
/* DM9000 register address locking.
 *
 * The DM9000 uses an address register to control where data written
 * to the data register goes. This means that the address register
 * must be preserved over interrupts or similar calls.
 *
 * During interrupt and other critical calls, a spinlock is used to
 * protect the system, but the calls themselves save the address
 * in the address register in case they are interrupting another
 * access to the device.
 *
 * For general accesses a lock is provided so that calls which are
 * allowed to sleep are serialised so that the address register does
 * not need to be saved. This lock also serves to serialise access
 * to the EEPROM and PHY access registers which are shared between
 * these two devices.
 */

S
Sascha Hauer 已提交
123 124 125 126 127 128 129 130 131 132 133 134 135
/* Structure/enum declaration ------------------------------- */
typedef struct board_info {

	void __iomem *io_addr;	/* Register I/O base address */
	void __iomem *io_data;	/* Data I/O address */
	u16 irq;		/* IRQ */

	u16 tx_pkt_cnt;
	u16 queue_pkt_len;
	u16 queue_start_addr;
	u16 dbug_cnt;
	u8 io_mode;		/* 0:word, 2:byte */
	u8 phy_addr;
136
	unsigned int flags;
137
	unsigned int in_suspend :1;
S
Sascha Hauer 已提交
138

139 140
	int debug_level;

S
Sascha Hauer 已提交
141 142 143 144
	void (*inblk)(void __iomem *port, void *data, int length);
	void (*outblk)(void __iomem *port, void *data, int length);
	void (*dumpblk)(void __iomem *port, int length);

145 146
	struct device	*dev;	     /* parent device */

S
Sascha Hauer 已提交
147 148 149 150 151 152
	struct resource	*addr_res;   /* resources found */
	struct resource *data_res;
	struct resource	*addr_req;   /* resources requested */
	struct resource *data_req;
	struct resource *irq_res;

B
Ben Dooks 已提交
153 154
	struct mutex	 addr_lock;	/* phy and eeprom access lock */

S
Sascha Hauer 已提交
155 156 157 158 159 160
	spinlock_t lock;

	struct mii_if_info mii;
	u32 msg_enable;
} board_info_t;

161 162 163 164 165 166 167 168 169
/* debug code */

#define dm9000_dbg(db, lev, msg...) do {		\
	if ((lev) < CONFIG_DM9000_DEBUGLEVEL &&		\
	    (lev) < db->debug_level) {			\
		dev_dbg(db->dev, msg);			\
	}						\
} while (0)

B
Ben Dooks 已提交
170 171 172 173 174
static inline board_info_t *to_dm9000_board(struct net_device *dev)
{
	return dev->priv;
}

S
Sascha Hauer 已提交
175
/* function declaration ------------------------------------- */
176
static int dm9000_probe(struct platform_device *);
S
Sascha Hauer 已提交
177 178 179 180 181 182
static int dm9000_open(struct net_device *);
static int dm9000_start_xmit(struct sk_buff *, struct net_device *);
static int dm9000_stop(struct net_device *);

static void dm9000_init_dm9000(struct net_device *);

183
static irqreturn_t dm9000_interrupt(int, void *);
S
Sascha Hauer 已提交
184 185 186 187

static int dm9000_phy_read(struct net_device *dev, int phyaddr_unsused, int reg);
static void dm9000_phy_write(struct net_device *dev, int phyaddr_unused, int reg,
			   int value);
188

189 190
static void dm9000_read_eeprom(board_info_t *, int addr, u8 *to);
static void dm9000_write_eeprom(board_info_t *, int addr, u8 *dp);
S
Sascha Hauer 已提交
191 192 193 194 195 196 197 198
static void dm9000_rx(struct net_device *);
static void dm9000_hash_table(struct net_device *);

/* DM9000 network board routine ---------------------------- */

static void
dm9000_reset(board_info_t * db)
{
199 200
	dev_dbg(db->dev, "resetting device\n");

S
Sascha Hauer 已提交
201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249
	/* RESET device */
	writeb(DM9000_NCR, db->io_addr);
	udelay(200);
	writeb(NCR_RST, db->io_data);
	udelay(200);
}

/*
 *   Read a byte from I/O port
 */
static u8
ior(board_info_t * db, int reg)
{
	writeb(reg, db->io_addr);
	return readb(db->io_data);
}

/*
 *   Write a byte to I/O port
 */

static void
iow(board_info_t * db, int reg, int value)
{
	writeb(reg, db->io_addr);
	writeb(value, db->io_data);
}

/* routines for sending block to chip */

static void dm9000_outblk_8bit(void __iomem *reg, void *data, int count)
{
	writesb(reg, data, count);
}

static void dm9000_outblk_16bit(void __iomem *reg, void *data, int count)
{
	writesw(reg, data, (count+1) >> 1);
}

static void dm9000_outblk_32bit(void __iomem *reg, void *data, int count)
{
	writesl(reg, data, (count+3) >> 2);
}

/* input block from chip to memory */

static void dm9000_inblk_8bit(void __iomem *reg, void *data, int count)
{
250
	readsb(reg, data, count);
S
Sascha Hauer 已提交
251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317
}


static void dm9000_inblk_16bit(void __iomem *reg, void *data, int count)
{
	readsw(reg, data, (count+1) >> 1);
}

static void dm9000_inblk_32bit(void __iomem *reg, void *data, int count)
{
	readsl(reg, data, (count+3) >> 2);
}

/* dump block from chip to null */

static void dm9000_dumpblk_8bit(void __iomem *reg, int count)
{
	int i;
	int tmp;

	for (i = 0; i < count; i++)
		tmp = readb(reg);
}

static void dm9000_dumpblk_16bit(void __iomem *reg, int count)
{
	int i;
	int tmp;

	count = (count + 1) >> 1;

	for (i = 0; i < count; i++)
		tmp = readw(reg);
}

static void dm9000_dumpblk_32bit(void __iomem *reg, int count)
{
	int i;
	int tmp;

	count = (count + 3) >> 2;

	for (i = 0; i < count; i++)
		tmp = readl(reg);
}

/* dm9000_set_io
 *
 * select the specified set of io routines to use with the
 * device
 */

static void dm9000_set_io(struct board_info *db, int byte_width)
{
	/* use the size of the data resource to work out what IO
	 * routines we want to use
	 */

	switch (byte_width) {
	case 1:
		db->dumpblk = dm9000_dumpblk_8bit;
		db->outblk  = dm9000_outblk_8bit;
		db->inblk   = dm9000_inblk_8bit;
		break;


	case 3:
318 319
		dev_dbg(db->dev, ": 3 byte IO, falling back to 16bit\n");
	case 2:
S
Sascha Hauer 已提交
320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343
		db->dumpblk = dm9000_dumpblk_16bit;
		db->outblk  = dm9000_outblk_16bit;
		db->inblk   = dm9000_inblk_16bit;
		break;

	case 4:
	default:
		db->dumpblk = dm9000_dumpblk_32bit;
		db->outblk  = dm9000_outblk_32bit;
		db->inblk   = dm9000_inblk_32bit;
		break;
	}
}


/* Our watchdog timed out. Called by the networking layer */
static void dm9000_timeout(struct net_device *dev)
{
	board_info_t *db = (board_info_t *) dev->priv;
	u8 reg_save;
	unsigned long flags;

	/* Save previous register address */
	reg_save = readb(db->io_addr);
B
Ben Dooks 已提交
344
	spin_lock_irqsave(&db->lock,flags);
S
Sascha Hauer 已提交
345 346 347 348 349 350 351 352 353 354

	netif_stop_queue(dev);
	dm9000_reset(db);
	dm9000_init_dm9000(dev);
	/* We can accept TX packets again */
	dev->trans_start = jiffies;
	netif_wake_queue(dev);

	/* Restore previous register address */
	writeb(reg_save, db->io_addr);
B
Ben Dooks 已提交
355
	spin_unlock_irqrestore(&db->lock,flags);
S
Sascha Hauer 已提交
356 357
}

358 359 360 361 362 363 364
#ifdef CONFIG_NET_POLL_CONTROLLER
/*
 *Used by netconsole
 */
static void dm9000_poll_controller(struct net_device *dev)
{
	disable_irq(dev->irq);
A
Al Viro 已提交
365
	dm9000_interrupt(dev->irq,dev);
366 367 368
	enable_irq(dev->irq);
}
#endif
S
Sascha Hauer 已提交
369

B
Ben Dooks 已提交
370 371 372 373 374 375 376 377 378 379 380 381
/* ethtool ops */

static void dm9000_get_drvinfo(struct net_device *dev,
			       struct ethtool_drvinfo *info)
{
	board_info_t *dm = to_dm9000_board(dev);

	strcpy(info->driver, CARDNAME);
	strcpy(info->version, DRV_VERSION);
	strcpy(info->bus_info, to_platform_device(dm->dev)->name);
}

382 383 384 385 386 387 388 389 390 391 392 393 394 395
static u32 dm9000_get_msglevel(struct net_device *dev)
{
	board_info_t *dm = to_dm9000_board(dev);

	return dm->msg_enable;
}

static void dm9000_set_msglevel(struct net_device *dev, u32 value)
{
	board_info_t *dm = to_dm9000_board(dev);

	dm->msg_enable = value;
}

B
Ben Dooks 已提交
396 397 398 399 400 401 402 403 404 405 406 407
static int dm9000_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
	board_info_t *dm = to_dm9000_board(dev);

	mii_ethtool_gset(&dm->mii, cmd);
	return 0;
}

static int dm9000_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
	board_info_t *dm = to_dm9000_board(dev);

B
Ben Dooks 已提交
408
	return mii_ethtool_sset(&dm->mii, cmd);
B
Ben Dooks 已提交
409 410 411 412 413 414 415 416 417 418 419 420 421 422
}

static int dm9000_nway_reset(struct net_device *dev)
{
	board_info_t *dm = to_dm9000_board(dev);
	return mii_nway_restart(&dm->mii);
}

static u32 dm9000_get_link(struct net_device *dev)
{
	board_info_t *dm = to_dm9000_board(dev);
	return mii_link_ok(&dm->mii);
}

423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472
#define DM_EEPROM_MAGIC		(0x444D394B)

static int dm9000_get_eeprom_len(struct net_device *dev)
{
	return 128;
}

static int dm9000_get_eeprom(struct net_device *dev,
			     struct ethtool_eeprom *ee, u8 *data)
{
	board_info_t *dm = to_dm9000_board(dev);
	int offset = ee->offset;
	int len = ee->len;
	int i;

	/* EEPROM access is aligned to two bytes */

	if ((len & 1) != 0 || (offset & 1) != 0)
		return -EINVAL;

	ee->magic = DM_EEPROM_MAGIC;

	for (i = 0; i < len; i += 2)
		dm9000_read_eeprom(dm, (offset + i) / 2, data + i);

	return 0;
}

static int dm9000_set_eeprom(struct net_device *dev,
			     struct ethtool_eeprom *ee, u8 *data)
{
	board_info_t *dm = to_dm9000_board(dev);
	int offset = ee->offset;
	int len = ee->len;
	int i;

	/* EEPROM access is aligned to two bytes */

	if ((len & 1) != 0 || (offset & 1) != 0)
		return -EINVAL;

	if (ee->magic != DM_EEPROM_MAGIC)
		return -EINVAL;

	for (i = 0; i < len; i += 2)
		dm9000_write_eeprom(dm, (offset + i) / 2, data + i);

	return 0;
}

B
Ben Dooks 已提交
473 474 475 476
static const struct ethtool_ops dm9000_ethtool_ops = {
	.get_drvinfo		= dm9000_get_drvinfo,
	.get_settings		= dm9000_get_settings,
	.set_settings		= dm9000_set_settings,
477 478
	.get_msglevel		= dm9000_get_msglevel,
	.set_msglevel		= dm9000_set_msglevel,
B
Ben Dooks 已提交
479 480
	.nway_reset		= dm9000_nway_reset,
	.get_link		= dm9000_get_link,
481 482 483
 	.get_eeprom_len		= dm9000_get_eeprom_len,
 	.get_eeprom		= dm9000_get_eeprom,
 	.set_eeprom		= dm9000_set_eeprom,
B
Ben Dooks 已提交
484 485 486
};


S
Sascha Hauer 已提交
487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512
/* dm9000_release_board
 *
 * release a board, and any mapped resources
 */

static void
dm9000_release_board(struct platform_device *pdev, struct board_info *db)
{
	if (db->data_res == NULL) {
		if (db->addr_res != NULL)
			release_mem_region((unsigned long)db->io_addr, 4);
		return;
	}

	/* unmap our resources */

	iounmap(db->io_addr);
	iounmap(db->io_data);

	/* release the resources */

	if (db->data_req != NULL) {
		release_resource(db->data_req);
		kfree(db->data_req);
	}

D
Dirk Opfer 已提交
513 514
	if (db->addr_req != NULL) {
		release_resource(db->addr_req);
S
Sascha Hauer 已提交
515 516 517 518 519 520 521 522 523 524
		kfree(db->addr_req);
	}
}

#define res_size(_r) (((_r)->end - (_r)->start) + 1)

/*
 * Search DM9000 board, allocate space and register it
 */
static int
525
dm9000_probe(struct platform_device *pdev)
S
Sascha Hauer 已提交
526 527 528 529 530 531 532 533 534 535 536 537 538
{
	struct dm9000_plat_data *pdata = pdev->dev.platform_data;
	struct board_info *db;	/* Point a board information structure */
	struct net_device *ndev;
	unsigned long base;
	int ret = 0;
	int iosize;
	int i;
	u32 id_val;

	/* Init network device */
	ndev = alloc_etherdev(sizeof (struct board_info));
	if (!ndev) {
539
		dev_err(&pdev->dev, "could not allocate device.\n");
S
Sascha Hauer 已提交
540 541 542
		return -ENOMEM;
	}

543
	SET_NETDEV_DEV(ndev, &pdev->dev);
S
Sascha Hauer 已提交
544

545
	dev_dbg(&pdev->dev, "dm9000_probe()");
S
Sascha Hauer 已提交
546 547 548 549 550

	/* setup board info structure */
	db = (struct board_info *) ndev->priv;
	memset(db, 0, sizeof (*db));

551 552
	db->dev = &pdev->dev;

B
Ben Dooks 已提交
553
	spin_lock_init(&db->lock);
B
Ben Dooks 已提交
554
	mutex_init(&db->addr_lock);
B
Ben Dooks 已提交
555

S
Sascha Hauer 已提交
556 557 558
	if (pdev->num_resources < 2) {
		ret = -ENODEV;
		goto out;
559
	} else if (pdev->num_resources == 2) {
S
Sascha Hauer 已提交
560 561 562 563 564 565 566 567 568
		base = pdev->resource[0].start;

		if (!request_mem_region(base, 4, ndev->name)) {
			ret = -EBUSY;
			goto out;
		}

		ndev->base_addr = base;
		ndev->irq = pdev->resource[1].start;
569 570
		db->io_addr = (void __iomem *)base;
		db->io_data = (void __iomem *)(base + 4);
S
Sascha Hauer 已提交
571

572 573 574
		/* ensure at least we have a default set of IO routines */
		dm9000_set_io(db, 2);

575
	} else {
S
Sascha Hauer 已提交
576 577 578 579
		db->addr_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
		db->data_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
		db->irq_res  = platform_get_resource(pdev, IORESOURCE_IRQ, 0);

580 581
		if (db->addr_res == NULL || db->data_res == NULL ||
		    db->irq_res == NULL) {
582
			dev_err(db->dev, "insufficient resources\n");
S
Sascha Hauer 已提交
583 584 585 586 587 588 589 590 591
			ret = -ENOENT;
			goto out;
		}

		i = res_size(db->addr_res);
		db->addr_req = request_mem_region(db->addr_res->start, i,
						  pdev->name);

		if (db->addr_req == NULL) {
592
			dev_err(db->dev, "cannot claim address reg area\n");
S
Sascha Hauer 已提交
593 594 595 596 597 598 599
			ret = -EIO;
			goto out;
		}

		db->io_addr = ioremap(db->addr_res->start, i);

		if (db->io_addr == NULL) {
600
			dev_err(db->dev, "failed to ioremap address reg\n");
S
Sascha Hauer 已提交
601 602 603 604 605 606 607 608 609
			ret = -EINVAL;
			goto out;
		}

		iosize = res_size(db->data_res);
		db->data_req = request_mem_region(db->data_res->start, iosize,
						  pdev->name);

		if (db->data_req == NULL) {
610
			dev_err(db->dev, "cannot claim data reg area\n");
S
Sascha Hauer 已提交
611 612 613 614 615 616 617
			ret = -EIO;
			goto out;
		}

		db->io_data = ioremap(db->data_res->start, iosize);

		if (db->io_data == NULL) {
618
			dev_err(db->dev,"failed to ioremap data reg\n");
S
Sascha Hauer 已提交
619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656
			ret = -EINVAL;
			goto out;
		}

		/* fill in parameters for net-dev structure */

		ndev->base_addr = (unsigned long)db->io_addr;
		ndev->irq	= db->irq_res->start;

		/* ensure at least we have a default set of IO routines */
		dm9000_set_io(db, iosize);
	}

	/* check to see if anything is being over-ridden */
	if (pdata != NULL) {
		/* check to see if the driver wants to over-ride the
		 * default IO width */

		if (pdata->flags & DM9000_PLATF_8BITONLY)
			dm9000_set_io(db, 1);

		if (pdata->flags & DM9000_PLATF_16BITONLY)
			dm9000_set_io(db, 2);

		if (pdata->flags & DM9000_PLATF_32BITONLY)
			dm9000_set_io(db, 4);

		/* check to see if there are any IO routine
		 * over-rides */

		if (pdata->inblk != NULL)
			db->inblk = pdata->inblk;

		if (pdata->outblk != NULL)
			db->outblk = pdata->outblk;

		if (pdata->dumpblk != NULL)
			db->dumpblk = pdata->dumpblk;
657 658

		db->flags = pdata->flags;
S
Sascha Hauer 已提交
659 660 661 662 663 664 665 666 667 668 669 670 671
	}

	dm9000_reset(db);

	/* try two times, DM9000 sometimes gets the first read wrong */
	for (i = 0; i < 2; i++) {
		id_val  = ior(db, DM9000_VIDL);
		id_val |= (u32)ior(db, DM9000_VIDH) << 8;
		id_val |= (u32)ior(db, DM9000_PIDL) << 16;
		id_val |= (u32)ior(db, DM9000_PIDH) << 24;

		if (id_val == DM9000_ID)
			break;
672
		dev_err(db->dev, "read wrong id 0x%08x\n", id_val);
S
Sascha Hauer 已提交
673 674 675
	}

	if (id_val != DM9000_ID) {
676
		dev_err(db->dev, "wrong id: 0x%08x\n", id_val);
M
Mike Rapoport 已提交
677 678
		ret = -ENODEV;
		goto out;
S
Sascha Hauer 已提交
679 680 681 682 683 684 685 686 687 688 689 690 691
	}

	/* from this point we assume that we have found a DM9000 */

	/* driver system function */
	ether_setup(ndev);

	ndev->open		 = &dm9000_open;
	ndev->hard_start_xmit    = &dm9000_start_xmit;
	ndev->tx_timeout         = &dm9000_timeout;
	ndev->watchdog_timeo = msecs_to_jiffies(watchdog);
	ndev->stop		 = &dm9000_stop;
	ndev->set_multicast_list = &dm9000_hash_table;
B
Ben Dooks 已提交
692 693
	ndev->ethtool_ops	 = &dm9000_ethtool_ops;

694 695 696
#ifdef CONFIG_NET_POLL_CONTROLLER
	ndev->poll_controller	 = &dm9000_poll_controller;
#endif
S
Sascha Hauer 已提交
697 698 699 700 701 702 703 704 705 706

	db->msg_enable       = NETIF_MSG_LINK;
	db->mii.phy_id_mask  = 0x1f;
	db->mii.reg_num_mask = 0x1f;
	db->mii.force_media  = 0;
	db->mii.full_duplex  = 0;
	db->mii.dev	     = ndev;
	db->mii.mdio_read    = dm9000_phy_read;
	db->mii.mdio_write   = dm9000_phy_write;

707 708 709
	/* try reading the node address from the attached EEPROM */
	for (i = 0; i < 6; i += 2)
		dm9000_read_eeprom(db, i / 2, ndev->dev_addr+i);
S
Sascha Hauer 已提交
710

711 712 713 714 715 716 717
	if (!is_valid_ether_addr(ndev->dev_addr)) {
		/* try reading from mac */

		for (i = 0; i < 6; i++)
			ndev->dev_addr[i] = ior(db, i+DM9000_PAR);
	}

S
Sascha Hauer 已提交
718
	if (!is_valid_ether_addr(ndev->dev_addr))
719 720
		dev_warn(db->dev, "%s: Invalid ethernet MAC address. Please "
			 "set using ifconfig\n", ndev->name);
S
Sascha Hauer 已提交
721

722
	platform_set_drvdata(pdev, ndev);
S
Sascha Hauer 已提交
723 724 725
	ret = register_netdev(ndev);

	if (ret == 0) {
726 727 728 729
		DECLARE_MAC_BUF(mac);
		printk("%s: dm9000 at %p,%p IRQ %d MAC: %s\n",
		       ndev->name,  db->io_addr, db->io_data, ndev->irq,
		       print_mac(mac, ndev->dev_addr));
S
Sascha Hauer 已提交
730 731 732
	}
	return 0;

M
Mike Rapoport 已提交
733
out:
734
	dev_err(db->dev, "not found (%d).\n", ret);
S
Sascha Hauer 已提交
735 736

	dm9000_release_board(pdev, db);
737
	free_netdev(ndev);
S
Sascha Hauer 已提交
738 739 740 741 742 743 744 745 746 747 748 749

	return ret;
}

/*
 *  Open the interface.
 *  The interface is opened whenever "ifconfig" actives it.
 */
static int
dm9000_open(struct net_device *dev)
{
	board_info_t *db = (board_info_t *) dev->priv;
750
	unsigned long irqflags = db->irq_res->flags & IRQF_TRIGGER_MASK;
S
Sascha Hauer 已提交
751

752
	dev_dbg(db->dev, "entering %s\n", __func__);
S
Sascha Hauer 已提交
753

754 755 756 757 758 759 760 761 762 763 764
	/* If there is no IRQ type specified, default to something that
	 * may work, and tell the user that this is a problem */

	if (irqflags == IRQF_TRIGGER_NONE) {
		dev_warn(db->dev, "WARNING: no IRQ resource flags set.\n");
		irqflags = DEFAULT_TRIGGER;
	}
	
	irqflags |= IRQF_SHARED;

	if (request_irq(dev->irq, &dm9000_interrupt, irqflags, dev->name, dev))
S
Sascha Hauer 已提交
765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787
		return -EAGAIN;

	/* Initialize DM9000 board */
	dm9000_reset(db);
	dm9000_init_dm9000(dev);

	/* Init driver variable */
	db->dbug_cnt = 0;

	mii_check_media(&db->mii, netif_msg_link(db), 1);
	netif_start_queue(dev);

	return 0;
}

/*
 * Initilize dm9000 board
 */
static void
dm9000_init_dm9000(struct net_device *dev)
{
	board_info_t *db = (board_info_t *) dev->priv;

788
	dm9000_dbg(db, 1, "entering %s\n", __func__);
S
Sascha Hauer 已提交
789 790 791 792 793 794 795 796 797

	/* I/O mode */
	db->io_mode = ior(db, DM9000_ISR) >> 6;	/* ISR bit7:6 keeps I/O mode */

	/* GPIO0 on pre-activate PHY */
	iow(db, DM9000_GPR, 0);	/* REG_1F bit0 activate phyxcer */
	iow(db, DM9000_GPCR, GPCR_GEP_CNTL);	/* Let GPIO0 output */
	iow(db, DM9000_GPR, 0);	/* Enable PHY */

798 799 800
	if (db->flags & DM9000_PLATF_EXT_PHY)
		iow(db, DM9000_NCR, NCR_EXT_PHY);

S
Sascha Hauer 已提交
801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830
	/* Program operating register */
	iow(db, DM9000_TCR, 0);	        /* TX Polling clear */
	iow(db, DM9000_BPTR, 0x3f);	/* Less 3Kb, 200us */
	iow(db, DM9000_FCR, 0xff);	/* Flow Control */
	iow(db, DM9000_SMCR, 0);        /* Special Mode */
	/* clear TX status */
	iow(db, DM9000_NSR, NSR_WAKEST | NSR_TX2END | NSR_TX1END);
	iow(db, DM9000_ISR, ISR_CLR_STATUS); /* Clear interrupt status */

	/* Set address filter table */
	dm9000_hash_table(dev);

	/* Activate DM9000 */
	iow(db, DM9000_RCR, RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN);
	/* Enable TX/RX interrupt mask */
	iow(db, DM9000_IMR, IMR_PAR | IMR_PTM | IMR_PRM);

	/* Init Driver variable */
	db->tx_pkt_cnt = 0;
	db->queue_pkt_len = 0;
	dev->trans_start = 0;
}

/*
 *  Hardware start transmission.
 *  Send a packet to media from the upper layer.
 */
static int
dm9000_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
831
	unsigned long flags;
S
Sascha Hauer 已提交
832 833
	board_info_t *db = (board_info_t *) dev->priv;

834
	dm9000_dbg(db, 3, "%s:\n", __func__);
S
Sascha Hauer 已提交
835 836 837 838

	if (db->tx_pkt_cnt > 1)
		return 1;

839
	spin_lock_irqsave(&db->lock, flags);
S
Sascha Hauer 已提交
840 841 842 843 844

	/* Move data to DM9000 TX RAM */
	writeb(DM9000_MWCMD, db->io_addr);

	(db->outblk)(db->io_data, skb->data, skb->len);
845
	dev->stats.tx_bytes += skb->len;
S
Sascha Hauer 已提交
846

847
	db->tx_pkt_cnt++;
S
Sascha Hauer 已提交
848
	/* TX control: First packet immediately send, second packet queue */
849
	if (db->tx_pkt_cnt == 1) {
S
Sascha Hauer 已提交
850 851 852 853 854 855 856 857 858 859 860
		/* Set TX length to DM9000 */
		iow(db, DM9000_TXPLL, skb->len & 0xff);
		iow(db, DM9000_TXPLH, (skb->len >> 8) & 0xff);

		/* Issue TX polling command */
		iow(db, DM9000_TCR, TCR_TXREQ);	/* Cleared after TX complete */

		dev->trans_start = jiffies;	/* save the time stamp */
	} else {
		/* Second packet */
		db->queue_pkt_len = skb->len;
861
		netif_stop_queue(dev);
S
Sascha Hauer 已提交
862 863
	}

864 865
	spin_unlock_irqrestore(&db->lock, flags);

S
Sascha Hauer 已提交
866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892
	/* free this SKB */
	dev_kfree_skb(skb);

	return 0;
}

static void
dm9000_shutdown(struct net_device *dev)
{
	board_info_t *db = (board_info_t *) dev->priv;

	/* RESET device */
	dm9000_phy_write(dev, 0, MII_BMCR, BMCR_RESET);	/* PHY RESET */
	iow(db, DM9000_GPR, 0x01);	/* Power-Down PHY */
	iow(db, DM9000_IMR, IMR_PAR);	/* Disable all interrupt */
	iow(db, DM9000_RCR, 0x00);	/* Disable RX */
}

/*
 * Stop the interface.
 * The interface is stopped when it is brought.
 */
static int
dm9000_stop(struct net_device *ndev)
{
	board_info_t *db = (board_info_t *) ndev->priv;

893
	dm9000_dbg(db, 1, "entering %s\n", __func__);
S
Sascha Hauer 已提交
894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910

	netif_stop_queue(ndev);
	netif_carrier_off(ndev);

	/* free interrupt */
	free_irq(ndev->irq, ndev);

	dm9000_shutdown(ndev);

	return 0;
}

/*
 * DM9000 interrupt handler
 * receive the packet to upper layer, free the transmitted packet
 */

B
Ben Dooks 已提交
911
static void
S
Sascha Hauer 已提交
912 913 914 915 916 917 918
dm9000_tx_done(struct net_device *dev, board_info_t * db)
{
	int tx_status = ior(db, DM9000_NSR);	/* Got TX status */

	if (tx_status & (NSR_TX2END | NSR_TX1END)) {
		/* One packet sent complete */
		db->tx_pkt_cnt--;
919
		dev->stats.tx_packets++;
S
Sascha Hauer 已提交
920 921 922 923 924 925 926 927 928 929 930 931 932

		/* Queue packet check & send */
		if (db->tx_pkt_cnt > 0) {
			iow(db, DM9000_TXPLL, db->queue_pkt_len & 0xff);
			iow(db, DM9000_TXPLH, (db->queue_pkt_len >> 8) & 0xff);
			iow(db, DM9000_TCR, TCR_TXREQ);
			dev->trans_start = jiffies;
		}
		netif_wake_queue(dev);
	}
}

static irqreturn_t
933
dm9000_interrupt(int irq, void *dev_id)
S
Sascha Hauer 已提交
934 935
{
	struct net_device *dev = dev_id;
936
	board_info_t *db = (board_info_t *) dev->priv;
S
Sascha Hauer 已提交
937 938 939
	int int_status;
	u8 reg_save;

940
	dm9000_dbg(db, 3, "entering %s\n", __func__);
S
Sascha Hauer 已提交
941 942

	/* A real interrupt coming */
943

S
Sascha Hauer 已提交
944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975
	spin_lock(&db->lock);

	/* Save previous register address */
	reg_save = readb(db->io_addr);

	/* Disable all interrupts */
	iow(db, DM9000_IMR, IMR_PAR);

	/* Got DM9000 interrupt status */
	int_status = ior(db, DM9000_ISR);	/* Got ISR */
	iow(db, DM9000_ISR, int_status);	/* Clear ISR status */

	/* Received the coming packet */
	if (int_status & ISR_PRS)
		dm9000_rx(dev);

	/* Trnasmit Interrupt check */
	if (int_status & ISR_PTS)
		dm9000_tx_done(dev, db);

	/* Re-enable interrupt mask */
	iow(db, DM9000_IMR, IMR_PAR | IMR_PTM | IMR_PRM);

	/* Restore previous register address */
	writeb(reg_save, db->io_addr);

	spin_unlock(&db->lock);

	return IRQ_HANDLED;
}

struct dm9000_rxhdr {
976 977
	u8	RxPktReady;
	u8	RxStatus;
S
Sascha Hauer 已提交
978 979 980 981 982 983 984 985 986 987 988 989 990
	u16	RxLen;
} __attribute__((__packed__));

/*
 *  Received a packet and pass to upper layer
 */
static void
dm9000_rx(struct net_device *dev)
{
	board_info_t *db = (board_info_t *) dev->priv;
	struct dm9000_rxhdr rxhdr;
	struct sk_buff *skb;
	u8 rxbyte, *rdptr;
991
	bool GoodPacket;
S
Sascha Hauer 已提交
992 993 994 995 996 997 998 999 1000 1001 1002
	int RxLen;

	/* Check packet ready or not */
	do {
		ior(db, DM9000_MRCMDX);	/* Dummy read */

		/* Get most updated data */
		rxbyte = readb(db->io_data);

		/* Status check: this byte must be 0 or 1 */
		if (rxbyte > DM9000_PKT_RDY) {
1003
			dev_warn(db->dev, "status check fail: %d\n", rxbyte);
S
Sascha Hauer 已提交
1004 1005 1006 1007 1008 1009 1010 1011 1012
			iow(db, DM9000_RCR, 0x00);	/* Stop Device */
			iow(db, DM9000_ISR, IMR_PAR);	/* Stop INT request */
			return;
		}

		if (rxbyte != DM9000_PKT_RDY)
			return;

		/* A packet ready now  & Get status/length */
1013
		GoodPacket = true;
S
Sascha Hauer 已提交
1014 1015 1016 1017
		writeb(DM9000_MRCMD, db->io_addr);

		(db->inblk)(db->io_data, &rxhdr, sizeof(rxhdr));

1018
		RxLen = le16_to_cpu(rxhdr.RxLen);
S
Sascha Hauer 已提交
1019 1020 1021

		/* Packet Status check */
		if (RxLen < 0x40) {
1022
			GoodPacket = false;
1023
			dev_dbg(db->dev, "Bad Packet received (runt)\n");
S
Sascha Hauer 已提交
1024 1025 1026
		}

		if (RxLen > DM9000_PKT_MAX) {
1027
			dev_dbg(db->dev, "RST: RX Len:%x\n", RxLen);
S
Sascha Hauer 已提交
1028 1029
		}

1030
		if (rxhdr.RxStatus & 0xbf) {
1031
			GoodPacket = false;
1032
			if (rxhdr.RxStatus & 0x01) {
1033
				dev_dbg(db->dev, "fifo error\n");
1034
				dev->stats.rx_fifo_errors++;
S
Sascha Hauer 已提交
1035
			}
1036
			if (rxhdr.RxStatus & 0x02) {
1037
				dev_dbg(db->dev, "crc error\n");
1038
				dev->stats.rx_crc_errors++;
S
Sascha Hauer 已提交
1039
			}
1040
			if (rxhdr.RxStatus & 0x80) {
1041
				dev_dbg(db->dev, "length error\n");
1042
				dev->stats.rx_length_errors++;
S
Sascha Hauer 已提交
1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054
			}
		}

		/* Move data from DM9000 */
		if (GoodPacket
		    && ((skb = dev_alloc_skb(RxLen + 4)) != NULL)) {
			skb_reserve(skb, 2);
			rdptr = (u8 *) skb_put(skb, RxLen - 4);

			/* Read received packet from RX SRAM */

			(db->inblk)(db->io_data, rdptr, RxLen);
1055
			dev->stats.rx_bytes += RxLen;
S
Sascha Hauer 已提交
1056 1057 1058 1059

			/* Pass to upper layer */
			skb->protocol = eth_type_trans(skb, dev);
			netif_rx(skb);
1060
			dev->stats.rx_packets++;
S
Sascha Hauer 已提交
1061 1062 1063 1064 1065 1066 1067 1068 1069 1070

		} else {
			/* need to dump the packet's data */

			(db->dumpblk)(db->io_data, RxLen);
		}
	} while (rxbyte == DM9000_PKT_RDY);
}

/*
1071
 *  Read a word data from EEPROM
S
Sascha Hauer 已提交
1072
 */
1073
static void
1074
dm9000_read_eeprom(board_info_t *db, int offset, u8 *to)
S
Sascha Hauer 已提交
1075
{
B
Ben Dooks 已提交
1076 1077
	mutex_lock(&db->addr_lock);

S
Sascha Hauer 已提交
1078 1079 1080 1081 1082
	iow(db, DM9000_EPAR, offset);
	iow(db, DM9000_EPCR, EPCR_ERPRR);
	mdelay(8);		/* according to the datasheet 200us should be enough,
				   but it doesn't work */
	iow(db, DM9000_EPCR, 0x0);
1083 1084 1085

	to[0] = ior(db, DM9000_EPDRL);
	to[1] = ior(db, DM9000_EPDRH);
B
Ben Dooks 已提交
1086 1087

	mutex_unlock(&db->addr_lock);
S
Sascha Hauer 已提交
1088 1089 1090 1091 1092 1093
}

/*
 * Write a word data to SROM
 */
static void
1094
dm9000_write_eeprom(board_info_t *db, int offset, u8 *data)
S
Sascha Hauer 已提交
1095
{
B
Ben Dooks 已提交
1096 1097
	mutex_lock(&db->addr_lock);

S
Sascha Hauer 已提交
1098
	iow(db, DM9000_EPAR, offset);
1099 1100
	iow(db, DM9000_EPDRH, data[1]);
	iow(db, DM9000_EPDRL, data[0]);
S
Sascha Hauer 已提交
1101 1102 1103
	iow(db, DM9000_EPCR, EPCR_WEP | EPCR_ERPRW);
	mdelay(8);		/* same shit */
	iow(db, DM9000_EPCR, 0);
B
Ben Dooks 已提交
1104 1105

	mutex_unlock(&db->addr_lock);
S
Sascha Hauer 已提交
1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138
}

/*
 *  Calculate the CRC valude of the Rx packet
 *  flag = 1 : return the reverse CRC (for the received packet CRC)
 *         0 : return the normal CRC (for Hash Table index)
 */

static unsigned long
cal_CRC(unsigned char *Data, unsigned int Len, u8 flag)
{

       u32 crc = ether_crc_le(Len, Data);

       if (flag)
               return ~crc;

       return crc;
}

/*
 *  Set DM9000 multicast address
 */
static void
dm9000_hash_table(struct net_device *dev)
{
	board_info_t *db = (board_info_t *) dev->priv;
	struct dev_mc_list *mcptr = dev->mc_list;
	int mc_cnt = dev->mc_count;
	u32 hash_val;
	u16 i, oft, hash_table[4];
	unsigned long flags;

1139
	dm9000_dbg(db, 1, "entering %s\n", __func__);
S
Sascha Hauer 已提交
1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168

	spin_lock_irqsave(&db->lock,flags);

	for (i = 0, oft = 0x10; i < 6; i++, oft++)
		iow(db, oft, dev->dev_addr[i]);

	/* Clear Hash Table */
	for (i = 0; i < 4; i++)
		hash_table[i] = 0x0;

	/* broadcast address */
	hash_table[3] = 0x8000;

	/* the multicast address in Hash Table : 64 bits */
	for (i = 0; i < mc_cnt; i++, mcptr = mcptr->next) {
		hash_val = cal_CRC((char *) mcptr->dmi_addr, 6, 0) & 0x3f;
		hash_table[hash_val / 16] |= (u16) 1 << (hash_val % 16);
	}

	/* Write the hash table to MAC MD table */
	for (i = 0, oft = 0x16; i < 4; i++) {
		iow(db, oft++, hash_table[i] & 0xff);
		iow(db, oft++, (hash_table[i] >> 8) & 0xff);
	}

	spin_unlock_irqrestore(&db->lock,flags);
}


1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180
/*
 * Sleep, either by using msleep() or if we are suspending, then
 * use mdelay() to sleep.
 */
static void dm9000_msleep(board_info_t *db, unsigned int ms)
{
	if (db->in_suspend)
		mdelay(ms);
	else
		msleep(ms);
}

S
Sascha Hauer 已提交
1181 1182 1183 1184 1185 1186 1187 1188
/*
 *   Read a word from phyxcer
 */
static int
dm9000_phy_read(struct net_device *dev, int phy_reg_unused, int reg)
{
	board_info_t *db = (board_info_t *) dev->priv;
	unsigned long flags;
B
Ben Dooks 已提交
1189
	unsigned int reg_save;
S
Sascha Hauer 已提交
1190 1191
	int ret;

B
Ben Dooks 已提交
1192 1193
	mutex_lock(&db->addr_lock);

S
Sascha Hauer 已提交
1194
	spin_lock_irqsave(&db->lock,flags);
B
Ben Dooks 已提交
1195 1196 1197 1198

	/* Save previous register address */
	reg_save = readb(db->io_addr);

S
Sascha Hauer 已提交
1199 1200 1201 1202
	/* Fill the phyxcer register into REG_0C */
	iow(db, DM9000_EPAR, DM9000_PHY | reg);

	iow(db, DM9000_EPCR, 0xc);	/* Issue phyxcer read command */
1203 1204 1205 1206

	writeb(reg_save, db->io_addr);
	spin_unlock_irqrestore(&db->lock,flags);

1207
	dm9000_msleep(db, 1);		/* Wait read complete */
1208 1209 1210 1211

	spin_lock_irqsave(&db->lock,flags);
	reg_save = readb(db->io_addr);

S
Sascha Hauer 已提交
1212 1213 1214 1215 1216
	iow(db, DM9000_EPCR, 0x0);	/* Clear phyxcer read command */

	/* The read data keeps on REG_0D & REG_0E */
	ret = (ior(db, DM9000_EPDRH) << 8) | ior(db, DM9000_EPDRL);

B
Ben Dooks 已提交
1217 1218
	/* restore the previous address */
	writeb(reg_save, db->io_addr);
S
Sascha Hauer 已提交
1219 1220
	spin_unlock_irqrestore(&db->lock,flags);

B
Ben Dooks 已提交
1221
	mutex_unlock(&db->addr_lock);
S
Sascha Hauer 已提交
1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232
	return ret;
}

/*
 *   Write a word to phyxcer
 */
static void
dm9000_phy_write(struct net_device *dev, int phyaddr_unused, int reg, int value)
{
	board_info_t *db = (board_info_t *) dev->priv;
	unsigned long flags;
B
Ben Dooks 已提交
1233
	unsigned long reg_save;
S
Sascha Hauer 已提交
1234

B
Ben Dooks 已提交
1235 1236
	mutex_lock(&db->addr_lock);

S
Sascha Hauer 已提交
1237 1238
	spin_lock_irqsave(&db->lock,flags);

B
Ben Dooks 已提交
1239 1240 1241
	/* Save previous register address */
	reg_save = readb(db->io_addr);

S
Sascha Hauer 已提交
1242 1243 1244 1245 1246 1247 1248 1249
	/* Fill the phyxcer register into REG_0C */
	iow(db, DM9000_EPAR, DM9000_PHY | reg);

	/* Fill the written data into REG_0D & REG_0E */
	iow(db, DM9000_EPDRL, (value & 0xff));
	iow(db, DM9000_EPDRH, ((value >> 8) & 0xff));

	iow(db, DM9000_EPCR, 0xa);	/* Issue phyxcer write command */
1250 1251

	writeb(reg_save, db->io_addr);
B
Ben Dooks 已提交
1252
	spin_unlock_irqrestore(&db->lock, flags);
1253

1254
	dm9000_msleep(db, 1);		/* Wait write complete */
1255 1256 1257 1258

	spin_lock_irqsave(&db->lock,flags);
	reg_save = readb(db->io_addr);

S
Sascha Hauer 已提交
1259 1260
	iow(db, DM9000_EPCR, 0x0);	/* Clear phyxcer write command */

B
Ben Dooks 已提交
1261 1262 1263
	/* restore the previous address */
	writeb(reg_save, db->io_addr);

B
Ben Dooks 已提交
1264 1265
	spin_unlock_irqrestore(&db->lock, flags);
	mutex_unlock(&db->addr_lock);
S
Sascha Hauer 已提交
1266 1267 1268
}

static int
1269
dm9000_drv_suspend(struct platform_device *dev, pm_message_t state)
S
Sascha Hauer 已提交
1270
{
1271
	struct net_device *ndev = platform_get_drvdata(dev);
1272
	board_info_t *db;
S
Sascha Hauer 已提交
1273

1274
	if (ndev) {
1275 1276 1277
		db = (board_info_t *) ndev->priv;
		db->in_suspend = 1;

S
Sascha Hauer 已提交
1278 1279 1280 1281 1282 1283 1284 1285 1286
		if (netif_running(ndev)) {
			netif_device_detach(ndev);
			dm9000_shutdown(ndev);
		}
	}
	return 0;
}

static int
1287
dm9000_drv_resume(struct platform_device *dev)
S
Sascha Hauer 已提交
1288
{
1289
	struct net_device *ndev = platform_get_drvdata(dev);
S
Sascha Hauer 已提交
1290 1291
	board_info_t *db = (board_info_t *) ndev->priv;

1292
	if (ndev) {
S
Sascha Hauer 已提交
1293 1294 1295 1296 1297 1298 1299

		if (netif_running(ndev)) {
			dm9000_reset(db);
			dm9000_init_dm9000(ndev);

			netif_device_attach(ndev);
		}
1300 1301

		db->in_suspend = 0;
S
Sascha Hauer 已提交
1302 1303 1304 1305 1306
	}
	return 0;
}

static int
1307
dm9000_drv_remove(struct platform_device *pdev)
S
Sascha Hauer 已提交
1308
{
1309
	struct net_device *ndev = platform_get_drvdata(pdev);
S
Sascha Hauer 已提交
1310

1311
	platform_set_drvdata(pdev, NULL);
S
Sascha Hauer 已提交
1312 1313 1314

	unregister_netdev(ndev);
	dm9000_release_board(pdev, (board_info_t *) ndev->priv);
1315
	free_netdev(ndev);		/* free device structure */
S
Sascha Hauer 已提交
1316

1317
	dev_dbg(&pdev->dev, "released and freed device\n");
S
Sascha Hauer 已提交
1318 1319 1320
	return 0;
}

1321
static struct platform_driver dm9000_driver = {
B
Ben Dooks 已提交
1322 1323 1324 1325
	.driver	= {
		.name    = "dm9000",
		.owner	 = THIS_MODULE,
	},
S
Sascha Hauer 已提交
1326 1327 1328 1329 1330 1331 1332 1333 1334
	.probe   = dm9000_probe,
	.remove  = dm9000_drv_remove,
	.suspend = dm9000_drv_suspend,
	.resume  = dm9000_drv_resume,
};

static int __init
dm9000_init(void)
{
B
Ben Dooks 已提交
1335
	printk(KERN_INFO "%s Ethernet Driver, V%s\n", CARDNAME, DRV_VERSION);
1336

1337
	return platform_driver_register(&dm9000_driver);	/* search board and register */
S
Sascha Hauer 已提交
1338 1339 1340 1341 1342
}

static void __exit
dm9000_cleanup(void)
{
1343
	platform_driver_unregister(&dm9000_driver);
S
Sascha Hauer 已提交
1344 1345 1346 1347 1348 1349 1350 1351
}

module_init(dm9000_init);
module_exit(dm9000_cleanup);

MODULE_AUTHOR("Sascha Hauer, Ben Dooks");
MODULE_DESCRIPTION("Davicom DM9000 network driver");
MODULE_LICENSE("GPL");