netxen_nic_main.c 84.1 KB
Newer Older
A
Amit S. Kale 已提交
1
/*
D
Dhananjay Phadke 已提交
2
 * Copyright (C) 2003 - 2009 NetXen, Inc.
D
Dhananjay Phadke 已提交
3
 * Copyright (C) 2009 - QLogic Corporation.
A
Amit S. Kale 已提交
4
 * All rights reserved.
5
 *
A
Amit S. Kale 已提交
6 7 8 9
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
10
 *
A
Amit S. Kale 已提交
11 12 13 14
 * 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.
15
 *
A
Amit S. Kale 已提交
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
18
 *
A
Amit S. Kale 已提交
19
 * The full GNU General Public License is included in this distribution
A
Amit Kumar Salecha 已提交
20
 * in the file called "COPYING".
21
 *
A
Amit S. Kale 已提交
22 23
 */

24
#include <linux/slab.h>
25
#include <linux/vmalloc.h>
D
Dhananjay Phadke 已提交
26
#include <linux/interrupt.h>
A
Amit S. Kale 已提交
27 28 29 30
#include "netxen_nic_hw.h"

#include "netxen_nic.h"

J
Jeff Garzik 已提交
31
#include <linux/dma-mapping.h>
32
#include <linux/if_vlan.h>
33
#include <net/ip.h>
34
#include <linux/ipv6.h>
35
#include <linux/inetdevice.h>
36
#include <linux/sysfs.h>
37
#include <linux/aer.h>
J
Jeff Garzik 已提交
38

39
MODULE_DESCRIPTION("QLogic/NetXen (1/10) GbE Intelligent Ethernet Driver");
A
Amit S. Kale 已提交
40 41
MODULE_LICENSE("GPL");
MODULE_VERSION(NETXEN_NIC_LINUX_VERSIONID);
D
Dhananjay Phadke 已提交
42
MODULE_FIRMWARE(NX_UNIFIED_ROMIMAGE_NAME);
A
Amit S. Kale 已提交
43

44
char netxen_nic_driver_name[] = "netxen_nic";
D
Dhananjay Phadke 已提交
45
static char netxen_nic_driver_string[] = "QLogic/NetXen Network Driver v"
46
    NETXEN_NIC_LINUX_VERSIONID;
A
Amit S. Kale 已提交
47

48 49 50 51 52 53 54 55 56
static int port_mode = NETXEN_PORT_MODE_AUTO_NEG;

/* Default to restricted 1G auto-neg mode */
static int wol_port_mode = 5;

static int use_msi = 1;

static int use_msi_x = 1;

57 58 59
static int auto_fw_reset = AUTO_FW_RESET_ENABLED;
module_param(auto_fw_reset, int, 0644);
MODULE_PARM_DESC(auto_fw_reset,"Auto firmware reset (0=disabled, 1=enabled");
60

B
Bill Pemberton 已提交
61
static int netxen_nic_probe(struct pci_dev *pdev,
62
		const struct pci_device_id *ent);
B
Bill Pemberton 已提交
63
static void netxen_nic_remove(struct pci_dev *pdev);
A
Amit S. Kale 已提交
64 65
static int netxen_nic_open(struct net_device *netdev);
static int netxen_nic_close(struct net_device *netdev);
66 67
static netdev_tx_t netxen_nic_xmit_frame(struct sk_buff *,
					       struct net_device *);
A
Amit S. Kale 已提交
68
static void netxen_tx_timeout(struct net_device *netdev);
69
static void netxen_tx_timeout_task(struct work_struct *work);
70 71 72 73
static void netxen_fw_poll_work(struct work_struct *work);
static void netxen_schedule_work(struct netxen_adapter *adapter,
		work_func_t func, int delay);
static void netxen_cancel_fw_work(struct netxen_adapter *adapter);
74
static int netxen_nic_poll(struct napi_struct *napi, int budget);
A
Amit S. Kale 已提交
75 76 77
#ifdef CONFIG_NET_POLL_CONTROLLER
static void netxen_nic_poll_controller(struct net_device *netdev);
#endif
78 79 80

static void netxen_create_sysfs_entries(struct netxen_adapter *adapter);
static void netxen_remove_sysfs_entries(struct netxen_adapter *adapter);
81 82
static void netxen_create_diag_entries(struct netxen_adapter *adapter);
static void netxen_remove_diag_entries(struct netxen_adapter *adapter);
83
static int nx_dev_request_aer(struct netxen_adapter *adapter);
84 85 86
static int nx_decr_dev_ref_cnt(struct netxen_adapter *adapter);
static int netxen_can_start_firmware(struct netxen_adapter *adapter);

J
Jeff Garzik 已提交
87
static irqreturn_t netxen_intr(int irq, void *data);
D
Dhananjay Phadke 已提交
88
static irqreturn_t netxen_msi_intr(int irq, void *data);
89
static irqreturn_t netxen_msix_intr(int irq, void *data);
A
Amit S. Kale 已提交
90

91
static void netxen_free_ip_list(struct netxen_adapter *, bool);
R
Rajesh Borundia 已提交
92
static void netxen_restore_indev_addr(struct net_device *dev, unsigned long);
93 94
static void netxen_nic_get_stats(struct net_device *dev,
				 struct rtnl_link_stats64 *stats);
95
static int netxen_nic_set_mac(struct net_device *netdev, void *p);
96

A
Amit S. Kale 已提交
97
/*  PCI Device ID Table  */
98
#define ENTRY(device) \
D
Dhananjay Phadke 已提交
99
	{PCI_DEVICE(PCI_VENDOR_ID_NETXEN, (device)), \
100 101
	.class = PCI_CLASS_NETWORK_ETHERNET << 8, .class_mask = ~0}

102
static const struct pci_device_id netxen_pci_tbl[] = {
D
Dhananjay Phadke 已提交
103 104 105 106 107 108 109 110
	ENTRY(PCI_DEVICE_ID_NX2031_10GXSR),
	ENTRY(PCI_DEVICE_ID_NX2031_10GCX4),
	ENTRY(PCI_DEVICE_ID_NX2031_4GCU),
	ENTRY(PCI_DEVICE_ID_NX2031_IMEZ),
	ENTRY(PCI_DEVICE_ID_NX2031_HMEZ),
	ENTRY(PCI_DEVICE_ID_NX2031_XG_MGMT),
	ENTRY(PCI_DEVICE_ID_NX2031_XG_MGMT2),
	ENTRY(PCI_DEVICE_ID_NX3031),
A
Amit S. Kale 已提交
111 112 113 114 115
	{0,}
};

MODULE_DEVICE_TABLE(pci, netxen_pci_tbl);

116 117 118 119 120
static uint32_t crb_cmd_producer[4] = {
	CRB_CMD_PRODUCER_OFFSET, CRB_CMD_PRODUCER_OFFSET_1,
	CRB_CMD_PRODUCER_OFFSET_2, CRB_CMD_PRODUCER_OFFSET_3
};

121
void
122
netxen_nic_update_cmd_producer(struct netxen_adapter *adapter,
123
		struct nx_host_tx_ring *tx_ring)
124
{
125
	NXWRIO(adapter, tx_ring->crb_cmd_producer, tx_ring->producer);
126 127
}

128 129 130 131 132
static uint32_t crb_cmd_consumer[4] = {
	CRB_CMD_CONSUMER_OFFSET, CRB_CMD_CONSUMER_OFFSET_1,
	CRB_CMD_CONSUMER_OFFSET_2, CRB_CMD_CONSUMER_OFFSET_3
};

133 134
static inline void
netxen_nic_update_cmd_consumer(struct netxen_adapter *adapter,
135
		struct nx_host_tx_ring *tx_ring)
136
{
137
	NXWRIO(adapter, tx_ring->crb_cmd_consumer, tx_ring->sw_consumer);
138 139
}

140
static uint32_t msi_tgt_status[8] = {
D
Dhananjay Phadke 已提交
141
	ISR_INT_TARGET_STATUS, ISR_INT_TARGET_STATUS_F1,
142 143 144
	ISR_INT_TARGET_STATUS_F2, ISR_INT_TARGET_STATUS_F3,
	ISR_INT_TARGET_STATUS_F4, ISR_INT_TARGET_STATUS_F5,
	ISR_INT_TARGET_STATUS_F6, ISR_INT_TARGET_STATUS_F7
D
Dhananjay Phadke 已提交
145 146
};

147 148
static struct netxen_legacy_intr_set legacy_intr[] = NX_LEGACY_INTR_CONFIG;

149
static inline void netxen_nic_disable_int(struct nx_host_sds_ring *sds_ring)
150
{
151 152
	struct netxen_adapter *adapter = sds_ring->adapter;

153
	NXWRIO(adapter, sds_ring->crb_intr_mask, 0);
154 155
}

156
static inline void netxen_nic_enable_int(struct nx_host_sds_ring *sds_ring)
157
{
158 159
	struct netxen_adapter *adapter = sds_ring->adapter;

160
	NXWRIO(adapter, sds_ring->crb_intr_mask, 0x1);
161

162
	if (!NETXEN_IS_MSI_FAMILY(adapter))
163
		NXWRIO(adapter, adapter->tgt_mask_reg, 0xfbff);
164 165
}

166 167 168 169 170 171 172
static int
netxen_alloc_sds_rings(struct netxen_recv_context *recv_ctx, int count)
{
	int size = sizeof(struct nx_host_sds_ring) * count;

	recv_ctx->sds_rings = kzalloc(size, GFP_KERNEL);

173
	return recv_ctx->sds_rings == NULL;
174 175
}

176
static void
177 178
netxen_free_sds_rings(struct netxen_recv_context *recv_ctx)
{
179
	kfree(recv_ctx->sds_rings);
180
	recv_ctx->sds_rings = NULL;
181 182 183
}

static int
184 185 186 187 188 189
netxen_napi_add(struct netxen_adapter *adapter, struct net_device *netdev)
{
	int ring;
	struct nx_host_sds_ring *sds_ring;
	struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;

190
	if (netxen_alloc_sds_rings(recv_ctx, adapter->max_sds_rings))
191
		return -ENOMEM;
192

193 194 195
	for (ring = 0; ring < adapter->max_sds_rings; ring++) {
		sds_ring = &recv_ctx->sds_rings[ring];
		netif_napi_add(netdev, &sds_ring->napi,
M
Michal Schmidt 已提交
196
				netxen_nic_poll, NAPI_POLL_WEIGHT);
197
	}
198 199

	return 0;
200 201
}

202 203 204 205 206 207 208 209 210 211 212 213 214 215 216
static void
netxen_napi_del(struct netxen_adapter *adapter)
{
	int ring;
	struct nx_host_sds_ring *sds_ring;
	struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;

	for (ring = 0; ring < adapter->max_sds_rings; ring++) {
		sds_ring = &recv_ctx->sds_rings[ring];
		netif_napi_del(&sds_ring->napi);
	}

	netxen_free_sds_rings(&adapter->recv_ctx);
}

217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239
static void
netxen_napi_enable(struct netxen_adapter *adapter)
{
	int ring;
	struct nx_host_sds_ring *sds_ring;
	struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;

	for (ring = 0; ring < adapter->max_sds_rings; ring++) {
		sds_ring = &recv_ctx->sds_rings[ring];
		napi_enable(&sds_ring->napi);
		netxen_nic_enable_int(sds_ring);
	}
}

static void
netxen_napi_disable(struct netxen_adapter *adapter)
{
	int ring;
	struct nx_host_sds_ring *sds_ring;
	struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;

	for (ring = 0; ring < adapter->max_sds_rings; ring++) {
		sds_ring = &recv_ctx->sds_rings[ring];
240
		netxen_nic_disable_int(sds_ring);
241 242
		napi_synchronize(&sds_ring->napi);
		napi_disable(&sds_ring->napi);
243 244 245
	}
}

246
static int nx_set_dma_mask(struct netxen_adapter *adapter)
247 248
{
	struct pci_dev *pdev = adapter->pdev;
249 250 251
	uint64_t mask, cmask;

	adapter->pci_using_dac = 0;
252

253 254
	mask = DMA_BIT_MASK(32);
	cmask = DMA_BIT_MASK(32);
255

256
	if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
257
#ifndef CONFIG_IA64
258
		mask = DMA_BIT_MASK(35);
259
#endif
260 261 262 263 264
	} else {
		mask = DMA_BIT_MASK(39);
		cmask = mask;
	}

265
	if (pci_set_dma_mask(pdev, mask) == 0 &&
266
		pci_set_consistent_dma_mask(pdev, cmask) == 0) {
267 268 269 270
		adapter->pci_using_dac = 1;
		return 0;
	}

271 272 273 274 275 276 277 278
	return -EIO;
}

/* Update addressable range if firmware supports it */
static int
nx_update_dma_mask(struct netxen_adapter *adapter)
{
	int change, shift, err;
279
	uint64_t mask, old_mask, old_cmask;
280 281 282 283
	struct pci_dev *pdev = adapter->pdev;

	change = 0;

284
	shift = NXRD32(adapter, CRB_DMA_SHIFT);
285
	if (shift > 32)
286 287 288 289 290 291 292 293 294
		return 0;

	if (NX_IS_REVISION_P3(adapter->ahw.revision_id) && (shift > 9))
		change = 1;
	else if ((adapter->ahw.revision_id == NX_P2_C1) && (shift <= 4))
		change = 1;

	if (change) {
		old_mask = pdev->dma_mask;
295 296
		old_cmask = pdev->dev.coherent_dma_mask;

297
		mask = DMA_BIT_MASK(32+shift);
298 299 300

		err = pci_set_dma_mask(pdev, mask);
		if (err)
301 302 303 304 305 306 307 308 309
			goto err_out;

		if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {

			err = pci_set_consistent_dma_mask(pdev, mask);
			if (err)
				goto err_out;
		}
		dev_info(&pdev->dev, "using %d-bit dma mask\n", 32+shift);
310 311 312
	}

	return 0;
313 314 315 316 317

err_out:
	pci_set_dma_mask(pdev, old_mask);
	pci_set_consistent_dma_mask(pdev, old_cmask);
	return err;
318 319 320 321 322
}

static int
netxen_check_hw_init(struct netxen_adapter *adapter, int first_boot)
{
D
Dhananjay Phadke 已提交
323
	u32 val, timeout;
324 325 326

	if (first_boot == 0x55555555) {
		/* This is the first boot after power up */
327
		NXWR32(adapter, NETXEN_CAM_RAM(0x1fc), NETXEN_BDINFO_MAGIC);
D
Dhananjay Phadke 已提交
328 329 330

		if (!NX_IS_REVISION_P2(adapter->ahw.revision_id))
			return 0;
331 332

		/* PCI bus master workaround */
333
		first_boot = NXRD32(adapter, NETXEN_PCIE_REG(0x4));
334 335
		if (!(first_boot & 0x4)) {
			first_boot |= 0x4;
336
			NXWR32(adapter, NETXEN_PCIE_REG(0x4), first_boot);
A
Amit Kumar Salecha 已提交
337
			NXRD32(adapter, NETXEN_PCIE_REG(0x4));
338 339 340
		}

		/* This is the first boot after power up */
341
		first_boot = NXRD32(adapter, NETXEN_ROMUSB_GLB_SW_RESET);
342 343
		if (first_boot != 0x80000f) {
			/* clear the register for future unloads/loads */
344
			NXWR32(adapter, NETXEN_CAM_RAM(0x1fc), 0);
D
Dhananjay Phadke 已提交
345
			return -EIO;
346 347
		}

D
Dhananjay Phadke 已提交
348
		/* Start P2 boot loader */
349 350
		val = NXRD32(adapter, NETXEN_ROMUSB_GLB_PEGTUNE_DONE);
		NXWR32(adapter, NETXEN_ROMUSB_GLB_PEGTUNE_DONE, val | 0x1);
D
Dhananjay Phadke 已提交
351 352 353
		timeout = 0;
		do {
			msleep(1);
354
			val = NXRD32(adapter, NETXEN_CAM_RAM(0x1fc));
D
Dhananjay Phadke 已提交
355 356 357 358 359

			if (++timeout > 5000)
				return -EIO;

		} while (val == NETXEN_BDINFO_MAGIC);
360
	}
D
Dhananjay Phadke 已提交
361
	return 0;
362 363 364 365 366 367
}

