netxen_nic_init.c 29.0 KB
Newer Older
A
Amit S. Kale 已提交
1
/*
D
Dhananjay Phadke 已提交
2
 * Copyright (C) 2003 - 2009 NetXen, Inc.
A
Amit S. Kale 已提交
3
 * All rights reserved.
4
 *
A
Amit S. Kale 已提交
5 6 7 8
 * 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.
9
 *
A
Amit S. Kale 已提交
10 11 12 13
 * 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.
14
 *
A
Amit S. Kale 已提交
15 16 17 18
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
 * MA  02111-1307, USA.
19
 *
A
Amit S. Kale 已提交
20 21
 * The full GNU General Public License is included in this distribution
 * in the file called LICENSE.
22
 *
A
Amit S. Kale 已提交
23 24
 * Contact Information:
 *    info@netxen.com
D
Dhananjay Phadke 已提交
25 26 27
 * NetXen Inc,
 * 18922 Forge Drive
 * Cupertino, CA 95014-0701
A
Amit S. Kale 已提交
28 29 30 31 32 33 34 35 36 37
 *
 */

#include <linux/netdevice.h>
#include <linux/delay.h>
#include "netxen_nic.h"
#include "netxen_nic_hw.h"
#include "netxen_nic_phan_reg.h"

struct crb_addr_pair {
38 39
	u32 addr;
	u32 data;
A
Amit S. Kale 已提交
40 41 42 43
};

#define NETXEN_MAX_CRB_XFORM 60
static unsigned int crb_addr_xform[NETXEN_MAX_CRB_XFORM];
44
#define NETXEN_ADDR_ERROR (0xffffffff)
A
Amit S. Kale 已提交
45 46 47 48 49

#define crb_addr_transform(name) \
	crb_addr_xform[NETXEN_HW_PX_MAP_CRB_##name] = \
	NETXEN_HW_CRB_HUB_AGT_ADR_##name << 20

50 51
#define NETXEN_NIC_XDMA_RESET 0x8000ff

52 53
static void
netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter, uint32_t ringid);
A
Adrian Bunk 已提交
54

A
Amit S. Kale 已提交
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
static void crb_addr_transform_setup(void)
{
	crb_addr_transform(XDMA);
	crb_addr_transform(TIMR);
	crb_addr_transform(SRE);
	crb_addr_transform(SQN3);
	crb_addr_transform(SQN2);
	crb_addr_transform(SQN1);
	crb_addr_transform(SQN0);
	crb_addr_transform(SQS3);
	crb_addr_transform(SQS2);
	crb_addr_transform(SQS1);
	crb_addr_transform(SQS0);
	crb_addr_transform(RPMX7);
	crb_addr_transform(RPMX6);
	crb_addr_transform(RPMX5);
	crb_addr_transform(RPMX4);
	crb_addr_transform(RPMX3);
	crb_addr_transform(RPMX2);
	crb_addr_transform(RPMX1);
	crb_addr_transform(RPMX0);
	crb_addr_transform(ROMUSB);
	crb_addr_transform(SN);
	crb_addr_transform(QMN);
	crb_addr_transform(QMS);
	crb_addr_transform(PGNI);
	crb_addr_transform(PGND);
	crb_addr_transform(PGN3);
	crb_addr_transform(PGN2);
	crb_addr_transform(PGN1);
	crb_addr_transform(PGN0);
	crb_addr_transform(PGSI);
	crb_addr_transform(PGSD);
	crb_addr_transform(PGS3);
	crb_addr_transform(PGS2);
	crb_addr_transform(PGS1);
	crb_addr_transform(PGS0);
	crb_addr_transform(PS);
	crb_addr_transform(PH);
	crb_addr_transform(NIU);
	crb_addr_transform(I2Q);
	crb_addr_transform(EG);
	crb_addr_transform(MN);
	crb_addr_transform(MS);
	crb_addr_transform(CAS2);
	crb_addr_transform(CAS1);
	crb_addr_transform(CAS0);
	crb_addr_transform(CAM);
	crb_addr_transform(C2C1);
	crb_addr_transform(C2C0);
105
	crb_addr_transform(SMB);
106 107
	crb_addr_transform(OCM0);
	crb_addr_transform(I2C0);
A
Amit S. Kale 已提交
108 109 110 111 112 113 114
}

int netxen_init_firmware(struct netxen_adapter *adapter)
{
	u32 state = 0, loops = 0, err = 0;

	/* Window 1 call */
115
	state = adapter->pci_read_normalize(adapter, CRB_CMDPEG_STATE);
A
Amit S. Kale 已提交
116 117 118 119 120

	if (state == PHAN_INITIALIZE_ACK)
		return 0;

	while (state != PHAN_INITIALIZE_COMPLETE && loops < 2000) {
121
		msleep(1);
A
Amit S. Kale 已提交
122
		/* Window 1 call */
123
		state = adapter->pci_read_normalize(adapter, CRB_CMDPEG_STATE);
A
Amit S. Kale 已提交
124 125 126 127 128 129 130 131 132 133

		loops++;
	}
	if (loops >= 2000) {
		printk(KERN_ERR "Cmd Peg initialization not complete:%x.\n",
		       state);
		err = -EIO;
		return err;
	}
	/* Window 1 call */
134 135 136 137 138 139 140 141
	adapter->pci_write_normalize(adapter,
			CRB_NIC_CAPABILITIES_HOST, INTR_SCHEME_PERPORT);
	adapter->pci_write_normalize(adapter,
			CRB_NIC_MSI_MODE_HOST, MSI_MODE_MULTIFUNC);
	adapter->pci_write_normalize(adapter,
			CRB_MPORT_MODE, MPORT_MULTI_FUNCTION_MODE);
	adapter->pci_write_normalize(adapter,
			CRB_CMDPEG_STATE, PHAN_INITIALIZE_ACK);
A
Amit S. Kale 已提交
142 143 144 145

	return err;
}

