pasemi_mac.c 47.6 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 23 24 25 26 27 28 29 30 31 32 33 34
/*
 * 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>
#include <linux/interrupt.h>
#include <linux/dmaengine.h>
#include <linux/delay.h>
#include <linux/netdevice.h>
#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>
35
#include <linux/inet_lro.h>
36

37
#include <asm/irq.h>
O
Olof Johansson 已提交
38
#include <asm/firmware.h>
39
#include <asm/pasemi_dma.h>
40

41 42
#include "pasemi_mac.h"

43 44 45 46 47 48
/* 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
49 50 51 52 53

/* TODO list
 *
 * - Multicast support
 * - Large MTU support
O
Olof Johansson 已提交
54 55
 * - SW LRO
 * - Multiqueue RX/TX
56 57
 */

58 59
#define LRO_MAX_AGGR 64

60
#define PE_MIN_MTU	64
O
Olof Johansson 已提交
61
#define PE_MAX_MTU	9000
62 63
#define PE_DEF_MTU	ETH_DATA_LEN

64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
#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");
81

82 83
extern const struct ethtool_ops pasemi_mac_ethtool_ops;

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

93
static void write_iob_reg(unsigned int reg, unsigned int val)
94
{
95
	pasemi_write_iob_reg(reg, val);
96 97
}

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

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

109
static unsigned int read_dma_reg(unsigned int reg)
110
{
111
	return pasemi_read_dma_reg(reg);
112 113
}

114
static void write_dma_reg(unsigned int reg, unsigned int val)
115
{
116
	pasemi_write_dma_reg(reg, val);
117 118
}

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

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

O
Olof Johansson 已提交
129 130 131 132 133 134 135 136 137 138
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);
}

139 140 141 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
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;
}

167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184
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);
}

185 186 187 188
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);
189
	int len;
190 191 192 193 194 195 196 197 198
	const u8 *maddr;
	u8 addr[6];

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

199 200 201 202 203 204 205 206 207 208
	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.
	 */
209 210

	if (maddr == NULL)
211
		maddr = of_get_property(dn, "mac-address", NULL);
212

213 214 215 216 217 218 219 220 221 222 223 224 225
	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;
	}

226 227
	memcpy(mac->mac_addr, addr, 6);

228 229 230
	return 0;
}

231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257
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))
		return -EINVAL;

	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;
}

258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288
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 */
	if (iph->tot_len < ip_len + tcp_hdrlen(skb))
		return -1;

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

	return 0;
}

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

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

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

O
Olof Johansson 已提交
302
		pci_unmap_page(pdev, dmas[f+1], frag->size, PCI_DMA_TODEVICE);
O
Olof Johansson 已提交
303 304 305 306 307 308 309 310 311
	}
	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 已提交
312 313 314 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
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);
407
	pasemi_dma_free_fun(csring->fun);
O
Olof Johansson 已提交
408 409
}

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

417 418
	ring = pasemi_dma_alloc_chan(RXCHAN, sizeof(struct pasemi_mac_rxring),
				     offsetof(struct pasemi_mac_rxring, chan));
419

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

	spin_lock_init(&ring->lock);

428
	ring->size = RX_RING_SIZE;
429
	ring->ring_info = kzalloc(sizeof(struct pasemi_mac_buffer) *
430 431
				  RX_RING_SIZE, GFP_KERNEL);

432 433
	if (!ring->ring_info)
		goto out_ring_info;
434 435

	/* Allocate descriptors */
436
	if (pasemi_dma_alloc_ring(&ring->chan, RX_RING_SIZE))
437
		goto out_ring_desc;
438 439 440 441 442

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

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

447 448
	write_dma_reg(PAS_DMA_RXCHAN_BASEL(chno),
		      PAS_DMA_RXCHAN_BASEL_BRBL(ring->chan.ring_dma));
449

450 451 452
	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));
453

O
Olof Johansson 已提交
454
	cfg = PAS_DMA_RXCHAN_CFG_HBU(2);
O
Olof Johansson 已提交
455 456 457 458

	if (translation_enabled())
		cfg |= PAS_DMA_RXCHAN_CFG_CTR;

459
	write_dma_reg(PAS_DMA_RXCHAN_CFG(chno), cfg);
