fs_enet-main.c 26.3 KB
Newer Older
1 2 3
/*
 * Combined Ethernet driver for Motorola MPC8xx and MPC82xx.
 *
V
Vitaly Bordug 已提交
4
 * Copyright (c) 2003 Intracom S.A.
5
 *  by Pantelis Antoniou <panto@intracom.gr>
V
Vitaly Bordug 已提交
6 7
 *
 * 2005 (c) MontaVista Software, Inc.
8 9 10 11 12
 * Vitaly Bordug <vbordug@ru.mvista.com>
 *
 * Heavily based on original FEC driver by Dan Malek <dan@embeddededge.com>
 * and modifications by Joakim Tjernlund <joakim.tjernlund@lumentis.se>
 *
V
Vitaly Bordug 已提交
13 14
 * This file is licensed under the terms of the GNU General Public License
 * version 2. This program is licensed "as is" without any warranty of any
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
 * kind, whether express or implied.
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/string.h>
#include <linux/ptrace.h>
#include <linux/errno.h>
#include <linux/ioport.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/spinlock.h>
#include <linux/mii.h>
#include <linux/ethtool.h>
#include <linux/bitops.h>
#include <linux/fs.h>
M
Marcelo Tosatti 已提交
36
#include <linux/platform_device.h>
37
#include <linux/phy.h>
38 39
#include <linux/of.h>
#include <linux/of_mdio.h>
40
#include <linux/of_platform.h>
41
#include <linux/of_gpio.h>
42
#include <linux/of_net.h>
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57

#include <linux/vmalloc.h>
#include <asm/pgtable.h>
#include <asm/irq.h>
#include <asm/uaccess.h>

#include "fs_enet.h"

/*************************************************/

MODULE_AUTHOR("Pantelis Antoniou <panto@intracom.gr>");
MODULE_DESCRIPTION("Freescale Ethernet Driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_MODULE_VERSION);

S
Scott Wood 已提交
58
static int fs_enet_debug = -1; /* -1 == use FS_ENET_DEF_MSG_ENABLE as value */
R
Rusty Russell 已提交
59
module_param(fs_enet_debug, int, 0);
60 61 62
MODULE_PARM_DESC(fs_enet_debug,
		 "Freescale bitmapped debugging message enable value");

V
Vitaly Bordug 已提交
63 64 65
#ifdef CONFIG_NET_POLL_CONTROLLER
static void fs_enet_netpoll(struct net_device *dev);
#endif
66 67 68 69 70 71 72 73

static void fs_set_multicast_list(struct net_device *dev)
{
	struct fs_enet_private *fep = netdev_priv(dev);

	(*fep->ops->set_multicast_list)(dev);
}

S
Scott Wood 已提交
74 75 76 77 78 79 80 81
static void skb_align(struct sk_buff *skb, int align)
{
	int off = ((unsigned long)skb->data) & (align - 1);

	if (off)
		skb_reserve(skb, align - off);
}

82
/* NAPI receive function */
83
static int fs_enet_rx_napi(struct napi_struct *napi, int budget)
84
{
85
	struct fs_enet_private *fep = container_of(napi, struct fs_enet_private, napi);
S
Scott Wood 已提交
86
	struct net_device *dev = fep->ndev;
87
	const struct fs_platform_info *fpi = fep->fpi;
S
Scott Wood 已提交
88
	cbd_t __iomem *bdp;
89
	struct sk_buff *skb, *skbn;
90 91 92 93
	int received = 0;
	u16 pkt_len, sc;
	int curidx;

94 95 96
	if (budget <= 0)
		return received;

97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
	/*
	 * First, grab all of the stats for the incoming packet.
	 * These get messed up if we get called due to a busy condition.
	 */
	bdp = fep->cur_rx;

	/* clear RX status bits for napi*/
	(*fep->ops->napi_clear_rx_event)(dev);

	while (((sc = CBDR_SC(bdp)) & BD_ENET_RX_EMPTY) == 0) {
		curidx = bdp - fep->rx_bd_base;

		/*
		 * Since we have allocated space to hold a complete frame,
		 * the last indicator should be set.
		 */
		if ((sc & BD_ENET_RX_LAST) == 0)
114
			dev_warn(fep->dev, "rcv is not +last\n");
115 116

		/*
V
Vitaly Bordug 已提交
117
		 * Check for errors.
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
		 */
		if (sc & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_CL |
			  BD_ENET_RX_NO | BD_ENET_RX_CR | BD_ENET_RX_OV)) {
			fep->stats.rx_errors++;
			/* Frame too long or too short. */
			if (sc & (BD_ENET_RX_LG | BD_ENET_RX_SH))
				fep->stats.rx_length_errors++;
			/* Frame alignment */
			if (sc & (BD_ENET_RX_NO | BD_ENET_RX_CL))
				fep->stats.rx_frame_errors++;
			/* CRC Error */
			if (sc & BD_ENET_RX_CR)
				fep->stats.rx_crc_errors++;
			/* FIFO overrun */
			if (sc & BD_ENET_RX_OV)
				fep->stats.rx_crc_errors++;

			skb = fep->rx_skbuff[curidx];

137
			dma_unmap_single(fep->dev, CBDR_BUFADDR(bdp),
138 139 140 141 142 143 144 145
				L1_CACHE_ALIGN(PKT_MAXBUF_SIZE),
				DMA_FROM_DEVICE);

			skbn = skb;

		} else {
			skb = fep->rx_skbuff[curidx];

146
			dma_unmap_single(fep->dev, CBDR_BUFADDR(bdp),
147 148 149 150 151 152 153 154 155 156 157 158
				L1_CACHE_ALIGN(PKT_MAXBUF_SIZE),
				DMA_FROM_DEVICE);

			/*
			 * Process the incoming frame.
			 */
			fep->stats.rx_packets++;
			pkt_len = CBDR_DATLEN(bdp) - 4;	/* remove CRC */
			fep->stats.rx_bytes += pkt_len + 4;

			if (pkt_len <= fpi->rx_copybreak) {
				/* +2 to make IP header L1 cache aligned */
159
				skbn = netdev_alloc_skb(dev, pkt_len + 2);
160 161
				if (skbn != NULL) {
					skb_reserve(skbn, 2);	/* align IP header */
162 163
					skb_copy_from_linear_data(skb,
						      skbn->data, pkt_len);
164
					swap(skb, skbn);
165
				}
S
Scott Wood 已提交
166
			} else {
167
				skbn = netdev_alloc_skb(dev, ENET_RX_FRSIZE);
168

S
Scott Wood 已提交
169 170 171 172
				if (skbn)
					skb_align(skbn, ENET_RX_ALIGN);
			}

173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
			if (skbn != NULL) {
				skb_put(skb, pkt_len);	/* Make room */
				skb->protocol = eth_type_trans(skb, dev);
				received++;
				netif_receive_skb(skb);
			} else {
				fep->stats.rx_dropped++;
				skbn = skb;
			}
		}

		fep->rx_skbuff[curidx] = skbn;
		CBDW_BUFADDR(bdp, dma_map_single(fep->dev, skbn->data,
			     L1_CACHE_ALIGN(PKT_MAXBUF_SIZE),
			     DMA_FROM_DEVICE));
		CBDW_DATLEN(bdp, 0);
		CBDW_SC(bdp, (sc & ~BD_ENET_RX_STATS) | BD_ENET_RX_EMPTY);

		/*
V
Vitaly Bordug 已提交
192
		 * Update BD pointer to next entry.
193 194 195 196 197 198 199
		 */
		if ((sc & BD_ENET_RX_WRAP) == 0)
			bdp++;
		else
			bdp = fep->rx_bd_base;

		(*fep->ops->rx_bd_done)(dev);
200 201 202

		if (received >= budget)
			break;
203 204 205 206
	}

	fep->cur_rx = bdp;

S
Scott Wood 已提交
207
	if (received < budget) {
208
		/* done */
209
		napi_complete(napi);
210 211 212
		(*fep->ops->napi_enable_rx)(dev);
	}
	return received;
213 214
}