146
void netxen_release_rx_buffers(struct netxen_adapter *adapter)
A
Amit S. Kale 已提交
147
{
148
	struct netxen_recv_context *recv_ctx;
D
Dhananjay Phadke 已提交
149
	struct nx_host_rds_ring *rds_ring;
150
	struct netxen_rx_buffer *rx_buf;
151 152 153 154 155
	int i, ring;

	recv_ctx = &adapter->recv_ctx;
	for (ring = 0; ring < adapter->max_rds_rings; ring++) {
		rds_ring = &recv_ctx->rds_rings[ring];
156
		for (i = 0; i < rds_ring->num_desc; ++i) {
157 158 159 160 161 162 163 164 165
			rx_buf = &(rds_ring->rx_buf_arr[i]);
			if (rx_buf->state == NETXEN_BUFFER_FREE)
				continue;
			pci_unmap_single(adapter->pdev,
					rx_buf->dma,
					rds_ring->dma_size,
					PCI_DMA_FROMDEVICE);
			if (rx_buf->skb != NULL)
				dev_kfree_skb_any(rx_buf->skb);
166 167 168 169 170 171 172 173 174 175 176
		}
	}
}

void netxen_release_tx_buffers(struct netxen_adapter *adapter)
{
	struct netxen_cmd_buffer *cmd_buf;
	struct netxen_skb_frag *buffrag;
	int i, j;

	cmd_buf = adapter->cmd_buf_arr;
177
	for (i = 0; i < adapter->num_txd; i++) {
178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203
		buffrag = cmd_buf->frag_array;
		if (buffrag->dma) {
			pci_unmap_single(adapter->pdev, buffrag->dma,
					 buffrag->length, PCI_DMA_TODEVICE);
			buffrag->dma = 0ULL;
		}
		for (j = 0; j < cmd_buf->frag_count; j++) {
			buffrag++;
			if (buffrag->dma) {
				pci_unmap_page(adapter->pdev, buffrag->dma,
					       buffrag->length,
					       PCI_DMA_TODEVICE);
				buffrag->dma = 0ULL;
			}
		}
		if (cmd_buf->skb) {
			dev_kfree_skb_any(cmd_buf->skb);
			cmd_buf->skb = NULL;
		}
		cmd_buf++;
	}
}

void netxen_free_sw_resources(struct netxen_adapter *adapter)
{
	struct netxen_recv_context *recv_ctx;
D
Dhananjay Phadke 已提交
204
	struct nx_host_rds_ring *rds_ring;
205 206 207 208 209 210 211 212
	int ring;

	recv_ctx = &adapter->recv_ctx;
	for (ring = 0; ring < adapter->max_rds_rings; ring++) {
		rds_ring = &recv_ctx->rds_rings[ring];
		if (rds_ring->rx_buf_arr) {
			vfree(rds_ring->rx_buf_arr);
			rds_ring->rx_buf_arr = NULL;
213 214
		}
	}
215

216 217 218 219 220 221 222 223
	if (adapter->cmd_buf_arr)
		vfree(adapter->cmd_buf_arr);
	return;
}

int netxen_alloc_sw_resources(struct netxen_adapter *adapter)
{
	struct netxen_recv_context *recv_ctx;
D
Dhananjay Phadke 已提交
224
	struct nx_host_rds_ring *rds_ring;
225
	struct netxen_rx_buffer *rx_buf;
226
	int ring, i, num_rx_bufs;
227 228 229 230 231 232 233 234 235 236 237 238 239

	struct netxen_cmd_buffer *cmd_buf_arr;
	struct net_device *netdev = adapter->netdev;

	cmd_buf_arr = (struct netxen_cmd_buffer *)vmalloc(TX_RINGSIZE);
	if (cmd_buf_arr == NULL) {
		printk(KERN_ERR "%s: Failed to allocate cmd buffer ring\n",
		       netdev->name);
		return -ENOMEM;
	}
	memset(cmd_buf_arr, 0, TX_RINGSIZE);
	adapter->cmd_buf_arr = cmd_buf_arr;

240 241 242
	recv_ctx = &adapter->recv_ctx;
	for (ring = 0; ring < adapter->max_rds_rings; ring++) {
		rds_ring = &recv_ctx->rds_rings[ring];
243 244 245
		switch (ring) {
		case RCV_RING_NORMAL:
			rds_ring->num_desc = adapter->num_rxd;
246 247 248
			if (adapter->ahw.cut_through) {
				rds_ring->dma_size =
					NX_CT_DEFAULT_RX_BUF_LEN;
D
Dhananjay Phadke 已提交
249
				rds_ring->skb_size =
250 251 252 253 254 255 256
					NX_CT_DEFAULT_RX_BUF_LEN;
			} else {
				rds_ring->dma_size = RX_DMA_MAP_LEN;
				rds_ring->skb_size =
					MAX_RX_BUFFER_LENGTH;
			}
			break;
257

258 259
		case RCV_RING_JUMBO:
			rds_ring->num_desc = adapter->num_jumbo_rxd;
260 261 262 263 264 265 266 267 268
			if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
				rds_ring->dma_size =
					NX_P3_RX_JUMBO_BUF_MAX_LEN;
			else
				rds_ring->dma_size =
					NX_P2_RX_JUMBO_BUF_MAX_LEN;
			rds_ring->skb_size =
				rds_ring->dma_size + NET_IP_ALIGN;
			break;
269

270
		case RCV_RING_LRO:
271
			rds_ring->num_desc = adapter->num_lro_rxd;
272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291
			rds_ring->dma_size = RX_LRO_DMA_MAP_LEN;
			rds_ring->skb_size = MAX_RX_LRO_BUFFER_LENGTH;
			break;

		}
		rds_ring->rx_buf_arr = (struct netxen_rx_buffer *)
			vmalloc(RCV_BUFFSIZE);
		if (rds_ring->rx_buf_arr == NULL) {
			printk(KERN_ERR "%s: Failed to allocate "
				"rx buffer ring %d\n",
				netdev->name, ring);
			/* free whatever was already allocated */
			goto err_out;
		}
		memset(rds_ring->rx_buf_arr, 0, RCV_BUFFSIZE);
		INIT_LIST_HEAD(&rds_ring->free_list);
		/*
		 * Now go through all of them, set reference handles
		 * and put them in the queues.
		 */
292
		num_rx_bufs = rds_ring->num_desc;
293 294 295 296 297 298 299
		rx_buf = rds_ring->rx_buf_arr;
		for (i = 0; i < num_rx_bufs; i++) {
			list_add_tail(&rx_buf->list,
					&rds_ring->free_list);
			rx_buf->ref_handle = i;
			rx_buf->state = NETXEN_BUFFER_FREE;
			rx_buf++;
A
Amit S. Kale 已提交
300 301
		}
	}
302 303 304 305 306 307

	return 0;

err_out:
	netxen_free_sw_resources(adapter);
	return -ENOMEM;
A
Amit S. Kale 已提交
308 309 310 311
}

