ax88796.c 23.4 KB
Newer Older
1
/* drivers/net/ethernet/8390/ax88796.c
B
Ben Dooks 已提交
2 3 4 5 6 7 8 9 10 11
 *
 * Copyright 2005,2007 Simtec Electronics
 *	Ben Dooks <ben@simtec.co.uk>
 *
 * Asix AX88796 10/100 Ethernet controller support
 *	Based on ne.c, by Donald Becker, et-al.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
12
 */
B
Ben Dooks 已提交
13 14 15 16 17 18

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/isapnp.h>
#include <linux/interrupt.h>
19
#include <linux/io.h>
B
Ben Dooks 已提交
20 21 22 23 24 25
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/timer.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/ethtool.h>
26 27
#include <linux/mdio-bitbang.h>
#include <linux/phy.h>
M
Magnus Damm 已提交
28
#include <linux/eeprom_93cx6.h>
29
#include <linux/slab.h>
B
Ben Dooks 已提交
30 31 32 33 34

#include <net/ax88796.h>


/* Rename the lib8390.c functions to show that they are in this driver */
35 36 37
#define __ei_open ax_ei_open
#define __ei_close ax_ei_close
#define __ei_poll ax_ei_poll
38
#define __ei_start_xmit ax_ei_start_xmit
B
Ben Dooks 已提交
39
#define __ei_tx_timeout ax_ei_tx_timeout
40
#define __ei_get_stats ax_ei_get_stats
41
#define __ei_set_multicast_list ax_ei_set_multicast_list
42
#define __ei_interrupt ax_ei_interrupt
B
Ben Dooks 已提交
43
#define ____alloc_ei_netdev ax__alloc_ei_netdev
44
#define __NS8390_init ax_NS8390_init
B
Ben Dooks 已提交
45 46 47 48

/* force unsigned long back to 'void __iomem *' */
#define ax_convert_addr(_a) ((void __force __iomem *)(_a))

49
#define ei_inb(_a) readb(ax_convert_addr(_a))
B
Ben Dooks 已提交
50 51
#define ei_outb(_v, _a) writeb(_v, ax_convert_addr(_a))

52
#define ei_inb_p(_a) ei_inb(_a)
B
Ben Dooks 已提交
53 54 55
#define ei_outb_p(_v, _a) ei_outb(_v, _a)

/* define EI_SHIFT() to take into account our register offsets */
56
#define EI_SHIFT(x) (ei_local->reg_offset[(x)])
B
Ben Dooks 已提交
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73

/* Ensure we have our RCR base value */
#define AX88796_PLATFORM

static unsigned char version[] = "ax88796.c: Copyright 2005,2007 Simtec Electronics\n";

#include "lib8390.c"

#define DRV_NAME "ax88796"
#define DRV_VERSION "1.00"

/* from ne.c */
#define NE_CMD		EI_SHIFT(0x00)
#define NE_RESET	EI_SHIFT(0x1f)
#define NE_DATAPORT	EI_SHIFT(0x10)

#define NE1SM_START_PG	0x20	/* First page of TX buffer */
74
#define NE1SM_STOP_PG	0x40	/* Last page +1 of RX ring */
B
Ben Dooks 已提交
75 76 77
#define NESM_START_PG	0x40	/* First page of TX buffer */
#define NESM_STOP_PG	0x80	/* Last page +1 of RX ring */

78 79
#define AX_GPOC_PPDSET	BIT(6)

B
Ben Dooks 已提交
80 81 82
/* device private data */

struct ax_device {
83 84 85 86 87 88 89
	struct mii_bus *mii_bus;
	struct mdiobb_ctrl bb_ctrl;
	void __iomem *addr_memr;
	u8 reg_memr;
	int link;
	int speed;
	int duplex;
90 91

	void __iomem *map2;
92
	const struct ax_plat_data *plat;
93 94 95 96 97 98

	unsigned char running;
	unsigned char resume_open;
	unsigned int irqflags;

	u32 reg_offsets[0x20];
B
Ben Dooks 已提交
99 100 101 102 103
};

static inline struct ax_device *to_ax_dev(struct net_device *dev)
{
	struct ei_device *ei_local = netdev_priv(dev);
104
	return (struct ax_device *)(ei_local + 1);
B
Ben Dooks 已提交
105 106
}

107 108
/*
 * ax_initial_check
B
Ben Dooks 已提交
109
 *
110
 * do an initial probe for the card to check whether it exists
B
Ben Dooks 已提交
111 112 113 114 115 116 117 118 119 120 121 122 123
 * and is functional
 */
static int ax_initial_check(struct net_device *dev)
{
	struct ei_device *ei_local = netdev_priv(dev);
	void __iomem *ioaddr = ei_local->mem;
	int reg0;
	int regd;

	reg0 = ei_inb(ioaddr);
	if (reg0 == 0xFF)
		return -ENODEV;

124
	ei_outb(E8390_NODMA + E8390_PAGE1 + E8390_STOP, ioaddr + E8390_CMD);
B
Ben Dooks 已提交
125 126
	regd = ei_inb(ioaddr + 0x0d);
	ei_outb(0xff, ioaddr + 0x0d);
127
	ei_outb(E8390_NODMA + E8390_PAGE0, ioaddr + E8390_CMD);
B
Ben Dooks 已提交
128 129 130 131 132 133 134 135 136 137
	ei_inb(ioaddr + EN0_COUNTER0); /* Clear the counter by reading. */
	if (ei_inb(ioaddr + EN0_COUNTER0) != 0) {
		ei_outb(reg0, ioaddr);
		ei_outb(regd, ioaddr + 0x0d);	/* Restore the old values. */
		return -ENODEV;
	}

	return 0;
}