static void netxen_set_port_mode(struct netxen_adapter *adapter)
{
	u32 val, data;

368
	val = adapter->ahw.board_type;
369 370 371 372
	if ((val == NETXEN_BRDTYPE_P3_HMEZ) ||
		(val == NETXEN_BRDTYPE_P3_XG_LOM)) {
		if (port_mode == NETXEN_PORT_MODE_802_3_AP) {
			data = NETXEN_PORT_MODE_802_3_AP;
373
			NXWR32(adapter, NETXEN_PORT_MODE_ADDR, data);
374 375
		} else if (port_mode == NETXEN_PORT_MODE_XG) {
			data = NETXEN_PORT_MODE_XG;
376
			NXWR32(adapter, NETXEN_PORT_MODE_ADDR, data);
377 378
		} else if (port_mode == NETXEN_PORT_MODE_AUTO_NEG_1G) {
			data = NETXEN_PORT_MODE_AUTO_NEG_1G;
379
			NXWR32(adapter, NETXEN_PORT_MODE_ADDR, data);
380 381
		} else if (port_mode == NETXEN_PORT_MODE_AUTO_NEG_XG) {
			data = NETXEN_PORT_MODE_AUTO_NEG_XG;
382
			NXWR32(adapter, NETXEN_PORT_MODE_ADDR, data);
383 384
		} else {
			data = NETXEN_PORT_MODE_AUTO_NEG;
385
			NXWR32(adapter, NETXEN_PORT_MODE_ADDR, data);
386 387 388 389 390 391 392 393
		}

		if ((wol_port_mode != NETXEN_PORT_MODE_802_3_AP) &&
			(wol_port_mode != NETXEN_PORT_MODE_XG) &&
			(wol_port_mode != NETXEN_PORT_MODE_AUTO_NEG_1G) &&
			(wol_port_mode != NETXEN_PORT_MODE_AUTO_NEG_XG)) {
			wol_port_mode = NETXEN_PORT_MODE_AUTO_NEG;
		}
394
		NXWR32(adapter, NETXEN_WOL_PORT_MODE, wol_port_mode);
395 396 397
	}
}

R
Rajesh Borundia 已提交
398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454
#define PCI_CAP_ID_GEN  0x10

static void netxen_pcie_strap_init(struct netxen_adapter *adapter)
{
	u32 pdevfuncsave;
	u32 c8c9value = 0;
	u32 chicken = 0;
	u32 control = 0;
	int i, pos;
	struct pci_dev *pdev;

	pdev = adapter->pdev;

	chicken = NXRD32(adapter, NETXEN_PCIE_REG(PCIE_CHICKEN3));
	/* clear chicken3.25:24 */
	chicken &= 0xFCFFFFFF;
	/*
	 * if gen1 and B0, set F1020 - if gen 2, do nothing
	 * if gen2 set to F1000
	 */
	pos = pci_find_capability(pdev, PCI_CAP_ID_GEN);
	if (pos == 0xC0) {
		pci_read_config_dword(pdev, pos + 0x10, &control);
		if ((control & 0x000F0000) != 0x00020000) {
			/*  set chicken3.24 if gen1 */
			chicken |= 0x01000000;
		}
		dev_info(&adapter->pdev->dev, "Gen2 strapping detected\n");
		c8c9value = 0xF1000;
	} else {
		/* set chicken3.24 if gen1 */
		chicken |= 0x01000000;
		dev_info(&adapter->pdev->dev, "Gen1 strapping detected\n");
		if (adapter->ahw.revision_id == NX_P3_B0)
			c8c9value = 0xF1020;
		else
			c8c9value = 0;
	}

	NXWR32(adapter, NETXEN_PCIE_REG(PCIE_CHICKEN3), chicken);

	if (!c8c9value)
		return;

	pdevfuncsave = pdev->devfn;
	if (pdevfuncsave & 0x07)
		return;

	for (i = 0; i < 8; i++) {
		pci_read_config_dword(pdev, pos + 8, &control);
		pci_read_config_dword(pdev, pos + 8, &control);
		pci_write_config_dword(pdev, pos + 8, c8c9value);
		pdev->devfn++;
	}
	pdev->devfn = pdevfuncsave;
}

455 456 457 458
static void netxen_set_msix_bit(struct pci_dev *pdev, int enable)
{
	u32 control;

459 460
	if (pdev->msix_cap) {
		pci_read_config_dword(pdev, pdev->msix_cap, &control);
461 462 463 464
		if (enable)
			control |= PCI_MSIX_FLAGS_ENABLE;
		else
			control = 0;
465
		pci_write_config_dword(pdev, pdev->msix_cap, control);
466 467 468
	}
}

469
static void netxen_init_msix_entries(struct netxen_adapter *adapter, int count)
470 471 472
{
	int i;

473
	for (i = 0; i < count; i++)
474 475 476
		adapter->msix_entries[i].entry = i;
}

D
Dhananjay Phadke 已提交
477 478 479 480 481
static int
netxen_read_mac_addr(struct netxen_adapter *adapter)
{
	int i;
	unsigned char *p;
482
	u64 mac_addr;
D
Dhananjay Phadke 已提交
483 484 485 486 487 488 489 490 491 492 493 494 495 496 497
	struct net_device *netdev = adapter->netdev;
	struct pci_dev *pdev = adapter->pdev;

	if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
		if (netxen_p3_get_mac_addr(adapter, &mac_addr) != 0)
			return -EIO;
	} else {
		if (netxen_get_flash_mac_addr(adapter, &mac_addr) != 0)
			return -EIO;
	}

	p = (unsigned char *)&mac_addr;
	for (i = 0; i < 6; i++)
		netdev->dev_addr[i] = *(p + 5 - i);

498
	memcpy(adapter->mac_addr, netdev->dev_addr, netdev->addr_len);
D
Dhananjay Phadke 已提交
499 500 501

	/* set station address */

502
	if (!is_valid_ether_addr(netdev->dev_addr))
J
Johannes Berg 已提交
503
		dev_warn(&pdev->dev, "Bad MAC address %pM.\n", netdev->dev_addr);
D
Dhananjay Phadke 已提交
504 505 506 507

	return 0;
}

508
static int netxen_nic_set_mac(struct net_device *netdev, void *p)
D
Dhananjay Phadke 已提交
509 510 511 512 513
{
	struct netxen_adapter *adapter = netdev_priv(netdev);
	struct sockaddr *addr = p;

	if (!is_valid_ether_addr(addr->sa_data))
514
		return -EADDRNOTAVAIL;
D
Dhananjay Phadke 已提交
515 516 517 518 519 520

	if (netif_running(netdev)) {
		netif_device_detach(netdev);
		netxen_napi_disable(adapter);
	}

521
	memcpy(adapter->mac_addr, addr->sa_data, netdev->addr_len);
D
Dhananjay Phadke 已提交
522 523 524 525 526 527 528 529 530 531
	memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
	adapter->macaddr_set(adapter, addr->sa_data);

	if (netif_running(netdev)) {
		netif_device_attach(netdev);
		netxen_napi_enable(adapter);
	}
	return 0;
}

532 533 534 535
static void netxen_set_multicast_list(struct net_device *dev)
{
	struct netxen_adapter *adapter = netdev_priv(dev);

D
Dhananjay Phadke 已提交
536
	adapter->set_multi(dev);
537 538
}

539 540
static netdev_features_t netxen_fix_features(struct net_device *dev,
	netdev_features_t features)
541 542 543 544 545 546 547 548 549 550
{
	if (!(features & NETIF_F_RXCSUM)) {
		netdev_info(dev, "disabling LRO as RXCSUM is off\n");

		features &= ~NETIF_F_LRO;
	}

	return features;
}

551 552
static int netxen_set_features(struct net_device *dev,
	netdev_features_t features)
553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571
{
	struct netxen_adapter *adapter = netdev_priv(dev);
	int hw_lro;

	if (!((dev->features ^ features) & NETIF_F_LRO))
		return 0;

	hw_lro = (features & NETIF_F_LRO) ? NETXEN_NIC_LRO_ENABLED
	         : NETXEN_NIC_LRO_DISABLED;

	if (netxen_config_hw_lro(adapter, hw_lro))
		return -EIO;

	if (!(features & NETIF_F_LRO) && netxen_send_lro_cleanup(adapter))
		return -EIO;

	return 0;
}

572 573 574 575
static const struct net_device_ops netxen_netdev_ops = {
	.ndo_open	   = netxen_nic_open,
	.ndo_stop	   = netxen_nic_close,
	.ndo_start_xmit    = netxen_nic_xmit_frame,
576
	.ndo_get_stats64   = netxen_nic_get_stats,
577
	.ndo_validate_addr = eth_validate_addr,
578
	.ndo_set_rx_mode   = netxen_set_multicast_list,
579 580 581
	.ndo_set_mac_address    = netxen_nic_set_mac,
	.ndo_change_mtu	   = netxen_nic_change_mtu,
	.ndo_tx_timeout	   = netxen_tx_timeout,
582 583
	.ndo_fix_features = netxen_fix_features,
	.ndo_set_features = netxen_set_features,
584 585 586 587 588
#ifdef CONFIG_NET_POLL_CONTROLLER
	.ndo_poll_controller = netxen_nic_poll_controller,
#endif
};

589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604
static inline bool netxen_function_zero(struct pci_dev *pdev)
{
	return (PCI_FUNC(pdev->devfn) == 0) ? true : false;
}

static inline void netxen_set_interrupt_mode(struct netxen_adapter *adapter,
					     u32 mode)
{
	NXWR32(adapter, NETXEN_INTR_MODE_REG, mode);
}

static inline u32 netxen_get_interrupt_mode(struct netxen_adapter *adapter)
{
	return NXRD32(adapter, NETXEN_INTR_MODE_REG);
}

D
Dhananjay Phadke 已提交
605
static void
606
netxen_initialize_interrupt_registers(struct netxen_adapter *adapter)
D
Dhananjay Phadke 已提交
607 608
{
	struct netxen_legacy_intr_set *legacy_intrp;
609
	u32 tgt_status_reg, int_state_reg;
D
Dhananjay Phadke 已提交
610 611 612 613 614

	if (adapter->ahw.revision_id >= NX_P3_B0)
		legacy_intrp = &legacy_intr[adapter->ahw.pci_func];
	else
		legacy_intrp = &legacy_intr[0];
615

616 617 618
	tgt_status_reg = legacy_intrp->tgt_status_reg;
	int_state_reg = ISR_INT_STATE_REG;

619
	adapter->int_vec_bit = legacy_intrp->int_vec_bit;
620
	adapter->tgt_status_reg = netxen_get_ioaddr(adapter, tgt_status_reg);
621
	adapter->tgt_mask_reg = netxen_get_ioaddr(adapter,
622
						  legacy_intrp->tgt_mask_reg);
623
	adapter->pci_int_reg = netxen_get_ioaddr(adapter,
624
						 legacy_intrp->pci_int_reg);
625 626 627 628
	adapter->isr_int_vec = netxen_get_ioaddr(adapter, ISR_INT_VECTOR);

	if (adapter->ahw.revision_id >= NX_P3_B1)
		adapter->crb_int_state_reg = netxen_get_ioaddr(adapter,
629
							       int_state_reg);
630 631
	else
		adapter->crb_int_state_reg = netxen_get_ioaddr(adapter,
632 633
							       CRB_INT_VECTOR);
}
D
Dhananjay Phadke 已提交
634

635 636 637 638 639 640
static int netxen_setup_msi_interrupts(struct netxen_adapter *adapter,
				       int num_msix)
{
	struct pci_dev *pdev = adapter->pdev;
	u32 value;
	int err;
D
Dhananjay Phadke 已提交
641 642

	if (adapter->msix_supported) {
643
		netxen_init_msix_entries(adapter, num_msix);
644 645 646
		err = pci_enable_msix_range(pdev, adapter->msix_entries,
					    num_msix, num_msix);
		if (err > 0) {
647 648
			adapter->flags |= NETXEN_NIC_MSIX_ENABLED;
			netxen_set_msix_bit(pdev, 1);
D
Dhananjay Phadke 已提交
649

650 651
			if (adapter->rss_supported)
				adapter->max_sds_rings = num_msix;
D
Dhananjay Phadke 已提交
652

653
			dev_info(&pdev->dev, "using msi-x interrupts\n");
654
			return 0;
655 656
		}
		/* fall through for msi */
D
Dhananjay Phadke 已提交
657
	}
658 659

	if (use_msi && !pci_enable_msi(pdev)) {
660
		value = msi_tgt_status[adapter->ahw.pci_func];
661
		adapter->flags |= NETXEN_NIC_MSI_ENABLED;
662
		adapter->tgt_status_reg = netxen_get_ioaddr(adapter, value);
D
Dhananjay Phadke 已提交
663
		adapter->msix_entries[0].vector = pdev->irq;
664 665
		dev_info(&pdev->dev, "using msi interrupts\n");
		return 0;
666 667
	}

668
	dev_err(&pdev->dev, "Failed to acquire MSI-X/MSI interrupt vector\n");
669 670 671
	return -EIO;
}

672
static int netxen_setup_intr(struct netxen_adapter *adapter)
673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688
{
	struct pci_dev *pdev = adapter->pdev;
	int num_msix;

	if (adapter->rss_supported)
		num_msix = (num_online_cpus() >= MSIX_ENTRIES_PER_ADAPTER) ?
			    MSIX_ENTRIES_PER_ADAPTER : 2;
	else
		num_msix = 1;

	adapter->max_sds_rings = 1;
	adapter->flags &= ~(NETXEN_NIC_MSI_ENABLED | NETXEN_NIC_MSIX_ENABLED);

	netxen_initialize_interrupt_registers(adapter);
	netxen_set_msix_bit(pdev, 0);

689 690 691 692 693 694 695 696 697 698 699 700
	if (netxen_function_zero(pdev)) {
		if (!netxen_setup_msi_interrupts(adapter, num_msix))
			netxen_set_interrupt_mode(adapter, NETXEN_MSI_MODE);
		else
			netxen_set_interrupt_mode(adapter, NETXEN_INTX_MODE);
	} else {
		if (netxen_get_interrupt_mode(adapter) == NETXEN_MSI_MODE &&
		    netxen_setup_msi_interrupts(adapter, num_msix)) {
			dev_err(&pdev->dev, "Co-existence of MSI-X/MSI and INTx interrupts is not supported\n");
			return -EIO;
		}
	}
701

702 703 704 705 706
	if (!NETXEN_IS_MSI_FAMILY(adapter)) {
		adapter->msix_entries[0].vector = pdev->irq;
		dev_info(&pdev->dev, "using legacy interrupts\n");
	}
	return 0;
D
Dhananjay Phadke 已提交
707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735
}

static void
netxen_teardown_intr(struct netxen_adapter *adapter)
{
	if (adapter->flags & NETXEN_NIC_MSIX_ENABLED)
		pci_disable_msix(adapter->pdev);
	if (adapter->flags & NETXEN_NIC_MSI_ENABLED)
		pci_disable_msi(adapter->pdev);
}

static void
netxen_cleanup_pci_map(struct netxen_adapter *adapter)
{
	if (adapter->ahw.db_base != NULL)
		iounmap(adapter->ahw.db_base);
	if (adapter->ahw.pci_base0 != NULL)
		iounmap(adapter->ahw.pci_base0);
	if (adapter->ahw.pci_base1 != NULL)
		iounmap(adapter->ahw.pci_base1);
	if (adapter->ahw.pci_base2 != NULL)
		iounmap(adapter->ahw.pci_base2);
}

static int
netxen_setup_pci_map(struct netxen_adapter *adapter)
{
	void __iomem *db_ptr = NULL;

D
Dhananjay Phadke 已提交
736
	resource_size_t mem_base, db_base;
737
	unsigned long mem_len, db_len = 0;
D
Dhananjay Phadke 已提交
738 739 740

	struct pci_dev *pdev = adapter->pdev;
	int pci_func = adapter->ahw.pci_func;
741
	struct netxen_hardware_context *ahw = &adapter->ahw;
D
Dhananjay Phadke 已提交
742 743 744 745 746 747 748

	int err = 0;

	/*
	 * Set the CRB window to invalid. If any register in window 0 is
	 * accessed it should set the window to 0 and then reset it to 1.
	 */
749
	adapter->ahw.crb_win = -1;
750
	adapter->ahw.ocm_win = -1;
D
Dhananjay Phadke 已提交
751 752 753 754 755 756 757

	/* remap phys address */
	mem_base = pci_resource_start(pdev, 0);	/* 0 is for BAR 0 */
	mem_len = pci_resource_len(pdev, 0);

	/* 128 Meg of memory */
	if (mem_len == NETXEN_PCI_128MB_SIZE) {
758 759 760

		ahw->pci_base0 = ioremap(mem_base, FIRST_PAGE_GROUP_SIZE);
		ahw->pci_base1 = ioremap(mem_base + SECOND_PAGE_GROUP_START,
D
Dhananjay Phadke 已提交
761
				SECOND_PAGE_GROUP_SIZE);
762
		ahw->pci_base2 = ioremap(mem_base + THIRD_PAGE_GROUP_START,
D
Dhananjay Phadke 已提交
763
				THIRD_PAGE_GROUP_SIZE);
764 765 766 767 768 769 770 771 772
		if (ahw->pci_base0 == NULL || ahw->pci_base1 == NULL ||
						ahw->pci_base2 == NULL) {
			dev_err(&pdev->dev, "failed to map PCI bar 0\n");
			err = -EIO;
			goto err_out;
		}

		ahw->pci_len0 = FIRST_PAGE_GROUP_SIZE;

D
Dhananjay Phadke 已提交
773
	} else if (mem_len == NETXEN_PCI_32MB_SIZE) {
774 775 776

		ahw->pci_base1 = ioremap(mem_base, SECOND_PAGE_GROUP_SIZE);
		ahw->pci_base2 = ioremap(mem_base + THIRD_PAGE_GROUP_START -
D
Dhananjay Phadke 已提交
777
			SECOND_PAGE_GROUP_START, THIRD_PAGE_GROUP_SIZE);
778 779 780 781 782 783
		if (ahw->pci_base1 == NULL || ahw->pci_base2 == NULL) {
			dev_err(&pdev->dev, "failed to map PCI bar 0\n");
			err = -EIO;
			goto err_out;
		}

D
Dhananjay Phadke 已提交
784 785
	} else if (mem_len == NETXEN_PCI_2MB_SIZE) {

786 787
		ahw->pci_base0 = pci_ioremap_bar(pdev, 0);
		if (ahw->pci_base0 == NULL) {
D
Dhananjay Phadke 已提交
788 789 790
			dev_err(&pdev->dev, "failed to map PCI bar 0\n");
			return -EIO;
		}
791
		ahw->pci_len0 = mem_len;
D
Dhananjay Phadke 已提交
792 793 794 795
	} else {
		return -EIO;
	}

796 797
	netxen_setup_hwops(adapter);

D
Dhananjay Phadke 已提交
798 799
	dev_info(&pdev->dev, "%dMB memory map\n", (int)(mem_len>>20));

800 801 802 803 804
	if (NX_IS_REVISION_P3P(adapter->ahw.revision_id)) {
		adapter->ahw.ocm_win_crb = netxen_get_ioaddr(adapter,
			NETXEN_PCIX_PS_REG(PCIX_OCM_WINDOW_REG(pci_func)));

	} else if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
805 806 807 808
		adapter->ahw.ocm_win_crb = netxen_get_ioaddr(adapter,
			NETXEN_PCIX_PS_REG(PCIE_MN_WINDOW_REG(pci_func)));
	}