void netxen_initialize_adapter_ops(struct netxen_adapter *adapter)
{
312
	switch (adapter->ahw.port_type) {
A
Amit S. Kale 已提交
313
	case NETXEN_NIC_GBE:
314
		adapter->enable_phy_interrupts =
A
Amit S. Kale 已提交
315
		    netxen_niu_gbe_enable_phy_interrupts;
316
		adapter->disable_phy_interrupts =
A
Amit S. Kale 已提交
317
		    netxen_niu_gbe_disable_phy_interrupts;
318 319 320 321 322
		adapter->macaddr_set = netxen_niu_macaddr_set;
		adapter->set_mtu = netxen_nic_set_mtu_gb;
		adapter->set_promisc = netxen_niu_set_promiscuous_mode;
		adapter->phy_read = netxen_niu_gbe_phy_read;
		adapter->phy_write = netxen_niu_gbe_phy_write;
323
		adapter->init_port = netxen_niu_gbe_init_port;
324
		adapter->stop_port = netxen_niu_disable_gbe_port;
A
Amit S. Kale 已提交
325 326 327
		break;

	case NETXEN_NIC_XGBE:
328
		adapter->enable_phy_interrupts =
A
Amit S. Kale 已提交
329
		    netxen_niu_xgbe_enable_phy_interrupts;
330
		adapter->disable_phy_interrupts =
A
Amit S. Kale 已提交
331
		    netxen_niu_xgbe_disable_phy_interrupts;
332 333 334 335 336
		adapter->macaddr_set = netxen_niu_xg_macaddr_set;
		adapter->set_mtu = netxen_nic_set_mtu_xgb;
		adapter->init_port = netxen_niu_xg_init_port;
		adapter->set_promisc = netxen_niu_xg_set_promiscuous_mode;
		adapter->stop_port = netxen_niu_disable_xg_port;
A
Amit S. Kale 已提交
337 338 339 340 341
		break;

	default:
		break;
	}
342 343 344 345 346

	if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
		adapter->set_mtu = nx_fw_cmd_set_mtu;
		adapter->set_promisc = netxen_p3_nic_set_promisc;
	}
A
Amit S. Kale 已提交
347 348 349 350 351 352
}

/*
 * netxen_decode_crb_addr(0 - utility to translate from internal Phantom CRB
 * address to external PCI CRB address.
 */
A
Adrian Bunk 已提交
353
static u32 netxen_decode_crb_addr(u32 addr)
A
Amit S. Kale 已提交
354 355
{
	int i;
356
	u32 base_addr, offset, pci_base;
A
Amit S. Kale 已提交
357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375

	crb_addr_transform_setup();

	pci_base = NETXEN_ADDR_ERROR;
	base_addr = addr & 0xfff00000;
	offset = addr & 0x000fffff;

	for (i = 0; i < NETXEN_MAX_CRB_XFORM; i++) {
		if (crb_addr_xform[i] == base_addr) {
			pci_base = i << 20;
			break;
		}
	}
	if (pci_base == NETXEN_ADDR_ERROR)
		return pci_base;
	else
		return (pci_base + offset);
}

376 377
static long rom_max_timeout = 100;
static long rom_lock_timeout = 10000;
A
Amit S. Kale 已提交
378

A
Adrian Bunk 已提交
379
static int rom_lock(struct netxen_adapter *adapter)
A
Amit S. Kale 已提交
380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408
{
	int iter;
	u32 done = 0;
	int timeout = 0;

	while (!done) {
		/* acquire semaphore2 from PCI HW block */
		netxen_nic_read_w0(adapter, NETXEN_PCIE_REG(PCIE_SEM2_LOCK),
				   &done);
		if (done == 1)
			break;
		if (timeout >= rom_lock_timeout)
			return -EIO;

		timeout++;
		/*
		 * Yield CPU
		 */
		if (!in_atomic())
			schedule();
		else {
			for (iter = 0; iter < 20; iter++)
				cpu_relax();	/*This a nop instr on i386 */
		}
	}
	netxen_nic_reg_write(adapter, NETXEN_ROM_LOCK_ID, ROM_LOCK_DRIVER);
	return 0;
}

A
Adrian Bunk 已提交
409
static int netxen_wait_rom_done(struct netxen_adapter *adapter)
A
Amit S. Kale 已提交
410 411 412 413
{
	long timeout = 0;
	long done = 0;

D
Dhananjay Phadke 已提交
414 415
	cond_resched();

A
Amit S. Kale 已提交
416 417 418 419 420 421 422 423 424 425 426 427
	while (done == 0) {
		done = netxen_nic_reg_read(adapter, NETXEN_ROMUSB_GLB_STATUS);
		done &= 2;
		timeout++;
		if (timeout >= rom_max_timeout) {
			printk("Timeout reached  waiting for rom done");
			return -EIO;
		}
	}
	return 0;
}

A
Adrian Bunk 已提交
428
static void netxen_rom_unlock(struct netxen_adapter *adapter)
429 430 431 432 433 434 435 436
{
	u32 val;

	/* release semaphore2 */
	netxen_nic_read_w0(adapter, NETXEN_PCIE_REG(PCIE_SEM2_UNLOCK), &val);

}

A
Adrian Bunk 已提交
437 438
static int do_rom_fast_read(struct netxen_adapter *adapter,
			    int addr, int *valp)
A
Amit S. Kale 已提交
439 440 441
{
	netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ADDRESS, addr);
	netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
D
Dhananjay Phadke 已提交
442
	netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 3);