460

461 462
	write_dma_reg(PAS_DMA_RXINT_BASEL(mac->dma_if),
		      PAS_DMA_RXINT_BASEL_BRBL(ring->buf_dma));
463

464 465 466
	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));
467

O
Olof Johansson 已提交
468
	cfg = PAS_DMA_RXINT_CFG_DHL(2) | PAS_DMA_RXINT_CFG_L2 |
O
Olof Johansson 已提交
469 470 471 472 473 474
	      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;

475
	write_dma_reg(PAS_DMA_RXINT_CFG(mac->dma_if), cfg);
476

477 478
	ring->next_to_fill = 0;
	ring->next_to_clean = 0;
479
	ring->mac = mac;
480 481 482 483
	mac->rx = ring;

	return 0;

484 485 486
out_ring_desc:
	kfree(ring->ring_info);
out_ring_info:
487 488
	pasemi_dma_free_chan(&ring->chan);
out_chan:
489 490 491
	return -ENOMEM;
}

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

501 502 503 504 505 506 507 508 509
	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;
510 511 512

	spin_lock_init(&ring->lock);

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

	/* Allocate descriptors */
520
	if (pasemi_dma_alloc_ring(&ring->chan, TX_RING_SIZE))
521
		goto out_ring_desc;
522

523 524 525
	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);
526
	val |= PAS_DMA_TXCHAN_BASEU_SIZ(TX_RING_SIZE >> 3);
527

528
	write_dma_reg(PAS_DMA_TXCHAN_BASEU(chno), val);
529

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

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

538
	write_dma_reg(PAS_DMA_TXCHAN_CFG(chno), cfg);
539

540
	ring->next_to_fill = 0;
541
	ring->next_to_clean = 0;
542
	ring->mac = mac;
543

544
	return ring;
545

546 547 548
out_ring_desc:
	kfree(ring->ring_info);
out_ring_info:
549 550
	pasemi_dma_free_chan(&ring->chan);
out_chan:
551
	return NULL;
552 553
}

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

563 564
	start = txring->next_to_clean;
	limit = txring->next_to_fill;
565 566 567 568 569 570

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

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

583
	kfree(txring->ring_info);
584 585
	pasemi_dma_free_chan(&txring->chan);

586 587
}

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

	for (i = 0; i < RX_RING_SIZE; i++) {
595
		info = &RX_DESC_INFO(rx, i);
596 597 598 599 600 601
		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);
602
		}
603 604
		info->dma = 0;
		info->skb = NULL;
605 606
	}

607
	for (i = 0; i < RX_RING_SIZE; i++)
608 609 610 611 612 613
		RX_BUFF(rx, i) = 0;
}

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

615
	dma_free_coherent(&mac->dma_pdev->dev, RX_RING_SIZE * sizeof(u64),
616
			  rx_ring(mac)->buffers, rx_ring(mac)->buf_dma);
617

618
	kfree(rx_ring(mac)->ring_info);
619
	pasemi_dma_free_chan(&rx_ring(mac)->chan);
620 621 622
	mac->rx = NULL;
}

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

630
	if (limit <= 0)
631 632
		return;

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

640 641 642
		/* Entry in use? */
		WARN_ON(*buff);

643
		skb = dev_alloc_skb(mac->bufsz);
644
		skb_reserve(skb, LOCAL_SKB_ALIGN);
645

646
		if (unlikely(!skb))
647 648
			break;

649
		dma = pci_map_single(mac->dma_pdev, skb->data,
650
				     mac->bufsz - LOCAL_SKB_ALIGN,
651 652
				     PCI_DMA_FROMDEVICE);

653
		if (unlikely(dma_mapping_error(dma))) {
654 655 656 657 658 659
			dev_kfree_skb_irq(info->skb);
			break;
		}

		info->skb = skb;
		info->dma = dma;
660
		*buff = XCT_RXB_LEN(mac->bufsz) | XCT_RXB_ADDR(dma);
661
		fill++;
662 663 664 665
	}

	wmb();

666
	write_dma_reg(PAS_DMA_RXINT_INCR(mac->dma_if), count);
667

668
	rx_ring(mac)->next_to_fill = (rx_ring(mac)->next_to_fill + count) &