L
LEROY Christophe 已提交
215
static int fs_enet_tx_napi(struct napi_struct *napi, int budget)
216
{
L
LEROY Christophe 已提交
217 218 219
	struct fs_enet_private *fep = container_of(napi, struct fs_enet_private,
						   napi_tx);
	struct net_device *dev = fep->ndev;
S
Scott Wood 已提交
220
	cbd_t __iomem *bdp;
221 222 223
	struct sk_buff *skb;
	int dirtyidx, do_wake, do_restart;
	u16 sc;
L
LEROY Christophe 已提交
224
	int has_tx_work = 0;
225

226
	spin_lock(&fep->tx_lock);
227 228
	bdp = fep->dirty_tx;

L
LEROY Christophe 已提交
229 230 231
	/* clear TX status bits for napi*/
	(*fep->ops->napi_clear_tx_event)(dev);

232 233 234 235 236 237 238 239 240 241
	do_wake = do_restart = 0;
	while (((sc = CBDR_SC(bdp)) & BD_ENET_TX_READY) == 0) {
		dirtyidx = bdp - fep->tx_bd_base;

		if (fep->tx_free == fep->tx_ring)
			break;

		skb = fep->tx_skbuff[dirtyidx];

		/*
V
Vitaly Bordug 已提交
242
		 * Check for errors.
243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264
		 */
		if (sc & (BD_ENET_TX_HB | BD_ENET_TX_LC |
			  BD_ENET_TX_RL | BD_ENET_TX_UN | BD_ENET_TX_CSL)) {

			if (sc & BD_ENET_TX_HB)	/* No heartbeat */
				fep->stats.tx_heartbeat_errors++;
			if (sc & BD_ENET_TX_LC)	/* Late collision */
				fep->stats.tx_window_errors++;
			if (sc & BD_ENET_TX_RL)	/* Retrans limit */
				fep->stats.tx_aborted_errors++;
			if (sc & BD_ENET_TX_UN)	/* Underrun */
				fep->stats.tx_fifo_errors++;
			if (sc & BD_ENET_TX_CSL)	/* Carrier lost */
				fep->stats.tx_carrier_errors++;

			if (sc & (BD_ENET_TX_LC | BD_ENET_TX_RL | BD_ENET_TX_UN)) {
				fep->stats.tx_errors++;
				do_restart = 1;
			}
		} else
			fep->stats.tx_packets++;

265 266 267 268
		if (sc & BD_ENET_TX_READY) {
			dev_warn(fep->dev,
				 "HEY! Enet xmit interrupt and TX_READY.\n");
		}
269 270 271 272 273 274 275 276 277

		/*
		 * Deferred means some collisions occurred during transmit,
		 * but we eventually sent the packet OK.
		 */
		if (sc & BD_ENET_TX_DEF)
			fep->stats.collisions++;

		/* unmap */
278 279 280 281 282 283
		if (fep->mapped_as_page[dirtyidx])
			dma_unmap_page(fep->dev, CBDR_BUFADDR(bdp),
				       CBDR_DATLEN(bdp), DMA_TO_DEVICE);
		else
			dma_unmap_single(fep->dev, CBDR_BUFADDR(bdp),
					 CBDR_DATLEN(bdp), DMA_TO_DEVICE);
284 285

		/*
V
Vitaly Bordug 已提交
286
		 * Free the sk buffer associated with this last transmit.
287
		 */
288 289 290 291
		if (skb) {
			dev_kfree_skb(skb);
			fep->tx_skbuff[dirtyidx] = NULL;
		}
292 293

		/*
V
Vitaly Bordug 已提交
294
		 * Update pointer to next buffer descriptor to be transmitted.
295 296 297 298 299 300 301 302 303 304
		 */
		if ((sc & BD_ENET_TX_WRAP) == 0)
			bdp++;
		else
			bdp = fep->tx_bd_base;

		/*
		 * Since we have freed up a buffer, the ring is no longer
		 * full.
		 */
305
		if (++fep->tx_free >= MAX_SKB_FRAGS)
306
			do_wake = 1;
L
LEROY Christophe 已提交
307
		has_tx_work = 1;
308 309 310 311 312 313 314
	}

	fep->dirty_tx = bdp;

	if (do_restart)
		(*fep->ops->tx_restart)(dev);

L
LEROY Christophe 已提交
315 316 317 318 319
	if (!has_tx_work) {
		napi_complete(napi);
		(*fep->ops->napi_enable_tx)(dev);
	}

320
	spin_unlock(&fep->tx_lock);
321 322 323

	if (do_wake)
		netif_wake_queue(dev);
L
LEROY Christophe 已提交
324 325 326 327

	if (has_tx_work)
		return budget;
	return 0;
328 329 330 331 332 333 334
}

