pasemi_mac.c 47.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
/*
 * Copyright (C) 2006-2007 PA Semi, Inc
 *
 * Driver for the PA Semi PWRficient onchip 1G/10G Ethernet MACs
 *
 * 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.
 *
 * 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 */

#include <linux/init.h>
#include <linux/module.h>
#include <linux/pci.h>
23
#include <linux/slab.h>
24 25 26 27
#include <linux/interrupt.h>
#include <linux/dmaengine.h>
#include <linux/delay.h>
#include <linux/netdevice.h>
28
#include <linux/of_mdio.h>
29 30 31 32 33 34 35 36
#include <linux/etherdevice.h>
#include <asm/dma-mapping.h>
#include <linux/in.h>
#include <linux/skbuff.h>

#include <linux/ip.h>
#include <linux/tcp.h>
#include <net/checksum.h>
37
#include <linux/inet_lro.h>
38
#include <linux/prefetch.h>
39

40
#include <asm/irq.h>
O
Olof Johansson 已提交
41
#include <asm/firmware.h>
42
#include <asm/pasemi_dma.h>
43

44 45
#include "pasemi_mac.h"

46 47 48 49 50 51
/* We have our own align, since ppc64 in general has it at 0 because
 * of design flaws in some of the server bridge chips. However, for
 * PWRficient doing the unaligned copies is more expensive than doing
 * unaligned DMA, so make sure the data is aligned instead.
 */
#define LOCAL_SKB_ALIGN	2
52 53 54 55 56

/* TODO list
 *
 * - Multicast support
 * - Large MTU support
O
Olof Johansson 已提交
57 58
 * - SW LRO
 * - Multiqueue RX/TX
59 60
 */

61 62
#define LRO_MAX_AGGR 64

63
#define PE_MIN_MTU	64
O
Olof Johansson 已提交
64
#define PE_MAX_MTU	9000
65 66
#define PE_DEF_MTU	ETH_DATA_LEN

67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
#define DEFAULT_MSG_ENABLE	  \
	(NETIF_MSG_DRV		| \
	 NETIF_MSG_PROBE	| \
	 NETIF_MSG_LINK		| \
	 NETIF_MSG_TIMER	| \
	 NETIF_MSG_IFDOWN	| \
	 NETIF_MSG_IFUP		| \
	 NETIF_MSG_RX_ERR	| \
	 NETIF_MSG_TX_ERR)

MODULE_LICENSE("GPL");
MODULE_AUTHOR ("Olof Johansson <olof@lixom.net>");
MODULE_DESCRIPTION("PA Semi PWRficient Ethernet driver");

static int debug = -1;	/* -1 == use DEFAULT_MSG_ENABLE as value */
module_param(debug, int, 0);
MODULE_PARM_DESC(debug, "PA Semi MAC bitmapped debugging message enable value");
84

85 86
extern const struct ethtool_ops pasemi_mac_ethtool_ops;

O
Olof Johansson 已提交
87 88 89 90 91 92 93 94 95
static int translation_enabled(void)
{
#if defined(CONFIG_PPC_PASEMI_IOMMU_DMA_FORCE)
	return 1;
#else
	return firmware_has_feature(FW_FEATURE_LPAR);
#endif
}

96
static void write_iob_reg(unsigned int reg, unsigned int val)
97
{
98
	pasemi_write_iob_reg(reg, val);
99 100
}

O
Olof Johansson 已提交
101
static unsigned int read_mac_reg(const struct pasemi_mac *mac, unsigned int reg)
102
{
103
	return pasemi_read_mac_reg(mac->dma_if, reg);
104 105
}

O
Olof Johansson 已提交
106
static void write_mac_reg(const struct pasemi_mac *mac, unsigned int reg,
107 108
			  unsigned int val)
{
109
	pasemi_write_mac_reg(mac->dma_if, reg, val);
110 111
}

112
static unsigned int read_dma_reg(unsigned int reg)
113
{
114
	return pasemi_read_dma_reg(reg);
115 116
}

117
static void write_dma_reg(unsigned int reg, unsigned int val)
118
{
119
	pasemi_write_dma_reg(reg, val);
120 121
}

O
Olof Johansson 已提交
122
static struct pasemi_mac_rxring *rx_ring(const struct pasemi_mac *mac)
123 124 125 126
{
	return mac->rx;
}

O
Olof Johansson 已提交
127
static struct pasemi_mac_txring *tx_ring(const struct pasemi_mac *mac)
128 129 130 131
{
	return mac->tx;
}

O
Olof Johansson 已提交
132 133 134 135 136 137 138 139 140 141
static inline void prefetch_skb(const struct sk_buff *skb)
{
	const void *d = skb;

	prefetch(d);
	prefetch(d+64);
	prefetch(d+128);
	prefetch(d+192);
}

142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
static int mac_to_intf(struct pasemi_mac *mac)
{
	struct pci_dev *pdev = mac->pdev;
	u32 tmp;
	int nintf, off, i, j;
	int devfn = pdev->devfn;

	tmp = read_dma_reg(PAS_DMA_CAP_IFI);
	nintf = (tmp & PAS_DMA_CAP_IFI_NIN_M) >> PAS_DMA_CAP_IFI_NIN_S;
	off = (tmp & PAS_DMA_CAP_IFI_IOFF_M) >> PAS_DMA_CAP_IFI_IOFF_S;

	/* IOFF contains the offset to the registers containing the
	 * DMA interface-to-MAC-pci-id mappings, and NIN contains number
	 * of total interfaces. Each register contains 4 devfns.
	 * Just do a linear search until we find the devfn of the MAC
	 * we're trying to look up.
	 */

	for (i = 0; i < (nintf+3)/4; i++) {
		tmp = read_dma_reg(off+4*i);
		for (j = 0; j < 4; j++) {
			if (((tmp >> (8*j)) & 0xff) == devfn)
				return i*4 + j;
		}
	}
	return -1;
}

170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187
static void pasemi_mac_intf_disable(struct pasemi_mac *mac)
{
	unsigned int flags;

	flags = read_mac_reg(mac, PAS_MAC_CFG_PCFG);
	flags &= ~PAS_MAC_CFG_PCFG_PE;
	write_mac_reg(mac, PAS_MAC_CFG_PCFG, flags);
}

static void pasemi_mac_intf_enable(struct pasemi_mac *mac)
{
	unsigned int flags;

	flags = read_mac_reg(mac, PAS_MAC_CFG_PCFG);
	flags |= PAS_MAC_CFG_PCFG_PE;
	write_mac_reg(mac, PAS_MAC_CFG_PCFG, flags);
}

188 189 190 191
static int pasemi_get_mac_addr(struct pasemi_mac *mac)
{
	struct pci_dev *pdev = mac->pdev;
	struct device_node *dn = pci_device_to_OF_node(pdev);
192
	int len;
193 194 195 196 197 198 199 200 201
	const u8 *maddr;
	u8 addr[6];

	if (!dn) {
		dev_dbg(&pdev->dev,
			  "No device node for mac, not configuring\n");
		return -ENOENT;
	}

202 203 204 205 206 207 208 209 210 211
	maddr = of_get_property(dn, "local-mac-address", &len);

	if (maddr && len == 6) {
		memcpy(mac->mac_addr, maddr, 6);
		return 0;
	}

	/* Some old versions of firmware mistakenly uses mac-address
	 * (and as a string) instead of a byte array in local-mac-address.
	 */
212 213

	if (maddr == NULL)
214
		maddr = of_get_property(dn, "mac-address", NULL);
215

216 217 218 219 220 221 222 223 224 225 226 227 228
	if (maddr == NULL) {
		dev_warn(&pdev->dev,
			 "no mac address in device tree, not configuring\n");
		return -ENOENT;
	}

	if (sscanf(maddr, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &addr[0],
		   &addr[1], &addr[2], &addr[3], &addr[4], &addr[5]) != 6) {
		dev_warn(&pdev->dev,
			 "can't parse mac address, not configuring\n");
		return -EINVAL;
	}

229 230
	memcpy(mac->mac_addr, addr, 6);

231 232 233
	return 0;
}

234 235 236 237 238 239 240
static int pasemi_mac_set_mac_addr(struct net_device *dev, void *p)
{
	struct pasemi_mac *mac = netdev_priv(dev);
	struct sockaddr *addr = p;
	unsigned int adr0, adr1;

	if (!is_valid_ether_addr(addr->sa_data))
241
		return -EADDRNOTAVAIL;
242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260

	memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);

	adr0 = dev->dev_addr[2] << 24 |
	       dev->dev_addr[3] << 16 |
	       dev->dev_addr[4] << 8 |
	       dev->dev_addr[5];
	adr1 = read_mac_reg(mac, PAS_MAC_CFG_ADR1);
	adr1 &= ~0xffff;
	adr1 |= dev->dev_addr[0] << 8 | dev->dev_addr[1];

	pasemi_mac_intf_disable(mac);
	write_mac_reg(mac, PAS_MAC_CFG_ADR0, adr0);
	write_mac_reg(mac, PAS_MAC_CFG_ADR1, adr1);
	pasemi_mac_intf_enable(mac);

	return 0;
}

261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282
static int get_skb_hdr(struct sk_buff *skb, void **iphdr,
		       void **tcph, u64 *hdr_flags, void *data)
{
	u64 macrx = (u64) data;
	unsigned int ip_len;
	struct iphdr *iph;

	/* IPv4 header checksum failed */
	if ((macrx & XCT_MACRX_HTY_M) != XCT_MACRX_HTY_IPV4_OK)
		return -1;

	/* non tcp packet */
	skb_reset_network_header(skb);
	iph = ip_hdr(skb);
	if (iph->protocol != IPPROTO_TCP)
		return -1;

	ip_len = ip_hdrlen(skb);
	skb_set_transport_header(skb, ip_len);
	*tcph = tcp_hdr(skb);

	/* check if ip header and tcp header are complete */
283
	if (ntohs(iph->tot_len) < ip_len + tcp_hdrlen(skb))
284 285 286 287 288 289 290 291
		return -1;

	*hdr_flags = LRO_IPV4 | LRO_TCP;
	*iphdr = iph;

	return 0;
}

O
Olof Johansson 已提交
292
static int pasemi_mac_unmap_tx_skb(struct pasemi_mac *mac,
293
				    const int nfrags,
O
Olof Johansson 已提交
294
				    struct sk_buff *skb,
O
Olof Johansson 已提交
295
				    const dma_addr_t *dmas)