669
				(RX_RING_SIZE - 1);
670 671
}

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

680
	pcnt = *rx->chan.status & PAS_STATUS_PCNT_M;
681

O
Olof Johansson 已提交
682
	reg = PAS_IOB_DMA_RXCH_RESET_PCNT(pcnt) | PAS_IOB_DMA_RXCH_RESET_PINTC;
683

684 685 686
	if (*rx->chan.status & PAS_STATUS_TIMER)
		reg |= PAS_IOB_DMA_RXCH_RESET_TINTC;

687
	write_iob_reg(PAS_IOB_DMA_RXCH_RESET(mac->rx->chan.chno), reg);
688 689
}

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

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

O
Olof Johansson 已提交
697
	reg = PAS_IOB_DMA_TXCH_RESET_PCNT(pcnt) | PAS_IOB_DMA_TXCH_RESET_PINTC;
698

699
	write_iob_reg(PAS_IOB_DMA_TXCH_RESET(tx_ring(mac)->chan.chno), reg);
700 701 702
}


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

	if (!netif_msg_rx_err(mac))
		return;

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

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

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

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

	if (!netif_msg_tx_err(mac))
		return;

731
	cmdsta = read_dma_reg(PAS_DMA_TXCHAN_TCMDSTA(chan->chno));
O
Olof Johansson 已提交
732 733

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

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

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

	tot_bytes = 0;
	packets = 0;
755

756
	spin_lock(&rx->lock);
757

758
	n = rx->next_to_clean;
759

760
	prefetch(&RX_DESC(rx, n));
761 762

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

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

770
		if (!(macrx & XCT_MACRX_O))
771 772 773 774
			break;

		info = NULL;

775
		BUG_ON(!(macrx & XCT_MACRX_RR_8BRES));
776

777
		eval = (RX_DESC(rx, n+1) & XCT_RXRES_8B_EVAL_M) >>
778 779 780
			XCT_RXRES_8B_EVAL_S;
		buf_index = eval-1;

781 782
		dma = (RX_DESC(rx, n+2) & XCT_PTR_ADDR_M);
		info = &RX_DESC_INFO(rx, buf_index);
783

784
		skb = info->skb;
785

O
Olof Johansson 已提交
786
		prefetch_skb(skb);
787

788
		len = (macrx & XCT_MACRX_LLEN_M) >> XCT_MACRX_LLEN_S;
789

790
		pci_unmap_single(pdev, dma, mac->bufsz - LOCAL_SKB_ALIGN,
O
Olof Johansson 已提交
791
				 PCI_DMA_FROMDEVICE);
O
Olof Johansson 已提交
792 793 794 795 796

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

801
		info->skb = NULL;
802
		info->dma = 0;
803

O
Olof Johansson 已提交
804
		if (likely((macrx & XCT_MACRX_HTY_M) == XCT_MACRX_HTY_IPV4_OK)) {
O
Olof Johansson 已提交
805
			skb->ip_summed = CHECKSUM_UNNECESSARY;
806
			skb->csum = (macrx & XCT_MACRX_CSUM_M) >>
807 808 809 810
					   XCT_MACRX_CSUM_S;
		} else
			skb->ip_summed = CHECKSUM_NONE;

O
Olof Johansson 已提交
811 812 813 814 815
		packets++;
		tot_bytes += len;

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

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

O
Olof Johansson 已提交
820
next:
821 822
		RX_DESC(rx, n) = 0;
		RX_DESC(rx, n+1) = 0;
823

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

829
		n += 4;
830 831
	}

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

838
	rx_ring(mac)->next_to_clean = n;
839

840 841
	lro_flush_all(&mac->lro_mgr);

842 843 844 845
	/* 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.
	 */
846
	write_dma_reg(PAS_DMA_RXCHAN_INCR(mac->rx->chan.chno), count << 1);
847 848

	pasemi_mac_replenish_rx_ring(mac->netdev, count);
849

O
Olof Johansson 已提交
850 851 852
	mac->netdev->stats.rx_bytes += tot_bytes;
	mac->netdev->stats.rx_packets += packets;

853
	spin_unlock(&rx_ring(mac)->lock);