138 139 140 141
/*
 * Hard reset the card. This used to pause for the same period that a
 * 8390 reset command required, but that shouldn't be necessary.
 */
B
Ben Dooks 已提交
142 143 144 145 146 147
static void ax_reset_8390(struct net_device *dev)
{
	struct ei_device *ei_local = netdev_priv(dev);
	unsigned long reset_start_time = jiffies;
	void __iomem *addr = (void __iomem *)dev->base_addr;

148
	netif_dbg(ei_local, hw, dev, "resetting the 8390 t=%ld...\n", jiffies);
B
Ben Dooks 已提交
149 150 151

	ei_outb(ei_inb(addr + NE_RESET), addr + NE_RESET);

152 153
	ei_local->txing = 0;
	ei_local->dmaing = 0;
B
Ben Dooks 已提交
154 155 156

	/* This check _should_not_ be necessary, omit eventually. */
	while ((ei_inb(addr + EN0_ISR) & ENISR_RESET) == 0) {
157
		if (time_after(jiffies, reset_start_time + 2 * HZ / 100)) {
158
			netdev_warn(dev, "%s: did not complete.\n", __func__);
B
Ben Dooks 已提交
159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
			break;
		}
	}

	ei_outb(ENISR_RESET, addr + EN0_ISR);	/* Ack intr. */
}


static void ax_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
			    int ring_page)
{
	struct ei_device *ei_local = netdev_priv(dev);
	void __iomem *nic_base = ei_local->mem;

	/* This *shouldn't* happen. If it does, it's the last thing you'll see */
174
	if (ei_local->dmaing) {
175
		netdev_err(dev, "DMAing conflict in %s "
176
			"[DMAstat:%d][irqlock:%d].\n",
177
			__func__,
178
			ei_local->dmaing, ei_local->irqlock);
B
Ben Dooks 已提交
179 180 181
		return;
	}

182
	ei_local->dmaing |= 0x01;
183
	ei_outb(E8390_NODMA + E8390_PAGE0 + E8390_START, nic_base + NE_CMD);
B
Ben Dooks 已提交
184 185 186 187 188 189
	ei_outb(sizeof(struct e8390_pkt_hdr), nic_base + EN0_RCNTLO);
	ei_outb(0, nic_base + EN0_RCNTHI);
	ei_outb(0, nic_base + EN0_RSARLO);		/* On page boundary */
	ei_outb(ring_page, nic_base + EN0_RSARHI);
	ei_outb(E8390_RREAD+E8390_START, nic_base + NE_CMD);

190
	if (ei_local->word16)
191 192
		ioread16_rep(nic_base + NE_DATAPORT, hdr,
			     sizeof(struct e8390_pkt_hdr) >> 1);
B
Ben Dooks 已提交
193
	else
194 195
		ioread8_rep(nic_base + NE_DATAPORT, hdr,
			    sizeof(struct e8390_pkt_hdr));
B
Ben Dooks 已提交
196 197

	ei_outb(ENISR_RDC, nic_base + EN0_ISR);	/* Ack intr. */
198
	ei_local->dmaing &= ~0x01;
B
Ben Dooks 已提交
199 200 201 202 203

	le16_to_cpus(&hdr->count);
}


204 205 206 207 208 209 210
/*
 * Block input and output, similar to the Crynwr packet driver. If
 * you are porting to a new ethercard, look at the packet driver
 * source for hints. The NEx000 doesn't share the on-board packet
 * memory -- you have to put the packet out through the "remote DMA"
 * dataport using ei_outb.
 */
B
Ben Dooks 已提交
211 212 213 214 215 216 217
static void ax_block_input(struct net_device *dev, int count,
			   struct sk_buff *skb, int ring_offset)
{
	struct ei_device *ei_local = netdev_priv(dev);
	void __iomem *nic_base = ei_local->mem;
	char *buf = skb->data;

218
	if (ei_local->dmaing) {
219 220
		netdev_err(dev,
			"DMAing conflict in %s "
B
Ben Dooks 已提交
221
			"[DMAstat:%d][irqlock:%d].\n",
222
			__func__,
223
			ei_local->dmaing, ei_local->irqlock);
B
Ben Dooks 已提交
224 225 226
		return;
	}

227
	ei_local->dmaing |= 0x01;
B
Ben Dooks 已提交
228

229
	ei_outb(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base + NE_CMD);
B
Ben Dooks 已提交
230 231 232 233 234 235
	ei_outb(count & 0xff, nic_base + EN0_RCNTLO);
	ei_outb(count >> 8, nic_base + EN0_RCNTHI);
	ei_outb(ring_offset & 0xff, nic_base + EN0_RSARLO);
	ei_outb(ring_offset >> 8, nic_base + EN0_RSARHI);
	ei_outb(E8390_RREAD+E8390_START, nic_base + NE_CMD);

236
	if (ei_local->word16) {
237
		ioread16_rep(nic_base + NE_DATAPORT, buf, count >> 1);
B
Ben Dooks 已提交
238 239 240 241
		if (count & 0x01)
			buf[count-1] = ei_inb(nic_base + NE_DATAPORT);

	} else {
242
		ioread8_rep(nic_base + NE_DATAPORT, buf, count);
B
Ben Dooks 已提交
243 244
	}

245
	ei_local->dmaing &= ~1;
B
Ben Dooks 已提交
246 247 248 249 250 251 252 253 254
}