O
Olof Johansson 已提交
296 297
{
	int f;
O
Olof Johansson 已提交
298
	struct pci_dev *pdev = mac->dma_pdev;
O
Olof Johansson 已提交
299

O
Olof Johansson 已提交
300
	pci_unmap_single(pdev, dmas[0], skb_headlen(skb), PCI_DMA_TODEVICE);
O
Olof Johansson 已提交
301 302

	for (f = 0; f < nfrags; f++) {
E
Eric Dumazet 已提交
303
		const skb_frag_t *frag = &skb_shinfo(skb)->frags[f];
O
Olof Johansson 已提交
304

E
Eric Dumazet 已提交
305
		pci_unmap_page(pdev, dmas[f+1], skb_frag_size(frag), PCI_DMA_TODEVICE);
O
Olof Johansson 已提交
306 307 308 309 310 311 312 313 314
	}
	dev_kfree_skb_irq(skb);

	/* Freed descriptor slot + main SKB ptr + nfrags additional ptrs,
	 * aligned up to a power of 2
	 */
	return (nfrags + 3) & ~1;
}

O
Olof Johansson 已提交
315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409
static struct pasemi_mac_csring *pasemi_mac_setup_csring(struct pasemi_mac *mac)
{
	struct pasemi_mac_csring *ring;
	u32 val;
	unsigned int cfg;
	int chno;

	ring = pasemi_dma_alloc_chan(TXCHAN, sizeof(struct pasemi_mac_csring),
				       offsetof(struct pasemi_mac_csring, chan));

	if (!ring) {
		dev_err(&mac->pdev->dev, "Can't allocate checksum channel\n");
		goto out_chan;
	}

	chno = ring->chan.chno;

	ring->size = CS_RING_SIZE;
	ring->next_to_fill = 0;

	/* Allocate descriptors */
	if (pasemi_dma_alloc_ring(&ring->chan, CS_RING_SIZE))
		goto out_ring_desc;

	write_dma_reg(PAS_DMA_TXCHAN_BASEL(chno),
		      PAS_DMA_TXCHAN_BASEL_BRBL(ring->chan.ring_dma));
	val = PAS_DMA_TXCHAN_BASEU_BRBH(ring->chan.ring_dma >> 32);
	val |= PAS_DMA_TXCHAN_BASEU_SIZ(CS_RING_SIZE >> 3);

	write_dma_reg(PAS_DMA_TXCHAN_BASEU(chno), val);

	ring->events[0] = pasemi_dma_alloc_flag();
	ring->events[1] = pasemi_dma_alloc_flag();
	if (ring->events[0] < 0 || ring->events[1] < 0)
		goto out_flags;

	pasemi_dma_clear_flag(ring->events[0]);
	pasemi_dma_clear_flag(ring->events[1]);

	ring->fun = pasemi_dma_alloc_fun();
	if (ring->fun < 0)
		goto out_fun;

	cfg = PAS_DMA_TXCHAN_CFG_TY_FUNC | PAS_DMA_TXCHAN_CFG_UP |
	      PAS_DMA_TXCHAN_CFG_TATTR(ring->fun) |
	      PAS_DMA_TXCHAN_CFG_LPSQ | PAS_DMA_TXCHAN_CFG_LPDQ;

	if (translation_enabled())
		cfg |= PAS_DMA_TXCHAN_CFG_TRD | PAS_DMA_TXCHAN_CFG_TRR;

	write_dma_reg(PAS_DMA_TXCHAN_CFG(chno), cfg);

	/* enable channel */
	pasemi_dma_start_chan(&ring->chan, PAS_DMA_TXCHAN_TCMDSTA_SZ |
					   PAS_DMA_TXCHAN_TCMDSTA_DB |
					   PAS_DMA_TXCHAN_TCMDSTA_DE |
					   PAS_DMA_TXCHAN_TCMDSTA_DA);

	return ring;

out_fun:
out_flags:
	if (ring->events[0] >= 0)
		pasemi_dma_free_flag(ring->events[0]);
	if (ring->events[1] >= 0)
		pasemi_dma_free_flag(ring->events[1]);
	pasemi_dma_free_ring(&ring->chan);
out_ring_desc:
	pasemi_dma_free_chan(&ring->chan);
out_chan:

	return NULL;
}

static void pasemi_mac_setup_csrings(struct pasemi_mac *mac)
{
	int i;
	mac->cs[0] = pasemi_mac_setup_csring(mac);
	if (mac->type == MAC_TYPE_XAUI)
		mac->cs[1] = pasemi_mac_setup_csring(mac);
	else
		mac->cs[1] = 0;

	for (i = 0; i < MAX_CS; i++)
		if (mac->cs[i])
			mac->num_cs++;
}

static void pasemi_mac_free_csring(struct pasemi_mac_csring *csring)
{
	pasemi_dma_stop_chan(&csring->chan);
	pasemi_dma_free_flag(csring->events[0]);
	pasemi_dma_free_flag(csring->events[1]);
	pasemi_dma_free_ring(&csring->chan);
	pasemi_dma_free_chan(&csring->chan);
410
	pasemi_dma_free_fun(csring->fun);
O
Olof Johansson 已提交
411 412
}

O
Olof Johansson 已提交
413
static int pasemi_mac_setup_rx_resources(const struct net_device *dev)
414 415 416
{
	struct pasemi_mac_rxring *ring;
	struct pasemi_mac *mac = netdev_priv(dev);
417
	int chno;
O
Olof Johansson 已提交
418
	unsigned int cfg;
419

420 421
	ring = pasemi_dma_alloc_chan(RXCHAN, sizeof(struct pasemi_mac_rxring),
				     offsetof(struct pasemi_mac_rxring, chan));
422

423 424 425 426 427
	if (!ring) {
		dev_err(&mac->pdev->dev, "Can't allocate RX channel\n");
		goto out_chan;
	}
	chno = ring->chan.chno;
428 429 430

	spin_lock_init(&ring->lock);

431
	ring->size = RX_RING_SIZE;
432
	ring->ring_info = kzalloc(sizeof(struct pasemi_mac_buffer) *
433 434
				  RX_RING_SIZE, GFP_KERNEL);

435 436
	if (!ring->ring_info)
		goto out_ring_info;
437 438

	/* Allocate descriptors */
439
	if (pasemi_dma_alloc_ring(&ring->chan, RX_RING_SIZE))
440
		goto out_ring_desc;
441 442 443 444 445

	ring->buffers = dma_alloc_coherent(&mac->dma_pdev->dev,
					   RX_RING_SIZE * sizeof(u64),
					   &ring->buf_dma, GFP_KERNEL);
	if (!ring->buffers)
446
		goto out_ring_desc;
447 448 449

	memset(ring->buffers, 0, RX_RING_SIZE * sizeof(u64));

450 451
	write_dma_reg(PAS_DMA_RXCHAN_BASEL(chno),
		      PAS_DMA_RXCHAN_BASEL_BRBL(ring->chan.ring_dma));
452

453 454 455
	write_dma_reg(PAS_DMA_RXCHAN_BASEU(chno),
		      PAS_DMA_RXCHAN_BASEU_BRBH(ring->chan.ring_dma >> 32) |
		      PAS_DMA_RXCHAN_BASEU_SIZ(RX_RING_SIZE >> 3));
456

O
Olof Johansson 已提交
457
	cfg = PAS_DMA_RXCHAN_CFG_HBU(2);
O
Olof Johansson 已提交
458 459 460 461

	if (translation_enabled())
		cfg |= PAS_DMA_RXCHAN_CFG_CTR;

462
	write_dma_reg(PAS_DMA_RXCHAN_CFG(chno), cfg);
463

464 465
	write_dma_reg(PAS_DMA_RXINT_BASEL(mac->dma_if),
		      PAS_DMA_RXINT_BASEL_BRBL(ring->buf_dma));
466

467 468 469
	write_dma_reg(PAS_DMA_RXINT_BASEU(mac->dma_if),
		      PAS_DMA_RXINT_BASEU_BRBH(ring->buf_dma >> 32) |
		      PAS_DMA_RXINT_BASEU_SIZ(RX_RING_SIZE >> 3));
470

O
Olof Johansson 已提交
471
	cfg = PAS_DMA_RXINT_CFG_DHL(2) | PAS_DMA_RXINT_CFG_L2 |
O
Olof Johansson 已提交
472 473 474 475 476 477
	      PAS_DMA_RXINT_CFG_LW | PAS_DMA_RXINT_CFG_RBP |
	      PAS_DMA_RXINT_CFG_HEN;

	if (translation_enabled())
		cfg |= PAS_DMA_RXINT_CFG_ITRR | PAS_DMA_RXINT_CFG_ITR;

478
	write_dma_reg(PAS_DMA_RXINT_CFG(mac->dma_if), cfg);
479

480 481
	ring->next_to_fill = 0;
	ring->next_to_clean = 0;
482
	ring->mac = mac;
483 484 485 486
	mac->rx = ring;

	return 0;

487 488 489
out_ring_desc:
	kfree(ring->ring_info);
out_ring_info:
490 491
	pasemi_dma_free_chan(&ring->chan);
out_chan:
492 493 494
	return -ENOMEM;
}