854 855 856 857

	return count;
}

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

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

875
	total_count = 0;
876
	batch_limit = TX_CLEAN_BATCHSIZE;
877
restart:
878
	spin_lock_irqsave(&txring->lock, flags);
879

880 881
	start = txring->next_to_clean;
	ring_limit = txring->next_to_fill;
882

883 884
	prefetch(&TX_DESC_INFO(txring, start+1).skb);

885 886 887
	/* Compensate for when fill has wrapped but clean has not */
	if (start > ring_limit)
		ring_limit += TX_RING_SIZE;
888

O
Olof Johansson 已提交
889 890
	buf_count = 0;
	descr_count = 0;
891

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

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

O
Olof Johansson 已提交
902 903 904 905 906 907 908 909 910 911 912
		/* 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;

913
		if (unlikely(mactx & XCT_MACTX_O))
914
			/* Not yet transmitted */
915 916
			break;

917 918 919 920 921 922
		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 已提交
923

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

927 928 929
		skbs[descr_count] = skb;
		nf[descr_count] = nr_frags;

930 931
		TX_DESC(txring, i) = 0;
		TX_DESC(txring, i+1) = 0;
932

O
Olof Johansson 已提交
933
		descr_count++;
934
	}
935
	txring->next_to_clean = i & (TX_RING_SIZE-1);
O
Olof Johansson 已提交
936

937
	spin_unlock_irqrestore(&txring->lock, flags);
938 939
	netif_wake_queue(mac->netdev);

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

O
Olof Johansson 已提交
943
	total_count += descr_count;
944 945

	/* If the batch was full, try to clean more */
946
	if (descr_count == batch_limit)
947 948 949
		goto restart;

	return total_count;
950 951 952 953 954
}


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

961
	if (!(*chan->status & PAS_STATUS_CAUSE_M))
962 963
		return IRQ_NONE;

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

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

974
	netif_rx_schedule(dev, &mac->napi);
975

976
	write_iob_reg(PAS_IOB_DMA_RXCH_RESET(chan->chno), reg);
977 978 979 980

	return IRQ_HANDLED;
}

O
Olof Johansson 已提交
981 982 983 984 985 986 987 988 989 990 991 992 993 994
#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);
}

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

1002
	if (!(*chan->status & PAS_STATUS_CAUSE_M))
1003 1004
		return IRQ_NONE;

O
Olof Johansson 已提交
1005
	reg = 0;
1006

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

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

	netif_rx_schedule(mac->netdev, &mac->napi);

	if (reg)
		write_iob_reg(PAS_IOB_DMA_TXCH_RESET(chan->chno), reg);
1018 1019 1020 1021

	return IRQ_HANDLED;
}

O
Olof Johansson 已提交
1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036
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);
1037
		pasemi_mac_intf_disable(mac);
O
Olof Johansson 已提交
1038 1039 1040
		mac->link = 0;

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

1046
	flags = read_mac_reg(mac, PAS_MAC_CFG_PCFG);
O
Olof Johansson 已提交
1047 1048 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
	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)
1078
		write_mac_reg(mac, PAS_MAC_CFG_PCFG, new_flags);
O
Olof Johansson 已提交
1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096

	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;
	unsigned int phy_id;
	const phandle *ph;
	const unsigned int *prop;
	struct resource r;
	int ret;

	dn = pci_device_to_OF_node(mac->pdev);
1097
	ph = of_get_property(dn, "phy-handle", NULL);
O
Olof Johansson 已提交
1098 1099 1100 1101
	if (!ph)
		return -ENODEV;
	phy_dn = of_find_node_by_phandle(*ph);

1102
	prop = of_get_property(phy_dn, "reg", NULL);
O
Olof Johansson 已提交
1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132
	ret = of_address_to_resource(phy_dn->parent, 0, &r);
	if (ret)
		goto err;

	phy_id = *prop;
	snprintf(mac->phy_id, BUS_ID_SIZE, PHY_ID_FMT, (int)r.start, phy_id);

	of_node_put(phy_dn);

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

	phydev = phy_connect(dev, mac->phy_id, &pasemi_adjust_link, 0, PHY_INTERFACE_MODE_SGMII);

	if (IS_ERR(phydev)) {
		printk(KERN_ERR "%s: Could not attach to phy\n", dev->name);
		return PTR_ERR(phydev);
	}

	mac->phydev = phydev;

	return 0;