static void ax_block_output(struct net_device *dev, int count,
			    const unsigned char *buf, const int start_page)
{
	struct ei_device *ei_local = netdev_priv(dev);
	void __iomem *nic_base = ei_local->mem;
	unsigned long dma_start;

255 256 257 258 259
	/*
	 * Round the count up for word writes. Do we need to do this?
	 * What effect will an odd byte count have on the 8390?  I
	 * should check someday.
	 */
260
	if (ei_local->word16 && (count & 0x01))
B
Ben Dooks 已提交
261 262 263
		count++;

	/* This *shouldn't* happen. If it does, it's the last thing you'll see */
264
	if (ei_local->dmaing) {
265
		netdev_err(dev, "DMAing conflict in %s."
B
Ben Dooks 已提交
266
			"[DMAstat:%d][irqlock:%d]\n",
267
			__func__,
268
		       ei_local->dmaing, ei_local->irqlock);
B
Ben Dooks 已提交
269 270 271
		return;
	}

272
	ei_local->dmaing |= 0x01;
B
Ben Dooks 已提交
273 274 275 276 277 278 279
	/* We should already be in page 0, but to be safe... */
	ei_outb(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base + NE_CMD);

	ei_outb(ENISR_RDC, nic_base + EN0_ISR);

	/* Now the normal output. */
	ei_outb(count & 0xff, nic_base + EN0_RCNTLO);
280
	ei_outb(count >> 8, nic_base + EN0_RCNTHI);
B
Ben Dooks 已提交
281 282 283 284
	ei_outb(0x00, nic_base + EN0_RSARLO);
	ei_outb(start_page, nic_base + EN0_RSARHI);

	ei_outb(E8390_RWRITE+E8390_START, nic_base + NE_CMD);
285
	if (ei_local->word16)
286
		iowrite16_rep(nic_base + NE_DATAPORT, buf, count >> 1);
287
	else
288
		iowrite8_rep(nic_base + NE_DATAPORT, buf, count);
B
Ben Dooks 已提交
289 290 291 292

	dma_start = jiffies;

	while ((ei_inb(nic_base + EN0_ISR) & ENISR_RDC) == 0) {
293
		if (time_after(jiffies, dma_start + 2 * HZ / 100)) { /* 20ms */
294
			netdev_warn(dev, "timeout waiting for Tx RDC.\n");
B
Ben Dooks 已提交
295
			ax_reset_8390(dev);
296
			ax_NS8390_init(dev, 1);
B
Ben Dooks 已提交
297 298 299 300 301
			break;
		}
	}

	ei_outb(ENISR_RDC, nic_base + EN0_ISR);	/* Ack intr. */
302
	ei_local->dmaing &= ~0x01;
B
Ben Dooks 已提交
303 304 305 306 307
}

/* definitions for accessing MII/EEPROM interface */

#define AX_MEMR			EI_SHIFT(0x14)
308 309 310 311 312 313 314 315 316
#define AX_MEMR_MDC		BIT(0)
#define AX_MEMR_MDIR		BIT(1)
#define AX_MEMR_MDI		BIT(2)
#define AX_MEMR_MDO		BIT(3)
#define AX_MEMR_EECS		BIT(4)
#define AX_MEMR_EEI		BIT(5)
#define AX_MEMR_EEO		BIT(6)
#define AX_MEMR_EECLK		BIT(7)

317
static void ax_handle_link_change(struct net_device *dev)
B
Ben Dooks 已提交
318
{
319
	struct ax_device  *ax = to_ax_dev(dev);
320
	struct phy_device *phy_dev = dev->phydev;
321
	int status_change = 0;
B
Ben Dooks 已提交
322

323 324
	if (phy_dev->link && ((ax->speed != phy_dev->speed) ||
			     (ax->duplex != phy_dev->duplex))) {
B
Ben Dooks 已提交
325

326 327 328
		ax->speed = phy_dev->speed;
		ax->duplex = phy_dev->duplex;
		status_change = 1;
B
Ben Dooks 已提交
329 330
	}

331 332 333 334 335 336
	if (phy_dev->link != ax->link) {
		if (!phy_dev->link) {
			ax->speed = 0;
			ax->duplex = -1;
		}
		ax->link = phy_dev->link;
B
Ben Dooks 已提交
337

338
		status_change = 1;
B
Ben Dooks 已提交
339 340
	}

341 342
	if (status_change)
		phy_print_status(phy_dev);
B
Ben Dooks 已提交
343 344
}