495
static struct pasemi_mac_txring *
O
Olof Johansson 已提交
496
pasemi_mac_setup_tx_resources(const struct net_device *dev)
497 498 499 500
{
	struct pasemi_mac *mac = netdev_priv(dev);
	u32 val;
	struct pasemi_mac_txring *ring;
O
Olof Johansson 已提交
501
	unsigned int cfg;
502
	int chno;
503

504 505 506 507 508 509 510 511 512
	ring = pasemi_dma_alloc_chan(TXCHAN, sizeof(struct pasemi_mac_txring),
				     offsetof(struct pasemi_mac_txring, chan));

	if (!ring) {
		dev_err(&mac->pdev->dev, "Can't allocate TX channel\n");
		goto out_chan;
	}

	chno = ring->chan.chno;
513 514 515

	spin_lock_init(&ring->lock);

516
	ring->size = TX_RING_SIZE;
517
	ring->ring_info = kzalloc(sizeof(struct pasemi_mac_buffer) *
518
				  TX_RING_SIZE, GFP_KERNEL);
519 520
	if (!ring->ring_info)
		goto out_ring_info;
521 522

	/* Allocate descriptors */
523
	if (pasemi_dma_alloc_ring(&ring->chan, TX_RING_SIZE))
524
		goto out_ring_desc;
525

526 527 528
	write_dma_reg(PAS_DMA_TXCHAN_BASEL(chno),
		      PAS_DMA_TXCHAN_BASEL_BRBL(ring->chan.ring_dma));
	val = PAS_DMA_TXCHAN_BASEU_BRBH(ring->chan.ring_dma >> 32);
529
	val |= PAS_DMA_TXCHAN_BASEU_SIZ(TX_RING_SIZE >> 3);
530

531
	write_dma_reg(PAS_DMA_TXCHAN_BASEU(chno), val);
532

O
Olof Johansson 已提交
533 534 535
	cfg = PAS_DMA_TXCHAN_CFG_TY_IFACE |
	      PAS_DMA_TXCHAN_CFG_TATTR(mac->dma_if) |
	      PAS_DMA_TXCHAN_CFG_UP |
O
Olof Johansson 已提交
536
	      PAS_DMA_TXCHAN_CFG_WT(4);
O
Olof Johansson 已提交
537 538 539 540

	if (translation_enabled())
		cfg |= PAS_DMA_TXCHAN_CFG_TRD | PAS_DMA_TXCHAN_CFG_TRR;

541
	write_dma_reg(PAS_DMA_TXCHAN_CFG(chno), cfg);
542

543
	ring->next_to_fill = 0;
544
	ring->next_to_clean = 0;
545
	ring->mac = mac;
546

547
	return ring;
548

549 550 551
out_ring_desc:
	kfree(ring->ring_info);
out_ring_info:
552 553
	pasemi_dma_free_chan(&ring->chan);
out_chan:
554
	return NULL;
555 556
}

557
static void pasemi_mac_free_tx_resources(struct pasemi_mac *mac)
558
{
559
	struct pasemi_mac_txring *txring = tx_ring(mac);
O
Olof Johansson 已提交
560
	unsigned int i, j;
561
	struct pasemi_mac_buffer *info;
O
Olof Johansson 已提交
562
	dma_addr_t dmas[MAX_SKB_FRAGS+1];
563
	int freed, nfrags;
564
	int start, limit;
565

566 567
	start = txring->next_to_clean;
	limit = txring->next_to_fill;
568 569 570 571 572 573

	/* Compensate for when fill has wrapped and clean has not */
	if (start > limit)
		limit += TX_RING_SIZE;

	for (i = start; i < limit; i += freed) {
574
		info = &txring->ring_info[(i+1) & (TX_RING_SIZE-1)];
575
		if (info->dma && info->skb) {
576 577
			nfrags = skb_shinfo(info->skb)->nr_frags;
			for (j = 0; j <= nfrags; j++)
578 579
				dmas[j] = txring->ring_info[(i+1+j) &
						(TX_RING_SIZE-1)].dma;
580 581
			freed = pasemi_mac_unmap_tx_skb(mac, nfrags,
							info->skb, dmas);
O
Olof Johansson 已提交
582 583
		} else
			freed = 2;
584 585
	}

586
	kfree(txring->ring_info);
587 588
	pasemi_dma_free_chan(&txring->chan);

589 590
}

591
static void pasemi_mac_free_rx_buffers(struct pasemi_mac *mac)
592
{
593
	struct pasemi_mac_rxring *rx = rx_ring(mac);
594 595 596 597
	unsigned int i;
	struct pasemi_mac_buffer *info;

	for (i = 0; i < RX_RING_SIZE; i++) {
598
		info = &RX_DESC_INFO(rx, i);
599 600 601 602 603 604
		if (info->skb && info->dma) {
			pci_unmap_single(mac->dma_pdev,
					 info->dma,
					 info->skb->len,
					 PCI_DMA_FROMDEVICE);
			dev_kfree_skb_any(info->skb);
605
		}
606 607
		info->dma = 0;
		info->skb = NULL;
608 609
	}

610
	for (i = 0; i < RX_RING_SIZE; i++)
611 612 613 614 615 616
		RX_BUFF(rx, i) = 0;
}

static void pasemi_mac_free_rx_resources(struct pasemi_mac *mac)
{
	pasemi_mac_free_rx_buffers(mac);
617

618
	dma_free_coherent(&mac->dma_pdev->dev, RX_RING_SIZE * sizeof(u64),
619
			  rx_ring(mac)->buffers, rx_ring(mac)->buf_dma);
620

621
	kfree(rx_ring(mac)->ring_info);
622
	pasemi_dma_free_chan(&rx_ring(mac)->chan);
623 624 625
	mac->rx = NULL;
}

626
static void pasemi_mac_replenish_rx_ring(struct net_device *dev,
O
Olof Johansson 已提交
627
					 const int limit)
628
{
O
Olof Johansson 已提交
629
	const struct pasemi_mac *mac = netdev_priv(dev);
630
	struct pasemi_mac_rxring *rx = rx_ring(mac);
631
	int fill, count;
632

633
	if (limit <= 0)
634 635
		return;

636
	fill = rx_ring(mac)->next_to_fill;
637
	for (count = 0; count < limit; count++) {
638 639
		struct pasemi_mac_buffer *info = &RX_DESC_INFO(rx, fill);
		u64 *buff = &RX_BUFF(rx, fill);
640 641 642
		struct sk_buff *skb;
		dma_addr_t dma;

643 644 645
		/* Entry in use? */
		WARN_ON(*buff);

646
		skb = netdev_alloc_skb(dev, mac->bufsz);
647
		skb_reserve(skb, LOCAL_SKB_ALIGN);
648

649
		if (unlikely(!skb))
650 651
			break;

652
		dma = pci_map_single(mac->dma_pdev, skb->data,
653
				     mac->bufsz - LOCAL_SKB_ALIGN,
654 655
				     PCI_DMA_FROMDEVICE);

656
		if (unlikely(pci_dma_mapping_error(mac->dma_pdev, dma))) {
657 658 659 660 661 662
			dev_kfree_skb_irq(info->skb);
			break;
		}

		info->skb = skb;
		info->dma = dma;
663
		*buff = XCT_RXB_LEN(mac->bufsz) | XCT_RXB_ADDR(dma);
664
		fill++;
665 666 667 668
	}

	wmb();

669
	write_dma_reg(PAS_DMA_RXINT_INCR(mac->dma_if), count);
670

671
	rx_ring(mac)->next_to_fill = (rx_ring(mac)->next_to_fill + count) &
672
				(RX_RING_SIZE - 1);
673 674
}

O
Olof Johansson 已提交
675
static void pasemi_mac_restart_rx_intr(const struct pasemi_mac *mac)
676
{
677
	struct pasemi_mac_rxring *rx = rx_ring(mac);
O
Olof Johansson 已提交
678
	unsigned int reg, pcnt;
679 680 681 682
	/* Re-enable packet count interrupts: finally
	 * ack the packet count interrupt we got in rx_intr.
	 */

683
	pcnt = *rx->chan.status & PAS_STATUS_PCNT_M;
684

O
Olof Johansson 已提交
685
	reg = PAS_IOB_DMA_RXCH_RESET_PCNT(pcnt) | PAS_IOB_DMA_RXCH_RESET_PINTC;
686

687 688 689
	if (*rx->chan.status & PAS_STATUS_TIMER)
		reg |= PAS_IOB_DMA_RXCH_RESET_TINTC;

690
	write_iob_reg(PAS_IOB_DMA_RXCH_RESET(mac->rx->chan.chno), reg);
691 692
}

O
Olof Johansson 已提交
693
static void pasemi_mac_restart_tx_intr(const struct pasemi_mac *mac)
694
{
O
Olof Johansson 已提交
695
	unsigned int reg, pcnt;
696 697

	/* Re-enable packet count interrupts */
698
	pcnt = *tx_ring(mac)->chan.status & PAS_STATUS_PCNT_M;
699

O
Olof Johansson 已提交
700
	reg = PAS_IOB_DMA_TXCH_RESET_PCNT(pcnt) | PAS_IOB_DMA_TXCH_RESET_PINTC;
701

702
	write_iob_reg(PAS_IOB_DMA_TXCH_RESET(tx_ring(mac)->chan.chno), reg);
703 704 705
}


O
Olof Johansson 已提交
706 707
static inline void pasemi_mac_rx_error(const struct pasemi_mac *mac,
				       const u64 macrx)
O
Olof Johansson 已提交
708 709
{
	unsigned int rcmdsta, ccmdsta;
710
	struct pasemi_dmachan *chan = &rx_ring(mac)->chan;
O
Olof Johansson 已提交
711 712 713 714

	if (!netif_msg_rx_err(mac))
		return;

715 716
	rcmdsta = read_dma_reg(PAS_DMA_RXINT_RCMDSTA(mac->dma_if));
	ccmdsta = read_dma_reg(PAS_DMA_RXCHAN_CCMDSTA(chan->chno));
O
Olof Johansson 已提交
717

718
	printk(KERN_ERR "pasemi_mac: rx error. macrx %016llx, rx status %llx\n",
719
		macrx, *chan->status);
O
Olof Johansson 已提交
720 721 722 723 724

	printk(KERN_ERR "pasemi_mac: rcmdsta %08x ccmdsta %08x\n",
		rcmdsta, ccmdsta);
}

O
Olof Johansson 已提交
725 726
static inline void pasemi_mac_tx_error(const struct pasemi_mac *mac,
				       const u64 mactx)
O
Olof Johansson 已提交
727 728
{
	unsigned int cmdsta;
729
	struct pasemi_dmachan *chan = &tx_ring(mac)->chan;
O
Olof Johansson 已提交
730 731 732 733

	if (!netif_msg_tx_err(mac))
		return;

734
	cmdsta = read_dma_reg(PAS_DMA_TXCHAN_TCMDSTA(chan->chno));
O
Olof Johansson 已提交
735

736 737
	printk(KERN_ERR "pasemi_mac: tx error. mactx 0x%016llx, "\
		"tx status 0x%016llx\n", mactx, *chan->status);
O
Olof Johansson 已提交
738 739 740 741

	printk(KERN_ERR "pasemi_mac: tcmdsta 0x%08x\n", cmdsta);
}

O
Olof Johansson 已提交
742 743
static int pasemi_mac_clean_rx(struct pasemi_mac_rxring *rx,
			       const int limit)