/*
 * The interrupt handler.
 * This is called from the MPC core interrupt.
 */
static irqreturn_t
335
fs_enet_interrupt(int irq, void *dev_id)
336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352
{
	struct net_device *dev = dev_id;
	struct fs_enet_private *fep;
	const struct fs_platform_info *fpi;
	u32 int_events;
	u32 int_clr_events;
	int nr, napi_ok;
	int handled;

	fep = netdev_priv(dev);
	fpi = fep->fpi;

	nr = 0;
	while ((int_events = (*fep->ops->get_int_events)(dev)) != 0) {
		nr++;

		int_clr_events = int_events;
353
		int_clr_events &= ~fep->ev_napi_rx;
354 355 356 357 358 359 360

		(*fep->ops->clear_int_events)(dev, int_clr_events);

		if (int_events & fep->ev_err)
			(*fep->ops->ev_error)(dev, int_events);

		if (int_events & fep->ev_rx) {
361 362 363 364 365 366 367 368 369
			napi_ok = napi_schedule_prep(&fep->napi);

			(*fep->ops->napi_disable_rx)(dev);
			(*fep->ops->clear_int_events)(dev, fep->ev_napi_rx);

			/* NOTE: it is possible for FCCs in NAPI mode    */
			/* to submit a spurious interrupt while in poll  */
			if (napi_ok)
				__napi_schedule(&fep->napi);
370 371
		}

L
LEROY Christophe 已提交
372 373 374 375 376 377 378 379 380 381 382
		if (int_events & fep->ev_tx) {
			napi_ok = napi_schedule_prep(&fep->napi_tx);

			(*fep->ops->napi_disable_tx)(dev);
			(*fep->ops->clear_int_events)(dev, fep->ev_napi_tx);

			/* NOTE: it is possible for FCCs in NAPI mode    */
			/* to submit a spurious interrupt while in poll  */
			if (napi_ok)
				__napi_schedule(&fep->napi_tx);
		}
383 384 385 386 387 388 389 390 391
	}

	handled = nr > 0;
	return IRQ_RETVAL(handled);
}

void fs_init_bds(struct net_device *dev)
{
	struct fs_enet_private *fep = netdev_priv(dev);
S
Scott Wood 已提交
392
	cbd_t __iomem *bdp;
393 394 395 396 397 398 399 400 401 402
	struct sk_buff *skb;
	int i;

	fs_cleanup_bds(dev);

	fep->dirty_tx = fep->cur_tx = fep->tx_bd_base;
	fep->tx_free = fep->tx_ring;
	fep->cur_rx = fep->rx_bd_base;

	/*
V
Vitaly Bordug 已提交
403
	 * Initialize the receive buffer descriptors.
404 405
	 */
	for (i = 0, bdp = fep->rx_bd_base; i < fep->rx_ring; i++, bdp++) {
406
		skb = netdev_alloc_skb(dev, ENET_RX_FRSIZE);
407
		if (skb == NULL)
408
			break;
409

S
Scott Wood 已提交
410
		skb_align(skb, ENET_RX_ALIGN);
411 412 413 414 415 416 417 418 419 420
		fep->rx_skbuff[i] = skb;
		CBDW_BUFADDR(bdp,
			dma_map_single(fep->dev, skb->data,
				L1_CACHE_ALIGN(PKT_MAXBUF_SIZE),
				DMA_FROM_DEVICE));
		CBDW_DATLEN(bdp, 0);	/* zero */
		CBDW_SC(bdp, BD_ENET_RX_EMPTY |
			((i < fep->rx_ring - 1) ? 0 : BD_SC_WRAP));
	}
	/*
V
Vitaly Bordug 已提交
421
	 * if we failed, fillup remainder
422 423 424 425 426 427 428
	 */
	for (; i < fep->rx_ring; i++, bdp++) {
		fep->rx_skbuff[i] = NULL;
		CBDW_SC(bdp, (i < fep->rx_ring - 1) ? 0 : BD_SC_WRAP);
	}

	/*
V
Vitaly Bordug 已提交
429
	 * ...and the same for transmit.
430 431 432 433 434 435 436 437 438 439 440 441 442
	 */
	for (i = 0, bdp = fep->tx_bd_base; i < fep->tx_ring; i++, bdp++) {
		fep->tx_skbuff[i] = NULL;
		CBDW_BUFADDR(bdp, 0);
		CBDW_DATLEN(bdp, 0);
		CBDW_SC(bdp, (i < fep->tx_ring - 1) ? 0 : BD_SC_WRAP);
	}
}