345
static int ax_mii_probe(struct net_device *dev)
B
Ben Dooks 已提交
346
{
347 348 349
	struct ax_device  *ax = to_ax_dev(dev);
	struct phy_device *phy_dev = NULL;
	int ret;
B
Ben Dooks 已提交
350

351 352 353 354 355 356
	/* find the first phy */
	phy_dev = phy_find_first(ax->mii_bus);
	if (!phy_dev) {
		netdev_err(dev, "no PHY found\n");
		return -ENODEV;
	}
B
Ben Dooks 已提交
357

358
	ret = phy_connect_direct(dev, phy_dev, ax_handle_link_change,
359 360 361 362 363
				 PHY_INTERFACE_MODE_MII);
	if (ret) {
		netdev_err(dev, "Could not attach to PHY\n");
		return ret;
	}
B
Ben Dooks 已提交
364

365 366 367
	/* mask with MAC supported features */
	phy_dev->supported &= PHY_BASIC_FEATURES;
	phy_dev->advertising = phy_dev->supported;
B
Ben Dooks 已提交
368

369
	netdev_info(dev, "PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n",
A
Andrew Lunn 已提交
370
		    phy_dev->drv->name, phydev_name(phy_dev), phy_dev->irq);
B
Ben Dooks 已提交
371

372
	return 0;
B
Ben Dooks 已提交
373 374
}

375
static void ax_phy_switch(struct net_device *dev, int on)
B
Ben Dooks 已提交
376
{
377
	struct ei_device *ei_local = netdev_priv(dev);
378
	struct ax_device *ax = to_ax_dev(dev);
B
Ben Dooks 已提交
379

380
	u8 reg_gpoc =  ax->plat->gpoc_val;
B
Ben Dooks 已提交
381

382 383 384 385 386 387
	if (!!on)
		reg_gpoc &= ~AX_GPOC_PPDSET;
	else
		reg_gpoc |= AX_GPOC_PPDSET;

	ei_outb(reg_gpoc, ei_local->mem + EI_SHIFT(0x17));
B
Ben Dooks 已提交
388 389 390 391
}

static int ax_open(struct net_device *dev)
{
392
	struct ax_device *ax = to_ax_dev(dev);
B
Ben Dooks 已提交
393 394
	int ret;

395
	netdev_dbg(dev, "open\n");
B
Ben Dooks 已提交
396

397 398
	ret = request_irq(dev->irq, ax_ei_interrupt, ax->irqflags,
			  dev->name, dev);
B
Ben Dooks 已提交
399
	if (ret)
400
		goto failed_request_irq;
B
Ben Dooks 已提交
401 402

	/* turn the phy on (if turned off) */
403
	ax_phy_switch(dev, 1);
B
Ben Dooks 已提交
404

405 406 407
	ret = ax_mii_probe(dev);
	if (ret)
		goto failed_mii_probe;
408
	phy_start(dev->phydev);
B
Ben Dooks 已提交
409

410 411 412
	ret = ax_ei_open(dev);
	if (ret)
		goto failed_ax_ei_open;
B
Ben Dooks 已提交
413

414
	ax->running = 1;
B
Ben Dooks 已提交
415 416

	return 0;
417 418

 failed_ax_ei_open:
419
	phy_disconnect(dev->phydev);
420 421 422 423 424
 failed_mii_probe:
	ax_phy_switch(dev, 0);
	free_irq(dev->irq, dev);
 failed_request_irq:
	return ret;
B
Ben Dooks 已提交
425 426 427 428 429 430
}

static int ax_close(struct net_device *dev)
{
	struct ax_device *ax = to_ax_dev(dev);

431
	netdev_dbg(dev, "close\n");
B
Ben Dooks 已提交
432 433 434 435 436 437

	ax->running = 0;
	wmb();

	ax_ei_close(dev);

438 439
	/* turn the phy off */
	ax_phy_switch(dev, 0);
440
	phy_disconnect(dev->phydev);
441

B
Ben Dooks 已提交
442 443 444 445 446 447
	free_irq(dev->irq, dev);
	return 0;
}

static int ax_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
{
448
	struct phy_device *phy_dev = dev->phydev;
B
Ben Dooks 已提交
449 450 451 452

	if (!netif_running(dev))
		return -EINVAL;

453 454
	if (!phy_dev)
		return -ENODEV;
B
Ben Dooks 已提交
455

456
	return phy_mii_ioctl(phy_dev, req, cmd);
B
Ben Dooks 已提交
457 458 459 460 461 462 463
}

/* ethtool ops */

static void ax_get_drvinfo(struct net_device *dev,
			   struct ethtool_drvinfo *info)
{
464
	struct platform_device *pdev = to_platform_device(dev->dev.parent);
B
Ben Dooks 已提交
465

466 467 468
	strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
	strlcpy(info->version, DRV_VERSION, sizeof(info->version));
	strlcpy(info->bus_info, pdev->name, sizeof(info->bus_info));
B
Ben Dooks 已提交
469 470
}

471 472 473 474 475 476 477 478 479 480 481 482 483 484
static u32 ax_get_msglevel(struct net_device *dev)
{
	struct ei_device *ei_local = netdev_priv(dev);

	return ei_local->msg_enable;
}