744
{
O
Olof Johansson 已提交
745
	const struct pasemi_dmachan *chan = &rx->chan;
746
	struct pasemi_mac *mac = rx->mac;
O
Olof Johansson 已提交
747
	struct pci_dev *pdev = mac->dma_pdev;
748
	unsigned int n;
O
Olof Johansson 已提交
749
	int count, buf_index, tot_bytes, packets;
750 751
	struct pasemi_mac_buffer *info;
	struct sk_buff *skb;
752
	unsigned int len;
O
Olof Johansson 已提交
753
	u64 macrx, eval;
754
	dma_addr_t dma;
O
Olof Johansson 已提交
755 756 757

	tot_bytes = 0;
	packets = 0;
758

759
	spin_lock(&rx->lock);
760

761
	n = rx->next_to_clean;
762

763
	prefetch(&RX_DESC(rx, n));
764 765

	for (count = 0; count < limit; count++) {
766
		macrx = RX_DESC(rx, n);
O
Olof Johansson 已提交
767
		prefetch(&RX_DESC(rx, n+4));
768

O
Olof Johansson 已提交
769
		if ((macrx & XCT_MACRX_E) ||
770
		    (*chan->status & PAS_STATUS_ERROR))
O
Olof Johansson 已提交
771 772
			pasemi_mac_rx_error(mac, macrx);

773
		if (!(macrx & XCT_MACRX_O))
774 775 776 777
			break;

		info = NULL;

778
		BUG_ON(!(macrx & XCT_MACRX_RR_8BRES));
779

780
		eval = (RX_DESC(rx, n+1) & XCT_RXRES_8B_EVAL_M) >>
781 782 783
			XCT_RXRES_8B_EVAL_S;
		buf_index = eval-1;

784 785
		dma = (RX_DESC(rx, n+2) & XCT_PTR_ADDR_M);
		info = &RX_DESC_INFO(rx, buf_index);
786

787
		skb = info->skb;
788

O
Olof Johansson 已提交
789
		prefetch_skb(skb);
790

791
		len = (macrx & XCT_MACRX_LLEN_M) >> XCT_MACRX_LLEN_S;
792

793
		pci_unmap_single(pdev, dma, mac->bufsz - LOCAL_SKB_ALIGN,
O
Olof Johansson 已提交
794
				 PCI_DMA_FROMDEVICE);
O
Olof Johansson 已提交
795 796 797 798 799

		if (macrx & XCT_MACRX_CRC) {
			/* CRC error flagged */
			mac->netdev->stats.rx_errors++;
			mac->netdev->stats.rx_crc_errors++;
800
			/* No need to free skb, it'll be reused */
O
Olof Johansson 已提交
801 802 803
			goto next;
		}

804
		info->skb = NULL;
805
		info->dma = 0;
806

O
Olof Johansson 已提交
807
		if (likely((macrx & XCT_MACRX_HTY_M) == XCT_MACRX_HTY_IPV4_OK)) {
O
Olof Johansson 已提交
808
			skb->ip_summed = CHECKSUM_UNNECESSARY;
809
			skb->csum = (macrx & XCT_MACRX_CSUM_M) >>
810 811
					   XCT_MACRX_CSUM_S;
		} else
812
			skb_checksum_none_assert(skb);
813

O
Olof Johansson 已提交
814 815 816 817 818
		packets++;
		tot_bytes += len;

		/* Don't include CRC */
		skb_put(skb, len-4);
819

O
Olof Johansson 已提交
820
		skb->protocol = eth_type_trans(skb, mac->netdev);
821
		lro_receive_skb(&mac->lro_mgr, skb, (void *)macrx);
822

O
Olof Johansson 已提交
823
next:
824 825
		RX_DESC(rx, n) = 0;
		RX_DESC(rx, n+1) = 0;
826

827 828 829
		/* Need to zero it out since hardware doesn't, since the
		 * replenish loop uses it to tell when it's done.
		 */
830
		RX_BUFF(rx, buf_index) = 0;
831

832
		n += 4;
833 834
	}

835 836
	if (n > RX_RING_SIZE) {
		/* Errata 5971 workaround: L2 target of headers */
837
		write_iob_reg(PAS_IOB_COM_PKTHDRCNT, 0);
838 839
		n &= (RX_RING_SIZE-1);
	}
840

841
	rx_ring(mac)->next_to_clean = n;
842

843 844
	lro_flush_all(&mac->lro_mgr);

845 846 847 848
	/* Increase is in number of 16-byte entries, and since each descriptor
	 * with an 8BRES takes up 3x8 bytes (padded to 4x8), increase with
	 * count*2.
	 */
849
	write_dma_reg(PAS_DMA_RXCHAN_INCR(mac->rx->chan.chno), count << 1);
850 851

	pasemi_mac_replenish_rx_ring(mac->netdev, count);
852

O
Olof Johansson 已提交
853 854 855
	mac->netdev->stats.rx_bytes += tot_bytes;
	mac->netdev->stats.rx_packets += packets;

856
	spin_unlock(&rx_ring(mac)->lock);
857 858 859 860

	return count;
}

O
Olof Johansson 已提交
861 862 863
/* Can't make this too large or we blow the kernel stack limits */
#define TX_CLEAN_BATCHSIZE (128/MAX_SKB_FRAGS)

864
static int pasemi_mac_clean_tx(struct pasemi_mac_txring *txring)
865
{
866
	struct pasemi_dmachan *chan = &txring->chan;
867
	struct pasemi_mac *mac = txring->mac;
O
Olof Johansson 已提交
868
	int i, j;
869 870
	unsigned int start, descr_count, buf_count, batch_limit;
	unsigned int ring_limit;
871
	unsigned int total_count;
872
	unsigned long flags;
O
Olof Johansson 已提交
873 874
	struct sk_buff *skbs[TX_CLEAN_BATCHSIZE];
	dma_addr_t dmas[TX_CLEAN_BATCHSIZE][MAX_SKB_FRAGS+1];
875 876
	int nf[TX_CLEAN_BATCHSIZE];
	int nr_frags;
877

878
	total_count = 0;
879
	batch_limit = TX_CLEAN_BATCHSIZE;
880
restart:
881
	spin_lock_irqsave(&txring->lock, flags);
882

883 884
	start = txring->next_to_clean;
	ring_limit = txring->next_to_fill;
885

886 887
	prefetch(&TX_DESC_INFO(txring, start+1).skb);

888 889 890
	/* Compensate for when fill has wrapped but clean has not */
	if (start > ring_limit)
		ring_limit += TX_RING_SIZE;
891

O
Olof Johansson 已提交
892 893
	buf_count = 0;
	descr_count = 0;
894

O
Olof Johansson 已提交
895
	for (i = start;
896
	     descr_count < batch_limit && i < ring_limit;
O
Olof Johansson 已提交
897
	     i += buf_count) {
898
		u64 mactx = TX_DESC(txring, i);
899
		struct sk_buff *skb;
O
Olof Johansson 已提交
900

901
		if ((mactx  & XCT_MACTX_E) ||
902
		    (*chan->status & PAS_STATUS_ERROR))
903
			pasemi_mac_tx_error(mac, mactx);
O
Olof Johansson 已提交
904

O
Olof Johansson 已提交
905 906 907 908 909 910 911 912 913 914 915
		/* Skip over control descriptors */
		if (!(mactx & XCT_MACTX_LLEN_M)) {
			TX_DESC(txring, i) = 0;
			TX_DESC(txring, i+1) = 0;
			buf_count = 2;
			continue;
		}

		skb = TX_DESC_INFO(txring, i+1).skb;
		nr_frags = TX_DESC_INFO(txring, i).dma;

916
		if (unlikely(mactx & XCT_MACTX_O))
917
			/* Not yet transmitted */
918 919
			break;

920 921 922 923 924 925
		buf_count = 2 + nr_frags;
		/* Since we always fill with an even number of entries, make
		 * sure we skip any unused one at the end as well.
		 */
		if (buf_count & 1)
			buf_count++;
O
Olof Johansson 已提交
926

927
		for (j = 0; j <= nr_frags; j++)
928
			dmas[descr_count][j] = TX_DESC_INFO(txring, i+1+j).dma;
O
Olof Johansson 已提交
929

930 931 932
		skbs[descr_count] = skb;
		nf[descr_count] = nr_frags;

933 934
		TX_DESC(txring, i) = 0;
		TX_DESC(txring, i+1) = 0;
935

O
Olof Johansson 已提交
936
		descr_count++;
937
	}
938
	txring->next_to_clean = i & (TX_RING_SIZE-1);
O
Olof Johansson 已提交
939

940
	spin_unlock_irqrestore(&txring->lock, flags);
941 942
	netif_wake_queue(mac->netdev);

O
Olof Johansson 已提交
943
	for (i = 0; i < descr_count; i++)
944
		pasemi_mac_unmap_tx_skb(mac, nf[i], skbs[i], dmas[i]);
945

O
Olof Johansson 已提交
946
	total_count += descr_count;
947 948

	/* If the batch was full, try to clean more */
949
	if (descr_count == batch_limit)
950 951 952
		goto restart;

	return total_count;
953 954 955 956 957
}


static irqreturn_t pasemi_mac_rx_intr(int irq, void *data)
{
O
Olof Johansson 已提交
958
	const struct pasemi_mac_rxring *rxring = data;
959
	struct pasemi_mac *mac = rxring->mac;
O
Olof Johansson 已提交
960
	const struct pasemi_dmachan *chan = &rxring->chan;
961 962
	unsigned int reg;

963
	if (!(*chan->status & PAS_STATUS_CAUSE_M))
964 965
		return IRQ_NONE;

966 967 968 969 970
	/* Don't reset packet count so it won't fire again but clear
	 * all others.
	 */

	reg = 0;
971
	if (*chan->status & PAS_STATUS_SOFT)
972
		reg |= PAS_IOB_DMA_RXCH_RESET_SINTC;
973
	if (*chan->status & PAS_STATUS_ERROR)
974
		reg |= PAS_IOB_DMA_RXCH_RESET_DINTC;
975

976
	napi_schedule(&mac->napi);
977

978
	write_iob_reg(PAS_IOB_DMA_RXCH_RESET(chan->chno), reg);
979 980 981 982

	return IRQ_HANDLED;
}

O
Olof Johansson 已提交
983 984 985 986 987 988 989 990 991 992 993 994 995 996
#define TX_CLEAN_INTERVAL HZ

static void pasemi_mac_tx_timer(unsigned long data)
{
	struct pasemi_mac_txring *txring = (struct pasemi_mac_txring *)data;
	struct pasemi_mac *mac = txring->mac;

	pasemi_mac_clean_tx(txring);

	mod_timer(&txring->clean_timer, jiffies + TX_CLEAN_INTERVAL);

	pasemi_mac_restart_tx_intr(mac);
}