err:
	of_node_put(phy_dn);
	return -ENODEV;
}


1133 1134 1135 1136
static int pasemi_mac_open(struct net_device *dev)
{
	struct pasemi_mac *mac = netdev_priv(dev);
	unsigned int flags;
1137
	int i, ret;
1138 1139 1140 1141 1142

	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);

1143
	write_mac_reg(mac, PAS_MAC_CFG_TXP, flags);
1144 1145 1146 1147 1148

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

1149
	mac->tx = pasemi_mac_setup_tx_resources(dev);
1150 1151 1152

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

1154 1155 1156 1157
	/* 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 已提交
1158 1159 1160 1161 1162
		pasemi_mac_setup_csrings(mac);
		if (!mac->num_cs)
			goto out_tx_ring;
	}

1163 1164 1165 1166
	/* Zero out rmon counters */
	for (i = 0; i < 32; i++)
		write_mac_reg(mac, PAS_MAC_RMON(i), 0);

1167 1168 1169 1170
	/* 0x3ff with 33MHz clock is about 31us */
	write_iob_reg(PAS_IOB_DMA_COM_TIMEOUTCFG,
		      PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(0x3ff));

1171
	write_iob_reg(PAS_IOB_DMA_RXCH_CFG(mac->rx->chan.chno),
1172
		      PAS_IOB_DMA_RXCH_CFG_CNTTH(256));
1173 1174

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

1177
	write_mac_reg(mac, PAS_MAC_IPC_CHNL,
1178 1179
		      PAS_MAC_IPC_CHNL_DCHNO(mac->rx->chan.chno) |
		      PAS_MAC_IPC_CHNL_BCH(mac->rx->chan.chno));
1180 1181

	/* enable rx if */
1182 1183 1184 1185 1186 1187
	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);
1188 1189

	/* enable rx channel */
1190 1191 1192 1193
	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);
1194 1195

	/* enable tx channel */
1196 1197 1198 1199
	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);
1200

1201
	pasemi_mac_replenish_rx_ring(dev, RX_RING_SIZE);
1202

1203 1204
	write_dma_reg(PAS_DMA_RXCHAN_INCR(rx_ring(mac)->chan.chno),
		      RX_RING_SIZE>>1);
1205

1206 1207 1208 1209
	/* Clear out any residual packet count state from firmware */
	pasemi_mac_restart_rx_intr(mac);
	pasemi_mac_restart_tx_intr(mac);

1210
	flags = PAS_MAC_CFG_PCFG_S1 | PAS_MAC_CFG_PCFG_PR | PAS_MAC_CFG_PCFG_CE;
1211 1212 1213 1214 1215 1216 1217 1218 1219

	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 已提交
1220
	ret = pasemi_mac_phy_init(dev);
1221 1222 1223 1224 1225 1226 1227 1228 1229 1230
	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");
		}
1231
	}
O
Olof Johansson 已提交
1232

1233
	netif_start_queue(dev);
1234
	napi_enable(&mac->napi);
1235

1236 1237
	snprintf(mac->tx_irq_name, sizeof(mac->tx_irq_name), "%s tx",
		 dev->name);
1238

1239
	ret = request_irq(mac->tx->chan.irq, &pasemi_mac_tx_intr, IRQF_DISABLED,
1240
			  mac->tx_irq_name, mac->tx);
1241 1242
	if (ret) {
		dev_err(&mac->pdev->dev, "request_irq of irq %d failed: %d\n",
1243
			mac->tx->chan.irq, ret);
1244 1245 1246
		goto out_tx_int;
	}

1247 1248 1249
	snprintf(mac->rx_irq_name, sizeof(mac->rx_irq_name), "%s rx",
		 dev->name);

1250 1251
	ret = request_irq(mac->rx->chan.irq, &pasemi_mac_rx_intr, IRQF_DISABLED,
			  mac->rx_irq_name, mac->rx);
1252 1253
	if (ret) {
		dev_err(&mac->pdev->dev, "request_irq of irq %d failed: %d\n",
1254
			mac->rx->chan.irq, ret);
1255 1256 1257
		goto out_rx_int;
	}