static void ax_set_msglevel(struct net_device *dev, u32 v)
{
	struct ei_device *ei_local = netdev_priv(dev);

	ei_local->msg_enable = v;
}

B
Ben Dooks 已提交
485 486
static const struct ethtool_ops ax_ethtool_ops = {
	.get_drvinfo		= ax_get_drvinfo,
487
	.get_link		= ethtool_op_get_link,
488
	.get_ts_info		= ethtool_op_get_ts_info,
489 490
	.get_msglevel		= ax_get_msglevel,
	.set_msglevel		= ax_set_msglevel,
491 492
	.get_link_ksettings	= phy_ethtool_get_link_ksettings,
	.set_link_ksettings	= phy_ethtool_set_link_ksettings,
B
Ben Dooks 已提交
493 494
};

M
Magnus Damm 已提交
495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525
#ifdef CONFIG_AX88796_93CX6
static void ax_eeprom_register_read(struct eeprom_93cx6 *eeprom)
{
	struct ei_device *ei_local = eeprom->data;
	u8 reg = ei_inb(ei_local->mem + AX_MEMR);

	eeprom->reg_data_in = reg & AX_MEMR_EEI;
	eeprom->reg_data_out = reg & AX_MEMR_EEO; /* Input pin */
	eeprom->reg_data_clock = reg & AX_MEMR_EECLK;
	eeprom->reg_chip_select = reg & AX_MEMR_EECS;
}

static void ax_eeprom_register_write(struct eeprom_93cx6 *eeprom)
{
	struct ei_device *ei_local = eeprom->data;
	u8 reg = ei_inb(ei_local->mem + AX_MEMR);

	reg &= ~(AX_MEMR_EEI | AX_MEMR_EECLK | AX_MEMR_EECS);

	if (eeprom->reg_data_in)
		reg |= AX_MEMR_EEI;
	if (eeprom->reg_data_clock)
		reg |= AX_MEMR_EECLK;
	if (eeprom->reg_chip_select)
		reg |= AX_MEMR_EECS;

	ei_outb(reg, ei_local->mem + AX_MEMR);
	udelay(10);
}
#endif

526 527 528 529 530 531 532 533
static const struct net_device_ops ax_netdev_ops = {
	.ndo_open		= ax_open,
	.ndo_stop		= ax_close,
	.ndo_do_ioctl		= ax_ioctl,

	.ndo_start_xmit		= ax_ei_start_xmit,
	.ndo_tx_timeout		= ax_ei_tx_timeout,
	.ndo_get_stats		= ax_ei_get_stats,
534
	.ndo_set_rx_mode	= ax_ei_set_multicast_list,
535
	.ndo_validate_addr	= eth_validate_addr,
536
	.ndo_set_mac_address	= eth_mac_addr,
537 538 539 540 541
#ifdef CONFIG_NET_POLL_CONTROLLER
	.ndo_poll_controller	= ax_ei_poll,
#endif
};

542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585
static void ax_bb_mdc(struct mdiobb_ctrl *ctrl, int level)
{
	struct ax_device *ax = container_of(ctrl, struct ax_device, bb_ctrl);

	if (level)
		ax->reg_memr |= AX_MEMR_MDC;
	else
		ax->reg_memr &= ~AX_MEMR_MDC;

	ei_outb(ax->reg_memr, ax->addr_memr);
}

static void ax_bb_dir(struct mdiobb_ctrl *ctrl, int output)
{
	struct ax_device *ax = container_of(ctrl, struct ax_device, bb_ctrl);

	if (output)
		ax->reg_memr &= ~AX_MEMR_MDIR;
	else
		ax->reg_memr |= AX_MEMR_MDIR;

	ei_outb(ax->reg_memr, ax->addr_memr);
}

static void ax_bb_set_data(struct mdiobb_ctrl *ctrl, int value)
{
	struct ax_device *ax = container_of(ctrl, struct ax_device, bb_ctrl);

	if (value)
		ax->reg_memr |= AX_MEMR_MDO;
	else
		ax->reg_memr &= ~AX_MEMR_MDO;

	ei_outb(ax->reg_memr, ax->addr_memr);
}

static int ax_bb_get_data(struct mdiobb_ctrl *ctrl)
{
	struct ax_device *ax = container_of(ctrl, struct ax_device, bb_ctrl);
	int reg_memr = ei_inb(ax->addr_memr);

	return reg_memr & AX_MEMR_MDI ? 1 : 0;
}

586
static const struct mdiobb_ops bb_ops = {
587 588 589 590 591 592 593
	.owner = THIS_MODULE,
	.set_mdc = ax_bb_mdc,
	.set_mdio_dir = ax_bb_dir,
	.set_mdio_data = ax_bb_set_data,
	.get_mdio_data = ax_bb_get_data,
};

B
Ben Dooks 已提交
594 595
/* setup code */