D
Dhananjay Phadke 已提交
809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839
	if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
		goto skip_doorbell;

	db_base = pci_resource_start(pdev, 4);	/* doorbell is on bar 4 */
	db_len = pci_resource_len(pdev, 4);

	if (db_len == 0) {
		printk(KERN_ERR "%s: doorbell is disabled\n",
				netxen_nic_driver_name);
		err = -EIO;
		goto err_out;
	}

	db_ptr = ioremap(db_base, NETXEN_DB_MAPSIZE_BYTES);
	if (!db_ptr) {
		printk(KERN_ERR "%s: Failed to allocate doorbell map.",
				netxen_nic_driver_name);
		err = -EIO;
		goto err_out;
	}

skip_doorbell:
	adapter->ahw.db_base = db_ptr;
	adapter->ahw.db_len = db_len;
	return 0;

err_out:
	netxen_cleanup_pci_map(adapter);
	return err;
}

840 841 842
static void
netxen_check_options(struct netxen_adapter *adapter)
{
M
Manish chopra 已提交
843
	u32 fw_major, fw_minor, fw_build, prev_fw_version;
844 845
	char brd_name[NETXEN_MAX_SHORT_NAME];
	char serial_num[32];
M
Manish chopra 已提交
846
	int i, offset, val, err;
847
	__le32 *ptr32;
848 849 850 851
	struct pci_dev *pdev = adapter->pdev;

	adapter->driver_mismatch = 0;

852
	ptr32 = (__le32 *)&serial_num;
853 854
	offset = NX_FW_SERIAL_NUM_OFFSET;
	for (i = 0; i < 8; i++) {
855 856
		err = netxen_rom_fast_read(adapter, offset, &val);
		if (err) {
857 858 859 860 861 862 863 864 865 866 867
			dev_err(&pdev->dev, "error reading board info\n");
			adapter->driver_mismatch = 1;
			return;
		}
		ptr32[i] = cpu_to_le32(val);
		offset += sizeof(u32);
	}

	fw_major = NXRD32(adapter, NETXEN_FW_VERSION_MAJOR);
	fw_minor = NXRD32(adapter, NETXEN_FW_VERSION_MINOR);
	fw_build = NXRD32(adapter, NETXEN_FW_VERSION_SUB);
M
Manish chopra 已提交
868
	prev_fw_version = adapter->fw_version;
869 870
	adapter->fw_version = NETXEN_VERSION_CODE(fw_major, fw_minor, fw_build);

M
Manish chopra 已提交
871 872 873 874 875 876 877 878 879 880 881 882 883
	/* Get FW Mini Coredump template and store it */
	 if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
		if (adapter->mdump.md_template == NULL ||
				adapter->fw_version > prev_fw_version) {
			kfree(adapter->mdump.md_template);
			adapter->mdump.md_template = NULL;
			err = netxen_setup_minidump(adapter);
			if (err)
				dev_err(&adapter->pdev->dev,
				"Failed to setup minidump rcode = %d\n", err);
		}
	}

884
	if (adapter->portnum == 0) {
885 886 887
		if (netxen_nic_get_brd_name_by_type(adapter->ahw.board_type,
						    brd_name))
			strcpy(serial_num, "Unknown");
888

D
Dhananjay Phadke 已提交
889 890
		pr_info("%s: %s Board S/N %s  Chip rev 0x%x\n",
				module_name(THIS_MODULE),
891 892 893 894 895 896 897 898 899 900 901 902 903 904 905
				brd_name, serial_num, adapter->ahw.revision_id);
	}

	if (adapter->fw_version < NETXEN_VERSION_CODE(3, 4, 216)) {
		adapter->driver_mismatch = 1;
		dev_warn(&pdev->dev, "firmware version %d.%d.%d unsupported\n",
				fw_major, fw_minor, fw_build);
		return;
	}

	if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
		i = NXRD32(adapter, NETXEN_SRE_MISC);
		adapter->ahw.cut_through = (i & 0x8000) ? 1 : 0;
	}

906 907 908
	dev_info(&pdev->dev, "Driver v%s, firmware v%d.%d.%d [%s]\n",
		 NETXEN_NIC_LINUX_VERSIONID, fw_major, fw_minor, fw_build,
		 adapter->ahw.cut_through ? "cut-through" : "legacy");
909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924

	if (adapter->fw_version >= NETXEN_VERSION_CODE(4, 0, 222))
		adapter->capabilities = NXRD32(adapter, CRB_FW_CAPABILITIES_1);

	if (adapter->ahw.port_type == NETXEN_NIC_XGBE) {
		adapter->num_rxd = DEFAULT_RCV_DESCRIPTORS_10G;
		adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_10G;
	} else if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
		adapter->num_rxd = DEFAULT_RCV_DESCRIPTORS_1G;
		adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_1G;
	}

	adapter->msix_supported = 0;
	if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
		adapter->msix_supported = !!use_msi_x;
		adapter->rss_supported = !!use_msi_x;
925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940
	} else {
		u32 flashed_ver = 0;
		netxen_rom_fast_read(adapter,
				NX_FW_VERSION_OFFSET, (int *)&flashed_ver);
		flashed_ver = NETXEN_DECODE_VERSION(flashed_ver);

		if (flashed_ver >= NETXEN_VERSION_CODE(3, 4, 336)) {
			switch (adapter->ahw.board_type) {
			case NETXEN_BRDTYPE_P2_SB31_10G:
			case NETXEN_BRDTYPE_P2_SB31_10G_CX4:
				adapter->msix_supported = !!use_msi_x;
				adapter->rss_supported = !!use_msi_x;
				break;
			default:
				break;
			}
941 942 943 944 945 946 947 948 949 950 951 952 953 954
		}
	}

	adapter->num_txd = MAX_CMD_DESCRIPTORS;

	if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
		adapter->num_lro_rxd = MAX_LRO_RCV_DESCRIPTORS;
		adapter->max_rds_rings = 3;
	} else {
		adapter->num_lro_rxd = 0;
		adapter->max_rds_rings = 2;
	}
}

955
static int
956
netxen_start_firmware(struct netxen_adapter *adapter)
957 958 959 960
{
	int val, err, first_boot;
	struct pci_dev *pdev = adapter->pdev;

961 962 963 964 965
	/* required for NX2031 dummy dma */
	err = nx_set_dma_mask(adapter);
	if (err)
		return err;

M
Manish chopra 已提交
966 967 968 969 970 971
	err = netxen_can_start_firmware(adapter);

	if (err < 0)
		return err;

	if (!err)
972
		goto wait_init;
973

974
	first_boot = NXRD32(adapter, NETXEN_CAM_RAM(0x1fc));
975 976 977 978 979 980 981

	err = netxen_check_hw_init(adapter, first_boot);
	if (err) {
		dev_err(&pdev->dev, "error in init HW init sequence\n");
		return err;
	}

982
	netxen_request_firmware(adapter);
D
Dhananjay Phadke 已提交
983

984
	err = netxen_need_fw_reset(adapter);
985
	if (err < 0)
986
		goto err_out;
987
	if (err == 0)
R
Rajesh Borundia 已提交
988
		goto pcie_strap_init;
989

990
	if (first_boot != 0x55555555) {
991
		NXWR32(adapter, CRB_CMDPEG_STATE, 0);
992
		netxen_pinit_from_rom(adapter);
993 994
		msleep(1);
	}
995

996
	NXWR32(adapter, CRB_DMA_SHIFT, 0x55555555);
997 998 999
	NXWR32(adapter, NETXEN_PEG_HALT_STATUS1, 0);
	NXWR32(adapter, NETXEN_PEG_HALT_STATUS2, 0);

1000 1001 1002
	if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
		netxen_set_port_mode(adapter);

1003 1004 1005
	err = netxen_load_firmware(adapter);
	if (err)
		goto err_out;
1006

1007 1008
	netxen_release_firmware(adapter);

1009 1010 1011 1012
	if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {

		/* Initialize multicast addr pool owners */
		val = 0x7654;
1013
		if (adapter->ahw.port_type == NETXEN_NIC_XGBE)
1014
			val |= 0x0f000000;
1015
		NXWR32(adapter, NETXEN_MAC_ADDR_CNTL_REG, val);
1016 1017 1018

	}

1019
	err = netxen_init_dummy_dma(adapter);
1020
	if (err)
1021
		goto err_out;
1022 1023 1024 1025 1026 1027 1028

	/*
	 * Tell the hardware our version number.
	 */
	val = (_NETXEN_NIC_LINUX_MAJOR << 16)
		| ((_NETXEN_NIC_LINUX_MINOR << 8))
		| (_NETXEN_NIC_LINUX_SUBVERSION);
1029
	NXWR32(adapter, CRB_DRIVER_VERSION, val);
1030

R
Rajesh Borundia 已提交
1031 1032 1033 1034
pcie_strap_init:
	if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
		netxen_pcie_strap_init(adapter);

1035
wait_init:
1036 1037 1038
	/* Handshake with the card before we register the devices. */
	err = netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE);
	if (err) {
1039
		netxen_free_dummy_dma(adapter);
1040
		goto err_out;
1041 1042
	}

1043 1044
	NXWR32(adapter, NX_CRB_DEV_STATE, NX_DEV_READY);

1045 1046
	nx_update_dma_mask(adapter);

1047
	netxen_check_options(adapter);
1048

1049 1050
	adapter->need_fw_reset = 0;

1051
	/* fall through and release firmware */
1052 1053 1054 1055

err_out:
	netxen_release_firmware(adapter);
	return err;
1056 1057
}

1058 1059 1060 1061
static int
netxen_nic_request_irq(struct netxen_adapter *adapter)
{
	irq_handler_t handler;
1062 1063 1064
	struct nx_host_sds_ring *sds_ring;
	int err, ring;

1065
	unsigned long flags = 0;
1066
	struct net_device *netdev = adapter->netdev;
1067
	struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078

	if (adapter->flags & NETXEN_NIC_MSIX_ENABLED)
		handler = netxen_msix_intr;
	else if (adapter->flags & NETXEN_NIC_MSI_ENABLED)
		handler = netxen_msi_intr;
	else {
		flags |= IRQF_SHARED;
		handler = netxen_intr;
	}
	adapter->irq = netdev->irq;

1079 1080
	for (ring = 0; ring < adapter->max_sds_rings; ring++) {
		sds_ring = &recv_ctx->sds_rings[ring];
1081
		sprintf(sds_ring->name, "%s[%d]", netdev->name, ring);
1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102
		err = request_irq(sds_ring->irq, handler,
				  flags, sds_ring->name, sds_ring);
		if (err)
			return err;
	}

	return 0;
}

static void
netxen_nic_free_irq(struct netxen_adapter *adapter)
{
	int ring;
	struct nx_host_sds_ring *sds_ring;

	struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;

	for (ring = 0; ring < adapter->max_sds_rings; ring++) {
		sds_ring = &recv_ctx->sds_rings[ring];
		free_irq(sds_ring->irq, sds_ring);
	}
1103 1104
}

1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118
static void
netxen_nic_init_coalesce_defaults(struct netxen_adapter *adapter)
{
	adapter->coal.flags = NETXEN_NIC_INTR_DEFAULT;
	adapter->coal.normal.data.rx_time_us =
		NETXEN_DEFAULT_INTR_COALESCE_RX_TIME_US;
	adapter->coal.normal.data.rx_packets =
		NETXEN_DEFAULT_INTR_COALESCE_RX_PACKETS;
	adapter->coal.normal.data.tx_time_us =
		NETXEN_DEFAULT_INTR_COALESCE_TX_TIME_US;
	adapter->coal.normal.data.tx_packets =
		NETXEN_DEFAULT_INTR_COALESCE_TX_PACKETS;
}

1119
/* with rtnl_lock */
1120
static int
1121
__netxen_nic_up(struct netxen_adapter *adapter, struct net_device *netdev)
1122 1123 1124
{
	int err;

1125 1126 1127
	if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC)
		return -EIO;

1128 1129 1130 1131 1132 1133
	err = adapter->init_port(adapter, adapter->physical_port);
	if (err) {
		printk(KERN_ERR "%s: Failed to initialize port %d\n",
				netxen_nic_driver_name, adapter->portnum);
		return err;
	}
D
Dhananjay Phadke 已提交
1134
	if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
1135
		adapter->macaddr_set(adapter, adapter->mac_addr);
1136

D
Dhananjay Phadke 已提交
1137 1138
	adapter->set_multi(netdev);
	adapter->set_mtu(adapter, netdev->mtu);
1139 1140 1141

	adapter->ahw.linkup = 0;

1142 1143
	if (adapter->max_sds_rings > 1)
		netxen_config_rss(adapter, 1);
1144

1145 1146 1147
	if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
		netxen_config_intr_coalesce(adapter);

1148
	if (netdev->features & NETIF_F_LRO)
1149 1150
		netxen_config_hw_lro(adapter, NETXEN_NIC_LRO_ENABLED);

1151 1152
	netxen_napi_enable(adapter);

1153
	if (adapter->capabilities & NX_FW_CAPABILITY_LINK_NOTIFICATION)
1154
		netxen_linkevent_request(adapter, 1);
D
Dhananjay Phadke 已提交
1155 1156 1157
	else
		netxen_nic_set_link_parameters(adapter);

1158
	set_bit(__NX_DEV_UP, &adapter->state);
1159 1160 1161
	return 0;
}

1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177
/* Usage: During resume and firmware recovery module.*/

static inline int
netxen_nic_up(struct netxen_adapter *adapter, struct net_device *netdev)
{
	int err = 0;

	rtnl_lock();
	if (netif_running(netdev))
		err = __netxen_nic_up(adapter, netdev);
	rtnl_unlock();

	return err;
}

/* with rtnl_lock */
1178
static void
1179
__netxen_nic_down(struct netxen_adapter *adapter, struct net_device *netdev)
1180
{
1181 1182 1183
	if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC)
		return;

1184 1185
	if (!test_and_clear_bit(__NX_DEV_UP, &adapter->state))
		return;
1186

1187
	smp_mb();
1188
	netif_carrier_off(netdev);
1189
	netif_tx_disable(netdev);
1190

1191 1192 1193
	if (adapter->capabilities & NX_FW_CAPABILITY_LINK_NOTIFICATION)
		netxen_linkevent_request(adapter, 0);

1194 1195 1196
	if (adapter->stop_port)
		adapter->stop_port(adapter);

1197 1198 1199
	if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
		netxen_p3_free_mac_list(adapter);

1200 1201
	adapter->set_promisc(adapter, NETXEN_NIU_NON_PROMISC_MODE);

1202 1203
	netxen_napi_disable(adapter);

1204 1205 1206
	netxen_release_tx_buffers(adapter);
}

1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217
/* Usage: During suspend and firmware recovery module */

static inline void
netxen_nic_down(struct netxen_adapter *adapter, struct net_device *netdev)
{
	rtnl_lock();
	if (netif_running(netdev))
		__netxen_nic_down(adapter, netdev);
	rtnl_unlock();

}
1218 1219 1220 1221 1222 1223

static int
netxen_nic_attach(struct netxen_adapter *adapter)
{
	struct net_device *netdev = adapter->netdev;
	struct pci_dev *pdev = adapter->pdev;
1224
	int err, ring;
1225
	struct nx_host_rds_ring *rds_ring;
1226
	struct nx_host_tx_ring *tx_ring;
1227
	u32 capab2;
1228

1229 1230 1231
	if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC)
		return 0;

1232
	err = netxen_init_firmware(adapter);
1233 1234 1235
	if (err)
		return err;

1236 1237 1238 1239 1240 1241 1242
	adapter->flags &= ~NETXEN_FW_MSS_CAP;
	if (adapter->capabilities & NX_FW_CAPABILITY_MORE_CAPS) {
		capab2 = NXRD32(adapter, CRB_FW_CAPABILITIES_2);
		if (capab2 & NX_FW_CAPABILITY_2_LRO_MAX_TCP_SEG)
			adapter->flags |= NETXEN_FW_MSS_CAP;
	}