void fs_cleanup_bds(struct net_device *dev)
{
	struct fs_enet_private *fep = netdev_priv(dev);
	struct sk_buff *skb;
S
Scott Wood 已提交
443
	cbd_t __iomem *bdp;
444 445 446
	int i;

	/*
V
Vitaly Bordug 已提交
447
	 * Reset SKB transmit buffers.
448
	 */
449
	for (i = 0, bdp = fep->tx_bd_base; i < fep->tx_ring; i++, bdp++) {
450 451 452 453
		if ((skb = fep->tx_skbuff[i]) == NULL)
			continue;

		/* unmap */
454 455
		dma_unmap_single(fep->dev, CBDR_BUFADDR(bdp),
				skb->len, DMA_TO_DEVICE);
456 457 458 459 460 461

		fep->tx_skbuff[i] = NULL;
		dev_kfree_skb(skb);
	}

	/*
V
Vitaly Bordug 已提交
462
	 * Reset SKB receive buffers
463
	 */
464
	for (i = 0, bdp = fep->rx_bd_base; i < fep->rx_ring; i++, bdp++) {
465 466 467 468
		if ((skb = fep->rx_skbuff[i]) == NULL)
			continue;

		/* unmap */
469
		dma_unmap_single(fep->dev, CBDR_BUFADDR(bdp),
470 471 472 473 474 475 476 477 478 479 480
			L1_CACHE_ALIGN(PKT_MAXBUF_SIZE),
			DMA_FROM_DEVICE);

		fep->rx_skbuff[i] = NULL;

		dev_kfree_skb(skb);
	}
}

/**********************************************************************************/

481 482 483 484 485 486 487 488 489
#ifdef CONFIG_FS_ENET_MPC5121_FEC
/*
 * MPC5121 FEC requeries 4-byte alignment for TX data buffer!
 */
static struct sk_buff *tx_skb_align_workaround(struct net_device *dev,
					       struct sk_buff *skb)
{
	struct sk_buff *new_skb;

490 491 492
	if (skb_linearize(skb))
		return NULL;

493
	/* Alloc new skb */
494
	new_skb = netdev_alloc_skb(dev, skb->len + 4);
495
	if (!new_skb)
496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511
		return NULL;

	/* Make sure new skb is properly aligned */
	skb_align(new_skb, 4);

	/* Copy data to new skb ... */
	skb_copy_from_linear_data(skb, new_skb->data, skb->len);
	skb_put(new_skb, skb->len);

	/* ... and free an old one */
	dev_kfree_skb_any(skb);

	return new_skb;
}
#endif

512 513 514
static int fs_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
	struct fs_enet_private *fep = netdev_priv(dev);
S
Scott Wood 已提交
515
	cbd_t __iomem *bdp;
516 517
	int curidx;
	u16 sc;
518
	int nr_frags;
519 520
	skb_frag_t *frag;
	int len;
521
#ifdef CONFIG_FS_ENET_MPC5121_FEC
522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538
	int is_aligned = 1;
	int i;

	if (!IS_ALIGNED((unsigned long)skb->data, 4)) {
		is_aligned = 0;
	} else {
		nr_frags = skb_shinfo(skb)->nr_frags;
		frag = skb_shinfo(skb)->frags;
		for (i = 0; i < nr_frags; i++, frag++) {
			if (!IS_ALIGNED(frag->page_offset, 4)) {
				is_aligned = 0;
				break;
			}
		}
	}

	if (!is_aligned) {
539 540 541 542 543 544 545 546 547 548 549
		skb = tx_skb_align_workaround(dev, skb);
		if (!skb) {
			/*
			 * We have lost packet due to memory allocation error
			 * in tx_skb_align_workaround(). Hopefully original
			 * skb is still valid, so try transmit it later.
			 */
			return NETDEV_TX_BUSY;
		}
	}
#endif
550

L
LEROY Christophe 已提交
551
	spin_lock(&fep->tx_lock);
552 553

	/*
V
Vitaly Bordug 已提交
554
	 * Fill in a Tx ring entry
555 556 557
	 */
	bdp = fep->cur_tx;

558
	nr_frags = skb_shinfo(skb)->nr_frags;
559
	if (fep->tx_free <= nr_frags || (CBDR_SC(bdp) & BD_ENET_TX_READY)) {
560
		netif_stop_queue(dev);
L
LEROY Christophe 已提交
561
		spin_unlock(&fep->tx_lock);
562 563 564 565 566

		/*
		 * Ooops.  All transmit buffers are full.  Bail out.
		 * This should not happen, since the tx queue should be stopped.
		 */
567
		dev_warn(fep->dev, "tx queue full!.\n");
568 569 570 571 572
		return NETDEV_TX_BUSY;
	}

	curidx = bdp - fep->tx_bd_base;