A
Amit S. Kale 已提交
443 444 445 446 447 448 449
	netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_INSTR_OPCODE, 0xb);
	if (netxen_wait_rom_done(adapter)) {
		printk("Error waiting for rom done\n");
		return -EIO;
	}
	/* reset abyte_cnt and dummy_byte_cnt */
	netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 0);
D
Dhananjay Phadke 已提交
450
	udelay(10);
A
Amit S. Kale 已提交
451 452 453 454 455 456
	netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);

	*valp = netxen_nic_reg_read(adapter, NETXEN_ROMUSB_ROM_RDATA);
	return 0;
}

A
Adrian Bunk 已提交
457 458
static int do_rom_fast_read_words(struct netxen_adapter *adapter, int addr,
				  u8 *bytes, size_t size)
459 460 461 462 463
{
	int addridx;
	int ret = 0;

	for (addridx = addr; addridx < (addr + size); addridx += 4) {
A
Al Viro 已提交
464 465
		int v;
		ret = do_rom_fast_read(adapter, addridx, &v);
466 467
		if (ret != 0)
			break;
A
Al Viro 已提交
468
		*(__le32 *)bytes = cpu_to_le32(v);
469 470 471 472 473 474 475
		bytes += 4;
	}

	return ret;
}

int
476
netxen_rom_fast_read_words(struct netxen_adapter *adapter, int addr,
477 478 479 480 481 482 483 484 485 486 487 488 489 490
				u8 *bytes, size_t size)
{
	int ret;

	ret = rom_lock(adapter);
	if (ret < 0)
		return ret;

	ret = do_rom_fast_read_words(adapter, addr, bytes, size);

	netxen_rom_unlock(adapter);
	return ret;
}

A
Amit S. Kale 已提交
491 492 493 494 495 496 497 498
int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp)
{
	int ret;

	if (rom_lock(adapter) != 0)
		return -EIO;

	ret = do_rom_fast_read(adapter, addr, valp);
499 500 501 502
	netxen_rom_unlock(adapter);
	return ret;
}

A
Amit S. Kale 已提交
503 504 505 506 507 508
#define NETXEN_BOARDTYPE		0x4008
#define NETXEN_BOARDNUM 		0x400c
#define NETXEN_CHIPNUM			0x4010

int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose)
{
509
	int addr, val;
D
Dhananjay Phadke 已提交
510
	int i, n, init_delay = 0;
A
Amit S. Kale 已提交
511
	struct crb_addr_pair *buf;
D
Dhananjay Phadke 已提交
512
	unsigned offset;
513
	u32 off;
A
Amit S. Kale 已提交
514 515

	/* resetall */
D
Dhananjay Phadke 已提交
516
	rom_lock(adapter);
A
Amit S. Kale 已提交
517
	netxen_crb_writelit_adapter(adapter, NETXEN_ROMUSB_GLB_SW_RESET,
518
				    0xffffffff);
D
Dhananjay Phadke 已提交
519
	netxen_rom_unlock(adapter);
A
Amit S. Kale 已提交
520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535

	if (verbose) {
		if (netxen_rom_fast_read(adapter, NETXEN_BOARDTYPE, &val) == 0)
			printk("P2 ROM board type: 0x%08x\n", val);
		else
			printk("Could not read board type\n");
		if (netxen_rom_fast_read(adapter, NETXEN_BOARDNUM, &val) == 0)
			printk("P2 ROM board  num: 0x%08x\n", val);
		else
			printk("Could not read board number\n");
		if (netxen_rom_fast_read(adapter, NETXEN_CHIPNUM, &val) == 0)
			printk("P2 ROM chip   num: 0x%08x\n", val);
		else
			printk("Could not read chip number\n");
	}

536 537
	if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
		if (netxen_rom_fast_read(adapter, 0, &n) != 0 ||
D
Dhananjay Phadke 已提交
538
			(n != 0xcafecafe) ||
539 540 541
			netxen_rom_fast_read(adapter, 4, &n) != 0) {
			printk(KERN_ERR "%s: ERROR Reading crb_init area: "
					"n: %08x\n", netxen_nic_driver_name, n);
A
Amit S. Kale 已提交
542 543
			return -EIO;
		}
544 545 546 547 548 549 550 551
		offset = n & 0xffffU;
		n = (n >> 16) & 0xffffU;
	} else {
		if (netxen_rom_fast_read(adapter, 0, &n) != 0 ||
			!(n & 0x80000000)) {
			printk(KERN_ERR "%s: ERROR Reading crb_init area: "
					"n: %08x\n", netxen_nic_driver_name, n);
			return -EIO;
A
Amit S. Kale 已提交
552
		}
553 554 555 556 557 558 559 560 561 562 563 564 565
		offset = 1;
		n &= ~0x80000000;
	}

	if (n < 1024) {
		if (verbose)
			printk(KERN_DEBUG "%s: %d CRB init values found"
			       " in ROM.\n", netxen_nic_driver_name, n);
	} else {
		printk(KERN_ERR "%s:n=0x%x Error! NetXen card flash not"
		       " initialized.\n", __func__, n);
		return -EIO;
	}
A
Amit S. Kale 已提交
566