1243 1244 1245
	err = netxen_napi_add(adapter, netdev);
	if (err)
		return err;
1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260

	err = netxen_alloc_sw_resources(adapter);
	if (err) {
		printk(KERN_ERR "%s: Error in setting sw resources\n",
				netdev->name);
		return err;
	}

	err = netxen_alloc_hw_resources(adapter);
	if (err) {
		printk(KERN_ERR "%s: Error in setting hw resources\n",
				netdev->name);
		goto err_out_free_sw;
	}

1261
	if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
1262
		tx_ring = adapter->tx_ring;
1263 1264 1265 1266
		tx_ring->crb_cmd_producer = netxen_get_ioaddr(adapter,
				crb_cmd_producer[adapter->portnum]);
		tx_ring->crb_cmd_consumer = netxen_get_ioaddr(adapter,
				crb_cmd_consumer[adapter->portnum]);
1267

1268 1269 1270 1271 1272
		tx_ring->producer = 0;
		tx_ring->sw_consumer = 0;

		netxen_nic_update_cmd_producer(adapter, tx_ring);
		netxen_nic_update_cmd_consumer(adapter, tx_ring);
1273 1274
	}

1275 1276 1277 1278
	for (ring = 0; ring < adapter->max_rds_rings; ring++) {
		rds_ring = &adapter->recv_ctx.rds_rings[ring];
		netxen_post_rx_buffers(adapter, ring, rds_ring);
	}
1279 1280 1281 1282 1283 1284 1285 1286

	err = netxen_nic_request_irq(adapter);
	if (err) {
		dev_err(&pdev->dev, "%s: failed to setup interrupt\n",
				netdev->name);
		goto err_out_free_rxbuf;
	}

1287 1288 1289
	if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
		netxen_nic_init_coalesce_defaults(adapter);

1290 1291
	netxen_create_sysfs_entries(adapter);

1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305
	adapter->is_up = NETXEN_ADAPTER_UP_MAGIC;
	return 0;

err_out_free_rxbuf:
	netxen_release_rx_buffers(adapter);
	netxen_free_hw_resources(adapter);
err_out_free_sw:
	netxen_free_sw_resources(adapter);
	return err;
}

static void
netxen_nic_detach(struct netxen_adapter *adapter)
{
1306 1307 1308
	if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC)
		return;

1309 1310
	netxen_remove_sysfs_entries(adapter);

1311
	netxen_free_hw_resources(adapter);
1312
	netxen_release_rx_buffers(adapter);
1313
	netxen_nic_free_irq(adapter);
1314
	netxen_napi_del(adapter);
1315 1316 1317 1318 1319
	netxen_free_sw_resources(adapter);

	adapter->is_up = 0;
}

1320 1321 1322 1323 1324 1325
int
netxen_nic_reset_context(struct netxen_adapter *adapter)
{
	int err = 0;
	struct net_device *netdev = adapter->netdev;

1326 1327 1328
	if (test_and_set_bit(__NX_RESETTING, &adapter->state))
		return -EBUSY;

1329 1330
	if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) {

1331 1332
		netif_device_detach(netdev);

1333
		if (netif_running(netdev))
1334
			__netxen_nic_down(adapter, netdev);
1335 1336 1337

		netxen_nic_detach(adapter);

1338 1339 1340
		if (netif_running(netdev)) {
			err = netxen_nic_attach(adapter);
			if (!err)
1341
				err = __netxen_nic_up(adapter, netdev);
1342

1343 1344 1345 1346 1347
			if (err)
				goto done;
		}

		netif_device_attach(netdev);
1348
	}
1349

1350
done:
1351
	clear_bit(__NX_RESETTING, &adapter->state);
1352 1353 1354
	return err;
}

1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368
static int
netxen_setup_netdev(struct netxen_adapter *adapter,
		struct net_device *netdev)
{
	int err = 0;
	struct pci_dev *pdev = adapter->pdev;

	adapter->mc_enabled = 0;
	if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
		adapter->max_mc_count = 38;
	else
		adapter->max_mc_count = 16;

	netdev->netdev_ops	   = &netxen_netdev_ops;
1369
	netdev->watchdog_timeo     = 5*HZ;
1370 1371 1372

	netxen_nic_change_mtu(netdev, netdev->mtu);

1373
	netdev->ethtool_ops = &netxen_nic_ethtool_ops;
1374

1375 1376
	netdev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO |
	                      NETIF_F_RXCSUM;
1377

1378 1379 1380 1381
	if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
		netdev->hw_features |= NETIF_F_IPV6_CSUM | NETIF_F_TSO6;

	netdev->vlan_features |= netdev->hw_features;
1382 1383 1384 1385 1386 1387

	if (adapter->pci_using_dac) {
		netdev->features |= NETIF_F_HIGHDMA;
		netdev->vlan_features |= NETIF_F_HIGHDMA;
	}

1388
	if (adapter->capabilities & NX_FW_CAPABILITY_FVLANTX)
1389
		netdev->hw_features |= NETIF_F_HW_VLAN_CTAG_TX;
1390

1391
	if (adapter->capabilities & NX_FW_CAPABILITY_HW_LRO)
1392 1393 1394
		netdev->hw_features |= NETIF_F_LRO;

	netdev->features |= netdev->hw_features;
1395

1396 1397
	netdev->irq = adapter->msix_entries[0].vector;

1398
	INIT_WORK(&adapter->tx_timeout_task, netxen_tx_timeout_task);
1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413

	if (netxen_read_mac_addr(adapter))
		dev_warn(&pdev->dev, "failed to read mac addr\n");

	netif_carrier_off(netdev);

	err = register_netdev(netdev);
	if (err) {
		dev_err(&pdev->dev, "failed to register net device\n");
		return err;
	}

	return 0;
}

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
#define NETXEN_ULA_ADAPTER_KEY		(0xdaddad01)
#define NETXEN_NON_ULA_ADAPTER_KEY	(0xdaddad00)

static void netxen_read_ula_info(struct netxen_adapter *adapter)
{
	u32 temp;

	/* Print ULA info only once for an adapter */
	if (adapter->portnum != 0)
		return;

	temp = NXRD32(adapter, NETXEN_ULA_KEY);
	switch (temp) {
	case NETXEN_ULA_ADAPTER_KEY:
		dev_info(&adapter->pdev->dev, "ULA adapter");
		break;
	case NETXEN_NON_ULA_ADAPTER_KEY:
		dev_info(&adapter->pdev->dev, "non ULA adapter");
		break;
	default:
		break;
	}

	return;
}

A
amit salecha 已提交
1440 1441 1442 1443 1444 1445 1446
#ifdef CONFIG_PCIEAER
static void netxen_mask_aer_correctable(struct netxen_adapter *adapter)
{
	struct pci_dev *pdev = adapter->pdev;
	struct pci_dev *root = pdev->bus->self;
	u32 aer_pos;

1447 1448 1449 1450
	/* root bus? */
	if (!root)
		return;

A
amit salecha 已提交
1451 1452 1453 1454
	if (adapter->ahw.board_type != NETXEN_BRDTYPE_P3_4_GB_MM &&
		adapter->ahw.board_type != NETXEN_BRDTYPE_P3_10G_TP)
		return;

1455
	if (pci_pcie_type(root) != PCI_EXP_TYPE_ROOT_PORT)
A
amit salecha 已提交
1456 1457 1458 1459 1460 1461 1462 1463 1464 1465
		return;

	aer_pos = pci_find_ext_capability(root, PCI_EXT_CAP_ID_ERR);
	if (!aer_pos)
		return;

	pci_write_config_dword(root, aer_pos + PCI_ERR_COR_MASK, 0xffff);
}
#endif

B
Bill Pemberton 已提交
1466
static int
A
Amit S. Kale 已提交
1467 1468 1469 1470
netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
	struct net_device *netdev = NULL;
	struct netxen_adapter *adapter = NULL;
1471
	int i = 0, err;
1472
	int pci_func_id = PCI_FUNC(pdev->devfn);
1473
	uint8_t revision_id;
1474
	u32 val;
A
Amit S. Kale 已提交
1475

1476
	if (pdev->revision >= NX_P3_A0 && pdev->revision <= NX_P3_B1) {
1477 1478
		pr_warn("%s: chip revisions between 0x%x-0x%x will not be enabled\n",
			module_name(THIS_MODULE), NX_P3_A0, NX_P3_B1);
D
Dhananjay Phadke 已提交
1479 1480 1481
		return -ENODEV;
	}

A
Amit S. Kale 已提交
1482 1483
	if ((err = pci_enable_device(pdev)))
		return err;
1484

A
Amit S. Kale 已提交
1485 1486 1487 1488 1489 1490 1491 1492
	if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
		err = -ENODEV;
		goto err_out_disable_pdev;
	}

	if ((err = pci_request_regions(pdev, netxen_nic_driver_name)))
		goto err_out_disable_pdev;

1493 1494 1495
	if (NX_IS_REVISION_P3(pdev->revision))
		pci_enable_pcie_error_reporting(pdev);

A
Amit S. Kale 已提交
1496
	pci_set_master(pdev);
1497 1498 1499

	netdev = alloc_etherdev(sizeof(struct netxen_adapter));
	if(!netdev) {
1500
		err = -ENOMEM;
1501 1502 1503 1504 1505
		goto err_out_free_res;
	}

	SET_NETDEV_DEV(netdev, &pdev->dev);

1506
	adapter = netdev_priv(netdev);
1507 1508
	adapter->netdev  = netdev;
	adapter->pdev    = pdev;
1509
	adapter->ahw.pci_func  = pci_func_id;
1510 1511 1512 1513

	revision_id = pdev->revision;
	adapter->ahw.revision_id = revision_id;

1514 1515 1516
	rwlock_init(&adapter->ahw.crb_lock);
	spin_lock_init(&adapter->ahw.mem_lock);

1517
	spin_lock_init(&adapter->tx_clean_lock);
1518
	INIT_LIST_HEAD(&adapter->mac_list);
1519
	INIT_LIST_HEAD(&adapter->ip_list);
1520

D
Dhananjay Phadke 已提交
1521 1522
	err = netxen_setup_pci_map(adapter);
	if (err)
1523
		goto err_out_free_netdev;
A
Amit S. Kale 已提交
1524

1525
	/* This will be reset for mezz cards  */
1526 1527
	adapter->portnum = pci_func_id;

1528 1529 1530
	err = netxen_nic_get_board_info(adapter);
	if (err) {
		dev_err(&pdev->dev, "Error getting board config info.\n");
1531 1532
		goto err_out_iounmap;
	}
1533

A
amit salecha 已提交
1534 1535 1536 1537
#ifdef CONFIG_PCIEAER
	netxen_mask_aer_correctable(adapter);
#endif

1538
	/* Mezz cards have PCI function 0,2,3 enabled */
1539
	switch (adapter->ahw.board_type) {
1540 1541 1542
	case NETXEN_BRDTYPE_P2_SB31_10G_IMEZ:
	case NETXEN_BRDTYPE_P2_SB31_10G_HMEZ:
		if (pci_func_id >= 2)
1543
			adapter->portnum = pci_func_id - 2;
1544 1545 1546 1547
		break;
	default:
		break;
	}
1548

1549 1550 1551 1552
	err = netxen_check_flash_fw_compatibility(adapter);
	if (err)
		goto err_out_iounmap;

1553 1554 1555
	if (adapter->portnum == 0) {
		val = NXRD32(adapter, NX_CRB_DEV_REF_COUNT);
		if (val != 0xffffffff && val != 0) {
R
Rajesh Borundia 已提交
1556 1557 1558 1559 1560
			NXWR32(adapter, NX_CRB_DEV_REF_COUNT, 0);
			adapter->need_fw_reset = 1;
		}
	}

1561
	err = netxen_start_firmware(adapter);
1562
	if (err)
1563
		goto err_out_decr_ref;
1564

A
Amit S. Kale 已提交
1565
	/*
1566
	 * See if the firmware gave us a virtual-physical port mapping.
A
Amit S. Kale 已提交
1567
	 */
1568
	adapter->physical_port = adapter->portnum;
1569
	if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
1570
		i = NXRD32(adapter, CRB_V2P(adapter->portnum));
1571 1572 1573
		if (i != 0x55555555)
			adapter->physical_port = i;
	}
1574

1575 1576 1577 1578 1579 1580 1581
	/* MTU range: 0 - 8000 (P2) or 9600 (P3) */
	netdev->min_mtu = 0;
	if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
		netdev->max_mtu = P3_MAX_MTU;
	else
		netdev->max_mtu = P2_MAX_MTU;

1582
	netxen_nic_clear_stats(adapter);
1583

1584 1585 1586 1587 1588 1589 1590
	err = netxen_setup_intr(adapter);

	if (err) {
		dev_err(&adapter->pdev->dev,
			"Failed to setup interrupts, error = %d\n", err);
		goto err_out_disable_msi;
	}
1591

1592 1593
	netxen_read_ula_info(adapter);

1594
	err = netxen_setup_netdev(adapter, netdev);
D
Dhananjay Phadke 已提交
1595
	if (err)
1596
		goto err_out_disable_msi;
1597 1598

	pci_set_drvdata(pdev, adapter);
A
Amit S. Kale 已提交
1599

1600 1601
	netxen_schedule_work(adapter, netxen_fw_poll_work, FW_POLL_DELAY);

1602
	switch (adapter->ahw.port_type) {
1603 1604 1605 1606 1607 1608 1609 1610
	case NETXEN_NIC_GBE:
		dev_info(&adapter->pdev->dev, "%s: GbE port initialized\n",
				adapter->netdev->name);
		break;
	case NETXEN_NIC_XGBE:
		dev_info(&adapter->pdev->dev, "%s: XGbE port initialized\n",
				adapter->netdev->name);
		break;
A
Amit S. Kale 已提交
1611 1612
	}

1613 1614
	netxen_create_diag_entries(adapter);

1615 1616 1617
	return 0;

err_out_disable_msi:
D
Dhananjay Phadke 已提交
1618
	netxen_teardown_intr(adapter);
1619

1620
	netxen_free_dummy_dma(adapter);
A
Amit S. Kale 已提交
1621

1622
err_out_decr_ref:
1623 1624
	nx_decr_dev_ref_cnt(adapter);

1625
err_out_iounmap:
D
Dhananjay Phadke 已提交
1626
	netxen_cleanup_pci_map(adapter);
1627

1628 1629 1630 1631
err_out_free_netdev:
	free_netdev(netdev);

err_out_free_res:
A
Amit S. Kale 已提交
1632
	pci_release_regions(pdev);
1633 1634

err_out_disable_pdev:
A
Amit S. Kale 已提交
1635 1636 1637 1638
	pci_disable_device(pdev);
	return err;
}

M
Manish chopra 已提交
1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650
static
void netxen_cleanup_minidump(struct netxen_adapter *adapter)
{
	kfree(adapter->mdump.md_template);
	adapter->mdump.md_template = NULL;

	if (adapter->mdump.md_capture_buff) {
		vfree(adapter->mdump.md_capture_buff);
		adapter->mdump.md_capture_buff = NULL;
	}
}

B
Bill Pemberton 已提交
1651
static void netxen_nic_remove(struct pci_dev *pdev)
A
Amit S. Kale 已提交
1652 1653
{
	struct netxen_adapter *adapter;
1654
	struct net_device *netdev;
A
Amit S. Kale 已提交
1655

1656
	adapter = pci_get_drvdata(pdev);
A
Amit S. Kale 已提交
1657 1658 1659
	if (adapter == NULL)
		return;

1660 1661
	netdev = adapter->netdev;

1662 1663
	netxen_cancel_fw_work(adapter);

1664 1665
	unregister_netdev(netdev);

1666 1667
	cancel_work_sync(&adapter->tx_timeout_task);

1668
	netxen_free_ip_list(adapter, false);
1669
	netxen_nic_detach(adapter);
A
Amit S. Kale 已提交
1670

1671 1672
	nx_decr_dev_ref_cnt(adapter);

1673
	if (adapter->portnum == 0)
1674
		netxen_free_dummy_dma(adapter);
1675

1676 1677
	clear_bit(__NX_RESETTING, &adapter->state);

D
Dhananjay Phadke 已提交
1678
	netxen_teardown_intr(adapter);
1679
	netxen_set_interrupt_mode(adapter, 0);
1680 1681
	netxen_remove_diag_entries(adapter);

D
Dhananjay Phadke 已提交
1682
	netxen_cleanup_pci_map(adapter);
1683

D
Dhananjay Phadke 已提交
1684 1685
	netxen_release_firmware(adapter);

M
Manish chopra 已提交
1686 1687
	if (NX_IS_REVISION_P3(pdev->revision)) {
		netxen_cleanup_minidump(adapter);
1688
		pci_disable_pcie_error_reporting(pdev);
M
Manish chopra 已提交
1689
	}
1690

1691
	pci_release_regions(pdev);
1692
	pci_disable_device(pdev);
1693

1694
	free_netdev(netdev);
A
Amit S. Kale 已提交
1695
}
1696 1697