997 998
static irqreturn_t pasemi_mac_tx_intr(int irq, void *data)
{
999
	struct pasemi_mac_txring *txring = data;
O
Olof Johansson 已提交
1000
	const struct pasemi_dmachan *chan = &txring->chan;
O
Olof Johansson 已提交
1001 1002
	struct pasemi_mac *mac = txring->mac;
	unsigned int reg;
1003

1004
	if (!(*chan->status & PAS_STATUS_CAUSE_M))
1005 1006
		return IRQ_NONE;

O
Olof Johansson 已提交
1007
	reg = 0;
1008

1009
	if (*chan->status & PAS_STATUS_SOFT)
1010
		reg |= PAS_IOB_DMA_TXCH_RESET_SINTC;
1011
	if (*chan->status & PAS_STATUS_ERROR)
1012
		reg |= PAS_IOB_DMA_TXCH_RESET_DINTC;
1013

O
Olof Johansson 已提交
1014 1015
	mod_timer(&txring->clean_timer, jiffies + (TX_CLEAN_INTERVAL)*2);

1016
	napi_schedule(&mac->napi);
O
Olof Johansson 已提交
1017 1018 1019

	if (reg)
		write_iob_reg(PAS_IOB_DMA_TXCH_RESET(chan->chno), reg);
1020 1021 1022 1023

	return IRQ_HANDLED;
}

O
Olof Johansson 已提交
1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038
static void pasemi_adjust_link(struct net_device *dev)
{
	struct pasemi_mac *mac = netdev_priv(dev);
	int msg;
	unsigned int flags;
	unsigned int new_flags;

	if (!mac->phydev->link) {
		/* If no link, MAC speed settings don't matter. Just report
		 * link down and return.
		 */
		if (mac->link && netif_msg_link(mac))
			printk(KERN_INFO "%s: Link is down.\n", dev->name);

		netif_carrier_off(dev);
1039
		pasemi_mac_intf_disable(mac);
O
Olof Johansson 已提交
1040 1041 1042
		mac->link = 0;

		return;
1043 1044
	} else {
		pasemi_mac_intf_enable(mac);
O
Olof Johansson 已提交
1045
		netif_carrier_on(dev);
1046
	}
O
Olof Johansson 已提交
1047

1048
	flags = read_mac_reg(mac, PAS_MAC_CFG_PCFG);
O
Olof Johansson 已提交
1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079
	new_flags = flags & ~(PAS_MAC_CFG_PCFG_HD | PAS_MAC_CFG_PCFG_SPD_M |
			      PAS_MAC_CFG_PCFG_TSR_M);

	if (!mac->phydev->duplex)
		new_flags |= PAS_MAC_CFG_PCFG_HD;

	switch (mac->phydev->speed) {
	case 1000:
		new_flags |= PAS_MAC_CFG_PCFG_SPD_1G |
			     PAS_MAC_CFG_PCFG_TSR_1G;
		break;
	case 100:
		new_flags |= PAS_MAC_CFG_PCFG_SPD_100M |
			     PAS_MAC_CFG_PCFG_TSR_100M;
		break;
	case 10:
		new_flags |= PAS_MAC_CFG_PCFG_SPD_10M |
			     PAS_MAC_CFG_PCFG_TSR_10M;
		break;
	default:
		printk("Unsupported speed %d\n", mac->phydev->speed);
	}

	/* Print on link or speed/duplex change */
	msg = mac->link != mac->phydev->link || flags != new_flags;

	mac->duplex = mac->phydev->duplex;
	mac->speed = mac->phydev->speed;
	mac->link = mac->phydev->link;

	if (new_flags != flags)
1080
		write_mac_reg(mac, PAS_MAC_CFG_PCFG, new_flags);
O
Olof Johansson 已提交
1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093

	if (msg && netif_msg_link(mac))
		printk(KERN_INFO "%s: Link is up at %d Mbps, %s duplex.\n",
		       dev->name, mac->speed, mac->duplex ? "full" : "half");
}

static int pasemi_mac_phy_init(struct net_device *dev)
{
	struct pasemi_mac *mac = netdev_priv(dev);
	struct device_node *dn, *phy_dn;
	struct phy_device *phydev;

	dn = pci_device_to_OF_node(mac->pdev);
1094
	phy_dn = of_parse_phandle(dn, "phy-handle", 0);
O
Olof Johansson 已提交
1095 1096 1097 1098 1099 1100
	of_node_put(phy_dn);

	mac->link = 0;
	mac->speed = 0;
	mac->duplex = -1;

1101 1102
	phydev = of_phy_connect(dev, phy_dn, &pasemi_adjust_link, 0,
				PHY_INTERFACE_MODE_SGMII);
O
Olof Johansson 已提交
1103

1104
	if (!phydev) {
O
Olof Johansson 已提交
1105
		printk(KERN_ERR "%s: Could not attach to phy\n", dev->name);
1106
		return -ENODEV;
O
Olof Johansson 已提交
1107 1108 1109 1110 1111 1112 1113 1114
	}

	mac->phydev = phydev;

	return 0;
}


1115 1116 1117 1118
static int pasemi_mac_open(struct net_device *dev)
{
	struct pasemi_mac *mac = netdev_priv(dev);
	unsigned int flags;
1119
	int i, ret;
1120 1121 1122 1123 1124

	flags = PAS_MAC_CFG_TXP_FCE | PAS_MAC_CFG_TXP_FPC(3) |
		PAS_MAC_CFG_TXP_SL(3) | PAS_MAC_CFG_TXP_COB(0xf) |
		PAS_MAC_CFG_TXP_TIFT(8) | PAS_MAC_CFG_TXP_TIFG(12);

1125
	write_mac_reg(mac, PAS_MAC_CFG_TXP, flags);
1126 1127 1128 1129 1130

	ret = pasemi_mac_setup_rx_resources(dev);
	if (ret)
		goto out_rx_resources;

1131
	mac->tx = pasemi_mac_setup_tx_resources(dev);
1132 1133 1134

	if (!mac->tx)
		goto out_tx_ring;
1135

1136 1137 1138 1139
	/* We might already have allocated rings in case mtu was changed
	 * before interface was brought up.
	 */
	if (dev->mtu > 1500 && !mac->num_cs) {
O
Olof Johansson 已提交
1140 1141 1142 1143 1144
		pasemi_mac_setup_csrings(mac);
		if (!mac->num_cs)
			goto out_tx_ring;
	}

1145 1146 1147 1148
	/* Zero out rmon counters */
	for (i = 0; i < 32; i++)
		write_mac_reg(mac, PAS_MAC_RMON(i), 0);

1149 1150 1151 1152
	/* 0x3ff with 33MHz clock is about 31us */
	write_iob_reg(PAS_IOB_DMA_COM_TIMEOUTCFG,
		      PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(0x3ff));

1153
	write_iob_reg(PAS_IOB_DMA_RXCH_CFG(mac->rx->chan.chno),
1154
		      PAS_IOB_DMA_RXCH_CFG_CNTTH(256));
1155 1156

	write_iob_reg(PAS_IOB_DMA_TXCH_CFG(mac->tx->chan.chno),
O
Olof Johansson 已提交
1157
		      PAS_IOB_DMA_TXCH_CFG_CNTTH(32));
1158

1159
	write_mac_reg(mac, PAS_MAC_IPC_CHNL,
1160 1161
		      PAS_MAC_IPC_CHNL_DCHNO(mac->rx->chan.chno) |
		      PAS_MAC_IPC_CHNL_BCH(mac->rx->chan.chno));
1162 1163

	/* enable rx if */
1164 1165 1166 1167 1168 1169
	write_dma_reg(PAS_DMA_RXINT_RCMDSTA(mac->dma_if),
		      PAS_DMA_RXINT_RCMDSTA_EN |
		      PAS_DMA_RXINT_RCMDSTA_DROPS_M |
		      PAS_DMA_RXINT_RCMDSTA_BP |
		      PAS_DMA_RXINT_RCMDSTA_OO |
		      PAS_DMA_RXINT_RCMDSTA_BT);
1170 1171

	/* enable rx channel */
1172 1173 1174 1175
	pasemi_dma_start_chan(&rx_ring(mac)->chan, PAS_DMA_RXCHAN_CCMDSTA_DU |
						   PAS_DMA_RXCHAN_CCMDSTA_OD |
						   PAS_DMA_RXCHAN_CCMDSTA_FD |
						   PAS_DMA_RXCHAN_CCMDSTA_DT);
1176 1177

	/* enable tx channel */
1178 1179 1180 1181
	pasemi_dma_start_chan(&tx_ring(mac)->chan, PAS_DMA_TXCHAN_TCMDSTA_SZ |
						   PAS_DMA_TXCHAN_TCMDSTA_DB |
						   PAS_DMA_TXCHAN_TCMDSTA_DE |
						   PAS_DMA_TXCHAN_TCMDSTA_DA);
1182

1183
	pasemi_mac_replenish_rx_ring(dev, RX_RING_SIZE);
1184

1185 1186
	write_dma_reg(PAS_DMA_RXCHAN_INCR(rx_ring(mac)->chan.chno),
		      RX_RING_SIZE>>1);
1187

1188 1189 1190 1191
	/* Clear out any residual packet count state from firmware */
	pasemi_mac_restart_rx_intr(mac);
	pasemi_mac_restart_tx_intr(mac);

1192
	flags = PAS_MAC_CFG_PCFG_S1 | PAS_MAC_CFG_PCFG_PR | PAS_MAC_CFG_PCFG_CE;
1193 1194 1195 1196 1197 1198 1199 1200 1201

	if (mac->type == MAC_TYPE_GMAC)
		flags |= PAS_MAC_CFG_PCFG_TSR_1G | PAS_MAC_CFG_PCFG_SPD_1G;
	else
		flags |= PAS_MAC_CFG_PCFG_TSR_10G | PAS_MAC_CFG_PCFG_SPD_10G;

	/* Enable interface in MAC */
	write_mac_reg(mac, PAS_MAC_CFG_PCFG, flags);

O
Olof Johansson 已提交
1202
	ret = pasemi_mac_phy_init(dev);
1203 1204 1205 1206 1207 1208 1209 1210 1211 1212
	if (ret) {
		/* Since we won't get link notification, just enable RX */
		pasemi_mac_intf_enable(mac);
		if (mac->type == MAC_TYPE_GMAC) {
			/* Warn for missing PHY on SGMII (1Gig) ports */
			dev_warn(&mac->pdev->dev,
				 "PHY init failed: %d.\n", ret);
			dev_warn(&mac->pdev->dev,
				 "Defaulting to 1Gbit full duplex\n");
		}
1213
	}
O
Olof Johansson 已提交
1214

1215
	netif_start_queue(dev);
1216
	napi_enable(&mac->napi);
1217

1218 1219
	snprintf(mac->tx_irq_name, sizeof(mac->tx_irq_name), "%s tx",
		 dev->name);
1220

1221
	ret = request_irq(mac->tx->chan.irq, pasemi_mac_tx_intr, IRQF_DISABLED,
1222
			  mac->tx_irq_name, mac->tx);
1223 1224
	if (ret) {
		dev_err(&mac->pdev->dev, "request_irq of irq %d failed: %d\n",
1225
			mac->tx->chan.irq, ret);
1226 1227 1228
		goto out_tx_int;
	}

1229 1230 1231
	snprintf(mac->rx_irq_name, sizeof(mac->rx_irq_name), "%s rx",
		 dev->name);

1232
	ret = request_irq(mac->rx->chan.irq, pasemi_mac_rx_intr, IRQF_DISABLED,
1233
			  mac->rx_irq_name, mac->rx);
1234 1235
	if (ret) {
		dev_err(&mac->pdev->dev, "request_irq of irq %d failed: %d\n",
1236
			mac->rx->chan.irq, ret);
1237 1238 1239
		goto out_rx_int;
	}

O
Olof Johansson 已提交
1240 1241 1242
	if (mac->phydev)
		phy_start(mac->phydev);

O
Olof Johansson 已提交
1243 1244 1245 1246 1247 1248
	init_timer(&mac->tx->clean_timer);
	mac->tx->clean_timer.function = pasemi_mac_tx_timer;
	mac->tx->clean_timer.data = (unsigned long)mac->tx;
	mac->tx->clean_timer.expires = jiffies+HZ;
	add_timer(&mac->tx->clean_timer);

1249 1250 1251
	return 0;

out_rx_int:
1252
	free_irq(mac->tx->chan.irq, mac->tx);
1253
out_tx_int:
1254
	napi_disable(&mac->napi);
1255
	netif_stop_queue(dev);
1256 1257 1258 1259
out_tx_ring:
	if (mac->tx)
		pasemi_mac_free_tx_resources(mac);
	pasemi_mac_free_rx_resources(mac);
1260 1261 1262 1263 1264 1265 1266
out_rx_resources:

	return ret;
}