596 597 598 599 600
static int ax_mii_init(struct net_device *dev)
{
	struct platform_device *pdev = to_platform_device(dev->dev.parent);
	struct ei_device *ei_local = netdev_priv(dev);
	struct ax_device *ax = to_ax_dev(dev);
601
	int err;
602 603 604 605 606 607 608 609 610 611 612

	ax->bb_ctrl.ops = &bb_ops;
	ax->addr_memr = ei_local->mem + AX_MEMR;
	ax->mii_bus = alloc_mdio_bitbang(&ax->bb_ctrl);
	if (!ax->mii_bus) {
		err = -ENOMEM;
		goto out;
	}

	ax->mii_bus->name = "ax88796_mii_bus";
	ax->mii_bus->parent = dev->dev.parent;
613 614
	snprintf(ax->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
		pdev->name, pdev->id);
615 616 617

	err = mdiobus_register(ax->mii_bus);
	if (err)
618
		goto out_free_mdio_bitbang;
619 620 621 622 623 624 625 626 627

	return 0;

 out_free_mdio_bitbang:
	free_mdio_bitbang(ax->mii_bus);
 out:
	return err;
}

B
Ben Dooks 已提交
628 629 630 631 632
static void ax_initial_setup(struct net_device *dev, struct ei_device *ei_local)
{
	void __iomem *ioaddr = ei_local->mem;
	struct ax_device *ax = to_ax_dev(dev);

633 634
	/* Select page 0 */
	ei_outb(E8390_NODMA + E8390_PAGE0 + E8390_STOP, ioaddr + E8390_CMD);
B
Ben Dooks 已提交
635 636 637 638 639 640

	/* set to byte access */
	ei_outb(ax->plat->dcr_val & ~1, ioaddr + EN0_DCFG);
	ei_outb(ax->plat->gpoc_val, ioaddr + EI_SHIFT(0x17));
}

641 642
/*
 * ax_init_dev
B
Ben Dooks 已提交
643 644 645 646 647 648
 *
 * initialise the specified device, taking care to note the MAC
 * address it may already have (if configured), ensure
 * the device is ready to be used by lib8390.c and registerd with
 * the network layer.
 */
649
static int ax_init_dev(struct net_device *dev)
B
Ben Dooks 已提交
650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668
{
	struct ei_device *ei_local = netdev_priv(dev);
	struct ax_device *ax = to_ax_dev(dev);
	void __iomem *ioaddr = ei_local->mem;
	unsigned int start_page;
	unsigned int stop_page;
	int ret;
	int i;

	ret = ax_initial_check(dev);
	if (ret)
		goto err_out;

	/* setup goes here */

	ax_initial_setup(dev, ei_local);

	/* read the mac from the card prom if we need it */

669
	if (ax->plat->flags & AXFLG_HAS_EEPROM) {
B
Ben Dooks 已提交
670 671
		unsigned char SA_prom[32];

672
		for (i = 0; i < sizeof(SA_prom); i += 2) {
B
Ben Dooks 已提交
673
			SA_prom[i] = ei_inb(ioaddr + NE_DATAPORT);
674
			SA_prom[i + 1] = ei_inb(ioaddr + NE_DATAPORT);
B
Ben Dooks 已提交
675 676 677 678 679 680
		}

		if (ax->plat->wordlength == 2)
			for (i = 0; i < 16; i++)
				SA_prom[i] = SA_prom[i+i];

681
		memcpy(dev->dev_addr, SA_prom, ETH_ALEN);
B
Ben Dooks 已提交
682 683
	}

M
Magnus Damm 已提交
684
#ifdef CONFIG_AX88796_93CX6
685
	if (ax->plat->flags & AXFLG_HAS_93CX6) {
686
		unsigned char mac_addr[ETH_ALEN];
M
Magnus Damm 已提交
687 688 689 690 691 692 693 694 695 696 697
		struct eeprom_93cx6 eeprom;

		eeprom.data = ei_local;
		eeprom.register_read = ax_eeprom_register_read;
		eeprom.register_write = ax_eeprom_register_write;
		eeprom.width = PCI_EEPROM_WIDTH_93C56;

		eeprom_93cx6_multiread(&eeprom, 0,
				       (__le16 __force *)mac_addr,
				       sizeof(mac_addr) >> 1);

698
		memcpy(dev->dev_addr, mac_addr, ETH_ALEN);
M
Magnus Damm 已提交
699 700
	}
#endif
B
Ben Dooks 已提交
701 702 703 704 705 706 707 708 709 710
	if (ax->plat->wordlength == 2) {
		/* We must set the 8390 for word mode. */
		ei_outb(ax->plat->dcr_val, ei_local->mem + EN0_DCFG);
		start_page = NESM_START_PG;
		stop_page = NESM_STOP_PG;
	} else {
		start_page = NE1SM_START_PG;
		stop_page = NE1SM_STOP_PG;
	}

711 712 713 714
	/* load the mac-address from the device */
	if (ax->plat->flags & AXFLG_MAC_FROMDEV) {
		ei_outb(E8390_NODMA + E8390_PAGE1 + E8390_STOP,
			ei_local->mem + E8390_CMD); /* 0x61 */
715
		for (i = 0; i < ETH_ALEN; i++)
716 717
			dev->dev_addr[i] =
				ei_inb(ioaddr + EN1_PHYS_SHIFT(i));
B
Ben Dooks 已提交
718 719
	}

720 721
	if ((ax->plat->flags & AXFLG_MAC_FROMPLATFORM) &&
	    ax->plat->mac_addr)
722
		memcpy(dev->dev_addr, ax->plat->mac_addr, ETH_ALEN);
723

724 725 726 727 728 729
	if (!is_valid_ether_addr(dev->dev_addr)) {
		eth_hw_addr_random(dev);
		dev_info(&dev->dev, "Using random MAC address: %pM\n",
			 dev->dev_addr);
	}

B
Ben Dooks 已提交
730 731
	ax_reset_8390(dev);

732 733 734 735 736
	ei_local->name = "AX88796";
	ei_local->tx_start_page = start_page;
	ei_local->stop_page = stop_page;
	ei_local->word16 = (ax->plat->wordlength == 2);
	ei_local->rx_start_page = start_page + TX_PAGES;
B
Ben Dooks 已提交
737 738

#ifdef PACKETBUF_MEMSIZE
739
	/* Allow the packet buffer size to be overridden by know-it-alls. */
740
	ei_local->stop_page = ei_local->tx_start_page + PACKETBUF_MEMSIZE;
B
Ben Dooks 已提交
741 742
#endif

743 744 745 746 747
	ei_local->reset_8390 = &ax_reset_8390;
	ei_local->block_input = &ax_block_input;
	ei_local->block_output = &ax_block_output;
	ei_local->get_8390_hdr = &ax_get_8390_hdr;
	ei_local->priv = 0;
B
Ben Dooks 已提交
748

749 750
	dev->netdev_ops = &ax_netdev_ops;
	dev->ethtool_ops = &ax_ethtool_ops;
B
Ben Dooks 已提交
751

752 753
	ret = ax_mii_init(dev);
	if (ret)
754
		goto err_out;
B
Ben Dooks 已提交
755 756 757 758 759

	ax_NS8390_init(dev, 0);

	ret = register_netdev(dev);
	if (ret)
760
		goto err_out;
B
Ben Dooks 已提交
761

762 763 764 765
	netdev_info(dev, "%dbit, irq %d, %lx, MAC: %pM\n",
		    ei_local->word16 ? 16 : 8, dev->irq, dev->base_addr,
		    dev->dev_addr);

B
Ben Dooks 已提交
766 767 768 769 770 771
	return 0;

 err_out:
	return ret;
}