static void netxen_nic_detach_func(struct netxen_adapter *adapter)
1698 1699 1700 1701 1702
{
	struct net_device *netdev = adapter->netdev;

	netif_device_detach(netdev);

1703 1704
	netxen_cancel_fw_work(adapter);

1705 1706 1707
	if (netif_running(netdev))
		netxen_nic_down(adapter, netdev);

1708 1709
	cancel_work_sync(&adapter->tx_timeout_task);

1710
	netxen_nic_detach(adapter);
1711

1712 1713 1714
	if (adapter->portnum == 0)
		netxen_free_dummy_dma(adapter);

1715 1716 1717
	nx_decr_dev_ref_cnt(adapter);

	clear_bit(__NX_RESETTING, &adapter->state);
1718
}
1719

1720
static int netxen_nic_attach_func(struct pci_dev *pdev)
1721 1722 1723 1724 1725 1726 1727 1728 1729
{
	struct netxen_adapter *adapter = pci_get_drvdata(pdev);
	struct net_device *netdev = adapter->netdev;
	int err;

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

1730 1731 1732 1733
	pci_set_power_state(pdev, PCI_D0);
	pci_set_master(pdev);
	pci_restore_state(pdev);

1734
	adapter->ahw.crb_win = -1;
1735
	adapter->ahw.ocm_win = -1;
1736

1737
	err = netxen_start_firmware(adapter);
1738 1739 1740 1741 1742 1743 1744 1745
	if (err) {
		dev_err(&pdev->dev, "failed to start firmware\n");
		return err;
	}

	if (netif_running(netdev)) {
		err = netxen_nic_attach(adapter);
		if (err)
1746
			goto err_out;
1747 1748 1749

		err = netxen_nic_up(adapter, netdev);
		if (err)
1750
			goto err_out_detach;
1751

R
Rajesh Borundia 已提交
1752
		netxen_restore_indev_addr(netdev, NETDEV_UP);
1753 1754
	}

1755
	netif_device_attach(netdev);
1756
	netxen_schedule_work(adapter, netxen_fw_poll_work, FW_POLL_DELAY);
1757
	return 0;
1758 1759 1760 1761 1762 1763

err_out_detach:
	netxen_nic_detach(adapter);
err_out:
	nx_decr_dev_ref_cnt(adapter);
	return err;
1764
}
1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843

static pci_ers_result_t netxen_io_error_detected(struct pci_dev *pdev,
						pci_channel_state_t state)
{
	struct netxen_adapter *adapter = pci_get_drvdata(pdev);

	if (state == pci_channel_io_perm_failure)
		return PCI_ERS_RESULT_DISCONNECT;

	if (nx_dev_request_aer(adapter))
		return PCI_ERS_RESULT_RECOVERED;

	netxen_nic_detach_func(adapter);

	pci_disable_device(pdev);

	return PCI_ERS_RESULT_NEED_RESET;
}

static pci_ers_result_t netxen_io_slot_reset(struct pci_dev *pdev)
{
	int err = 0;

	err = netxen_nic_attach_func(pdev);

	return err ? PCI_ERS_RESULT_DISCONNECT : PCI_ERS_RESULT_RECOVERED;
}

static void netxen_io_resume(struct pci_dev *pdev)
{
	pci_cleanup_aer_uncorrect_error_status(pdev);
}

static void netxen_nic_shutdown(struct pci_dev *pdev)
{
	struct netxen_adapter *adapter = pci_get_drvdata(pdev);

	netxen_nic_detach_func(adapter);

	if (pci_save_state(pdev))
		return;

	if (netxen_nic_wol_supported(adapter)) {
		pci_enable_wake(pdev, PCI_D3cold, 1);
		pci_enable_wake(pdev, PCI_D3hot, 1);
	}

	pci_disable_device(pdev);
}

#ifdef CONFIG_PM
static int
netxen_nic_suspend(struct pci_dev *pdev, pm_message_t state)
{
	struct netxen_adapter *adapter = pci_get_drvdata(pdev);
	int retval;

	netxen_nic_detach_func(adapter);

	retval = pci_save_state(pdev);
	if (retval)
		return retval;

	if (netxen_nic_wol_supported(adapter)) {
		pci_enable_wake(pdev, PCI_D3cold, 1);
		pci_enable_wake(pdev, PCI_D3hot, 1);
	}

	pci_disable_device(pdev);
	pci_set_power_state(pdev, pci_choose_state(pdev, state));

	return 0;
}

static int
netxen_nic_resume(struct pci_dev *pdev)
{
	return netxen_nic_attach_func(pdev);
}
1844
#endif
1845

A
Amit S. Kale 已提交
1846 1847
static int netxen_nic_open(struct net_device *netdev)
{
1848
	struct netxen_adapter *adapter = netdev_priv(netdev);
A
Amit S. Kale 已提交
1849 1850
	int err = 0;

1851 1852 1853
	if (adapter->driver_mismatch)
		return -EIO;

1854 1855 1856
	err = netxen_nic_attach(adapter);
	if (err)
		return err;
1857

1858
	err = __netxen_nic_up(adapter, netdev);
1859 1860
	if (err)
		goto err_out;
D
Dhananjay Phadke 已提交
1861

1862
	netif_start_queue(netdev);
A
Amit S. Kale 已提交
1863 1864

	return 0;
1865

1866 1867
err_out:
	netxen_nic_detach(adapter);
1868
	return err;
A
Amit S. Kale 已提交
1869 1870 1871 1872 1873 1874 1875
}

/*
 * netxen_nic_close - Disables a network interface entry point
 */
static int netxen_nic_close(struct net_device *netdev)
{
1876
	struct netxen_adapter *adapter = netdev_priv(netdev);
A
Amit S. Kale 已提交
1877

1878
	__netxen_nic_down(adapter, netdev);
A
Amit S. Kale 已提交
1879 1880 1881
	return 0;
}

D
Dhananjay Phadke 已提交
1882 1883 1884 1885 1886
static void
netxen_tso_check(struct net_device *netdev,
		struct nx_host_tx_ring *tx_ring,
		struct cmd_desc_type0 *first_desc,
		struct sk_buff *skb)
1887
{
1888
	u8 opcode = TX_ETHER_PKT;
1889
	__be16 protocol = skb->protocol;
1890
	u16 flags = 0, vid = 0;
D
Dhananjay Phadke 已提交
1891
	u32 producer;
1892
	int copied, offset, copy_len, hdr_len = 0, tso = 0, vlan_oob = 0;
D
Dhananjay Phadke 已提交
1893
	struct cmd_desc_type0 *hwdesc;
1894
	struct vlan_ethhdr *vh;
1895

1896
	if (protocol == cpu_to_be16(ETH_P_8021Q)) {
1897 1898

		vh = (struct vlan_ethhdr *)skb->data;
1899 1900
		protocol = vh->h_vlan_encapsulated_proto;
		flags = FLAGS_VLAN_TAGGED;
1901

1902
	} else if (skb_vlan_tag_present(skb)) {
1903
		flags = FLAGS_VLAN_OOB;
1904
		vid = skb_vlan_tag_get(skb);
1905 1906
		netxen_set_tx_vlan_tci(first_desc, vid);
		vlan_oob = 1;
1907
	}
1908

1909 1910 1911
	if ((netdev->features & (NETIF_F_TSO | NETIF_F_TSO6)) &&
			skb_shinfo(skb)->gso_size > 0) {

D
Dhananjay Phadke 已提交
1912 1913 1914 1915
		hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);

		first_desc->mss = cpu_to_le16(skb_shinfo(skb)->gso_size);
		first_desc->total_hdr_length = hdr_len;
1916 1917 1918 1919 1920 1921 1922
		if (vlan_oob) {
			first_desc->total_hdr_length += VLAN_HLEN;
			first_desc->tcp_hdr_offset = VLAN_HLEN;
			first_desc->ip_hdr_offset = VLAN_HLEN;
			/* Only in case of TSO on vlan device */
			flags |= FLAGS_VLAN_TAGGED;
		}
1923

1924
		opcode = (protocol == cpu_to_be16(ETH_P_IPV6)) ?
1925
				TX_TCP_LSO6 : TX_TCP_LSO;
D
Dhananjay Phadke 已提交
1926
		tso = 1;
1927 1928

	} else if (skb->ip_summed == CHECKSUM_PARTIAL) {
1929 1930
		u8 l4proto;

1931
		if (protocol == cpu_to_be16(ETH_P_IP)) {
1932 1933 1934 1935 1936 1937
			l4proto = ip_hdr(skb)->protocol;

			if (l4proto == IPPROTO_TCP)
				opcode = TX_TCP_PKT;
			else if(l4proto == IPPROTO_UDP)
				opcode = TX_UDP_PKT;
1938
		} else if (protocol == cpu_to_be16(ETH_P_IPV6)) {
1939 1940 1941 1942 1943 1944 1945
			l4proto = ipv6_hdr(skb)->nexthdr;

			if (l4proto == IPPROTO_TCP)
				opcode = TX_TCPV6_PKT;
			else if(l4proto == IPPROTO_UDP)
				opcode = TX_UDPV6_PKT;
		}
1946
	}
1947 1948 1949

	first_desc->tcp_hdr_offset += skb_transport_offset(skb);
	first_desc->ip_hdr_offset += skb_network_offset(skb);
D
Dhananjay Phadke 已提交
1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961
	netxen_set_tx_flags_opcode(first_desc, flags, opcode);

	if (!tso)
		return;

	/* For LSO, we need to copy the MAC/IP/TCP headers into
	 * the descriptor ring
	 */
	producer = tx_ring->producer;
	copied = 0;
	offset = 2;

1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977
	if (vlan_oob) {
		/* Create a TSO vlan header template for firmware */

		hwdesc = &tx_ring->desc_head[producer];
		tx_ring->cmd_buf_arr[producer].skb = NULL;

		copy_len = min((int)sizeof(struct cmd_desc_type0) - offset,
				hdr_len + VLAN_HLEN);

		vh = (struct vlan_ethhdr *)((char *)hwdesc + 2);
		skb_copy_from_linear_data(skb, vh, 12);
		vh->h_vlan_proto = htons(ETH_P_8021Q);
		vh->h_vlan_TCI = htons(vid);
		skb_copy_from_linear_data_offset(skb, 12,
				(char *)vh + 16, copy_len - 16);

D
Dhananjay Phadke 已提交
1978
		copied = copy_len - VLAN_HLEN;
1979 1980 1981 1982 1983
		offset = 0;

		producer = get_next_index(producer, tx_ring->num_desc);
	}

D
Dhananjay Phadke 已提交
1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002
	while (copied < hdr_len) {

		copy_len = min((int)sizeof(struct cmd_desc_type0) - offset,
				(hdr_len - copied));

		hwdesc = &tx_ring->desc_head[producer];
		tx_ring->cmd_buf_arr[producer].skb = NULL;

		skb_copy_from_linear_data_offset(skb, copied,
				 (char *)hwdesc + offset, copy_len);

		copied += copy_len;
		offset = 0;

		producer = get_next_index(producer, tx_ring->num_desc);
	}

	tx_ring->producer = producer;
	barrier();
2003 2004
}

2005 2006 2007
static int
netxen_map_tx_skb(struct pci_dev *pdev,
		struct sk_buff *skb, struct netxen_cmd_buffer *pbuf)
2008
{
2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020
	struct netxen_skb_frag *nf;
	struct skb_frag_struct *frag;
	int i, nr_frags;
	dma_addr_t map;

	nr_frags = skb_shinfo(skb)->nr_frags;
	nf = &pbuf->frag_array[0];

	map = pci_map_single(pdev, skb->data,
			skb_headlen(skb), PCI_DMA_TODEVICE);
	if (pci_dma_mapping_error(pdev, map))
		goto out_err;
2021

2022 2023 2024 2025 2026 2027 2028
	nf->dma = map;
	nf->length = skb_headlen(skb);

	for (i = 0; i < nr_frags; i++) {
		frag = &skb_shinfo(skb)->frags[i];
		nf = &pbuf->frag_array[i+1];

E
Eric Dumazet 已提交
2029
		map = skb_frag_dma_map(&pdev->dev, frag, 0, skb_frag_size(frag),
2030 2031
				       DMA_TO_DEVICE);
		if (dma_mapping_error(&pdev->dev, map))
2032 2033 2034
			goto unwind;

		nf->dma = map;
E
Eric Dumazet 已提交
2035
		nf->length = skb_frag_size(frag);
2036 2037 2038
	}

	return 0;
2039

2040
unwind:
2041 2042
	while (--i >= 0) {
		nf = &pbuf->frag_array[i+1];
2043
		pci_unmap_page(pdev, nf->dma, nf->length, PCI_DMA_TODEVICE);
2044
		nf->dma = 0ULL;
2045
	}
2046 2047 2048

	nf = &pbuf->frag_array[0];
	pci_unmap_single(pdev, nf->dma, skb_headlen(skb), PCI_DMA_TODEVICE);
2049
	nf->dma = 0ULL;
2050 2051 2052

out_err:
	return -ENOMEM;
2053 2054
}

2055 2056 2057
static inline void
netxen_clear_cmddesc(u64 *desc)
{
D
Dhananjay Phadke 已提交
2058 2059
	desc[0] = 0ULL;
	desc[2] = 0ULL;
2060 2061
}

2062
static netdev_tx_t
2063
netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
A
Amit S. Kale 已提交
2064
{
2065
	struct netxen_adapter *adapter = netdev_priv(netdev);
2066
	struct nx_host_tx_ring *tx_ring = adapter->tx_ring;
2067
	struct netxen_cmd_buffer *pbuf;
A
Amit S. Kale 已提交
2068
	struct netxen_skb_frag *buffrag;
D
Dhananjay Phadke 已提交
2069 2070
	struct cmd_desc_type0 *hwdesc, *first_desc;
	struct pci_dev *pdev;
2071
	int i, k;
2072 2073
	int delta = 0;
	struct skb_frag_struct *frag;
A
Amit S. Kale 已提交
2074

2075
	u32 producer;
2076
	int frag_count, no_of_desc;
2077
	u32 num_txd = tx_ring->num_desc;
A
Amit S. Kale 已提交
2078 2079 2080

	frag_count = skb_shinfo(skb)->nr_frags + 1;

2081 2082 2083 2084 2085 2086 2087
	/* 14 frags supported for normal packet and
	 * 32 frags supported for TSO packet
	 */
	if (!skb_is_gso(skb) && frag_count > NETXEN_MAX_FRAGS_PER_TX) {

		for (i = 0; i < (frag_count - NETXEN_MAX_FRAGS_PER_TX); i++) {
			frag = &skb_shinfo(skb)->frags[i];
E
Eric Dumazet 已提交
2088
			delta += skb_frag_size(frag);
2089 2090 2091 2092 2093 2094 2095
		}

		if (!__pskb_pull_tail(skb, delta))
			goto drop_packet;

		frag_count = 1 + skb_shinfo(skb)->nr_frags;
	}
2096
	/* 4 fragments per cmd des */
A
Amit S. Kale 已提交
2097
	no_of_desc = (frag_count + 3) >> 2;
2098

2099
	if (unlikely(netxen_tx_avail(tx_ring) <= TX_STOP_THRESH)) {
2100
		netif_stop_queue(netdev);
2101 2102 2103 2104 2105
		smp_mb();
		if (netxen_tx_avail(tx_ring) > TX_STOP_THRESH)
			netif_start_queue(netdev);
		else
			return NETDEV_TX_BUSY;
2106
	}
A
Amit S. Kale 已提交
2107

2108
	producer = tx_ring->producer;
2109
	pbuf = &tx_ring->cmd_buf_arr[producer];
2110

D
Dhananjay Phadke 已提交
2111
	pdev = adapter->pdev;
2112

2113
	if (netxen_map_tx_skb(pdev, skb, pbuf))
D
Dhananjay Phadke 已提交
2114
		goto drop_packet;
2115

A
Amit S. Kale 已提交
2116 2117
	pbuf->skb = skb;
	pbuf->frag_count = frag_count;
2118

D
Dhananjay Phadke 已提交
2119 2120
	first_desc = hwdesc = &tx_ring->desc_head[producer];
	netxen_clear_cmddesc((u64 *)hwdesc);
A
Amit S. Kale 已提交
2121

2122 2123
	netxen_set_tx_frags_len(first_desc, frag_count, skb->len);
	netxen_set_tx_port(first_desc, adapter->portnum);
A
Amit S. Kale 已提交
2124

2125
	for (i = 0; i < frag_count; i++) {
A
Amit S. Kale 已提交
2126

2127 2128 2129 2130
		k = i % 4;

		if ((k == 0) && (i > 0)) {
			/* move to next desc.*/
2131
			producer = get_next_index(producer, num_txd);
2132
			hwdesc = &tx_ring->desc_head[producer];
2133
			netxen_clear_cmddesc((u64 *)hwdesc);
2134
			tx_ring->cmd_buf_arr[producer].skb = NULL;
2135
		}
A
Amit S. Kale 已提交
2136

2137
		buffrag = &pbuf->frag_array[i];
A
Amit S. Kale 已提交
2138

2139
		hwdesc->buffer_length[k] = cpu_to_le16(buffrag->length);
A
Amit S. Kale 已提交
2140 2141
		switch (k) {
		case 0:
2142
			hwdesc->addr_buffer1 = cpu_to_le64(buffrag->dma);
A
Amit S. Kale 已提交
2143 2144
			break;
		case 1:
2145
			hwdesc->addr_buffer2 = cpu_to_le64(buffrag->dma);
A
Amit S. Kale 已提交
2146 2147
			break;
		case 2:
2148
			hwdesc->addr_buffer3 = cpu_to_le64(buffrag->dma);
A
Amit S. Kale 已提交
2149 2150
			break;
		case 3:
2151
			hwdesc->addr_buffer4 = cpu_to_le64(buffrag->dma);
A
Amit S. Kale 已提交
2152 2153 2154
			break;
		}
	}
2155

D
Dhananjay Phadke 已提交
2156
	tx_ring->producer = get_next_index(producer, num_txd);
A
Amit S. Kale 已提交
2157

D
Dhananjay Phadke 已提交
2158
	netxen_tso_check(netdev, tx_ring, first_desc, skb);
2159

D
Dhananjay Phadke 已提交
2160
	adapter->stats.txbytes += skb->len;
2161
	adapter->stats.xmitcalled++;
A
Amit S. Kale 已提交
2162

2163 2164
	netxen_nic_update_cmd_producer(adapter, tx_ring);

A
Amit S. Kale 已提交
2165
	return NETDEV_TX_OK;
2166 2167 2168 2169 2170

drop_packet:
	adapter->stats.txdropped++;
	dev_kfree_skb_any(skb);
	return NETDEV_TX_OK;
A
Amit S. Kale 已提交
2171 2172
}