567 568 569 570 571 572 573 574
	buf = kcalloc(n, sizeof(struct crb_addr_pair), GFP_KERNEL);
	if (buf == NULL) {
		printk("%s: netxen_pinit_from_rom: Unable to calloc memory.\n",
				netxen_nic_driver_name);
		return -ENOMEM;
	}
	for (i = 0; i < n; i++) {
		if (netxen_rom_fast_read(adapter, 8*i + 4*offset, &val) != 0 ||
575 576
		netxen_rom_fast_read(adapter, 8*i + 4*offset + 4, &addr) != 0) {
			kfree(buf);
577
			return -EIO;
578
		}
579 580 581 582 583 584 585 586 587 588 589 590 591 592

		buf[i].addr = addr;
		buf[i].data = val;

		if (verbose)
			printk(KERN_DEBUG "%s: PCI:     0x%08x == 0x%08x\n",
				netxen_nic_driver_name,
				(u32)netxen_decode_crb_addr(addr), val);
	}
	for (i = 0; i < n; i++) {

		off = netxen_decode_crb_addr(buf[i].addr);
		if (off == NETXEN_ADDR_ERROR) {
			printk(KERN_ERR"CRB init value out of range %x\n",
593
					buf[i].addr);
594 595 596 597 598 599 600 601 602 603
			continue;
		}
		off += NETXEN_PCI_CRBSPACE;
		/* skipping cold reboot MAGIC */
		if (off == NETXEN_CAM_RAM(0x1fc))
			continue;

		if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
			/* do not reset PCI */
			if (off == (ROMUSB_GLB + 0xbc))
604
				continue;
D
Dhananjay Phadke 已提交
605 606 607 608 609 610 611 612
			if (off == (ROMUSB_GLB + 0xa8))
				continue;
			if (off == (ROMUSB_GLB + 0xc8)) /* core clock */
				continue;
			if (off == (ROMUSB_GLB + 0x24)) /* MN clock */
				continue;
			if (off == (ROMUSB_GLB + 0x1c)) /* MS clock */
				continue;
613 614 615 616
			if (off == (NETXEN_CRB_PEG_NET_1 + 0x18))
				buf[i].data = 0x1020;
			/* skip the function enable register */
			if (off == NETXEN_PCIE_REG(PCIE_SETUP_FUNCTION))
A
Amit S. Kale 已提交
617
				continue;
618 619 620 621 622
			if (off == NETXEN_PCIE_REG(PCIE_SETUP_FUNCTION2))
				continue;
			if ((off & 0x0ff00000) == NETXEN_CRB_SMB)
				continue;
		}
A
Amit S. Kale 已提交
623

624 625 626 627 628 629
		if (off == NETXEN_ADDR_ERROR) {
			printk(KERN_ERR "%s: Err: Unknown addr: 0x%08x\n",
					netxen_nic_driver_name, buf[i].addr);
			continue;
		}

D
Dhananjay Phadke 已提交
630
		init_delay = 1;
631 632 633
		/* After writing this register, HW needs time for CRB */
		/* to quiet down (else crb_window returns 0xffffffff) */
		if (off == NETXEN_ROMUSB_GLB_SW_RESET) {
D
Dhananjay Phadke 已提交
634
			init_delay = 1000;
635
			if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
A
Amit S. Kale 已提交
636
				/* hold xdma in reset also */
637
				buf[i].data = NETXEN_NIC_XDMA_RESET;
D
Dhananjay Phadke 已提交
638
				buf[i].data = 0x8000ff;
A
Amit S. Kale 已提交
639
			}
640
		}
A
Amit S. Kale 已提交
641

642
		adapter->hw_write_wx(adapter, off, &buf[i].data, 4);
A
Amit S. Kale 已提交
643

D
Dhananjay Phadke 已提交
644
		msleep(init_delay);
645 646
	}
	kfree(buf);
A
Amit S. Kale 已提交
647

648
	/* disable_peg_cache_all */
A
Amit S. Kale 已提交
649

650 651 652 653
	/* unreset_net_cache */
	if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
		adapter->hw_read_wx(adapter,
				NETXEN_ROMUSB_GLB_SW_RESET, &val, 4);
A
Amit S. Kale 已提交
654
		netxen_crb_writelit_adapter(adapter,
655
				NETXEN_ROMUSB_GLB_SW_RESET, (val & 0xffffff0f));
A
Amit S. Kale 已提交
656
	}
657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678

	/* p2dn replyCount */
	netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_D + 0xec, 0x1e);
	/* disable_peg_cache 0 */
	netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_D + 0x4c, 8);
	/* disable_peg_cache 1 */
	netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_I + 0x4c, 8);

	/* peg_clr_all */

	/* peg_clr 0 */
	netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_0 + 0x8, 0);
	netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_0 + 0xc, 0);
	/* peg_clr 1 */
	netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_1 + 0x8, 0);
	netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_1 + 0xc, 0);
	/* peg_clr 2 */
	netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_2 + 0x8, 0);
	netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_2 + 0xc, 0);
	/* peg_clr 3 */
	netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_3 + 0x8, 0);
	netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_3 + 0xc, 0);
A
Amit S. Kale 已提交
679 680 681
	return 0;
}

682 683 684 685 686 687 688
int netxen_initialize_adapter_offload(struct netxen_adapter *adapter)
{
	uint64_t addr;
	uint32_t hi;
	uint32_t lo;

	adapter->dummy_dma.addr =
689
	    pci_alloc_consistent(adapter->pdev,
690 691 692 693
				 NETXEN_HOST_DUMMY_DMA_SIZE,
				 &adapter->dummy_dma.phys_addr);
	if (adapter->dummy_dma.addr == NULL) {
		printk("%s: ERROR: Could not allocate dummy DMA memory\n",
694
		       __func__);
695 696 697 698 699 700 701
		return -ENOMEM;
	}

	addr = (uint64_t) adapter->dummy_dma.phys_addr;
	hi = (addr >> 32) & 0xffffffff;
	lo = addr & 0xffffffff;

702 703
	adapter->pci_write_normalize(adapter, CRB_HOST_DUMMY_BUF_ADDR_HI, hi);
	adapter->pci_write_normalize(adapter, CRB_HOST_DUMMY_BUF_ADDR_LO, lo);
704

705 706 707 708 709
	if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
		uint32_t temp = 0;
		adapter->hw_write_wx(adapter, CRB_HOST_DUMMY_BUF, &temp, 4);
	}

710 711 712 713 714
	return 0;
}

void netxen_free_adapter_offload(struct netxen_adapter *adapter)
{
D
Dhananjay Phadke 已提交
715 716 717 718
	int i = 100;

	if (!adapter->dummy_dma.addr)
		return;
719

D
Dhananjay Phadke 已提交
720
	if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
721 722 723 724 725 726 727
		do {
			if (dma_watchdog_shutdown_request(adapter) == 1)
				break;
			msleep(50);
			if (dma_watchdog_shutdown_poll_result(adapter) == 1)
				break;
		} while (--i);
D
Dhananjay Phadke 已提交
728
	}
729

D
Dhananjay Phadke 已提交
730 731 732 733 734 735 736 737 738
	if (i) {
		pci_free_consistent(adapter->pdev,
			    NETXEN_HOST_DUMMY_DMA_SIZE,
			    adapter->dummy_dma.addr,
			    adapter->dummy_dma.phys_addr);
		adapter->dummy_dma.addr = NULL;
	} else {
		printk(KERN_ERR "%s: dma_watchdog_shutdown failed\n",
				adapter->netdev->name);
739 740 741
	}
}