772
static int ax_remove(struct platform_device *pdev)
B
Ben Dooks 已提交
773
{
774
	struct net_device *dev = platform_get_drvdata(pdev);
775
	struct ei_device *ei_local = netdev_priv(dev);
776 777
	struct ax_device *ax = to_ax_dev(dev);
	struct resource *mem;
B
Ben Dooks 已提交
778 779 780 781

	unregister_netdev(dev);
	free_irq(dev->irq, dev);

782
	iounmap(ei_local->mem);
783 784
	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	release_mem_region(mem->start, resource_size(mem));
B
Ben Dooks 已提交
785 786 787

	if (ax->map2) {
		iounmap(ax->map2);
788 789
		mem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
		release_mem_region(mem->start, resource_size(mem));
B
Ben Dooks 已提交
790 791 792 793 794 795 796
	}

	free_netdev(dev);

	return 0;
}

797 798
/*
 * ax_probe
B
Ben Dooks 已提交
799 800
 *
 * This is the entry point when the platform device system uses to
801 802 803
 * notify us of a new device to attach to. Allocate memory, find the
 * resources and information passed, and map the necessary registers.
 */
B
Ben Dooks 已提交
804 805 806
static int ax_probe(struct platform_device *pdev)
{
	struct net_device *dev;
807
	struct ei_device *ei_local;
808
	struct ax_device *ax;
809
	struct resource *irq, *mem, *mem2;
810
	unsigned long mem_size, mem2_size = 0;
811
	int ret = 0;
B
Ben Dooks 已提交
812 813 814 815 816 817

	dev = ax__alloc_ei_netdev(sizeof(struct ax_device));
	if (dev == NULL)
		return -ENOMEM;

	/* ok, let's setup our device */
818
	SET_NETDEV_DEV(dev, &pdev->dev);
819
	ei_local = netdev_priv(dev);
B
Ben Dooks 已提交
820 821
	ax = to_ax_dev(dev);

822
	ax->plat = dev_get_platdata(&pdev->dev);
B
Ben Dooks 已提交
823 824
	platform_set_drvdata(pdev, dev);

825
	ei_local->rxcr_base = ax->plat->rcr_val;
B
Ben Dooks 已提交
826 827

	/* find the platform resources */
828 829
	irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (!irq) {
B
Ben Dooks 已提交
830
		dev_err(&pdev->dev, "no IRQ specified\n");
831
		ret = -ENXIO;
B
Ben Dooks 已提交
832 833
		goto exit_mem;
	}
834

835 836
	dev->irq = irq->start;
	ax->irqflags = irq->flags & IRQF_TRIGGER_MASK;
B
Ben Dooks 已提交
837

838 839
	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!mem) {
B
Ben Dooks 已提交
840 841 842 843 844
		dev_err(&pdev->dev, "no MEM specified\n");
		ret = -ENXIO;
		goto exit_mem;
	}