2173 2174 2175 2176 2177 2178
static int netxen_nic_check_temp(struct netxen_adapter *adapter)
{
	struct net_device *netdev = adapter->netdev;
	uint32_t temp, temp_state, temp_val;
	int rv = 0;

2179
	temp = NXRD32(adapter, CRB_TEMP_STATE);
2180 2181 2182 2183 2184 2185 2186 2187

	temp_state = nx_get_temp_state(temp);
	temp_val = nx_get_temp_val(temp);

	if (temp_state == NX_TEMP_PANIC) {
		printk(KERN_ALERT
		       "%s: Device temperature %d degrees C exceeds"
		       " maximum allowed. Hardware has been shut down.\n",
2188
		       netdev->name, temp_val);
2189 2190 2191 2192 2193 2194 2195
		rv = 1;
	} else if (temp_state == NX_TEMP_WARN) {
		if (adapter->temp == NX_TEMP_NORMAL) {
			printk(KERN_ALERT
			       "%s: Device temperature %d degrees C "
			       "exceeds operating range."
			       " Immediate action needed.\n",
2196
			       netdev->name, temp_val);
2197 2198 2199 2200 2201
		}
	} else {
		if (adapter->temp == NX_TEMP_WARN) {
			printk(KERN_INFO
			       "%s: Device temperature is now %d degrees C"
2202
			       " in normal range.\n", netdev->name,
2203 2204 2205 2206 2207 2208 2209
			       temp_val);
		}
	}
	adapter->temp = temp_state;
	return rv;
}

2210
void netxen_advert_link_change(struct netxen_adapter *adapter, int linkup)
2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221
{
	struct net_device *netdev = adapter->netdev;

	if (adapter->ahw.linkup && !linkup) {
		printk(KERN_INFO "%s: %s NIC Link is down\n",
		       netxen_nic_driver_name, netdev->name);
		adapter->ahw.linkup = 0;
		if (netif_running(netdev)) {
			netif_carrier_off(netdev);
			netif_stop_queue(netdev);
		}
2222
		adapter->link_changed = !adapter->has_link_events;
2223 2224 2225 2226 2227 2228 2229 2230
	} else if (!adapter->ahw.linkup && linkup) {
		printk(KERN_INFO "%s: %s NIC Link is up\n",
		       netxen_nic_driver_name, netdev->name);
		adapter->ahw.linkup = 1;
		if (netif_running(netdev)) {
			netif_carrier_on(netdev);
			netif_wake_queue(netdev);
		}
2231
		adapter->link_changed = !adapter->has_link_events;
2232 2233 2234
	}
}

2235 2236 2237 2238 2239 2240 2241
static void netxen_nic_handle_phy_intr(struct netxen_adapter *adapter)
{
	u32 val, port, linkup;

	port = adapter->physical_port;

	if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
2242
		val = NXRD32(adapter, CRB_XG_STATE_P3);
2243 2244 2245
		val = XG_LINK_STATE_P3(adapter->ahw.pci_func, val);
		linkup = (val == XG_LINK_UP_P3);
	} else {
2246
		val = NXRD32(adapter, CRB_XG_STATE);
2247 2248
		val = (val >> port*8) & 0xff;
		linkup = (val == XG_LINK_UP);
2249 2250 2251 2252 2253
	}

	netxen_advert_link_change(adapter, linkup);
}

A
Amit S. Kale 已提交
2254 2255
static void netxen_tx_timeout(struct net_device *netdev)
{
2256
	struct netxen_adapter *adapter = netdev_priv(netdev);
2257

2258 2259 2260
	if (test_bit(__NX_RESETTING, &adapter->state))
		return;

2261
	dev_err(&netdev->dev, "transmit timeout, resetting.\n");
2262
	schedule_work(&adapter->tx_timeout_task);
A
Amit S. Kale 已提交
2263 2264
}

2265
static void netxen_tx_timeout_task(struct work_struct *work)
A
Amit S. Kale 已提交
2266
{
2267
	struct netxen_adapter *adapter =
2268
		container_of(work, struct netxen_adapter, tx_timeout_task);
A
Amit S. Kale 已提交
2269

2270 2271 2272
	if (!netif_running(adapter->netdev))
		return;

2273
	if (test_and_set_bit(__NX_RESETTING, &adapter->state))
2274 2275
		return;

2276 2277 2278
	if (++adapter->tx_timeo_cnt >= NX_MAX_TX_TIMEOUTS)
		goto request_reset;

2279
	rtnl_lock();
2280 2281 2282
	if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
		/* try to scrub interrupt */
		netxen_napi_disable(adapter);
2283

2284 2285 2286 2287
		netxen_napi_enable(adapter);

		netif_wake_queue(adapter->netdev);

2288
		clear_bit(__NX_RESETTING, &adapter->state);
2289
	} else {
2290
		clear_bit(__NX_RESETTING, &adapter->state);
2291 2292 2293
		if (netxen_nic_reset_context(adapter)) {
			rtnl_unlock();
			goto request_reset;
2294 2295
		}
	}
2296
	netif_trans_update(adapter->netdev);
2297 2298
	rtnl_unlock();
	return;
2299 2300 2301

request_reset:
	adapter->need_fw_reset = 1;
2302
	clear_bit(__NX_RESETTING, &adapter->state);
A
Amit S. Kale 已提交
2303 2304
}

2305 2306
static void netxen_nic_get_stats(struct net_device *netdev,
				 struct rtnl_link_stats64 *stats)
2307 2308 2309
{
	struct netxen_adapter *adapter = netdev_priv(netdev);

2310
	stats->rx_packets = adapter->stats.rx_pkts + adapter->stats.lro_pkts;
D
Dhananjay Phadke 已提交
2311
	stats->tx_packets = adapter->stats.xmitfinished;
2312 2313 2314 2315 2316 2317
	stats->rx_bytes = adapter->stats.rxbytes;
	stats->tx_bytes = adapter->stats.txbytes;
	stats->rx_dropped = adapter->stats.rxdropped;
	stats->tx_dropped = adapter->stats.txdropped;
}

2318
static irqreturn_t netxen_intr(int irq, void *data)
A
Amit S. Kale 已提交
2319
{
2320 2321
	struct nx_host_sds_ring *sds_ring = data;
	struct netxen_adapter *adapter = sds_ring->adapter;
D
Dhananjay Phadke 已提交
2322 2323
	u32 status = 0;

2324
	status = readl(adapter->isr_int_vec);
D
Dhananjay Phadke 已提交
2325

2326
	if (!(status & adapter->int_vec_bit))
D
Dhananjay Phadke 已提交
2327
		return IRQ_NONE;
2328

2329
	if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
D
Dhananjay Phadke 已提交
2330
		/* check interrupt state machine, to be sure */
2331
		status = readl(adapter->crb_int_state_reg);
D
Dhananjay Phadke 已提交
2332 2333 2334
		if (!ISR_LEGACY_INT_TRIGGERED(status))
			return IRQ_NONE;

2335 2336
	} else {
		unsigned long our_int = 0;
D
Dhananjay Phadke 已提交
2337

2338
		our_int = readl(adapter->crb_int_state_reg);
2339

D
Dhananjay Phadke 已提交
2340
		/* not our interrupt */
2341
		if (!test_and_clear_bit((7 + adapter->portnum), &our_int))
D
Dhananjay Phadke 已提交
2342 2343
			return IRQ_NONE;

2344
		/* claim interrupt */
2345
		writel((our_int & 0xffffffff), adapter->crb_int_state_reg);
2346

2347
		/* clear interrupt */
2348
		netxen_nic_disable_int(sds_ring);
2349
	}
2350

2351
	writel(0xffffffff, adapter->tgt_status_reg);
2352
	/* read twice to ensure write is flushed */
2353 2354
	readl(adapter->isr_int_vec);
	readl(adapter->isr_int_vec);
2355

2356
	napi_schedule(&sds_ring->napi);
A
Amit S. Kale 已提交
2357 2358 2359 2360

	return IRQ_HANDLED;
}

2361
static irqreturn_t netxen_msi_intr(int irq, void *data)
D
Dhananjay Phadke 已提交
2362
{
2363 2364
	struct nx_host_sds_ring *sds_ring = data;
	struct netxen_adapter *adapter = sds_ring->adapter;
D
Dhananjay Phadke 已提交
2365

2366
	/* clear interrupt */
2367
	writel(0xffffffff, adapter->tgt_status_reg);
2368

2369
	napi_schedule(&sds_ring->napi);
D
Dhananjay Phadke 已提交
2370 2371 2372
	return IRQ_HANDLED;
}

2373 2374
static irqreturn_t netxen_msix_intr(int irq, void *data)
{
2375
	struct nx_host_sds_ring *sds_ring = data;
2376

2377
	napi_schedule(&sds_ring->napi);
2378 2379 2380
	return IRQ_HANDLED;
}

2381
static int netxen_nic_poll(struct napi_struct *napi, int budget)
A
Amit S. Kale 已提交
2382
{
2383 2384 2385 2386 2387
	struct nx_host_sds_ring *sds_ring =
		container_of(napi, struct nx_host_sds_ring, napi);

	struct netxen_adapter *adapter = sds_ring->adapter;

D
Dhananjay Phadke 已提交
2388
	int tx_complete;
2389
	int work_done;
A
Amit S. Kale 已提交
2390

D
Dhananjay Phadke 已提交
2391
	tx_complete = netxen_process_cmd_ring(adapter);
A
Amit S. Kale 已提交
2392

2393
	work_done = netxen_process_rcv_ring(sds_ring, budget);
A
Amit S. Kale 已提交
2394

2395 2396 2397 2398
	if (!tx_complete)
		work_done = budget;

	if (work_done < budget) {
2399
		napi_complete_done(&sds_ring->napi, work_done);
2400
		if (test_bit(__NX_DEV_UP, &adapter->state))
2401
			netxen_nic_enable_int(sds_ring);
A
Amit S. Kale 已提交
2402 2403
	}

2404
	return work_done;
A
Amit S. Kale 已提交
2405 2406 2407 2408 2409
}

#ifdef CONFIG_NET_POLL_CONTROLLER
static void netxen_nic_poll_controller(struct net_device *netdev)
{
Y
Yinglin Luan 已提交
2410 2411
	int ring;
	struct nx_host_sds_ring *sds_ring;
2412
	struct netxen_adapter *adapter = netdev_priv(netdev);
Y
Yinglin Luan 已提交
2413 2414
	struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;

A
Amit S. Kale 已提交
2415
	disable_irq(adapter->irq);
Y
Yinglin Luan 已提交
2416 2417 2418 2419
	for (ring = 0; ring < adapter->max_sds_rings; ring++) {
		sds_ring = &recv_ctx->sds_rings[ring];
		netxen_intr(adapter->irq, sds_ring);
	}
A
Amit S. Kale 已提交
2420 2421 2422 2423
	enable_irq(adapter->irq);
}
#endif

2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441
static int
nx_incr_dev_ref_cnt(struct netxen_adapter *adapter)
{
	int count;
	if (netxen_api_lock(adapter))
		return -EIO;

	count = NXRD32(adapter, NX_CRB_DEV_REF_COUNT);

	NXWR32(adapter, NX_CRB_DEV_REF_COUNT, ++count);

	netxen_api_unlock(adapter);
	return count;
}

static int
nx_decr_dev_ref_cnt(struct netxen_adapter *adapter)
{
M
Manish chopra 已提交
2442
	int count, state;
2443 2444 2445 2446 2447 2448 2449
	if (netxen_api_lock(adapter))
		return -EIO;

	count = NXRD32(adapter, NX_CRB_DEV_REF_COUNT);
	WARN_ON(count == 0);

	NXWR32(adapter, NX_CRB_DEV_REF_COUNT, --count);
M
Manish chopra 已提交
2450
	state = NXRD32(adapter, NX_CRB_DEV_STATE);
2451

M
Manish chopra 已提交
2452
	if (count == 0 && state != NX_DEV_FAILED)
2453 2454 2455 2456 2457 2458
		NXWR32(adapter, NX_CRB_DEV_STATE, NX_DEV_COLD);

	netxen_api_unlock(adapter);
	return count;
}

2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480
static int
nx_dev_request_aer(struct netxen_adapter *adapter)
{
	u32 state;
	int ret = -EINVAL;

	if (netxen_api_lock(adapter))
		return ret;

	state = NXRD32(adapter, NX_CRB_DEV_STATE);

	if (state == NX_DEV_NEED_AER)
		ret = 0;
	else if (state == NX_DEV_READY) {
		NXWR32(adapter, NX_CRB_DEV_STATE, NX_DEV_NEED_AER);
		ret = 0;
	}

	netxen_api_unlock(adapter);
	return ret;
}

M
Manish chopra 已提交
2481
int
2482 2483 2484
nx_dev_request_reset(struct netxen_adapter *adapter)
{
	u32 state;
2485
	int ret = -EINVAL;
2486 2487

	if (netxen_api_lock(adapter))
2488
		return ret;
2489 2490 2491

	state = NXRD32(adapter, NX_CRB_DEV_STATE);

M
Manish chopra 已提交
2492
	if (state == NX_DEV_NEED_RESET || state == NX_DEV_FAILED)
2493 2494
		ret = 0;
	else if (state != NX_DEV_INITALIZING && state != NX_DEV_NEED_AER) {
2495
		NXWR32(adapter, NX_CRB_DEV_STATE, NX_DEV_NEED_RESET);
M
Manish chopra 已提交
2496
		adapter->flags |= NETXEN_FW_RESET_OWNER;
2497 2498
		ret = 0;
	}
2499 2500

	netxen_api_unlock(adapter);
2501 2502

	return ret;
2503 2504
}

2505 2506 2507 2508 2509 2510
static int
netxen_can_start_firmware(struct netxen_adapter *adapter)
{
	int count;
	int can_start = 0;

M
Manish chopra 已提交
2511 2512 2513 2514
	if (netxen_api_lock(adapter)) {
		nx_incr_dev_ref_cnt(adapter);
		return -1;
	}
2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568

	count = NXRD32(adapter, NX_CRB_DEV_REF_COUNT);

	if ((count < 0) || (count >= NX_MAX_PCI_FUNC))
		count = 0;

	if (count == 0) {
		can_start = 1;
		NXWR32(adapter, NX_CRB_DEV_STATE, NX_DEV_INITALIZING);
	}

	NXWR32(adapter, NX_CRB_DEV_REF_COUNT, ++count);

	netxen_api_unlock(adapter);

	return can_start;
}

static void
netxen_schedule_work(struct netxen_adapter *adapter,
		work_func_t func, int delay)
{
	INIT_DELAYED_WORK(&adapter->fw_work, func);
	schedule_delayed_work(&adapter->fw_work, delay);
}

static void
netxen_cancel_fw_work(struct netxen_adapter *adapter)
{
	while (test_and_set_bit(__NX_RESETTING, &adapter->state))
		msleep(10);

	cancel_delayed_work_sync(&adapter->fw_work);
}

static void
netxen_attach_work(struct work_struct *work)
{
	struct netxen_adapter *adapter = container_of(work,
				struct netxen_adapter, fw_work.work);
	struct net_device *netdev = adapter->netdev;
	int err = 0;

	if (netif_running(netdev)) {
		err = netxen_nic_attach(adapter);
		if (err)
			goto done;

		err = netxen_nic_up(adapter, netdev);
		if (err) {
			netxen_nic_detach(adapter);
			goto done;
		}

R
Rajesh Borundia 已提交
2569
		netxen_restore_indev_addr(netdev, NETDEV_UP);
2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585
	}

	netif_device_attach(netdev);

done:
	adapter->fw_fail_cnt = 0;
	clear_bit(__NX_RESETTING, &adapter->state);
	netxen_schedule_work(adapter, netxen_fw_poll_work, FW_POLL_DELAY);
}