573 574 575 576 577
	len = skb->len;
	fep->stats.tx_bytes += len;
	if (nr_frags)
		len -= skb->data_len;
	fep->tx_free -= nr_frags + 1;
578
	/*
V
Vitaly Bordug 已提交
579
	 * Push the data cache so the CPM does not get stale memory data.
580 581
	 */
	CBDW_BUFADDR(bdp, dma_map_single(fep->dev,
582 583 584 585 586 587 588
				skb->data, len, DMA_TO_DEVICE));
	CBDW_DATLEN(bdp, len);

	fep->mapped_as_page[curidx] = 0;
	frag = skb_shinfo(skb)->frags;
	while (nr_frags) {
		CBDC_SC(bdp,
589 590
			BD_ENET_TX_STATS | BD_ENET_TX_INTR | BD_ENET_TX_LAST |
			BD_ENET_TX_TC);
591 592 593 594 595 596
		CBDS_SC(bdp, BD_ENET_TX_READY);

		if ((CBDR_SC(bdp) & BD_ENET_TX_WRAP) == 0)
			bdp++, curidx++;
		else
			bdp = fep->tx_bd_base, curidx = 0;
597

598 599 600 601
		len = skb_frag_size(frag);
		CBDW_BUFADDR(bdp, skb_frag_dma_map(fep->dev, frag, 0, len,
						   DMA_TO_DEVICE));
		CBDW_DATLEN(bdp, len);
602

603 604 605 606 607 608
		fep->tx_skbuff[curidx] = NULL;
		fep->mapped_as_page[curidx] = 1;

		frag++;
		nr_frags--;
	}
609 610 611 612 613 614 615 616 617 618

	/* Trigger transmission start */
	sc = BD_ENET_TX_READY | BD_ENET_TX_INTR |
	     BD_ENET_TX_LAST | BD_ENET_TX_TC;

	/* note that while FEC does not have this bit
	 * it marks it as available for software use
	 * yay for hw reuse :) */
	if (skb->len <= 60)
		sc |= BD_ENET_TX_PAD;
619
	CBDC_SC(bdp, BD_ENET_TX_STATS);
620 621
	CBDS_SC(bdp, sc);

622 623 624 625 626 627 628 629 630 631 632 633 634
	/* Save skb pointer. */
	fep->tx_skbuff[curidx] = skb;

	/* If this was the last BD in the ring, start at the beginning again. */
	if ((CBDR_SC(bdp) & BD_ENET_TX_WRAP) == 0)
		bdp++;
	else
		bdp = fep->tx_bd_base;
	fep->cur_tx = bdp;

	if (fep->tx_free < MAX_SKB_FRAGS)
		netif_stop_queue(dev);

635 636
	skb_tx_timestamp(skb);

637 638
	(*fep->ops->tx_kickstart)(dev);

L
LEROY Christophe 已提交
639
	spin_unlock(&fep->tx_lock);
640 641 642 643 644 645 646 647 648 649 650 651 652 653 654

	return NETDEV_TX_OK;
}

static void fs_timeout(struct net_device *dev)
{
	struct fs_enet_private *fep = netdev_priv(dev);
	unsigned long flags;
	int wake = 0;

	fep->stats.tx_errors++;

	spin_lock_irqsave(&fep->lock, flags);

	if (dev->flags & IFF_UP) {
655
		phy_stop(fep->phydev);
656 657
		(*fep->ops->stop)(dev);
		(*fep->ops->restart)(dev);
658
		phy_start(fep->phydev);
659 660
	}

661
	phy_start(fep->phydev);
662 663 664 665 666 667 668
	wake = fep->tx_free && !(CBDR_SC(fep->cur_tx) & BD_ENET_TX_READY);
	spin_unlock_irqrestore(&fep->lock, flags);

	if (wake)
		netif_wake_queue(dev);
}

669 670 671 672 673
/*-----------------------------------------------------------------------------
 *  generic link-change handler - should be sufficient for most cases
 *-----------------------------------------------------------------------------*/
static void generic_adjust_link(struct  net_device *dev)
{
S
Scott Wood 已提交
674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705
	struct fs_enet_private *fep = netdev_priv(dev);
	struct phy_device *phydev = fep->phydev;
	int new_state = 0;

	if (phydev->link) {
		/* adjust to duplex mode */
		if (phydev->duplex != fep->oldduplex) {
			new_state = 1;
			fep->oldduplex = phydev->duplex;
		}

		if (phydev->speed != fep->oldspeed) {
			new_state = 1;
			fep->oldspeed = phydev->speed;
		}

		if (!fep->oldlink) {
			new_state = 1;
			fep->oldlink = 1;
		}

		if (new_state)
			fep->ops->restart(dev);
	} else if (fep->oldlink) {
		new_state = 1;
		fep->oldlink = 0;
		fep->oldspeed = 0;
		fep->oldduplex = -1;
	}

	if (new_state && netif_msg_link(fep))
		phy_print_status(phydev);
706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727
}