742
int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val)
A
Amit S. Kale 已提交
743 744
{
	u32 val = 0;
745
	int retries = 60;
A
Amit S. Kale 已提交
746

747
	if (!pegtune_val) {
748
		do {
749 750
			val = adapter->pci_read_normalize(adapter,
					CRB_CMDPEG_STATE);
751 752 753 754 755

			if (val == PHAN_INITIALIZE_COMPLETE ||
				val == PHAN_INITIALIZE_ACK)
				return 0;

756 757
			msleep(500);

758
		} while (--retries);
759

760
		if (!retries) {
761 762
			pegtune_val = adapter->pci_read_normalize(adapter,
					NETXEN_ROMUSB_GLB_PEGTUNE_DONE);
763 764 765
			printk(KERN_WARNING "netxen_phantom_init: init failed, "
					"pegtune_val=%x\n", pegtune_val);
			return -1;
A
Amit S. Kale 已提交
766 767
		}
	}
768 769

	return 0;
A
Amit S. Kale 已提交
770 771
}

772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795
int netxen_receive_peg_ready(struct netxen_adapter *adapter)
{
	u32 val = 0;
	int retries = 2000;

	do {
		val = adapter->pci_read_normalize(adapter, CRB_RCVPEG_STATE);

		if (val == PHAN_PEG_RCV_INITIALIZED)
			return 0;

		msleep(10);

	} while (--retries);

	if (!retries) {
		printk(KERN_ERR "Receive Peg initialization not "
			      "complete, state: 0x%x.\n", val);
		return -EIO;
	}

	return 0;
}

796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828
static struct sk_buff *netxen_process_rxbuf(struct netxen_adapter *adapter,
		struct nx_host_rds_ring *rds_ring, u16 index, u16 cksum)
{
	struct netxen_rx_buffer *buffer;
	struct sk_buff *skb;

	buffer = &rds_ring->rx_buf_arr[index];

	pci_unmap_single(adapter->pdev, buffer->dma, rds_ring->dma_size,
			PCI_DMA_FROMDEVICE);

	skb = buffer->skb;
	if (!skb)
		goto no_skb;

	if (likely(adapter->rx_csum && cksum == STATUS_CKSUM_OK)) {
		adapter->stats.csummed++;
		skb->ip_summed = CHECKSUM_UNNECESSARY;
	} else
		skb->ip_summed = CHECKSUM_NONE;

	skb->dev = adapter->netdev;

	buffer->skb = NULL;

no_skb:
	buffer->state = NETXEN_BUFFER_FREE;
	buffer->lro_current_frags = 0;
	buffer->lro_expected_frags = 0;
	list_add_tail(&buffer->list, &rds_ring->free_list);
	return skb;
}

829
static void netxen_process_rcv(struct netxen_adapter *adapter,
D
Dhananjay Phadke 已提交
830
		struct status_desc *desc)
A
Amit S. Kale 已提交
831
{
832
	struct net_device *netdev = adapter->netdev;
833 834
	u64 sts_data = le64_to_cpu(desc->status_desc_data);
	int index = netxen_get_sts_refhandle(sts_data);
835
	struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
A
Amit S. Kale 已提交
836 837
	struct netxen_rx_buffer *buffer;
	struct sk_buff *skb;
838
	u32 length = netxen_get_sts_totallength(sts_data);
A
Amit S. Kale 已提交
839
	u32 desc_ctx;
840
	u16 pkt_offset = 0, cksum;
D
Dhananjay Phadke 已提交
841
	struct nx_host_rds_ring *rds_ring;
A
Amit S. Kale 已提交
842

843
	desc_ctx = netxen_get_sts_type(sts_data);
844
	if (unlikely(desc_ctx >= adapter->max_rds_rings))
A
Amit S. Kale 已提交
845 846
		return;

D
Dhananjay Phadke 已提交
847
	rds_ring = &recv_ctx->rds_rings[desc_ctx];
848
	if (unlikely(index > rds_ring->num_desc))
849
		return;
850

D
Dhananjay Phadke 已提交
851
	buffer = &rds_ring->rx_buf_arr[index];
852
	if (desc_ctx == RCV_RING_LRO) {
853 854 855 856 857 858 859 860 861 862
		buffer->lro_current_frags++;
		if (netxen_get_sts_desc_lro_last_frag(desc)) {
			buffer->lro_expected_frags =
			    netxen_get_sts_desc_lro_cnt(desc);
			buffer->lro_length = length;
		}
		if (buffer->lro_current_frags != buffer->lro_expected_frags) {
			return;
		}
	}
A
Amit S. Kale 已提交
863

864
	cksum = netxen_get_sts_status(sts_data);
A
Amit S. Kale 已提交
865

866 867 868
	skb = netxen_process_rxbuf(adapter, rds_ring, index, cksum);
	if (!skb)
		return;
D
Dhananjay Phadke 已提交
869

870
	if (desc_ctx == RCV_RING_LRO) {
871 872 873
		/* True length was only available on the last pkt */
		skb_put(skb, buffer->lro_length);
	} else {
874 875 876 877 878 879 880 881
		if (length > rds_ring->skb_size)
			skb_put(skb, rds_ring->skb_size);
		else
			skb_put(skb, length);

		pkt_offset = netxen_get_sts_pkt_offset(sts_data);
		if (pkt_offset)
			skb_pull(skb, pkt_offset);
882 883
	}

A
Amit S. Kale 已提交
884 885
	skb->protocol = eth_type_trans(skb, netdev);

D
Dhananjay Phadke 已提交
886
	netif_receive_skb(skb);
887

D
Dhananjay Phadke 已提交
888 889
	adapter->stats.no_rcv++;
	adapter->stats.rxbytes += length;
A
Amit S. Kale 已提交
890 891
}