O
Olof Johansson 已提交
1258 1259 1260
	if (mac->phydev)
		phy_start(mac->phydev);

O
Olof Johansson 已提交
1261 1262 1263 1264 1265 1266
	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);

1267 1268 1269
	return 0;

out_rx_int:
1270
	free_irq(mac->tx->chan.irq, mac->tx);
1271
out_tx_int:
1272
	napi_disable(&mac->napi);
1273
	netif_stop_queue(dev);
1274 1275 1276 1277
out_tx_ring:
	if (mac->tx)
		pasemi_mac_free_tx_resources(mac);
	pasemi_mac_free_rx_resources(mac);
1278 1279 1280 1281 1282 1283 1284
out_rx_resources:

	return ret;
}

#define MAX_RETRIES 5000

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 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345
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);
}

1346 1347 1348
static int pasemi_mac_close(struct net_device *dev)
{
	struct pasemi_mac *mac = netdev_priv(dev);
1349
	unsigned int sta;
O
Olof Johansson 已提交
1350
	int rxch, txch, i;
1351 1352 1353

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

O
Olof Johansson 已提交
1355 1356 1357 1358 1359
	if (mac->phydev) {
		phy_stop(mac->phydev);
		phy_disconnect(mac->phydev);
	}

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

1362
	netif_stop_queue(dev);
1363
	napi_disable(&mac->napi);
1364

1365
	sta = read_dma_reg(PAS_DMA_RXINT_RCMDSTA(mac->dma_if));
1366 1367 1368 1369 1370
	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);

1371
	sta = read_dma_reg(PAS_DMA_RXCHAN_CCMDSTA(rxch));
1372 1373 1374 1375 1376 1377
	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);

1378
	sta = read_dma_reg(PAS_DMA_TXCHAN_TCMDSTA(txch));
1379 1380
	if (sta & (PAS_DMA_TXCHAN_TCMDSTA_SZ | PAS_DMA_TXCHAN_TCMDSTA_DB |
		      PAS_DMA_TXCHAN_TCMDSTA_DE | PAS_DMA_TXCHAN_TCMDSTA_DA))
1381 1382
		printk(KERN_DEBUG "pasemi_mac: tcmdsta error: 0x%08x\n", sta);

1383
	/* Clean out any pending buffers */
1384 1385
	pasemi_mac_clean_tx(tx_ring(mac));
	pasemi_mac_clean_rx(rx_ring(mac), RX_RING_SIZE);
1386

1387 1388 1389
	pasemi_mac_pause_txchan(mac);
	pasemi_mac_pause_rxint(mac);
	pasemi_mac_pause_rxchan(mac);
1390
	pasemi_mac_intf_disable(mac);
1391

1392 1393
	free_irq(mac->tx->chan.irq, mac->tx);
	free_irq(mac->rx->chan.irq, mac->rx);
1394

1395
	for (i = 0; i < mac->num_cs; i++) {
O
Olof Johansson 已提交
1396
		pasemi_mac_free_csring(mac->cs[i]);
1397 1398 1399 1400
		mac->cs[i] = NULL;
	}

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

1402
	/* Free resources */
1403 1404
	pasemi_mac_free_rx_resources(mac);
	pasemi_mac_free_tx_resources(mac);
1405 1406 1407 1408

	return 0;
}

O
Olof Johansson 已提交
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 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497
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);

	return;
}

1498 1499
static int pasemi_mac_start_tx(struct sk_buff *skb, struct net_device *dev)
{
O
Olof Johansson 已提交
1500 1501 1502 1503 1504
	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 已提交
1505 1506
	dma_addr_t map[MAX_SKB_FRAGS+1];
	unsigned int map_size[MAX_SKB_FRAGS+1];
1507
	unsigned long flags;
O
Olof Johansson 已提交
1508
	int i, nfrags;
O
Olof Johansson 已提交
1509
	int fill;
O
Olof Johansson 已提交
1510 1511
	const int nh_off = skb_network_offset(skb);
	const int nh_len = skb_network_header_len(skb);
1512

O
Olof Johansson 已提交
1513
	prefetch(&txring->ring_info);
1514

O
Olof Johansson 已提交
1515
	dflags = XCT_MACTX_O | XCT_MACTX_ST | XCT_MACTX_CRC_PAD;
1516

O
Olof Johansson 已提交
1517 1518 1519 1520 1521 1522 1523 1524 1525 1526
	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);
	if (dma_mapping_error(map[0]))
		goto out_err_nolock;

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