static void fs_adjust_link(struct net_device *dev)
{
	struct fs_enet_private *fep = netdev_priv(dev);
	unsigned long flags;

	spin_lock_irqsave(&fep->lock, flags);

	if(fep->ops->adjust_link)
		fep->ops->adjust_link(dev);
	else
		generic_adjust_link(dev);

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

static int fs_init_phy(struct net_device *dev)
{
	struct fs_enet_private *fep = netdev_priv(dev);
	struct phy_device *phydev;
728
	phy_interface_t iface;
729 730 731 732

	fep->oldlink = 0;
	fep->oldspeed = 0;
	fep->oldduplex = -1;
733

734 735 736
	iface = fep->fpi->use_rmii ?
		PHY_INTERFACE_MODE_RMII : PHY_INTERFACE_MODE_MII;

737
	phydev = of_phy_connect(dev, fep->fpi->phy_node, &fs_adjust_link, 0,
738
				iface);
739 740 741
	if (!phydev) {
		dev_err(&dev->dev, "Could not attach to PHY\n");
		return -ENODEV;
742 743 744 745 746 747 748
	}

	fep->phydev = phydev;

	return 0;
}

749 750 751 752
static int fs_enet_open(struct net_device *dev)
{
	struct fs_enet_private *fep = netdev_priv(dev);
	int r;
753
	int err;
754

755 756 757 758
	/* to initialize the fep->cur_rx,... */
	/* not doing this, will cause a crash in fs_enet_rx_napi */
	fs_init_bds(fep->ndev);

759
	napi_enable(&fep->napi);
L
LEROY Christophe 已提交
760
	napi_enable(&fep->napi_tx);
761

762
	/* Install our interrupt handler. */
763 764
	r = request_irq(fep->interrupt, fs_enet_interrupt, IRQF_SHARED,
			"fs_enet-mac", dev);
765
	if (r != 0) {
766
		dev_err(fep->dev, "Could not allocate FS_ENET IRQ!");
767
		napi_disable(&fep->napi);
L
LEROY Christophe 已提交
768
		napi_disable(&fep->napi_tx);
769 770 771
		return -EINVAL;
	}

772
	err = fs_init_phy(dev);
S
Scott Wood 已提交
773
	if (err) {
774
		free_irq(fep->interrupt, dev);
775
		napi_disable(&fep->napi);
L
LEROY Christophe 已提交
776
		napi_disable(&fep->napi_tx);
777
		return err;
778
	}
779
	phy_start(fep->phydev);
780

781 782
	netif_start_queue(dev);

783 784 785 786 787 788 789 790 791 792
	return 0;
}

static int fs_enet_close(struct net_device *dev)
{
	struct fs_enet_private *fep = netdev_priv(dev);
	unsigned long flags;

	netif_stop_queue(dev);
	netif_carrier_off(dev);
793
	napi_disable(&fep->napi);
L
LEROY Christophe 已提交
794
	napi_disable(&fep->napi_tx);
795
	phy_stop(fep->phydev);
796 797

	spin_lock_irqsave(&fep->lock, flags);
798
	spin_lock(&fep->tx_lock);
799
	(*fep->ops->stop)(dev);
800
	spin_unlock(&fep->tx_lock);
801 802 803
	spin_unlock_irqrestore(&fep->lock, flags);

	/* release any irqs */
804 805
	phy_disconnect(fep->phydev);
	fep->phydev = NULL;
806
	free_irq(fep->interrupt, dev);
807 808 809 810 811 812 813 814 815 816 817 818 819 820 821

	return 0;
}

static struct net_device_stats *fs_enet_get_stats(struct net_device *dev)
{
	struct fs_enet_private *fep = netdev_priv(dev);
	return &fep->stats;
}

/*************************************************************************/

static void fs_get_drvinfo(struct net_device *dev,
			    struct ethtool_drvinfo *info)
{
822 823
	strlcpy(info->driver, DRV_MODULE_NAME, sizeof(info->driver));
	strlcpy(info->version, DRV_MODULE_VERSION, sizeof(info->version));
824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852
}

static int fs_get_regs_len(struct net_device *dev)
{
	struct fs_enet_private *fep = netdev_priv(dev);

	return (*fep->ops->get_regs_len)(dev);
}

static void fs_get_regs(struct net_device *dev, struct ethtool_regs *regs,
			 void *p)
{
	struct fs_enet_private *fep = netdev_priv(dev);
	unsigned long flags;
	int r, len;

	len = regs->len;

	spin_lock_irqsave(&fep->lock, flags);
	r = (*fep->ops->get_regs)(dev, p, &len);
	spin_unlock_irqrestore(&fep->lock, flags);

	if (r == 0)
		regs->version = 0;
}

static int fs_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
	struct fs_enet_private *fep = netdev_priv(dev);
853 854 855 856

	if (!fep->phydev)
		return -ENODEV;

857
	return phy_ethtool_gset(fep->phydev, cmd);
858 859 860 861 862
}

static int fs_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
	struct fs_enet_private *fep = netdev_priv(dev);
863 864 865 866 867

	if (!fep->phydev)
		return -ENODEV;

	return phy_ethtool_sset(fep->phydev, cmd);
868 869 870 871
}

static int fs_nway_reset(struct net_device *dev)
{
872
	return 0;
873 874 875 876 877 878 879 880 881 882 883 884 885 886
}

static u32 fs_get_msglevel(struct net_device *dev)
{
	struct fs_enet_private *fep = netdev_priv(dev);
	return fep->msg_enable;
}

static void fs_set_msglevel(struct net_device *dev, u32 value)
{
	struct fs_enet_private *fep = netdev_priv(dev);
	fep->msg_enable = value;
}