892 893
int
netxen_process_rcv_ring(struct netxen_adapter *adapter, int max)
A
Amit S. Kale 已提交
894
{
895
	struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
A
Amit S. Kale 已提交
896
	struct status_desc *desc_head = recv_ctx->rcv_status_desc_head;
D
Dhananjay Phadke 已提交
897
	struct status_desc *desc;
A
Amit S. Kale 已提交
898 899
	u32 consumer = recv_ctx->status_rx_consumer;
	int count = 0, ring;
900 901
	u64 sts_data;
	u16 opcode;
A
Amit S. Kale 已提交
902 903 904

	while (count < max) {
		desc = &desc_head[consumer];
D
Dhananjay Phadke 已提交
905 906 907
		sts_data = le64_to_cpu(desc->status_desc_data);

		if (!(sts_data & STATUS_OWNER_HOST))
A
Amit S. Kale 已提交
908
			break;
909 910 911

		opcode = netxen_get_sts_opcode(sts_data);

912
		netxen_process_rcv(adapter, desc);
913

D
Dhananjay Phadke 已提交
914
		desc->status_desc_data = cpu_to_le64(STATUS_OWNER_PHANTOM);
915

916
		consumer = get_next_index(consumer, adapter->num_rxd);
A
Amit S. Kale 已提交
917 918
		count++;
	}
D
Dhananjay Phadke 已提交
919

D
Dhananjay Phadke 已提交
920
	for (ring = 0; ring < adapter->max_rds_rings; ring++)
921
		netxen_post_rx_buffers_nodb(adapter, ring);
A
Amit S. Kale 已提交
922 923 924

	if (count) {
		recv_ctx->status_rx_consumer = consumer;
925 926
		adapter->pci_write_normalize(adapter,
				recv_ctx->crb_sts_consumer, consumer);
A
Amit S. Kale 已提交
927 928 929 930 931 932
	}

	return count;
}

/* Process Command status ring */
D
Dhananjay Phadke 已提交
933
int netxen_process_cmd_ring(struct netxen_adapter *adapter)
A
Amit S. Kale 已提交
934
{
935 936
	u32 last_consumer, consumer;
	int count = 0, i;
A
Amit S. Kale 已提交
937
	struct netxen_cmd_buffer *buffer;
938 939
	struct pci_dev *pdev = adapter->pdev;
	struct net_device *netdev = adapter->netdev;
A
Amit S. Kale 已提交
940
	struct netxen_skb_frag *frag;
941
	int done = 0;
A
Amit S. Kale 已提交
942 943

	last_consumer = adapter->last_cmd_consumer;
944
	barrier(); /* cmd_consumer can change underneath */
945
	consumer = le32_to_cpu(*(adapter->cmd_consumer));
A
Amit S. Kale 已提交
946

947
	while (last_consumer != consumer) {
A
Amit S. Kale 已提交
948
		buffer = &adapter->cmd_buf_arr[last_consumer];
949 950
		if (buffer->skb) {
			frag = &buffer->frag_array[0];
A
Amit S. Kale 已提交
951 952
			pci_unmap_single(pdev, frag->dma, frag->length,
					 PCI_DMA_TODEVICE);
953
			frag->dma = 0ULL;
A
Amit S. Kale 已提交
954 955 956 957
			for (i = 1; i < buffer->frag_count; i++) {
				frag++;	/* Get the next frag */
				pci_unmap_page(pdev, frag->dma, frag->length,
					       PCI_DMA_TODEVICE);
958
				frag->dma = 0ULL;
A
Amit S. Kale 已提交
959 960
			}

961
			adapter->stats.xmitfinished++;
962 963
			dev_kfree_skb_any(buffer->skb);
			buffer->skb = NULL;
A
Amit S. Kale 已提交
964 965 966
		}

		last_consumer = get_next_index(last_consumer,
967
					       adapter->num_txd);
968 969
		if (++count >= MAX_STATUS_HANDLE)
			break;
A
Amit S. Kale 已提交
970 971
	}

972
	if (count) {
A
Amit S. Kale 已提交
973
		adapter->last_cmd_consumer = last_consumer;
974 975 976 977 978 979
		smp_mb();
		if (netif_queue_stopped(netdev) && netif_running(netdev)) {
			netif_tx_lock(netdev);
			netif_wake_queue(netdev);
			smp_mb();
			netif_tx_unlock(netdev);
A
Amit S. Kale 已提交
980 981
		}
	}
982 983 984 985 986 987 988 989 990 991 992 993 994
	/*
	 * If everything is freed up to consumer then check if the ring is full
	 * If the ring is full then check if more needs to be freed and
	 * schedule the call back again.
	 *
	 * This happens when there are 2 CPUs. One could be freeing and the
	 * other filling it. If the ring is full when we get out of here and
	 * the card has already interrupted the host then the host can miss the
	 * interrupt.
	 *
	 * There is still a possible race condition and the host could miss an
	 * interrupt. The card has to take care of this.
	 */
995
	barrier(); /* cmd_consumer can change underneath */
996 997
	consumer = le32_to_cpu(*(adapter->cmd_consumer));
	done = (last_consumer == consumer);
A
Amit S. Kale 已提交
998

999
	return (done);
A
Amit S. Kale 已提交
1000 1001
}