O
Olof Johansson 已提交
1528 1529 1530 1531 1532 1533 1534 1535 1536
		map[i+1] = pci_map_page(mac->dma_pdev, frag->page,
					frag->page_offset, frag->size,
					PCI_DMA_TODEVICE);
		map_size[i+1] = frag->size;
		if (dma_mapping_error(map[i+1])) {
			nfrags = i;
			goto out_err_nolock;
		}
	}
1537

O
Olof Johansson 已提交
1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553
	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 已提交
1554

O
Olof Johansson 已提交
1555
	mactx = dflags | XCT_MACTX_LLEN(skb->len);
1556 1557 1558

	spin_lock_irqsave(&txring->lock, flags);

1559 1560 1561 1562
	/* 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 已提交
1563
	if (RING_AVAIL(txring) < nfrags + 14) {
1564 1565 1566
		/* no room -- stop the queue and wait for tx intr */
		netif_stop_queue(dev);
		goto out_err;
1567 1568
	}

O
Olof Johansson 已提交
1569 1570 1571 1572 1573 1574 1575 1576 1577
	/* 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 已提交
1578
	TX_DESC(txring, fill) = mactx;
1579
	TX_DESC_INFO(txring, fill).dma = nfrags;
O
Olof Johansson 已提交
1580 1581
	fill++;
	TX_DESC_INFO(txring, fill).skb = skb;
O
Olof Johansson 已提交
1582
	for (i = 0; i <= nfrags; i++) {
O
Olof Johansson 已提交
1583
		TX_DESC(txring, fill+i) =
1584
			XCT_PTR_LEN(map_size[i]) | XCT_PTR_ADDR(map[i]);
O
Olof Johansson 已提交
1585
		TX_DESC_INFO(txring, fill+i).dma = map[i];
O
Olof Johansson 已提交
1586 1587 1588 1589 1590 1591 1592 1593
	}

	/* 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++;
1594

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

1597 1598
	dev->stats.tx_packets++;
	dev->stats.tx_bytes += skb->len;
1599 1600 1601

	spin_unlock_irqrestore(&txring->lock, flags);

1602
	write_dma_reg(PAS_DMA_TXCHAN_INCR(txring->chan.chno), (nfrags+2) >> 1);
1603 1604 1605 1606 1607

	return NETDEV_TX_OK;

out_err:
	spin_unlock_irqrestore(&txring->lock, flags);
O
Olof Johansson 已提交
1608 1609 1610 1611 1612
out_err_nolock:
	while (nfrags--)
		pci_unmap_single(mac->dma_pdev, map[nfrags], map_size[nfrags],
				 PCI_DMA_TODEVICE);

1613 1614 1615 1616 1617
	return NETDEV_TX_BUSY;
}

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

1621
	flags = read_mac_reg(mac, PAS_MAC_CFG_PCFG);
1622 1623 1624 1625 1626 1627 1628

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

1629
	write_mac_reg(mac, PAS_MAC_CFG_PCFG, flags);
1630 1631 1632
}


1633
static int pasemi_mac_poll(struct napi_struct *napi, int budget)
1634
{
1635 1636 1637
	struct pasemi_mac *mac = container_of(napi, struct pasemi_mac, napi);
	struct net_device *dev = mac->netdev;
	int pkts;
1638

1639 1640
	pasemi_mac_clean_tx(tx_ring(mac));
	pkts = pasemi_mac_clean_rx(rx_ring(mac), budget);
1641
	if (pkts < budget) {
1642
		/* all done, no more packets present */
1643
		netif_rx_complete(dev, napi);
1644

1645
		pasemi_mac_restart_rx_intr(mac);
O
Olof Johansson 已提交
1646
		pasemi_mac_restart_tx_intr(mac);
1647
	}
1648
	return pkts;
1649 1650
}