887
static const struct ethtool_ops fs_ethtool_ops = {
888 889 890 891 892 893 894 895 896
	.get_drvinfo = fs_get_drvinfo,
	.get_regs_len = fs_get_regs_len,
	.get_settings = fs_get_settings,
	.set_settings = fs_set_settings,
	.nway_reset = fs_nway_reset,
	.get_link = ethtool_op_get_link,
	.get_msglevel = fs_get_msglevel,
	.set_msglevel = fs_set_msglevel,
	.get_regs = fs_get_regs,
897
	.get_ts_info = ethtool_op_get_ts_info,
898 899 900 901 902 903 904 905 906
};

static int fs_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
	struct fs_enet_private *fep = netdev_priv(dev);

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

907
	return phy_mii_ioctl(fep->phydev, rq, cmd);
908 909 910 911 912 913 914
}

extern int fs_mii_connect(struct net_device *dev);
extern void fs_mii_disconnect(struct net_device *dev);

/**************************************************************************************/

915 916 917 918 919 920
#ifdef CONFIG_FS_ENET_HAS_FEC
#define IS_FEC(match) ((match)->data == &fs_fec_ops)
#else
#define IS_FEC(match) 0
#endif

921 922 923 924 925 926
static const struct net_device_ops fs_enet_netdev_ops = {
	.ndo_open		= fs_enet_open,
	.ndo_stop		= fs_enet_close,
	.ndo_get_stats		= fs_enet_get_stats,
	.ndo_start_xmit		= fs_enet_start_xmit,
	.ndo_tx_timeout		= fs_timeout,
927
	.ndo_set_rx_mode	= fs_set_multicast_list,
928 929 930 931 932 933 934 935 936
	.ndo_do_ioctl		= fs_ioctl,
	.ndo_validate_addr	= eth_validate_addr,
	.ndo_set_mac_address	= eth_mac_addr,
	.ndo_change_mtu		= eth_change_mtu,
#ifdef CONFIG_NET_POLL_CONTROLLER
	.ndo_poll_controller	= fs_enet_netpoll,
#endif
};

937
static const struct of_device_id fs_enet_match[];
B
Bill Pemberton 已提交
938
static int fs_enet_probe(struct platform_device *ofdev)
939
{
940
	const struct of_device_id *match;
941 942 943 944
	struct net_device *ndev;
	struct fs_enet_private *fep;
	struct fs_platform_info *fpi;
	const u32 *data;
G
Gerhard Sittig 已提交
945 946
	struct clk *clk;
	int err;
947
	const u8 *mac_addr;
948
	const char *phy_connection_type;
949 950
	int privsize, len, ret = -ENODEV;

951 952
	match = of_match_device(fs_enet_match, &ofdev->dev);
	if (!match)
953 954
		return -EINVAL;

955 956 957 958
	fpi = kzalloc(sizeof(*fpi), GFP_KERNEL);
	if (!fpi)
		return -ENOMEM;

959
	if (!IS_FEC(match)) {
960
		data = of_get_property(ofdev->dev.of_node, "fsl,cpm-command", &len);
961 962 963 964 965 966 967
		if (!data || len != 4)
			goto out_free_fpi;

		fpi->cp_command = *data;
	}

	fpi->rx_ring = 32;
968
	fpi->tx_ring = 64;
969 970
	fpi->rx_copybreak = 240;
	fpi->napi_weight = 17;
971
	fpi->phy_node = of_parse_phandle(ofdev->dev.of_node, "phy-handle", 0);
972 973 974 975 976 977 978 979
	if (!fpi->phy_node && of_phy_is_fixed_link(ofdev->dev.of_node)) {
		err = of_phy_register_fixed_link(ofdev->dev.of_node);
		if (err)
			goto out_free_fpi;

		/* In the case of a fixed PHY, the DT node associated
		 * to the PHY is the Ethernet MAC DT node.
		 */
980
		fpi->phy_node = of_node_get(ofdev->dev.of_node);
981
	}
982

983 984 985 986 987 988 989
	if (of_device_is_compatible(ofdev->dev.of_node, "fsl,mpc5125-fec")) {
		phy_connection_type = of_get_property(ofdev->dev.of_node,
						"phy-connection-type", NULL);
		if (phy_connection_type && !strcmp("rmii", phy_connection_type))
			fpi->use_rmii = 1;
	}

G
Gerhard Sittig 已提交
990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003
	/* make clock lookup non-fatal (the driver is shared among platforms),
	 * but require enable to succeed when a clock was specified/found,
	 * keep a reference to the clock upon successful acquisition
	 */
	clk = devm_clk_get(&ofdev->dev, "per");
	if (!IS_ERR(clk)) {
		err = clk_prepare_enable(clk);
		if (err) {
			ret = err;
			goto out_free_fpi;
		}
		fpi->clk_per = clk;
	}

1004 1005
	privsize = sizeof(*fep) +
	           sizeof(struct sk_buff **) *
1006 1007
		     (fpi->rx_ring + fpi->tx_ring) +
		   sizeof(char) * fpi->tx_ring;
1008 1009 1010 1011

	ndev = alloc_etherdev(privsize);
	if (!ndev) {
		ret = -ENOMEM;
1012
		goto out_put;
1013 1014
	}

1015
	SET_NETDEV_DEV(ndev, &ofdev->dev);
1016
	platform_set_drvdata(ofdev, ndev);
1017 1018 1019

	fep = netdev_priv(ndev);
	fep->dev = &ofdev->dev;
S
Scott Wood 已提交
1020
	fep->ndev = ndev;
1021
	fep->fpi = fpi;
1022
	fep->ops = match->data;
1023 1024 1025 1026 1027 1028 1029

	ret = fep->ops->setup_data(ndev);
	if (ret)
		goto out_free_dev;

	fep->rx_skbuff = (struct sk_buff **)&fep[1];
	fep->tx_skbuff = fep->rx_skbuff + fpi->rx_ring;
1030 1031
	fep->mapped_as_page = (char *)(fep->rx_skbuff + fpi->rx_ring +
				       fpi->tx_ring);
1032 1033 1034 1035

	spin_lock_init(&fep->lock);
	spin_lock_init(&fep->tx_lock);

1036
	mac_addr = of_get_mac_address(ofdev->dev.of_node);
1037
	if (mac_addr)
1038
		memcpy(ndev->dev_addr, mac_addr, ETH_ALEN);
1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049

	ret = fep->ops->allocate_bd(ndev);
	if (ret)
		goto out_cleanup_data;

	fep->rx_bd_base = fep->ring_base;
	fep->tx_bd_base = fep->rx_bd_base + fpi->rx_ring;

	fep->tx_ring = fpi->tx_ring;
	fep->rx_ring = fpi->rx_ring;

1050
	ndev->netdev_ops = &fs_enet_netdev_ops;
1051
	ndev->watchdog_timeo = 2 * HZ;
1052
	netif_napi_add(ndev, &fep->napi, fs_enet_rx_napi, fpi->napi_weight);
L
LEROY Christophe 已提交
1053
	netif_napi_add(ndev, &fep->napi_tx, fs_enet_tx_napi, 2);
S
Scott Wood 已提交
1054

1055 1056 1057 1058 1059 1060
	ndev->ethtool_ops = &fs_ethtool_ops;

	init_timer(&fep->phy_timer_list);

	netif_carrier_off(ndev);

1061 1062
	ndev->features |= NETIF_F_SG;

1063 1064 1065 1066
	ret = register_netdev(ndev);
	if (ret)
		goto out_free_bd;

1067
	pr_info("%s: fs_enet: %pM\n", ndev->name, ndev->dev_addr);
1068 1069 1070 1071 1072 1073 1074 1075 1076

	return 0;

out_free_bd:
	fep->ops->free_bd(ndev);
out_cleanup_data:
	fep->ops->cleanup_data(ndev);
out_free_dev:
	free_netdev(ndev);
1077
out_put:
1078
	of_node_put(fpi->phy_node);
G
Gerhard Sittig 已提交
1079 1080
	if (fpi->clk_per)
		clk_disable_unprepare(fpi->clk_per);
1081 1082 1083 1084 1085
out_free_fpi:
	kfree(fpi);
	return ret;
}