#define MAX_RETRIES 5000

1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327
static void pasemi_mac_pause_txchan(struct pasemi_mac *mac)
{
	unsigned int sta, retries;
	int txch = tx_ring(mac)->chan.chno;

	write_dma_reg(PAS_DMA_TXCHAN_TCMDSTA(txch),
		      PAS_DMA_TXCHAN_TCMDSTA_ST);

	for (retries = 0; retries < MAX_RETRIES; retries++) {
		sta = read_dma_reg(PAS_DMA_TXCHAN_TCMDSTA(txch));
		if (!(sta & PAS_DMA_TXCHAN_TCMDSTA_ACT))
			break;
		cond_resched();
	}

	if (sta & PAS_DMA_TXCHAN_TCMDSTA_ACT)
		dev_err(&mac->dma_pdev->dev,
			"Failed to stop tx channel, tcmdsta %08x\n", sta);

	write_dma_reg(PAS_DMA_TXCHAN_TCMDSTA(txch), 0);
}

static void pasemi_mac_pause_rxchan(struct pasemi_mac *mac)
{
	unsigned int sta, retries;
	int rxch = rx_ring(mac)->chan.chno;

	write_dma_reg(PAS_DMA_RXCHAN_CCMDSTA(rxch),
		      PAS_DMA_RXCHAN_CCMDSTA_ST);
	for (retries = 0; retries < MAX_RETRIES; retries++) {
		sta = read_dma_reg(PAS_DMA_RXCHAN_CCMDSTA(rxch));
		if (!(sta & PAS_DMA_RXCHAN_CCMDSTA_ACT))
			break;
		cond_resched();
	}

	if (sta & PAS_DMA_RXCHAN_CCMDSTA_ACT)
		dev_err(&mac->dma_pdev->dev,
			"Failed to stop rx channel, ccmdsta 08%x\n", sta);
	write_dma_reg(PAS_DMA_RXCHAN_CCMDSTA(rxch), 0);
}

static void pasemi_mac_pause_rxint(struct pasemi_mac *mac)
{
	unsigned int sta, retries;

	write_dma_reg(PAS_DMA_RXINT_RCMDSTA(mac->dma_if),
		      PAS_DMA_RXINT_RCMDSTA_ST);
	for (retries = 0; retries < MAX_RETRIES; retries++) {
		sta = read_dma_reg(PAS_DMA_RXINT_RCMDSTA(mac->dma_if));
		if (!(sta & PAS_DMA_RXINT_RCMDSTA_ACT))
			break;
		cond_resched();
	}

	if (sta & PAS_DMA_RXINT_RCMDSTA_ACT)
		dev_err(&mac->dma_pdev->dev,
			"Failed to stop rx interface, rcmdsta %08x\n", sta);
	write_dma_reg(PAS_DMA_RXINT_RCMDSTA(mac->dma_if), 0);
}

1328 1329 1330
static int pasemi_mac_close(struct net_device *dev)
{
	struct pasemi_mac *mac = netdev_priv(dev);
1331
	unsigned int sta;
O
Olof Johansson 已提交
1332
	int rxch, txch, i;
1333 1334 1335

	rxch = rx_ring(mac)->chan.chno;
	txch = tx_ring(mac)->chan.chno;
1336

O
Olof Johansson 已提交
1337 1338 1339 1340 1341
	if (mac->phydev) {
		phy_stop(mac->phydev);
		phy_disconnect(mac->phydev);
	}

O
Olof Johansson 已提交
1342 1343
	del_timer_sync(&mac->tx->clean_timer);

1344
	netif_stop_queue(dev);
1345
	napi_disable(&mac->napi);
1346

1347
	sta = read_dma_reg(PAS_DMA_RXINT_RCMDSTA(mac->dma_if));
1348 1349 1350 1351 1352
	if (sta & (PAS_DMA_RXINT_RCMDSTA_BP |
		      PAS_DMA_RXINT_RCMDSTA_OO |
		      PAS_DMA_RXINT_RCMDSTA_BT))
		printk(KERN_DEBUG "pasemi_mac: rcmdsta error: 0x%08x\n", sta);

1353
	sta = read_dma_reg(PAS_DMA_RXCHAN_CCMDSTA(rxch));
1354 1355 1356 1357 1358 1359
	if (sta & (PAS_DMA_RXCHAN_CCMDSTA_DU |
		     PAS_DMA_RXCHAN_CCMDSTA_OD |
		     PAS_DMA_RXCHAN_CCMDSTA_FD |
		     PAS_DMA_RXCHAN_CCMDSTA_DT))
		printk(KERN_DEBUG "pasemi_mac: ccmdsta error: 0x%08x\n", sta);

1360
	sta = read_dma_reg(PAS_DMA_TXCHAN_TCMDSTA(txch));
1361 1362
	if (sta & (PAS_DMA_TXCHAN_TCMDSTA_SZ | PAS_DMA_TXCHAN_TCMDSTA_DB |
		      PAS_DMA_TXCHAN_TCMDSTA_DE | PAS_DMA_TXCHAN_TCMDSTA_DA))
1363 1364
		printk(KERN_DEBUG "pasemi_mac: tcmdsta error: 0x%08x\n", sta);

1365
	/* Clean out any pending buffers */
1366 1367
	pasemi_mac_clean_tx(tx_ring(mac));
	pasemi_mac_clean_rx(rx_ring(mac), RX_RING_SIZE);
1368

1369 1370 1371
	pasemi_mac_pause_txchan(mac);
	pasemi_mac_pause_rxint(mac);
	pasemi_mac_pause_rxchan(mac);
1372
	pasemi_mac_intf_disable(mac);
1373

1374 1375
	free_irq(mac->tx->chan.irq, mac->tx);
	free_irq(mac->rx->chan.irq, mac->rx);
1376

1377
	for (i = 0; i < mac->num_cs; i++) {
O
Olof Johansson 已提交
1378
		pasemi_mac_free_csring(mac->cs[i]);
1379 1380 1381 1382
		mac->cs[i] = NULL;
	}

	mac->num_cs = 0;
O
Olof Johansson 已提交
1383

1384
	/* Free resources */
1385 1386
	pasemi_mac_free_rx_resources(mac);
	pasemi_mac_free_tx_resources(mac);
1387 1388 1389 1390

	return 0;
}

O
Olof Johansson 已提交
1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477
static void pasemi_mac_queue_csdesc(const struct sk_buff *skb,
				    const dma_addr_t *map,
				    const unsigned int *map_size,
				    struct pasemi_mac_txring *txring,
				    struct pasemi_mac_csring *csring)
{
	u64 fund;
	dma_addr_t cs_dest;
	const int nh_off = skb_network_offset(skb);
	const int nh_len = skb_network_header_len(skb);
	const int nfrags = skb_shinfo(skb)->nr_frags;
	int cs_size, i, fill, hdr, cpyhdr, evt;
	dma_addr_t csdma;

	fund = XCT_FUN_ST | XCT_FUN_RR_8BRES |
	       XCT_FUN_O | XCT_FUN_FUN(csring->fun) |
	       XCT_FUN_CRM_SIG | XCT_FUN_LLEN(skb->len - nh_off) |
	       XCT_FUN_SHL(nh_len >> 2) | XCT_FUN_SE;

	switch (ip_hdr(skb)->protocol) {
	case IPPROTO_TCP:
		fund |= XCT_FUN_SIG_TCP4;
		/* TCP checksum is 16 bytes into the header */
		cs_dest = map[0] + skb_transport_offset(skb) + 16;
		break;
	case IPPROTO_UDP:
		fund |= XCT_FUN_SIG_UDP4;
		/* UDP checksum is 6 bytes into the header */
		cs_dest = map[0] + skb_transport_offset(skb) + 6;
		break;
	default:
		BUG();
	}

	/* Do the checksum offloaded */
	fill = csring->next_to_fill;
	hdr = fill;

	CS_DESC(csring, fill++) = fund;
	/* Room for 8BRES. Checksum result is really 2 bytes into it */
	csdma = csring->chan.ring_dma + (fill & (CS_RING_SIZE-1)) * 8 + 2;
	CS_DESC(csring, fill++) = 0;

	CS_DESC(csring, fill) = XCT_PTR_LEN(map_size[0]-nh_off) | XCT_PTR_ADDR(map[0]+nh_off);
	for (i = 1; i <= nfrags; i++)
		CS_DESC(csring, fill+i) = XCT_PTR_LEN(map_size[i]) | XCT_PTR_ADDR(map[i]);