1002 1003
void
netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ringid)
A
Amit S. Kale 已提交
1004
{
1005
	struct pci_dev *pdev = adapter->pdev;
A
Amit S. Kale 已提交
1006
	struct sk_buff *skb;
1007
	struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
D
Dhananjay Phadke 已提交
1008
	struct nx_host_rds_ring *rds_ring = NULL;
1009
	uint producer;
A
Amit S. Kale 已提交
1010 1011 1012
	struct rcv_desc *pdesc;
	struct netxen_rx_buffer *buffer;
	int count = 0;
1013 1014
	netxen_ctx_msg msg = 0;
	dma_addr_t dma;
1015
	struct list_head *head;
A
Amit S. Kale 已提交
1016

D
Dhananjay Phadke 已提交
1017
	rds_ring = &recv_ctx->rds_rings[ringid];
A
Amit S. Kale 已提交
1018

D
Dhananjay Phadke 已提交
1019
	producer = rds_ring->producer;
1020 1021
	head = &rds_ring->free_list;

A
Amit S. Kale 已提交
1022
	/* We can start writing rx descriptors into the phantom memory. */
1023 1024
	while (!list_empty(head)) {

D
Dhananjay Phadke 已提交
1025
		skb = dev_alloc_skb(rds_ring->skb_size);
A
Amit S. Kale 已提交
1026 1027 1028
		if (unlikely(!skb)) {
			break;
		}
1029

1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040
		if (!adapter->ahw.cut_through)
			skb_reserve(skb, 2);

		dma = pci_map_single(pdev, skb->data,
				rds_ring->dma_size, PCI_DMA_FROMDEVICE);
		if (pci_dma_mapping_error(pdev, dma)) {
			dev_kfree_skb_any(skb);
			break;
		}

		count++;
1041 1042 1043
		buffer = list_entry(head->next, struct netxen_rx_buffer, list);
		list_del(&buffer->list);

1044 1045 1046
		buffer->skb = skb;
		buffer->state = NETXEN_BUFFER_BUSY;
		buffer->dma = dma;
1047

1048
		/* make a rcv descriptor  */
1049 1050
		pdesc = &rds_ring->desc_head[producer];
		pdesc->addr_buffer = cpu_to_le64(dma);
A
Amit S. Kale 已提交
1051
		pdesc->reference_handle = cpu_to_le16(buffer->ref_handle);
D
Dhananjay Phadke 已提交
1052
		pdesc->buffer_length = cpu_to_le32(rds_ring->dma_size);
1053

1054
		producer = get_next_index(producer, rds_ring->num_desc);
1055 1056 1057
	}
	/* if we did allocate buffers, then write the count to Phantom */
	if (count) {
D
Dhananjay Phadke 已提交
1058
		rds_ring->producer = producer;
1059
			/* Window = 1 */
1060
		adapter->pci_write_normalize(adapter,
D
Dhananjay Phadke 已提交
1061
				rds_ring->crb_rcv_producer,
1062
				(producer-1) & (rds_ring->num_desc-1));
D
Dhananjay Phadke 已提交
1063 1064

		if (adapter->fw_major < 4) {
1065 1066 1067
			/*
			 * Write a doorbell msg to tell phanmon of change in
			 * receive ring producer
D
Dhananjay Phadke 已提交
1068
			 * Only for firmware version < 4.0.0
1069 1070 1071 1072
			 */
			netxen_set_msg_peg_id(msg, NETXEN_RCV_PEG_DB_ID);
			netxen_set_msg_privid(msg);
			netxen_set_msg_count(msg,
1073 1074
					     ((producer - 1) &
					      (rds_ring->num_desc - 1)));
1075
			netxen_set_msg_ctxid(msg, adapter->portnum);
1076 1077 1078 1079
			netxen_set_msg_opcode(msg, NETXEN_RCV_PRODUCER(ringid));
			writel(msg,
			       DB_NORMALIZE(adapter,
					    NETXEN_RCV_PRODUCER_OFFSET));
D
Dhananjay Phadke 已提交
1080
		}
1081 1082 1083
	}
}

1084 1085
static void
netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter, uint32_t ringid)
1086
{
1087
	struct pci_dev *pdev = adapter->pdev;
1088
	struct sk_buff *skb;
1089
	struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
D
Dhananjay Phadke 已提交
1090
	struct nx_host_rds_ring *rds_ring = NULL;
1091 1092 1093 1094
	u32 producer;
	struct rcv_desc *pdesc;
	struct netxen_rx_buffer *buffer;
	int count = 0;
1095
	struct list_head *head;
1096
	dma_addr_t dma;
1097

D
Dhananjay Phadke 已提交
1098
	rds_ring = &recv_ctx->rds_rings[ringid];
1099

D
Dhananjay Phadke 已提交
1100
	producer = rds_ring->producer;
1101
	head = &rds_ring->free_list;
1102
	/* We can start writing rx descriptors into the phantom memory. */
1103 1104
	while (!list_empty(head)) {

D
Dhananjay Phadke 已提交
1105
		skb = dev_alloc_skb(rds_ring->skb_size);
1106 1107 1108
		if (unlikely(!skb)) {
			break;
		}
1109

1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120
		if (!adapter->ahw.cut_through)
			skb_reserve(skb, 2);

		dma = pci_map_single(pdev, skb->data,
				rds_ring->dma_size, PCI_DMA_FROMDEVICE);
		if (pci_dma_mapping_error(pdev, dma)) {
			dev_kfree_skb_any(skb);
			break;
		}

		count++;
1121 1122 1123
		buffer = list_entry(head->next, struct netxen_rx_buffer, list);
		list_del(&buffer->list);

A
Amit S. Kale 已提交
1124 1125
		buffer->skb = skb;
		buffer->state = NETXEN_BUFFER_BUSY;
1126
		buffer->dma = dma;
1127

A
Amit S. Kale 已提交
1128
		/* make a rcv descriptor  */
1129
		pdesc = &rds_ring->desc_head[producer];
A
Amit S. Kale 已提交
1130
		pdesc->reference_handle = cpu_to_le16(buffer->ref_handle);
D
Dhananjay Phadke 已提交
1131
		pdesc->buffer_length = cpu_to_le32(rds_ring->dma_size);
A
Amit S. Kale 已提交
1132
		pdesc->addr_buffer = cpu_to_le64(buffer->dma);
1133

1134
		producer = get_next_index(producer, rds_ring->num_desc);
A
Amit S. Kale 已提交
1135 1136 1137 1138
	}

	/* if we did allocate buffers, then write the count to Phantom */
	if (count) {
D
Dhananjay Phadke 已提交
1139
		rds_ring->producer = producer;
A
Amit S. Kale 已提交
1140
			/* Window = 1 */
1141
		adapter->pci_write_normalize(adapter,
D
Dhananjay Phadke 已提交
1142
			rds_ring->crb_rcv_producer,
1143
				(producer - 1) & (rds_ring->num_desc - 1));
A
Amit S. Kale 已提交
1144 1145 1146 1147 1148 1149 1150
			wmb();
	}
}

void netxen_nic_clear_stats(struct netxen_adapter *adapter)
{
	memset(&adapter->stats, 0, sizeof(adapter->stats));
1151
	return;
A
Amit S. Kale 已提交
1152 1153
}