N
Nate Case 已提交
1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670
#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

1671 1672 1673 1674
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 已提交
1675
	unsigned int rcmdsta = 0;
1676
	int running;
O
Olof Johansson 已提交
1677
	int ret = 0;
1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698

	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 已提交
1699 1700 1701 1702 1703 1704 1705 1706 1707 1708

	}

	/* 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;
		}
1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722
	}

	/* 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 已提交
1723
out:
1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735
	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 已提交
1736
	return ret;
1737 1738
}

1739 1740 1741 1742 1743 1744
static int __devinit
pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
	struct net_device *dev;
	struct pasemi_mac *mac;
	int err;
1745
	DECLARE_MAC_BUF(mac_buf);
1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766

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

	dev = alloc_etherdev(sizeof(struct pasemi_mac));
	if (dev == NULL) {
		dev_err(&pdev->dev,
			"pasemi_mac: Could not allocate ethernet device.\n");
		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;

1767 1768
	netif_napi_add(dev, &mac->napi, pasemi_mac_poll, 64);

O
Olof Johansson 已提交
1769
	dev->features = NETIF_F_IP_CSUM | NETIF_F_LLTX | NETIF_F_SG |
1770
			NETIF_F_HIGHDMA | NETIF_F_GSO;
1771

1772 1773 1774 1775 1776 1777 1778 1779 1780 1781
	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;


1782 1783 1784 1785 1786 1787
	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;
	}
1788

1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808
	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));

	mac->dma_if = mac_to_intf(mac);
	if (mac->dma_if < 0) {
		dev_err(&mac->pdev->dev, "Can't map DMA interface\n");
		err = -ENODEV;
		goto out;
	}
1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825

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

	dev->open = pasemi_mac_open;
	dev->stop = pasemi_mac_close;
	dev->hard_start_xmit = pasemi_mac_start_tx;
	dev->set_multicast_list = pasemi_mac_set_rx_mode;
1826
	dev->set_mac_address = pasemi_mac_set_mac_addr;
1827 1828 1829
	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;
N
Nate Case 已提交
1830 1831 1832
#ifdef CONFIG_NET_POLL_CONTROLLER
	dev->poll_controller = pasemi_mac_netpoll;
#endif
1833 1834

	dev->change_mtu = pasemi_mac_change_mtu;
1835
	dev->ethtool_ops = &pasemi_mac_ethtool_ops;
1836

1837 1838
	if (err)
		goto out;
1839

1840 1841
	mac->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE);

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

1845 1846 1847 1848 1849 1850
	err = register_netdev(dev);

	if (err) {
		dev_err(&mac->pdev->dev, "register_netdev failed with error %d\n",
			err);
		goto out;
O
Olof Johansson 已提交
1851
	} else if netif_msg_probe(mac)
1852
		printk(KERN_INFO "%s: PA Semi %s: intf %d, hw addr %s\n",
1853
		       dev->name, mac->type == MAC_TYPE_GMAC ? "GMAC" : "XAUI",
1854
		       mac->dma_if, print_mac(mac_buf, dev->dev_addr));
1855 1856 1857 1858

	return err;

out:
1859 1860 1861 1862 1863
	if (mac->iob_pdev)
		pci_dev_put(mac->iob_pdev);
	if (mac->dma_pdev)
		pci_dev_put(mac->dma_pdev);

1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886
	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);

1887 1888
	pasemi_dma_free_chan(&mac->tx->chan);
	pasemi_dma_free_chan(&mac->rx->chan);
1889

1890 1891 1892 1893 1894 1895 1896
	pci_set_drvdata(pdev, NULL);
	free_netdev(netdev);
}

static struct pci_device_id pasemi_mac_pci_tbl[] = {
	{ PCI_DEVICE(PCI_VENDOR_ID_PASEMI, 0xa005) },
	{ PCI_DEVICE(PCI_VENDOR_ID_PASEMI, 0xa006) },
1897
	{ },
1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915
};

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)
{
1916 1917 1918 1919 1920 1921
	int err;

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

1922 1923 1924 1925 1926
	return pci_register_driver(&pasemi_mac_driver);
}

module_init(pasemi_mac_init_module);
module_exit(pasemi_mac_cleanup_module);