	fill += i;
	if (fill & 1)
		fill++;

	/* Copy the result into the TCP packet */
	cpyhdr = fill;
	CS_DESC(csring, fill++) = XCT_FUN_O | XCT_FUN_FUN(csring->fun) |
				  XCT_FUN_LLEN(2) | XCT_FUN_SE;
	CS_DESC(csring, fill++) = XCT_PTR_LEN(2) | XCT_PTR_ADDR(cs_dest) | XCT_PTR_T;
	CS_DESC(csring, fill++) = XCT_PTR_LEN(2) | XCT_PTR_ADDR(csdma);
	fill++;

	evt = !csring->last_event;
	csring->last_event = evt;

	/* Event handshaking with MAC TX */
	CS_DESC(csring, fill++) = CTRL_CMD_T | CTRL_CMD_META_EVT | CTRL_CMD_O |
				  CTRL_CMD_ETYPE_SET | CTRL_CMD_REG(csring->events[evt]);
	CS_DESC(csring, fill++) = 0;
	CS_DESC(csring, fill++) = CTRL_CMD_T | CTRL_CMD_META_EVT | CTRL_CMD_O |
				  CTRL_CMD_ETYPE_WCLR | CTRL_CMD_REG(csring->events[!evt]);
	CS_DESC(csring, fill++) = 0;
	csring->next_to_fill = fill & (CS_RING_SIZE-1);

	cs_size = fill - hdr;
	write_dma_reg(PAS_DMA_TXCHAN_INCR(csring->chan.chno), (cs_size) >> 1);

	/* TX-side event handshaking */
	fill = txring->next_to_fill;
	TX_DESC(txring, fill++) = CTRL_CMD_T | CTRL_CMD_META_EVT | CTRL_CMD_O |
				  CTRL_CMD_ETYPE_WSET | CTRL_CMD_REG(csring->events[evt]);
	TX_DESC(txring, fill++) = 0;
	TX_DESC(txring, fill++) = CTRL_CMD_T | CTRL_CMD_META_EVT | CTRL_CMD_O |
				  CTRL_CMD_ETYPE_CLR | CTRL_CMD_REG(csring->events[!evt]);
	TX_DESC(txring, fill++) = 0;
	txring->next_to_fill = fill;

	write_dma_reg(PAS_DMA_TXCHAN_INCR(txring->chan.chno), 2);
}

1478 1479
static int pasemi_mac_start_tx(struct sk_buff *skb, struct net_device *dev)
{
O
Olof Johansson 已提交
1480 1481 1482 1483 1484
	struct pasemi_mac * const mac = netdev_priv(dev);
	struct pasemi_mac_txring * const txring = tx_ring(mac);
	struct pasemi_mac_csring *csring;
	u64 dflags = 0;
	u64 mactx;
O
Olof Johansson 已提交
1485 1486
	dma_addr_t map[MAX_SKB_FRAGS+1];
	unsigned int map_size[MAX_SKB_FRAGS+1];
1487
	unsigned long flags;
O
Olof Johansson 已提交
1488
	int i, nfrags;
O
Olof Johansson 已提交
1489
	int fill;
O
Olof Johansson 已提交
1490 1491
	const int nh_off = skb_network_offset(skb);
	const int nh_len = skb_network_header_len(skb);
1492

O
Olof Johansson 已提交
1493
	prefetch(&txring->ring_info);
1494

O
Olof Johansson 已提交
1495
	dflags = XCT_MACTX_O | XCT_MACTX_ST | XCT_MACTX_CRC_PAD;
1496

O
Olof Johansson 已提交
1497 1498 1499 1500 1501
	nfrags = skb_shinfo(skb)->nr_frags;

	map[0] = pci_map_single(mac->dma_pdev, skb->data, skb_headlen(skb),
				PCI_DMA_TODEVICE);
	map_size[0] = skb_headlen(skb);
1502
	if (pci_dma_mapping_error(mac->dma_pdev, map[0]))
O
Olof Johansson 已提交
1503 1504 1505 1506
		goto out_err_nolock;

	for (i = 0; i < nfrags; i++) {
		skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
1507

1508
		map[i + 1] = skb_frag_dma_map(&mac->dma_pdev->dev, frag, 0,
E
Eric Dumazet 已提交
1509 1510
					      skb_frag_size(frag), DMA_TO_DEVICE);
		map_size[i+1] = skb_frag_size(frag);
1511
		if (dma_mapping_error(&mac->dma_pdev->dev, map[i + 1])) {
O
Olof Johansson 已提交
1512 1513 1514 1515
			nfrags = i;
			goto out_err_nolock;
		}
	}
1516

O
Olof Johansson 已提交
1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532
	if (skb->ip_summed == CHECKSUM_PARTIAL && skb->len <= 1540) {
		switch (ip_hdr(skb)->protocol) {
		case IPPROTO_TCP:
			dflags |= XCT_MACTX_CSUM_TCP;
			dflags |= XCT_MACTX_IPH(nh_len >> 2);
			dflags |= XCT_MACTX_IPO(nh_off);
			break;
		case IPPROTO_UDP:
			dflags |= XCT_MACTX_CSUM_UDP;
			dflags |= XCT_MACTX_IPH(nh_len >> 2);
			dflags |= XCT_MACTX_IPO(nh_off);
			break;
		default:
			WARN_ON(1);
		}
	}
O
Olof Johansson 已提交
1533

O
Olof Johansson 已提交
1534
	mactx = dflags | XCT_MACTX_LLEN(skb->len);
1535 1536 1537

	spin_lock_irqsave(&txring->lock, flags);

1538 1539 1540 1541
	/* Avoid stepping on the same cache line that the DMA controller
	 * is currently about to send, so leave at least 8 words available.
	 * Total free space needed is mactx + fragments + 8
	 */
O
Olof Johansson 已提交
1542
	if (RING_AVAIL(txring) < nfrags + 14) {
1543 1544 1545
		/* no room -- stop the queue and wait for tx intr */
		netif_stop_queue(dev);
		goto out_err;
1546 1547
	}

O
Olof Johansson 已提交
1548 1549 1550 1551 1552 1553 1554 1555 1556
	/* Queue up checksum + event descriptors, if needed */
	if (mac->num_cs && skb->ip_summed == CHECKSUM_PARTIAL && skb->len > 1540) {
		csring = mac->cs[mac->last_cs];
		mac->last_cs = (mac->last_cs + 1) % mac->num_cs;

		pasemi_mac_queue_csdesc(skb, map, map_size, txring, csring);
	}

	fill = txring->next_to_fill;
O
Olof Johansson 已提交
1557
	TX_DESC(txring, fill) = mactx;
1558
	TX_DESC_INFO(txring, fill).dma = nfrags;
O
Olof Johansson 已提交
1559 1560
	fill++;
	TX_DESC_INFO(txring, fill).skb = skb;
O
Olof Johansson 已提交
1561
	for (i = 0; i <= nfrags; i++) {
O
Olof Johansson 已提交
1562
		TX_DESC(txring, fill+i) =
1563
			XCT_PTR_LEN(map_size[i]) | XCT_PTR_ADDR(map[i]);
O
Olof Johansson 已提交
1564
		TX_DESC_INFO(txring, fill+i).dma = map[i];
O
Olof Johansson 已提交
1565 1566 1567 1568 1569 1570 1571 1572
	}

	/* We have to add an even number of 8-byte entries to the ring
	 * even if the last one is unused. That means always an odd number
	 * of pointers + one mactx descriptor.
	 */
	if (nfrags & 1)
		nfrags++;
1573

O
Olof Johansson 已提交
1574
	txring->next_to_fill = (fill + nfrags + 1) & (TX_RING_SIZE-1);
1575

1576 1577
	dev->stats.tx_packets++;
	dev->stats.tx_bytes += skb->len;
1578 1579 1580

	spin_unlock_irqrestore(&txring->lock, flags);

1581
	write_dma_reg(PAS_DMA_TXCHAN_INCR(txring->chan.chno), (nfrags+2) >> 1);
1582 1583 1584 1585 1586

	return NETDEV_TX_OK;

out_err:
	spin_unlock_irqrestore(&txring->lock, flags);
O
Olof Johansson 已提交
1587 1588 1589 1590 1591
out_err_nolock:
	while (nfrags--)
		pci_unmap_single(mac->dma_pdev, map[nfrags], map_size[nfrags],
				 PCI_DMA_TODEVICE);

1592 1593 1594 1595 1596
	return NETDEV_TX_BUSY;
}

static void pasemi_mac_set_rx_mode(struct net_device *dev)
{
O
Olof Johansson 已提交
1597
	const struct pasemi_mac *mac = netdev_priv(dev);
1598 1599
	unsigned int flags;

1600
	flags = read_mac_reg(mac, PAS_MAC_CFG_PCFG);
1601 1602 1603 1604 1605 1606 1607

	/* Set promiscuous */
	if (dev->flags & IFF_PROMISC)
		flags |= PAS_MAC_CFG_PCFG_PR;
	else
		flags &= ~PAS_MAC_CFG_PCFG_PR;

1608
	write_mac_reg(mac, PAS_MAC_CFG_PCFG, flags);
1609 1610 1611
}


1612
static int pasemi_mac_poll(struct napi_struct *napi, int budget)
1613
{
1614 1615
	struct pasemi_mac *mac = container_of(napi, struct pasemi_mac, napi);
	int pkts;
1616

1617 1618
	pasemi_mac_clean_tx(tx_ring(mac));
	pkts = pasemi_mac_clean_rx(rx_ring(mac), budget);
1619
	if (pkts < budget) {
1620
		/* all done, no more packets present */
1621
		napi_complete(napi);
1622

1623
		pasemi_mac_restart_rx_intr(mac);
O
Olof Johansson 已提交
1624
		pasemi_mac_restart_tx_intr(mac);
1625
	}
1626
	return pkts;
1627 1628
}

N
Nate Case 已提交
1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648
#ifdef CONFIG_NET_POLL_CONTROLLER
/*
 * Polling 'interrupt' - used by things like netconsole to send skbs
 * without having to re-enable interrupts. It's not called while
 * the interrupt routine is executing.
 */