845
	mem_size = resource_size(mem);
B
Ben Dooks 已提交
846

847 848 849 850
	/*
	 * setup the register offsets from either the platform data or
	 * by using the size of the resource provided
	 */
B
Ben Dooks 已提交
851
	if (ax->plat->reg_offsets)
852
		ei_local->reg_offset = ax->plat->reg_offsets;
B
Ben Dooks 已提交
853
	else {
854
		ei_local->reg_offset = ax->reg_offsets;
B
Ben Dooks 已提交
855
		for (ret = 0; ret < 0x18; ret++)
856
			ax->reg_offsets[ret] = (mem_size / 0x18) * ret;
B
Ben Dooks 已提交
857 858
	}

859
	if (!request_mem_region(mem->start, mem_size, pdev->name)) {
B
Ben Dooks 已提交
860
		dev_err(&pdev->dev, "cannot reserve registers\n");
861
		ret = -ENXIO;
B
Ben Dooks 已提交
862 863 864
		goto exit_mem;
	}

865
	ei_local->mem = ioremap(mem->start, mem_size);
866
	dev->base_addr = (unsigned long)ei_local->mem;
B
Ben Dooks 已提交
867

868
	if (ei_local->mem == NULL) {
869
		dev_err(&pdev->dev, "Cannot ioremap area %pR\n", mem);
B
Ben Dooks 已提交
870

871
		ret = -ENXIO;
B
Ben Dooks 已提交
872 873 874 875
		goto exit_req;
	}

	/* look for reset area */
876 877
	mem2 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
	if (!mem2) {
B
Ben Dooks 已提交
878 879
		if (!ax->plat->reg_offsets) {
			for (ret = 0; ret < 0x20; ret++)
880
				ax->reg_offsets[ret] = (mem_size / 0x20) * ret;
B
Ben Dooks 已提交
881 882
		}
	} else {
883
		mem2_size = resource_size(mem2);
B
Ben Dooks 已提交
884

885
		if (!request_mem_region(mem2->start, mem2_size, pdev->name)) {
B
Ben Dooks 已提交
886 887 888 889 890
			dev_err(&pdev->dev, "cannot reserve registers\n");
			ret = -ENXIO;
			goto exit_mem1;
		}

891 892
		ax->map2 = ioremap(mem2->start, mem2_size);
		if (!ax->map2) {
893
			dev_err(&pdev->dev, "cannot map reset register\n");
B
Ben Dooks 已提交
894 895 896 897
			ret = -ENXIO;
			goto exit_mem2;
		}

898
		ei_local->reg_offset[0x1f] = ax->map2 - ei_local->mem;
B
Ben Dooks 已提交
899 900 901
	}

	/* got resources, now initialise and register device */
902
	ret = ax_init_dev(dev);
B
Ben Dooks 已提交
903 904 905
	if (!ret)
		return 0;

906
	if (!ax->map2)
B
Ben Dooks 已提交
907 908 909 910 911
		goto exit_mem1;

	iounmap(ax->map2);

 exit_mem2:
912 913
	if (mem2)
		release_mem_region(mem2->start, mem2_size);
B
Ben Dooks 已提交
914 915

 exit_mem1:
916
	iounmap(ei_local->mem);
B
Ben Dooks 已提交
917 918

 exit_req:
919
	release_mem_region(mem->start, mem_size);
B
Ben Dooks 已提交
920 921 922 923 924 925 926 927 928 929 930 931 932

 exit_mem:
	free_netdev(dev);

	return ret;
}

/* suspend and resume */

#ifdef CONFIG_PM
static int ax_suspend(struct platform_device *dev, pm_message_t state)
{
	struct net_device *ndev = platform_get_drvdata(dev);
933
	struct ax_device *ax = to_ax_dev(ndev);
B
Ben Dooks 已提交
934 935 936 937 938 939 940 941 942 943 944 945

	ax->resume_open = ax->running;

	netif_device_detach(ndev);
	ax_close(ndev);

	return 0;
}

static int ax_resume(struct platform_device *pdev)
{
	struct net_device *ndev = platform_get_drvdata(pdev);
946
	struct ax_device *ax = to_ax_dev(ndev);
B
Ben Dooks 已提交
947 948 949 950 951 952 953 954 955 956 957 958 959

	ax_initial_setup(ndev, netdev_priv(ndev));
	ax_NS8390_init(ndev, ax->resume_open);
	netif_device_attach(ndev);

	if (ax->resume_open)
		ax_open(ndev);

	return 0;
}

#else
#define ax_suspend NULL
960
#define ax_resume NULL
B
Ben Dooks 已提交
961 962 963 964 965 966 967 968 969 970 971 972
#endif

static struct platform_driver axdrv = {
	.driver	= {
		.name		= "ax88796",
	},
	.probe		= ax_probe,
	.remove		= ax_remove,
	.suspend	= ax_suspend,
	.resume		= ax_resume,
};

973
module_platform_driver(axdrv);
B
Ben Dooks 已提交
974 975 976 977

MODULE_DESCRIPTION("AX88796 10/100 Ethernet platform driver");
MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
MODULE_LICENSE("GPL v2");
978
MODULE_ALIAS("platform:ax88796");