static void
netxen_fwinit_work(struct work_struct *work)
{
	struct netxen_adapter *adapter = container_of(work,
				struct netxen_adapter, fw_work.work);
	int dev_state;
M
Manish chopra 已提交
2586
	int count;
2587
	dev_state = NXRD32(adapter, NX_CRB_DEV_STATE);
M
Manish chopra 已提交
2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610
	if (adapter->flags & NETXEN_FW_RESET_OWNER) {
		count = NXRD32(adapter, NX_CRB_DEV_REF_COUNT);
		WARN_ON(count == 0);
		if (count == 1) {
			if (adapter->mdump.md_enabled) {
				rtnl_lock();
				netxen_dump_fw(adapter);
				rtnl_unlock();
			}
			adapter->flags &= ~NETXEN_FW_RESET_OWNER;
			if (netxen_api_lock(adapter)) {
				clear_bit(__NX_RESETTING, &adapter->state);
				NXWR32(adapter, NX_CRB_DEV_STATE,
						NX_DEV_FAILED);
				return;
			}
			count = NXRD32(adapter, NX_CRB_DEV_REF_COUNT);
			NXWR32(adapter, NX_CRB_DEV_REF_COUNT, --count);
			NXWR32(adapter, NX_CRB_DEV_STATE, NX_DEV_COLD);
			dev_state = NX_DEV_COLD;
			netxen_api_unlock(adapter);
		}
	}
2611 2612 2613 2614

	switch (dev_state) {
	case NX_DEV_COLD:
	case NX_DEV_READY:
2615 2616 2617 2618 2619
		if (!netxen_start_firmware(adapter)) {
			netxen_schedule_work(adapter, netxen_attach_work, 0);
			return;
		}
		break;
2620

2621
	case NX_DEV_NEED_RESET:
2622 2623 2624 2625 2626 2627 2628
	case NX_DEV_INITALIZING:
			netxen_schedule_work(adapter,
					netxen_fwinit_work, 2 * FW_POLL_DELAY);
			return;

	case NX_DEV_FAILED:
	default:
2629
		nx_incr_dev_ref_cnt(adapter);
2630 2631 2632
		break;
	}

M
Manish chopra 已提交
2633 2634 2635 2636 2637 2638 2639 2640 2641
	if (netxen_api_lock(adapter)) {
		clear_bit(__NX_RESETTING, &adapter->state);
		return;
	}
	NXWR32(adapter, NX_CRB_DEV_STATE, NX_DEV_FAILED);
	netxen_api_unlock(adapter);
	dev_err(&adapter->pdev->dev, "%s: Device initialization Failed\n",
				adapter->netdev->name);

2642 2643 2644 2645 2646 2647 2648 2649 2650
	clear_bit(__NX_RESETTING, &adapter->state);
}

static void
netxen_detach_work(struct work_struct *work)
{
	struct netxen_adapter *adapter = container_of(work,
				struct netxen_adapter, fw_work.work);
	struct net_device *netdev = adapter->netdev;
M
Manish chopra 已提交
2651
	int ref_cnt = 0, delay;
2652 2653 2654 2655
	u32 status;

	netif_device_detach(netdev);

2656
	netxen_nic_down(adapter, netdev);
2657

2658
	rtnl_lock();
2659
	netxen_nic_detach(adapter);
2660
	rtnl_unlock();
2661 2662 2663 2664

	status = NXRD32(adapter, NETXEN_PEG_HALT_STATUS1);

	if (status & NX_RCODE_FATAL_ERROR)
2665
		goto err_ret;
2666 2667

	if (adapter->temp == NX_TEMP_PANIC)
2668 2669
		goto err_ret;

M
Manish chopra 已提交
2670 2671
	if (!(adapter->flags & NETXEN_FW_RESET_OWNER))
		ref_cnt = nx_decr_dev_ref_cnt(adapter);
2672

2673 2674 2675
	if (ref_cnt == -EIO)
		goto err_ret;

2676 2677 2678 2679
	delay = (ref_cnt == 0) ? 0 : (2 * FW_POLL_DELAY);

	adapter->fw_wait_cnt = 0;
	netxen_schedule_work(adapter, netxen_fwinit_work, delay);
2680 2681 2682 2683 2684

	return;

err_ret:
	clear_bit(__NX_RESETTING, &adapter->state);
2685 2686 2687 2688 2689 2690
}

static int
netxen_check_health(struct netxen_adapter *adapter)
{
	u32 state, heartbit;
2691
	u32 peg_status;
2692 2693
	struct net_device *netdev = adapter->netdev;

2694 2695 2696 2697
	state = NXRD32(adapter, NX_CRB_DEV_STATE);
	if (state == NX_DEV_NEED_AER)
		return 0;

2698 2699 2700
	if (netxen_nic_check_temp(adapter))
		goto detach;

2701
	if (adapter->need_fw_reset) {
2702 2703
		if (nx_dev_request_reset(adapter))
			return 0;
2704 2705 2706
		goto detach;
	}

2707 2708 2709 2710 2711
	/* NX_DEV_NEED_RESET, this state can be marked in two cases
	 * 1. Tx timeout 2. Fw hang
	 * Send request to destroy context in case of tx timeout only
	 * and doesn't required in case of Fw hang
	 */
M
Manish chopra 已提交
2712
	if (state == NX_DEV_NEED_RESET || state == NX_DEV_FAILED) {
2713
		adapter->need_fw_reset = 1;
2714 2715
		if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
			goto detach;
2716
	}
2717 2718 2719 2720 2721 2722 2723 2724

	if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
		return 0;

	heartbit = NXRD32(adapter, NETXEN_PEG_ALIVE_COUNTER);
	if (heartbit != adapter->heartbit) {
		adapter->heartbit = heartbit;
		adapter->fw_fail_cnt = 0;
2725 2726
		if (adapter->need_fw_reset)
			goto detach;
2727 2728 2729 2730 2731 2732
		return 0;
	}

	if (++adapter->fw_fail_cnt < FW_FAIL_THRESH)
		return 0;

2733 2734 2735
	if (nx_dev_request_reset(adapter))
		return 0;

2736 2737
	clear_bit(__NX_FW_ATTACHED, &adapter->state);

2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755
	dev_err(&netdev->dev, "firmware hang detected\n");
	peg_status = NXRD32(adapter, NETXEN_PEG_HALT_STATUS1);
	dev_err(&adapter->pdev->dev, "Dumping hw/fw registers\n"
			"PEG_HALT_STATUS1: 0x%x, PEG_HALT_STATUS2: 0x%x,\n"
			"PEG_NET_0_PC: 0x%x, PEG_NET_1_PC: 0x%x,\n"
			"PEG_NET_2_PC: 0x%x, PEG_NET_3_PC: 0x%x,\n"
			"PEG_NET_4_PC: 0x%x\n",
			peg_status,
			NXRD32(adapter, NETXEN_PEG_HALT_STATUS2),
			NXRD32(adapter, NETXEN_CRB_PEG_NET_0 + 0x3c),
			NXRD32(adapter, NETXEN_CRB_PEG_NET_1 + 0x3c),
			NXRD32(adapter, NETXEN_CRB_PEG_NET_2 + 0x3c),
			NXRD32(adapter, NETXEN_CRB_PEG_NET_3 + 0x3c),
			NXRD32(adapter, NETXEN_CRB_PEG_NET_4 + 0x3c));
	if (NX_FWERROR_PEGSTAT1(peg_status) == 0x67)
		dev_err(&adapter->pdev->dev,
			"Firmware aborted with error code 0x00006700. "
				"Device is being reset.\n");
2756
detach:
2757 2758
	if ((auto_fw_reset == AUTO_FW_RESET_ENABLED) &&
			!test_and_set_bit(__NX_RESETTING, &adapter->state))
2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771
		netxen_schedule_work(adapter, netxen_detach_work, 0);
	return 1;
}

static void
netxen_fw_poll_work(struct work_struct *work)
{
	struct netxen_adapter *adapter = container_of(work,
				struct netxen_adapter, fw_work.work);

	if (test_bit(__NX_RESETTING, &adapter->state))
		goto reschedule;

M
Manish Chopra 已提交
2772 2773
	if (test_bit(__NX_DEV_UP, &adapter->state) &&
	    !(adapter->capabilities & NX_FW_CAPABILITY_LINK_NOTIFICATION)) {
2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789
		if (!adapter->has_link_events) {

			netxen_nic_handle_phy_intr(adapter);

			if (adapter->link_changed)
				netxen_nic_set_link_parameters(adapter);
		}
	}

	if (netxen_check_health(adapter))
		return;

reschedule:
	netxen_schedule_work(adapter, netxen_fw_poll_work, FW_POLL_DELAY);
}

2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804
static ssize_t
netxen_store_bridged_mode(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t len)
{
	struct net_device *net = to_net_dev(dev);
	struct netxen_adapter *adapter = netdev_priv(net);
	unsigned long new;
	int ret = -EINVAL;

	if (!(adapter->capabilities & NX_FW_CAPABILITY_BDG))
		goto err_out;

	if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC)
		goto err_out;

2805
	if (kstrtoul(buf, 2, &new))
2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836
		goto err_out;

	if (!netxen_config_bridged_mode(adapter, !!new))
		ret = len;

err_out:
	return ret;
}

static ssize_t
netxen_show_bridged_mode(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	struct net_device *net = to_net_dev(dev);
	struct netxen_adapter *adapter;
	int bridged_mode = 0;

	adapter = netdev_priv(net);

	if (adapter->capabilities & NX_FW_CAPABILITY_BDG)
		bridged_mode = !!(adapter->flags & NETXEN_NIC_BRIDGE_ENABLED);

	return sprintf(buf, "%d\n", bridged_mode);
}

static struct device_attribute dev_attr_bridged_mode = {
       .attr = {.name = "bridged_mode", .mode = (S_IRUGO | S_IWUSR)},
       .show = netxen_show_bridged_mode,
       .store = netxen_store_bridged_mode,
};

2837 2838 2839 2840 2841 2842 2843
static ssize_t
netxen_store_diag_mode(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t len)
{
	struct netxen_adapter *adapter = dev_get_drvdata(dev);
	unsigned long new;

2844
	if (kstrtoul(buf, 2, &new))
2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872
		return -EINVAL;

	if (!!new != !!(adapter->flags & NETXEN_NIC_DIAG_ENABLED))
		adapter->flags ^= NETXEN_NIC_DIAG_ENABLED;

	return len;
}

static ssize_t
netxen_show_diag_mode(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	struct netxen_adapter *adapter = dev_get_drvdata(dev);

	return sprintf(buf, "%d\n",
			!!(adapter->flags & NETXEN_NIC_DIAG_ENABLED));
}

static struct device_attribute dev_attr_diag_mode = {
	.attr = {.name = "diag_mode", .mode = (S_IRUGO | S_IWUSR)},
	.show = netxen_show_diag_mode,
	.store = netxen_store_diag_mode,
};

static int
netxen_sysfs_validate_crb(struct netxen_adapter *adapter,
		loff_t offset, size_t size)
{
2873 2874
	size_t crb_size = 4;

2875 2876 2877
	if (!(adapter->flags & NETXEN_NIC_DIAG_ENABLED))
		return -EIO;

2878 2879 2880
	if (offset < NETXEN_PCI_CRBSPACE) {
		if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
			return -EINVAL;
2881

2882 2883 2884 2885 2886 2887 2888 2889 2890
		if (ADDR_IN_RANGE(offset, NETXEN_PCI_CAMQM,
						NETXEN_PCI_CAMQM_2M_END))
			crb_size = 8;
		else
			return -EINVAL;
	}

	if ((size != crb_size) || (offset & (crb_size-1)))
		return  -EINVAL;
2891 2892 2893 2894 2895

	return 0;
}

static ssize_t
2896 2897
netxen_sysfs_read_crb(struct file *filp, struct kobject *kobj,
		struct bin_attribute *attr,
2898 2899
		char *buf, loff_t offset, size_t size)
{
A
Amitoj Kaur Chawla 已提交
2900
	struct device *dev = kobj_to_dev(kobj);
2901 2902
	struct netxen_adapter *adapter = dev_get_drvdata(dev);
	u32 data;
2903
	u64 qmdata;
2904 2905 2906 2907 2908 2909
	int ret;

	ret = netxen_sysfs_validate_crb(adapter, offset, size);
	if (ret != 0)
		return ret;

2910 2911 2912 2913 2914 2915 2916 2917 2918 2919
	if (NX_IS_REVISION_P3(adapter->ahw.revision_id) &&
		ADDR_IN_RANGE(offset, NETXEN_PCI_CAMQM,
					NETXEN_PCI_CAMQM_2M_END)) {
		netxen_pci_camqm_read_2M(adapter, offset, &qmdata);
		memcpy(buf, &qmdata, size);
	} else {
		data = NXRD32(adapter, offset);
		memcpy(buf, &data, size);
	}

2920 2921 2922 2923
	return size;
}

static ssize_t
2924 2925
netxen_sysfs_write_crb(struct file *filp, struct kobject *kobj,
		struct bin_attribute *attr,
2926 2927
		char *buf, loff_t offset, size_t size)
{
A
Amitoj Kaur Chawla 已提交
2928
	struct device *dev = kobj_to_dev(kobj);
2929 2930
	struct netxen_adapter *adapter = dev_get_drvdata(dev);
	u32 data;
2931
	u64 qmdata;
2932 2933 2934 2935 2936 2937
	int ret;

	ret = netxen_sysfs_validate_crb(adapter, offset, size);
	if (ret != 0)
		return ret;

2938 2939 2940 2941 2942 2943 2944 2945 2946 2947
	if (NX_IS_REVISION_P3(adapter->ahw.revision_id) &&
		ADDR_IN_RANGE(offset, NETXEN_PCI_CAMQM,
					NETXEN_PCI_CAMQM_2M_END)) {
		memcpy(&qmdata, buf, size);
		netxen_pci_camqm_write_2M(adapter, offset, qmdata);
	} else {
		memcpy(&data, buf, size);
		NXWR32(adapter, offset, data);
	}

2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964
	return size;
}

static int
netxen_sysfs_validate_mem(struct netxen_adapter *adapter,
		loff_t offset, size_t size)
{
	if (!(adapter->flags & NETXEN_NIC_DIAG_ENABLED))
		return -EIO;

	if ((size != 8) || (offset & 0x7))
		return  -EIO;

	return 0;
}

static ssize_t
2965 2966
netxen_sysfs_read_mem(struct file *filp, struct kobject *kobj,
		struct bin_attribute *attr,
2967 2968
		char *buf, loff_t offset, size_t size)
{
A
Amitoj Kaur Chawla 已提交
2969
	struct device *dev = kobj_to_dev(kobj);
2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985
	struct netxen_adapter *adapter = dev_get_drvdata(dev);
	u64 data;
	int ret;

	ret = netxen_sysfs_validate_mem(adapter, offset, size);
	if (ret != 0)
		return ret;

	if (adapter->pci_mem_read(adapter, offset, &data))
		return -EIO;

	memcpy(buf, &data, size);

	return size;
}

2986
static ssize_t netxen_sysfs_write_mem(struct file *filp, struct kobject *kobj,
2987 2988 2989
		struct bin_attribute *attr, char *buf,
		loff_t offset, size_t size)
{
A
Amitoj Kaur Chawla 已提交
2990
	struct device *dev = kobj_to_dev(kobj);
2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007
	struct netxen_adapter *adapter = dev_get_drvdata(dev);
	u64 data;
	int ret;

	ret = netxen_sysfs_validate_mem(adapter, offset, size);
	if (ret != 0)
		return ret;

	memcpy(&data, buf, size);

	if (adapter->pci_mem_write(adapter, offset, data))
		return -EIO;

	return size;
}


3008
static const struct bin_attribute bin_attr_crb = {
3009 3010 3011 3012 3013 3014
	.attr = {.name = "crb", .mode = (S_IRUGO | S_IWUSR)},
	.size = 0,
	.read = netxen_sysfs_read_crb,
	.write = netxen_sysfs_write_crb,
};

3015
static const struct bin_attribute bin_attr_mem = {
3016 3017 3018 3019 3020 3021
	.attr = {.name = "mem", .mode = (S_IRUGO | S_IWUSR)},
	.size = 0,
	.read = netxen_sysfs_read_mem,
	.write = netxen_sysfs_write_mem,
};