1086
static int fs_enet_remove(struct platform_device *ofdev)
1087
{
1088
	struct net_device *ndev = platform_get_drvdata(ofdev);
1089 1090 1091 1092 1093 1094 1095
	struct fs_enet_private *fep = netdev_priv(ndev);

	unregister_netdev(ndev);

	fep->ops->free_bd(ndev);
	fep->ops->cleanup_data(ndev);
	dev_set_drvdata(fep->dev, NULL);
1096
	of_node_put(fep->fpi->phy_node);
G
Gerhard Sittig 已提交
1097 1098
	if (fep->fpi->clk_per)
		clk_disable_unprepare(fep->fpi->clk_per);
1099 1100 1101 1102
	free_netdev(ndev);
	return 0;
}

1103
static const struct of_device_id fs_enet_match[] = {
1104 1105 1106 1107 1108
#ifdef CONFIG_FS_ENET_HAS_SCC
	{
		.compatible = "fsl,cpm1-scc-enet",
		.data = (void *)&fs_scc_ops,
	},
1109 1110 1111 1112
	{
		.compatible = "fsl,cpm2-scc-enet",
		.data = (void *)&fs_scc_ops,
	},
1113 1114 1115 1116 1117 1118 1119 1120
#endif
#ifdef CONFIG_FS_ENET_HAS_FCC
	{
		.compatible = "fsl,cpm2-fcc-enet",
		.data = (void *)&fs_fcc_ops,
	},
#endif
#ifdef CONFIG_FS_ENET_HAS_FEC
1121 1122 1123 1124 1125
#ifdef CONFIG_FS_ENET_MPC5121_FEC
	{
		.compatible = "fsl,mpc5121-fec",
		.data = (void *)&fs_fec_ops,
	},
1126 1127 1128 1129
	{
		.compatible = "fsl,mpc5125-fec",
		.data = (void *)&fs_fec_ops,
	},
1130
#else
1131 1132 1133 1134
	{
		.compatible = "fsl,pq1-fec-enet",
		.data = (void *)&fs_fec_ops,
	},
1135
#endif
1136 1137 1138
#endif
	{}
};
1139
MODULE_DEVICE_TABLE(of, fs_enet_match);
1140

1141
static struct platform_driver fs_enet_driver = {
1142 1143 1144 1145
	.driver = {
		.name = "fs_enet",
		.of_match_table = fs_enet_match,
	},
1146 1147 1148 1149
	.probe = fs_enet_probe,
	.remove = fs_enet_remove,
};

V
Vitaly Bordug 已提交
1150 1151 1152 1153
#ifdef CONFIG_NET_POLL_CONTROLLER
static void fs_enet_netpoll(struct net_device *dev)
{
       disable_irq(dev->irq);
A
Alexey Dobriyan 已提交
1154
       fs_enet_interrupt(dev->irq, dev);
V
Vitaly Bordug 已提交
1155 1156 1157 1158
       enable_irq(dev->irq);
}
#endif

1159
module_platform_driver(fs_enet_driver);