static void pasemi_mac_netpoll(struct net_device *dev)
{
	const struct pasemi_mac *mac = netdev_priv(dev);

	disable_irq(mac->tx->chan.irq);
	pasemi_mac_tx_intr(mac->tx->chan.irq, mac->tx);
	enable_irq(mac->tx->chan.irq);

	disable_irq(mac->rx->chan.irq);
	pasemi_mac_rx_intr(mac->rx->chan.irq, mac->rx);
	enable_irq(mac->rx->chan.irq);
}
#endif

1649 1650 1651 1652
static int pasemi_mac_change_mtu(struct net_device *dev, int new_mtu)
{
	struct pasemi_mac *mac = netdev_priv(dev);
	unsigned int reg;
O
Olof Johansson 已提交
1653
	unsigned int rcmdsta = 0;
1654
	int running;
O
Olof Johansson 已提交
1655
	int ret = 0;
1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676

	if (new_mtu < PE_MIN_MTU || new_mtu > PE_MAX_MTU)
		return -EINVAL;

	running = netif_running(dev);

	if (running) {
		/* Need to stop the interface, clean out all already
		 * received buffers, free all unused buffers on the RX
		 * interface ring, then finally re-fill the rx ring with
		 * the new-size buffers and restart.
		 */

		napi_disable(&mac->napi);
		netif_tx_disable(dev);
		pasemi_mac_intf_disable(mac);

		rcmdsta = read_dma_reg(PAS_DMA_RXINT_RCMDSTA(mac->dma_if));
		pasemi_mac_pause_rxint(mac);
		pasemi_mac_clean_rx(rx_ring(mac), RX_RING_SIZE);
		pasemi_mac_free_rx_buffers(mac);
O
Olof Johansson 已提交
1677 1678 1679 1680 1681 1682 1683 1684 1685 1686

	}

	/* Setup checksum channels if large MTU and none already allocated */
	if (new_mtu > 1500 && !mac->num_cs) {
		pasemi_mac_setup_csrings(mac);
		if (!mac->num_cs) {
			ret = -ENOMEM;
			goto out;
		}
1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700
	}

	/* Change maxf, i.e. what size frames are accepted.
	 * Need room for ethernet header and CRC word
	 */
	reg = read_mac_reg(mac, PAS_MAC_CFG_MACCFG);
	reg &= ~PAS_MAC_CFG_MACCFG_MAXF_M;
	reg |= PAS_MAC_CFG_MACCFG_MAXF(new_mtu + ETH_HLEN + 4);
	write_mac_reg(mac, PAS_MAC_CFG_MACCFG, reg);

	dev->mtu = new_mtu;
	/* MTU + ETH_HLEN + VLAN_HLEN + 2 64B cachelines */
	mac->bufsz = new_mtu + ETH_HLEN + ETH_FCS_LEN + LOCAL_SKB_ALIGN + 128;

O
Olof Johansson 已提交
1701
out:
1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713
	if (running) {
		write_dma_reg(PAS_DMA_RXINT_RCMDSTA(mac->dma_if),
			      rcmdsta | PAS_DMA_RXINT_RCMDSTA_EN);

		rx_ring(mac)->next_to_fill = 0;
		pasemi_mac_replenish_rx_ring(dev, RX_RING_SIZE-1);

		napi_enable(&mac->napi);
		netif_start_queue(dev);
		pasemi_mac_intf_enable(mac);
	}

O
Olof Johansson 已提交
1714
	return ret;
1715 1716
}

1717 1718 1719 1720
static const struct net_device_ops pasemi_netdev_ops = {
	.ndo_open		= pasemi_mac_open,
	.ndo_stop		= pasemi_mac_close,
	.ndo_start_xmit		= pasemi_mac_start_tx,
1721
	.ndo_set_rx_mode	= pasemi_mac_set_rx_mode,
1722 1723 1724 1725 1726 1727 1728 1729
	.ndo_set_mac_address	= pasemi_mac_set_mac_addr,
	.ndo_change_mtu		= pasemi_mac_change_mtu,
	.ndo_validate_addr	= eth_validate_addr,
#ifdef CONFIG_NET_POLL_CONTROLLER
	.ndo_poll_controller	= pasemi_mac_netpoll,
#endif
};

1730 1731 1732 1733 1734
static int __devinit
pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
	struct net_device *dev;
	struct pasemi_mac *mac;
1735
	int err, ret;
1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754

	err = pci_enable_device(pdev);
	if (err)
		return err;

	dev = alloc_etherdev(sizeof(struct pasemi_mac));
	if (dev == NULL) {
		err = -ENOMEM;
		goto out_disable_device;
	}

	pci_set_drvdata(pdev, dev);
	SET_NETDEV_DEV(dev, &pdev->dev);

	mac = netdev_priv(dev);

	mac->pdev = pdev;
	mac->netdev = dev;

1755 1756
	netif_napi_add(dev, &mac->napi, pasemi_mac_poll, 64);

O
Olof Johansson 已提交
1757
	dev->features = NETIF_F_IP_CSUM | NETIF_F_LLTX | NETIF_F_SG |
1758
			NETIF_F_HIGHDMA | NETIF_F_GSO;
1759

1760 1761 1762 1763 1764 1765 1766 1767 1768 1769
	mac->lro_mgr.max_aggr = LRO_MAX_AGGR;
	mac->lro_mgr.max_desc = MAX_LRO_DESCRIPTORS;
	mac->lro_mgr.lro_arr = mac->lro_desc;
	mac->lro_mgr.get_skb_header = get_skb_hdr;
	mac->lro_mgr.features = LRO_F_NAPI | LRO_F_EXTRACT_VLAN_ID;
	mac->lro_mgr.dev = mac->netdev;
	mac->lro_mgr.ip_summed = CHECKSUM_UNNECESSARY;
	mac->lro_mgr.ip_summed_aggr = CHECKSUM_UNNECESSARY;


1770 1771 1772 1773 1774 1775
	mac->dma_pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa007, NULL);
	if (!mac->dma_pdev) {
		dev_err(&mac->pdev->dev, "Can't find DMA Controller\n");
		err = -ENODEV;
		goto out;
	}
1776

1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790
	mac->iob_pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa001, NULL);
	if (!mac->iob_pdev) {
		dev_err(&mac->pdev->dev, "Can't find I/O Bridge\n");
		err = -ENODEV;
		goto out;
	}

	/* get mac addr from device tree */
	if (pasemi_get_mac_addr(mac) || !is_valid_ether_addr(mac->mac_addr)) {
		err = -ENODEV;
		goto out;
	}
	memcpy(dev->dev_addr, mac->mac_addr, sizeof(mac->mac_addr));

1791 1792
	ret = mac_to_intf(mac);
	if (ret < 0) {
1793 1794 1795 1796
		dev_err(&mac->pdev->dev, "Can't map DMA interface\n");
		err = -ENODEV;
		goto out;
	}
1797
	mac->dma_if = ret;
1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810

	switch (pdev->device) {
	case 0xa005:
		mac->type = MAC_TYPE_GMAC;
		break;
	case 0xa006:
		mac->type = MAC_TYPE_XAUI;
		break;
	default:
		err = -ENODEV;
		goto out;
	}

1811
	dev->netdev_ops = &pasemi_netdev_ops;
1812 1813 1814 1815
	dev->mtu = PE_DEF_MTU;
	/* 1500 MTU + ETH_HLEN + VLAN_HLEN + 2 64B cachelines */
	mac->bufsz = dev->mtu + ETH_HLEN + ETH_FCS_LEN + LOCAL_SKB_ALIGN + 128;

1816
	dev->ethtool_ops = &pasemi_mac_ethtool_ops;
1817

1818 1819
	if (err)
		goto out;
1820

1821 1822
	mac->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE);

O
Olof Johansson 已提交
1823 1824 1825
	/* Enable most messages by default */
	mac->msg_enable = (NETIF_MSG_IFUP << 1 ) - 1;

1826 1827 1828 1829 1830 1831
	err = register_netdev(dev);

	if (err) {
		dev_err(&mac->pdev->dev, "register_netdev failed with error %d\n",
			err);
		goto out;
O
Olof Johansson 已提交
1832
	} else if netif_msg_probe(mac)
J
Johannes Berg 已提交
1833
		printk(KERN_INFO "%s: PA Semi %s: intf %d, hw addr %pM\n",
1834
		       dev->name, mac->type == MAC_TYPE_GMAC ? "GMAC" : "XAUI",
J
Johannes Berg 已提交
1835
		       mac->dma_if, dev->dev_addr);
1836 1837 1838 1839

	return err;

out:
1840 1841 1842 1843 1844
	if (mac->iob_pdev)
		pci_dev_put(mac->iob_pdev);
	if (mac->dma_pdev)
		pci_dev_put(mac->dma_pdev);

1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867
	free_netdev(dev);
out_disable_device:
	pci_disable_device(pdev);
	return err;

}

static void __devexit pasemi_mac_remove(struct pci_dev *pdev)
{
	struct net_device *netdev = pci_get_drvdata(pdev);
	struct pasemi_mac *mac;

	if (!netdev)
		return;

	mac = netdev_priv(netdev);

	unregister_netdev(netdev);

	pci_disable_device(pdev);
	pci_dev_put(mac->dma_pdev);
	pci_dev_put(mac->iob_pdev);

1868 1869
	pasemi_dma_free_chan(&mac->tx->chan);
	pasemi_dma_free_chan(&mac->rx->chan);
1870

1871 1872 1873 1874
	pci_set_drvdata(pdev, NULL);
	free_netdev(netdev);
}

1875
static DEFINE_PCI_DEVICE_TABLE(pasemi_mac_pci_tbl) = {
1876 1877
	{ PCI_DEVICE(PCI_VENDOR_ID_PASEMI, 0xa005) },
	{ PCI_DEVICE(PCI_VENDOR_ID_PASEMI, 0xa006) },
1878
	{ },
1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896
};

MODULE_DEVICE_TABLE(pci, pasemi_mac_pci_tbl);

static struct pci_driver pasemi_mac_driver = {
	.name		= "pasemi_mac",
	.id_table	= pasemi_mac_pci_tbl,
	.probe		= pasemi_mac_probe,
	.remove		= __devexit_p(pasemi_mac_remove),
};

static void __exit pasemi_mac_cleanup_module(void)
{
	pci_unregister_driver(&pasemi_mac_driver);
}

int pasemi_mac_init_module(void)
{
1897 1898 1899 1900 1901 1902
	int err;

	err = pasemi_dma_init();
	if (err)
		return err;

1903 1904 1905 1906 1907
	return pci_register_driver(&pasemi_mac_driver);
}

module_init(pasemi_mac_init_module);
module_exit(pasemi_mac_cleanup_module);