3022 3023 3024 3025 3026
static ssize_t
netxen_sysfs_read_dimm(struct file *filp, struct kobject *kobj,
		struct bin_attribute *attr,
		char *buf, loff_t offset, size_t size)
{
A
Amitoj Kaur Chawla 已提交
3027
	struct device *dev = kobj_to_dev(kobj);
3028 3029 3030 3031 3032 3033
	struct netxen_adapter *adapter = dev_get_drvdata(dev);
	struct net_device *netdev = adapter->netdev;
	struct netxen_dimm_cfg dimm;
	u8 dw, rows, cols, banks, ranks;
	u32 val;

3034
	if (size < attr->size) {
3035
		netdev_err(netdev, "Invalid size\n");
3036
		return -EINVAL;
3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143
	}

	memset(&dimm, 0, sizeof(struct netxen_dimm_cfg));
	val = NXRD32(adapter, NETXEN_DIMM_CAPABILITY);

	/* Checks if DIMM info is valid. */
	if (val & NETXEN_DIMM_VALID_FLAG) {
		netdev_err(netdev, "Invalid DIMM flag\n");
		dimm.presence = 0xff;
		goto out;
	}

	rows = NETXEN_DIMM_NUMROWS(val);
	cols = NETXEN_DIMM_NUMCOLS(val);
	ranks = NETXEN_DIMM_NUMRANKS(val);
	banks = NETXEN_DIMM_NUMBANKS(val);
	dw = NETXEN_DIMM_DATAWIDTH(val);

	dimm.presence = (val & NETXEN_DIMM_PRESENT);

	/* Checks if DIMM info is present. */
	if (!dimm.presence) {
		netdev_err(netdev, "DIMM not present\n");
		goto out;
	}

	dimm.dimm_type = NETXEN_DIMM_TYPE(val);

	switch (dimm.dimm_type) {
	case NETXEN_DIMM_TYPE_RDIMM:
	case NETXEN_DIMM_TYPE_UDIMM:
	case NETXEN_DIMM_TYPE_SO_DIMM:
	case NETXEN_DIMM_TYPE_Micro_DIMM:
	case NETXEN_DIMM_TYPE_Mini_RDIMM:
	case NETXEN_DIMM_TYPE_Mini_UDIMM:
		break;
	default:
		netdev_err(netdev, "Invalid DIMM type %x\n", dimm.dimm_type);
		goto out;
	}

	if (val & NETXEN_DIMM_MEMTYPE_DDR2_SDRAM)
		dimm.mem_type = NETXEN_DIMM_MEM_DDR2_SDRAM;
	else
		dimm.mem_type = NETXEN_DIMM_MEMTYPE(val);

	if (val & NETXEN_DIMM_SIZE) {
		dimm.size = NETXEN_DIMM_STD_MEM_SIZE;
		goto out;
	}

	if (!rows) {
		netdev_err(netdev, "Invalid no of rows %x\n", rows);
		goto out;
	}

	if (!cols) {
		netdev_err(netdev, "Invalid no of columns %x\n", cols);
		goto out;
	}

	if (!banks) {
		netdev_err(netdev, "Invalid no of banks %x\n", banks);
		goto out;
	}

	ranks += 1;

	switch (dw) {
	case 0x0:
		dw = 32;
		break;
	case 0x1:
		dw = 33;
		break;
	case 0x2:
		dw = 36;
		break;
	case 0x3:
		dw = 64;
		break;
	case 0x4:
		dw = 72;
		break;
	case 0x5:
		dw = 80;
		break;
	case 0x6:
		dw = 128;
		break;
	case 0x7:
		dw = 144;
		break;
	default:
		netdev_err(netdev, "Invalid data-width %x\n", dw);
		goto out;
	}

	dimm.size = ((1 << rows) * (1 << cols) * dw * banks * ranks) / 8;
	/* Size returned in MB. */
	dimm.size = (dimm.size) / 0x100000;
out:
	memcpy(buf, &dimm, sizeof(struct netxen_dimm_cfg));
	return sizeof(struct netxen_dimm_cfg);

}

3144
static const struct bin_attribute bin_attr_dimm = {
3145
	.attr = { .name = "dimm", .mode = (S_IRUGO | S_IWUSR) },
3146
	.size = sizeof(struct netxen_dimm_cfg),
3147 3148 3149
	.read = netxen_sysfs_read_dimm,
};

3150

3151 3152 3153
static void
netxen_create_sysfs_entries(struct netxen_adapter *adapter)
{
3154
	struct device *dev = &adapter->pdev->dev;
3155 3156 3157 3158

	if (adapter->capabilities & NX_FW_CAPABILITY_BDG) {
		/* bridged_mode control */
		if (device_create_file(dev, &dev_attr_bridged_mode)) {
3159
			dev_warn(dev,
3160 3161 3162 3163 3164 3165 3166 3167
				"failed to create bridged_mode sysfs entry\n");
		}
	}
}

static void
netxen_remove_sysfs_entries(struct netxen_adapter *adapter)
{
3168
	struct device *dev = &adapter->pdev->dev;
3169 3170 3171 3172 3173

	if (adapter->capabilities & NX_FW_CAPABILITY_BDG)
		device_remove_file(dev, &dev_attr_bridged_mode);
}

3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186
static void
netxen_create_diag_entries(struct netxen_adapter *adapter)
{
	struct pci_dev *pdev = adapter->pdev;
	struct device *dev;

	dev = &pdev->dev;
	if (device_create_file(dev, &dev_attr_diag_mode))
		dev_info(dev, "failed to create diag_mode sysfs entry\n");
	if (device_create_bin_file(dev, &bin_attr_crb))
		dev_info(dev, "failed to create crb sysfs entry\n");
	if (device_create_bin_file(dev, &bin_attr_mem))
		dev_info(dev, "failed to create mem sysfs entry\n");
3187 3188
	if (device_create_bin_file(dev, &bin_attr_dimm))
		dev_info(dev, "failed to create dimm sysfs entry\n");
3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200
}


static void
netxen_remove_diag_entries(struct netxen_adapter *adapter)
{
	struct pci_dev *pdev = adapter->pdev;
	struct device *dev = &pdev->dev;

	device_remove_file(dev, &dev_attr_diag_mode);
	device_remove_bin_file(dev, &bin_attr_crb);
	device_remove_bin_file(dev, &bin_attr_mem);
3201
	device_remove_bin_file(dev, &bin_attr_dimm);
3202 3203
}

3204 3205
#ifdef CONFIG_INET

3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219
#define is_netxen_netdev(dev) (dev->netdev_ops == &netxen_netdev_ops)

static int
netxen_destip_supported(struct netxen_adapter *adapter)
{
	if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
		return 0;

	if (adapter->ahw.cut_through)
		return 0;

	return 1;
}

3220
static void
3221
netxen_free_ip_list(struct netxen_adapter *adapter, bool master)
R
Rajesh Borundia 已提交
3222
{
3223
	struct nx_ip_list  *cur, *tmp_cur;
R
Rajesh Borundia 已提交
3224

3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237
	list_for_each_entry_safe(cur, tmp_cur, &adapter->ip_list, list) {
		if (master) {
			if (cur->master) {
				netxen_config_ipaddr(adapter, cur->ip_addr,
						     NX_IP_DOWN);
				list_del(&cur->list);
				kfree(cur);
			}
		} else {
			netxen_config_ipaddr(adapter, cur->ip_addr, NX_IP_DOWN);
			list_del(&cur->list);
			kfree(cur);
		}
R
Rajesh Borundia 已提交
3238 3239
	}
}
3240 3241 3242

static bool
netxen_list_config_ip(struct netxen_adapter *adapter,
R
Rajesh Borundia 已提交
3243 3244 3245
		struct in_ifaddr *ifa, unsigned long event)
{
	struct net_device *dev;
3246
	struct nx_ip_list *cur, *tmp_cur;
R
Rajesh Borundia 已提交
3247
	struct list_head *head;
3248
	bool ret = false;
R
Rajesh Borundia 已提交
3249 3250 3251 3252

	dev = ifa->ifa_dev ? ifa->ifa_dev->dev : NULL;

	if (dev == NULL)
3253
		goto out;
R
Rajesh Borundia 已提交
3254 3255 3256

	switch (event) {
	case NX_IP_UP:
3257 3258
		list_for_each(head, &adapter->ip_list) {
			cur = list_entry(head, struct nx_ip_list, list);
R
Rajesh Borundia 已提交
3259 3260

			if (cur->ip_addr == ifa->ifa_address)
3261
				goto out;
R
Rajesh Borundia 已提交
3262 3263
		}

3264
		cur = kzalloc(sizeof(struct nx_ip_list), GFP_ATOMIC);
3265
		if (cur == NULL)
3266
			goto out;
3267
		if (is_vlan_dev(dev))
3268 3269
			dev = vlan_dev_real_dev(dev);
		cur->master = !!netif_is_bond_master(dev);
R
Rajesh Borundia 已提交
3270
		cur->ip_addr = ifa->ifa_address;
3271 3272 3273
		list_add_tail(&cur->list, &adapter->ip_list);
		netxen_config_ipaddr(adapter, ifa->ifa_address, NX_IP_UP);
		ret = true;
R
Rajesh Borundia 已提交
3274 3275 3276
		break;
	case NX_IP_DOWN:
		list_for_each_entry_safe(cur, tmp_cur,
3277
					&adapter->ip_list, list) {
R
Rajesh Borundia 已提交
3278 3279 3280
			if (cur->ip_addr == ifa->ifa_address) {
				list_del(&cur->list);
				kfree(cur);
3281 3282 3283
				netxen_config_ipaddr(adapter, ifa->ifa_address,
						     NX_IP_DOWN);
				ret = true;
R
Rajesh Borundia 已提交
3284 3285 3286 3287
				break;
			}
		}
	}
3288 3289
out:
	return ret;
R
Rajesh Borundia 已提交
3290
}
3291

R
Rajesh Borundia 已提交
3292 3293 3294
static void
netxen_config_indev_addr(struct netxen_adapter *adapter,
		struct net_device *dev, unsigned long event)
3295 3296 3297
{
	struct in_device *indev;

3298
	if (!netxen_destip_supported(adapter))
3299 3300 3301 3302 3303 3304 3305 3306 3307
		return;

	indev = in_dev_get(dev);
	if (!indev)
		return;

	for_ifa(indev) {
		switch (event) {
		case NETDEV_UP:
3308
			netxen_list_config_ip(adapter, ifa, NX_IP_UP);
3309 3310
			break;
		case NETDEV_DOWN:
3311
			netxen_list_config_ip(adapter, ifa, NX_IP_DOWN);
3312 3313 3314 3315 3316 3317 3318 3319 3320
			break;
		default:
			break;
		}
	} endfor_ifa(indev);

	in_dev_put(indev);
}

R
Rajesh Borundia 已提交
3321 3322 3323 3324 3325
static void
netxen_restore_indev_addr(struct net_device *netdev, unsigned long event)

{
	struct netxen_adapter *adapter = netdev_priv(netdev);
3326
	struct nx_ip_list *pos, *tmp_pos;
R
Rajesh Borundia 已提交
3327 3328 3329 3330 3331
	unsigned long ip_event;

	ip_event = (event == NETDEV_UP) ? NX_IP_UP : NX_IP_DOWN;
	netxen_config_indev_addr(adapter, netdev, event);

3332
	list_for_each_entry_safe(pos, tmp_pos, &adapter->ip_list, list) {
R
Rajesh Borundia 已提交
3333 3334 3335 3336
		netxen_config_ipaddr(adapter, pos->ip_addr, ip_event);
	}
}

3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376
static inline bool
netxen_config_checkdev(struct net_device *dev)
{
	struct netxen_adapter *adapter;

	if (!is_netxen_netdev(dev))
		return false;
	adapter = netdev_priv(dev);
	if (!adapter)
		return false;
	if (!netxen_destip_supported(adapter))
		return false;
	if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC)
		return false;

	return true;
}

/**
 * netxen_config_master - configure addresses based on master
 * @dev: netxen device
 * @event: netdev event
 */
static void netxen_config_master(struct net_device *dev, unsigned long event)
{
	struct net_device *master, *slave;
	struct netxen_adapter *adapter = netdev_priv(dev);

	rcu_read_lock();
	master = netdev_master_upper_dev_get_rcu(dev);
	/*
	 * This is the case where the netxen nic is being
	 * enslaved and is dev_open()ed in bond_enslave()
	 * Now we should program the bond's (and its vlans')
	 * addresses in the netxen NIC.
	 */
	if (master && netif_is_bond_master(master) &&
	    !netif_is_bond_slave(dev)) {
		netxen_config_indev_addr(adapter, master, event);
		for_each_netdev_rcu(&init_net, slave)
3377
			if (is_vlan_dev(slave) &&
3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390
			    vlan_dev_real_dev(slave) == master)
				netxen_config_indev_addr(adapter, slave, event);
	}
	rcu_read_unlock();
	/*
	 * This is the case where the netxen nic is being
	 * released and is dev_close()ed in bond_release()
	 * just before IFF_BONDING is stripped.
	 */
	if (!master && dev->priv_flags & IFF_BONDING)
		netxen_free_ip_list(adapter, true);
}

3391 3392 3393 3394
static int netxen_netdev_event(struct notifier_block *this,
				 unsigned long event, void *ptr)
{
	struct netxen_adapter *adapter;
3395
	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
R
Rajesh Borundia 已提交
3396
	struct net_device *orig_dev = dev;
3397
	struct net_device *slave;
3398 3399 3400 3401 3402

recheck:
	if (dev == NULL)
		goto done;

3403
	if (is_vlan_dev(dev)) {
3404 3405 3406
		dev = vlan_dev_real_dev(dev);
		goto recheck;
	}
3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428
	if (event == NETDEV_UP || event == NETDEV_DOWN) {
		/* If this is a bonding device, look for netxen-based slaves*/
		if (netif_is_bond_master(dev)) {
			rcu_read_lock();
			for_each_netdev_in_bond_rcu(dev, slave) {
				if (!netxen_config_checkdev(slave))
					continue;
				adapter = netdev_priv(slave);
				netxen_config_indev_addr(adapter,
							 orig_dev, event);
			}
			rcu_read_unlock();
		} else {
			if (!netxen_config_checkdev(dev))
				goto done;
			adapter = netdev_priv(dev);
			/* Act only if the actual netxen is the target */
			if (orig_dev == dev)
				netxen_config_master(dev, event);
			netxen_config_indev_addr(adapter, orig_dev, event);
		}
	}
3429 3430 3431 3432 3433 3434 3435 3436 3437
done:
	return NOTIFY_DONE;
}

static int
netxen_inetaddr_event(struct notifier_block *this,
		unsigned long event, void *ptr)
{
	struct netxen_adapter *adapter;
3438
	struct net_device *dev, *slave;
3439
	struct in_ifaddr *ifa = (struct in_ifaddr *)ptr;
3440
	unsigned long ip_event;
3441 3442

	dev = ifa->ifa_dev ? ifa->ifa_dev->dev : NULL;
3443
	ip_event = (event == NETDEV_UP) ? NX_IP_UP : NX_IP_DOWN;
3444
recheck:
R
Rajesh Borundia 已提交
3445
	if (dev == NULL)
3446 3447
		goto done;

3448
	if (is_vlan_dev(dev)) {
3449 3450 3451
		dev = vlan_dev_real_dev(dev);
		goto recheck;
	}
3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468
	if (event == NETDEV_UP || event == NETDEV_DOWN) {
		/* If this is a bonding device, look for netxen-based slaves*/
		if (netif_is_bond_master(dev)) {
			rcu_read_lock();
			for_each_netdev_in_bond_rcu(dev, slave) {
				if (!netxen_config_checkdev(slave))
					continue;
				adapter = netdev_priv(slave);
				netxen_list_config_ip(adapter, ifa, ip_event);
			}
			rcu_read_unlock();
		} else {
			if (!netxen_config_checkdev(dev))
				goto done;
			adapter = netdev_priv(dev);
			netxen_list_config_ip(adapter, ifa, ip_event);
		}
3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480
	}
done:
	return NOTIFY_DONE;
}

static struct notifier_block	netxen_netdev_cb = {
	.notifier_call = netxen_netdev_event,
};

static struct notifier_block netxen_inetaddr_cb = {
	.notifier_call = netxen_inetaddr_event,
};
R
Randy Dunlap 已提交
3481 3482
#else
static void
R
Rajesh Borundia 已提交
3483 3484 3485
netxen_restore_indev_addr(struct net_device *dev, unsigned long event)
{ }
static void
3486
netxen_free_ip_list(struct netxen_adapter *adapter, bool master)
R
Randy Dunlap 已提交
3487
{ }
3488
#endif
3489

3490
static const struct pci_error_handlers netxen_err_handler = {
3491 3492 3493 3494 3495
	.error_detected = netxen_io_error_detected,
	.slot_reset = netxen_io_slot_reset,
	.resume = netxen_io_resume,
};

A
Amit S. Kale 已提交
3496 3497 3498 3499
static struct pci_driver netxen_driver = {
	.name = netxen_nic_driver_name,
	.id_table = netxen_pci_tbl,
	.probe = netxen_nic_probe,
B
Bill Pemberton 已提交
3500
	.remove = netxen_nic_remove,
3501
#ifdef CONFIG_PM
3502
	.suspend = netxen_nic_suspend,
3503
	.resume = netxen_nic_resume,
3504
#endif
3505 3506
	.shutdown = netxen_nic_shutdown,
	.err_handler = &netxen_err_handler
A
Amit S. Kale 已提交
3507 3508 3509 3510
};

static int __init netxen_init_module(void)
{
3511 3512
	printk(KERN_INFO "%s\n", netxen_nic_driver_string);

3513
#ifdef CONFIG_INET
3514 3515
	register_netdevice_notifier(&netxen_netdev_cb);
	register_inetaddr_notifier(&netxen_inetaddr_cb);
3516
#endif
3517
	return pci_register_driver(&netxen_driver);
A
Amit S. Kale 已提交
3518 3519 3520 3521 3522 3523 3524
}

module_init(netxen_init_module);

static void __exit netxen_exit_module(void)
{
	pci_unregister_driver(&netxen_driver);
3525

3526
#ifdef CONFIG_INET
3527 3528
	unregister_inetaddr_notifier(&netxen_inetaddr_cb);
	unregister_netdevice_notifier(&netxen_netdev_cb);
3529
#endif
A
Amit S. Kale 已提交
3530 3531 3532
}

module_exit(netxen_exit_module);