13d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale/* 25d242f1cee2c85721bbe9d8205e98c1c01f5d805Dhananjay Phadke * Copyright (C) 2003 - 2009 NetXen, Inc. 313af7a6ea502fcdd4c0e3d7de6e332b102309491Dhananjay Phadke * Copyright (C) 2009 - QLogic Corporation. 43d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale * All rights reserved. 580922fbcb6f00127e91580e7565bb665947ac5d3Amit S. Kale * 63d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale * This program is free software; you can redistribute it and/or 73d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale * modify it under the terms of the GNU General Public License 83d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale * as published by the Free Software Foundation; either version 2 93d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale * of the License, or (at your option) any later version. 1080922fbcb6f00127e91580e7565bb665947ac5d3Amit S. Kale * 113d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale * This program is distributed in the hope that it will be useful, but 123d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale * WITHOUT ANY WARRANTY; without even the implied warranty of 133d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 143d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale * GNU General Public License for more details. 1580922fbcb6f00127e91580e7565bb665947ac5d3Amit S. Kale * 163d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale * You should have received a copy of the GNU General Public License 173d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale * along with this program; if not, write to the Free Software 183d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 193d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale * MA 02111-1307, USA. 2080922fbcb6f00127e91580e7565bb665947ac5d3Amit S. Kale * 213d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale * The full GNU General Public License is included in this distribution 224d21fef426c5cbbdf6da607de4c0adcaa3d4bbb0Amit Kumar Salecha * in the file called "COPYING". 2380922fbcb6f00127e91580e7565bb665947ac5d3Amit S. Kale * 243d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale */ 253d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale 263d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale#include <linux/netdevice.h> 273d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale#include <linux/delay.h> 285a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 2957569d0e12eaf31717e295960cd2a26f626c8e5bRajesh Borundia#include <linux/if_vlan.h> 303d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale#include "netxen_nic.h" 313d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale#include "netxen_nic_hw.h" 323d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale 333d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kalestruct crb_addr_pair { 34e0e20a1a0822aa64335c05013f0966de6a8fc2c6Linsys Contractor Mithlesh Thukral u32 addr; 35e0e20a1a0822aa64335c05013f0966de6a8fc2c6Linsys Contractor Mithlesh Thukral u32 data; 363d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale}; 373d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale 383d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale#define NETXEN_MAX_CRB_XFORM 60 393d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kalestatic unsigned int crb_addr_xform[NETXEN_MAX_CRB_XFORM]; 40e0e20a1a0822aa64335c05013f0966de6a8fc2c6Linsys Contractor Mithlesh Thukral#define NETXEN_ADDR_ERROR (0xffffffff) 413d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale 423d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale#define crb_addr_transform(name) \ 433d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale crb_addr_xform[NETXEN_HW_PX_MAP_CRB_##name] = \ 443d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale NETXEN_HW_CRB_HUB_AGT_ADR_##name << 20 453d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale 46cb8011ad53e0855ef088e0e5a4bcb98fa90c70b6Amit S. Kale#define NETXEN_NIC_XDMA_RESET 0x8000ff 47cb8011ad53e0855ef088e0e5a4bcb98fa90c70b6Amit S. Kale 48becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadkestatic void 49d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadkenetxen_post_rx_buffers_nodb(struct netxen_adapter *adapter, 50d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke struct nx_host_rds_ring *rds_ring); 51f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salechastatic int netxen_p3_has_mn(struct netxen_adapter *adapter); 52993fb90c5b1727342362c43ed4e29c26682f54f7Adrian Bunk 533d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kalestatic void crb_addr_transform_setup(void) 543d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale{ 553d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale crb_addr_transform(XDMA); 563d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale crb_addr_transform(TIMR); 573d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale crb_addr_transform(SRE); 583d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale crb_addr_transform(SQN3); 593d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale crb_addr_transform(SQN2); 603d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale crb_addr_transform(SQN1); 613d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale crb_addr_transform(SQN0); 623d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale crb_addr_transform(SQS3); 633d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale crb_addr_transform(SQS2); 643d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale crb_addr_transform(SQS1); 653d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale crb_addr_transform(SQS0); 663d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale crb_addr_transform(RPMX7); 673d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale crb_addr_transform(RPMX6); 683d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale crb_addr_transform(RPMX5); 693d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale crb_addr_transform(RPMX4); 703d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale crb_addr_transform(RPMX3); 713d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale crb_addr_transform(RPMX2); 723d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale crb_addr_transform(RPMX1); 733d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale crb_addr_transform(RPMX0); 743d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale crb_addr_transform(ROMUSB); 753d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale crb_addr_transform(SN); 763d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale crb_addr_transform(QMN); 773d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale crb_addr_transform(QMS); 783d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale crb_addr_transform(PGNI); 793d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale crb_addr_transform(PGND); 803d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale crb_addr_transform(PGN3); 813d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale crb_addr_transform(PGN2); 823d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale crb_addr_transform(PGN1); 833d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale crb_addr_transform(PGN0); 843d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale crb_addr_transform(PGSI); 853d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale crb_addr_transform(PGSD); 863d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale crb_addr_transform(PGS3); 873d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale crb_addr_transform(PGS2); 883d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale crb_addr_transform(PGS1); 893d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale crb_addr_transform(PGS0); 903d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale crb_addr_transform(PS); 913d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale crb_addr_transform(PH); 923d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale crb_addr_transform(NIU); 933d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale crb_addr_transform(I2Q); 943d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale crb_addr_transform(EG); 953d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale crb_addr_transform(MN); 963d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale crb_addr_transform(MS); 973d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale crb_addr_transform(CAS2); 983d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale crb_addr_transform(CAS1); 993d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale crb_addr_transform(CAS0); 1003d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale crb_addr_transform(CAM); 1013d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale crb_addr_transform(C2C1); 1023d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale crb_addr_transform(C2C0); 1031fcca1a5fc81689d191b7132318970c969b4b635Amit S. Kale crb_addr_transform(SMB); 104e4c93c817ce650401db42db6c869cf7688217ff4Dhananjay Phadke crb_addr_transform(OCM0); 105e4c93c817ce650401db42db6c869cf7688217ff4Dhananjay Phadke crb_addr_transform(I2C0); 1063d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale} 1073d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale 1082956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadkevoid netxen_release_rx_buffers(struct netxen_adapter *adapter) 1093d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale{ 1102956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke struct netxen_recv_context *recv_ctx; 11148bfd1e0fc66b27254ec742b014e689ef218e76cDhananjay Phadke struct nx_host_rds_ring *rds_ring; 1122956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke struct netxen_rx_buffer *rx_buf; 113becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadke int i, ring; 114becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadke 115becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadke recv_ctx = &adapter->recv_ctx; 116becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadke for (ring = 0; ring < adapter->max_rds_rings; ring++) { 117becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadke rds_ring = &recv_ctx->rds_rings[ring]; 118438627c77b877e445a4b918a50ff910a5ea2a12dDhananjay Phadke for (i = 0; i < rds_ring->num_desc; ++i) { 119becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadke rx_buf = &(rds_ring->rx_buf_arr[i]); 120becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadke if (rx_buf->state == NETXEN_BUFFER_FREE) 121becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadke continue; 122becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadke pci_unmap_single(adapter->pdev, 123becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadke rx_buf->dma, 124becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadke rds_ring->dma_size, 125becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadke PCI_DMA_FROMDEVICE); 126becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadke if (rx_buf->skb != NULL) 127becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadke dev_kfree_skb_any(rx_buf->skb); 1282956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke } 1292956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke } 1302956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke} 1312956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke 1322956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadkevoid netxen_release_tx_buffers(struct netxen_adapter *adapter) 1332956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke{ 1342956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke struct netxen_cmd_buffer *cmd_buf; 1352956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke struct netxen_skb_frag *buffrag; 1362956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke int i, j; 1374ea528a151549df795c984649d75860ea40390bdDhananjay Phadke struct nx_host_tx_ring *tx_ring = adapter->tx_ring; 1382956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke 139d877f1e344f5515988d9dcd6db5d4285911778a3Dhananjay Phadke cmd_buf = tx_ring->cmd_buf_arr; 140d877f1e344f5515988d9dcd6db5d4285911778a3Dhananjay Phadke for (i = 0; i < tx_ring->num_desc; i++) { 1412956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke buffrag = cmd_buf->frag_array; 1422956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke if (buffrag->dma) { 1432956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke pci_unmap_single(adapter->pdev, buffrag->dma, 1442956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke buffrag->length, PCI_DMA_TODEVICE); 1452956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke buffrag->dma = 0ULL; 1462956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke } 1472956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke for (j = 0; j < cmd_buf->frag_count; j++) { 1482956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke buffrag++; 1492956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke if (buffrag->dma) { 1502956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke pci_unmap_page(adapter->pdev, buffrag->dma, 1512956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke buffrag->length, 1522956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke PCI_DMA_TODEVICE); 1532956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke buffrag->dma = 0ULL; 1542956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke } 1552956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke } 1562956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke if (cmd_buf->skb) { 1572956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke dev_kfree_skb_any(cmd_buf->skb); 1582956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke cmd_buf->skb = NULL; 1592956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke } 1602956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke cmd_buf++; 1612956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke } 1622956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke} 1632956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke 1642956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadkevoid netxen_free_sw_resources(struct netxen_adapter *adapter) 1652956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke{ 1662956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke struct netxen_recv_context *recv_ctx; 16748bfd1e0fc66b27254ec742b014e689ef218e76cDhananjay Phadke struct nx_host_rds_ring *rds_ring; 168d877f1e344f5515988d9dcd6db5d4285911778a3Dhananjay Phadke struct nx_host_tx_ring *tx_ring; 169becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadke int ring; 170becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadke 171becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadke recv_ctx = &adapter->recv_ctx; 1724ea528a151549df795c984649d75860ea40390bdDhananjay Phadke 1734ea528a151549df795c984649d75860ea40390bdDhananjay Phadke if (recv_ctx->rds_rings == NULL) 1744ea528a151549df795c984649d75860ea40390bdDhananjay Phadke goto skip_rds; 1754ea528a151549df795c984649d75860ea40390bdDhananjay Phadke 176becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadke for (ring = 0; ring < adapter->max_rds_rings; ring++) { 177becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadke rds_ring = &recv_ctx->rds_rings[ring]; 178f2333a014c1e13ac8e1b73a6fd77731c524eff78Figo.zhang vfree(rds_ring->rx_buf_arr); 179f2333a014c1e13ac8e1b73a6fd77731c524eff78Figo.zhang rds_ring->rx_buf_arr = NULL; 1802956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke } 1814ea528a151549df795c984649d75860ea40390bdDhananjay Phadke kfree(recv_ctx->rds_rings); 1824ea528a151549df795c984649d75860ea40390bdDhananjay Phadke 1834ea528a151549df795c984649d75860ea40390bdDhananjay Phadkeskip_rds: 1844ea528a151549df795c984649d75860ea40390bdDhananjay Phadke if (adapter->tx_ring == NULL) 1854ea528a151549df795c984649d75860ea40390bdDhananjay Phadke return; 186becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadke 1874ea528a151549df795c984649d75860ea40390bdDhananjay Phadke tx_ring = adapter->tx_ring; 188f2333a014c1e13ac8e1b73a6fd77731c524eff78Figo.zhang vfree(tx_ring->cmd_buf_arr); 189011f4ea09768fdf6f95e3781cba2ed681a2ac710Amit Kumar Salecha kfree(tx_ring); 190011f4ea09768fdf6f95e3781cba2ed681a2ac710Amit Kumar Salecha adapter->tx_ring = NULL; 1912956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke} 1922956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke 1932956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadkeint netxen_alloc_sw_resources(struct netxen_adapter *adapter) 1942956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke{ 1952956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke struct netxen_recv_context *recv_ctx; 19648bfd1e0fc66b27254ec742b014e689ef218e76cDhananjay Phadke struct nx_host_rds_ring *rds_ring; 197d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke struct nx_host_sds_ring *sds_ring; 1984ea528a151549df795c984649d75860ea40390bdDhananjay Phadke struct nx_host_tx_ring *tx_ring; 1992956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke struct netxen_rx_buffer *rx_buf; 2004ea528a151549df795c984649d75860ea40390bdDhananjay Phadke int ring, i, size; 2012956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke 2022956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke struct netxen_cmd_buffer *cmd_buf_arr; 2032956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke struct net_device *netdev = adapter->netdev; 204d877f1e344f5515988d9dcd6db5d4285911778a3Dhananjay Phadke struct pci_dev *pdev = adapter->pdev; 2052956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke 2064ea528a151549df795c984649d75860ea40390bdDhananjay Phadke size = sizeof(struct nx_host_tx_ring); 2074ea528a151549df795c984649d75860ea40390bdDhananjay Phadke tx_ring = kzalloc(size, GFP_KERNEL); 2084ea528a151549df795c984649d75860ea40390bdDhananjay Phadke if (tx_ring == NULL) { 2094ea528a151549df795c984649d75860ea40390bdDhananjay Phadke dev_err(&pdev->dev, "%s: failed to allocate tx ring struct\n", 2104ea528a151549df795c984649d75860ea40390bdDhananjay Phadke netdev->name); 2114ea528a151549df795c984649d75860ea40390bdDhananjay Phadke return -ENOMEM; 2124ea528a151549df795c984649d75860ea40390bdDhananjay Phadke } 2134ea528a151549df795c984649d75860ea40390bdDhananjay Phadke adapter->tx_ring = tx_ring; 2144ea528a151549df795c984649d75860ea40390bdDhananjay Phadke 215d877f1e344f5515988d9dcd6db5d4285911778a3Dhananjay Phadke tx_ring->num_desc = adapter->num_txd; 216b2af9cb06d4de1b507ec0fd779ec2ecedee1480aDhananjay Phadke tx_ring->txq = netdev_get_tx_queue(netdev, 0); 2174ea528a151549df795c984649d75860ea40390bdDhananjay Phadke 21889bf67f1f080c947c92f8773482d9e57767ca292Eric Dumazet cmd_buf_arr = vzalloc(TX_BUFF_RINGSIZE(tx_ring)); 2192956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke if (cmd_buf_arr == NULL) { 220d877f1e344f5515988d9dcd6db5d4285911778a3Dhananjay Phadke dev_err(&pdev->dev, "%s: failed to allocate cmd buffer ring\n", 2212956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke netdev->name); 222bf445080dad9542c6bc6b693d941cae89605134cAmit Kumar Salecha goto err_out; 2232956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke } 224d877f1e344f5515988d9dcd6db5d4285911778a3Dhananjay Phadke tx_ring->cmd_buf_arr = cmd_buf_arr; 2252956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke 226becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadke recv_ctx = &adapter->recv_ctx; 2274ea528a151549df795c984649d75860ea40390bdDhananjay Phadke 2284ea528a151549df795c984649d75860ea40390bdDhananjay Phadke size = adapter->max_rds_rings * sizeof (struct nx_host_rds_ring); 2294ea528a151549df795c984649d75860ea40390bdDhananjay Phadke rds_ring = kzalloc(size, GFP_KERNEL); 2304ea528a151549df795c984649d75860ea40390bdDhananjay Phadke if (rds_ring == NULL) { 2314ea528a151549df795c984649d75860ea40390bdDhananjay Phadke dev_err(&pdev->dev, "%s: failed to allocate rds ring struct\n", 2324ea528a151549df795c984649d75860ea40390bdDhananjay Phadke netdev->name); 233bf445080dad9542c6bc6b693d941cae89605134cAmit Kumar Salecha goto err_out; 2344ea528a151549df795c984649d75860ea40390bdDhananjay Phadke } 2354ea528a151549df795c984649d75860ea40390bdDhananjay Phadke recv_ctx->rds_rings = rds_ring; 2364ea528a151549df795c984649d75860ea40390bdDhananjay Phadke 237becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadke for (ring = 0; ring < adapter->max_rds_rings; ring++) { 238becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadke rds_ring = &recv_ctx->rds_rings[ring]; 239438627c77b877e445a4b918a50ff910a5ea2a12dDhananjay Phadke switch (ring) { 240438627c77b877e445a4b918a50ff910a5ea2a12dDhananjay Phadke case RCV_RING_NORMAL: 241438627c77b877e445a4b918a50ff910a5ea2a12dDhananjay Phadke rds_ring->num_desc = adapter->num_rxd; 242becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadke if (adapter->ahw.cut_through) { 243becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadke rds_ring->dma_size = 244becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadke NX_CT_DEFAULT_RX_BUF_LEN; 24548bfd1e0fc66b27254ec742b014e689ef218e76cDhananjay Phadke rds_ring->skb_size = 246becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadke NX_CT_DEFAULT_RX_BUF_LEN; 247becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadke } else { 2489b08beba2d1bf7e4598deba2800a9ea5e5c3a282Dhananjay Phadke if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) 2499b08beba2d1bf7e4598deba2800a9ea5e5c3a282Dhananjay Phadke rds_ring->dma_size = 2509b08beba2d1bf7e4598deba2800a9ea5e5c3a282Dhananjay Phadke NX_P3_RX_BUF_MAX_LEN; 2519b08beba2d1bf7e4598deba2800a9ea5e5c3a282Dhananjay Phadke else 2529b08beba2d1bf7e4598deba2800a9ea5e5c3a282Dhananjay Phadke rds_ring->dma_size = 2539b08beba2d1bf7e4598deba2800a9ea5e5c3a282Dhananjay Phadke NX_P2_RX_BUF_MAX_LEN; 254becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadke rds_ring->skb_size = 2559b08beba2d1bf7e4598deba2800a9ea5e5c3a282Dhananjay Phadke rds_ring->dma_size + NET_IP_ALIGN; 256becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadke } 257becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadke break; 2582956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke 259438627c77b877e445a4b918a50ff910a5ea2a12dDhananjay Phadke case RCV_RING_JUMBO: 260438627c77b877e445a4b918a50ff910a5ea2a12dDhananjay Phadke rds_ring->num_desc = adapter->num_jumbo_rxd; 261becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadke if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) 262becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadke rds_ring->dma_size = 263becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadke NX_P3_RX_JUMBO_BUF_MAX_LEN; 264becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadke else 265becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadke rds_ring->dma_size = 266becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadke NX_P2_RX_JUMBO_BUF_MAX_LEN; 267bc75e5bfad2a6d24fc5a9885a2f6b93f82c6c5f1Dhananjay Phadke 268bc75e5bfad2a6d24fc5a9885a2f6b93f82c6c5f1Dhananjay Phadke if (adapter->capabilities & NX_CAP0_HW_LRO) 269bc75e5bfad2a6d24fc5a9885a2f6b93f82c6c5f1Dhananjay Phadke rds_ring->dma_size += NX_LRO_BUFFER_EXTRA; 270bc75e5bfad2a6d24fc5a9885a2f6b93f82c6c5f1Dhananjay Phadke 271becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadke rds_ring->skb_size = 272becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadke rds_ring->dma_size + NET_IP_ALIGN; 273becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadke break; 2742956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke 275becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadke case RCV_RING_LRO: 276438627c77b877e445a4b918a50ff910a5ea2a12dDhananjay Phadke rds_ring->num_desc = adapter->num_lro_rxd; 2779b08beba2d1bf7e4598deba2800a9ea5e5c3a282Dhananjay Phadke rds_ring->dma_size = NX_RX_LRO_BUFFER_LENGTH; 2789b08beba2d1bf7e4598deba2800a9ea5e5c3a282Dhananjay Phadke rds_ring->skb_size = rds_ring->dma_size + NET_IP_ALIGN; 279becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadke break; 280becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadke 281becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadke } 2820acdf68f495793143802dd4f3e47918dddcceed7Joe Perches rds_ring->rx_buf_arr = vzalloc(RCV_BUFF_RINGSIZE(rds_ring)); 283becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadke if (rds_ring->rx_buf_arr == NULL) { 284becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadke printk(KERN_ERR "%s: Failed to allocate " 285becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadke "rx buffer ring %d\n", 286becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadke netdev->name, ring); 287becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadke /* free whatever was already allocated */ 288becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadke goto err_out; 289becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadke } 290becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadke INIT_LIST_HEAD(&rds_ring->free_list); 291becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadke /* 292becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadke * Now go through all of them, set reference handles 293becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadke * and put them in the queues. 294becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadke */ 295becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadke rx_buf = rds_ring->rx_buf_arr; 2964ea528a151549df795c984649d75860ea40390bdDhananjay Phadke for (i = 0; i < rds_ring->num_desc; i++) { 297becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadke list_add_tail(&rx_buf->list, 298becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadke &rds_ring->free_list); 299becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadke rx_buf->ref_handle = i; 300becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadke rx_buf->state = NETXEN_BUFFER_FREE; 301becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadke rx_buf++; 3023d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale } 303d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke spin_lock_init(&rds_ring->lock); 304d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke } 305d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke 306d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke for (ring = 0; ring < adapter->max_sds_rings; ring++) { 307d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke sds_ring = &recv_ctx->sds_rings[ring]; 308d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke sds_ring->irq = adapter->msix_entries[ring].vector; 309d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke sds_ring->adapter = adapter; 310d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke sds_ring->num_desc = adapter->num_rxd; 311d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke 312d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke for (i = 0; i < NUM_RCV_DESC_RINGS; i++) 313d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke INIT_LIST_HEAD(&sds_ring->free_list[i]); 3143d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale } 3152956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke 3162956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke return 0; 3172956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke 3182956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadkeerr_out: 3192956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke netxen_free_sw_resources(adapter); 3202956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke return -ENOMEM; 3213d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale} 3223d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale 3233d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale/* 3243d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale * netxen_decode_crb_addr(0 - utility to translate from internal Phantom CRB 3253d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale * address to external PCI CRB address. 3263d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale */ 327993fb90c5b1727342362c43ed4e29c26682f54f7Adrian Bunkstatic u32 netxen_decode_crb_addr(u32 addr) 3283d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale{ 3293d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale int i; 330e0e20a1a0822aa64335c05013f0966de6a8fc2c6Linsys Contractor Mithlesh Thukral u32 base_addr, offset, pci_base; 3313d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale 3323d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale crb_addr_transform_setup(); 3333d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale 3343d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale pci_base = NETXEN_ADDR_ERROR; 3353d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale base_addr = addr & 0xfff00000; 3363d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale offset = addr & 0x000fffff; 3373d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale 3383d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale for (i = 0; i < NETXEN_MAX_CRB_XFORM; i++) { 3393d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale if (crb_addr_xform[i] == base_addr) { 3403d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale pci_base = i << 20; 3413d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale break; 3423d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale } 3433d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale } 3443d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale if (pci_base == NETXEN_ADDR_ERROR) 3453d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale return pci_base; 3463d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale else 347807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return pci_base + offset; 3483d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale} 3493d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale 350c9517e5893db03ca8bd32b8783b39af58176947cDhananjay Phadke#define NETXEN_MAX_ROM_WAIT_USEC 100 3513d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale 352993fb90c5b1727342362c43ed4e29c26682f54f7Adrian Bunkstatic int netxen_wait_rom_done(struct netxen_adapter *adapter) 3533d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale{ 3543d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale long timeout = 0; 3553d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale long done = 0; 3563d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale 35727c915a4d843b90eb4065298969578d15e5e6ab0Dhananjay Phadke cond_resched(); 35827c915a4d843b90eb4065298969578d15e5e6ab0Dhananjay Phadke 3593d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale while (done == 0) { 360f98a9f693b5f4919d9c4085a2fd8d67c7e152f3eDhananjay Phadke done = NXRD32(adapter, NETXEN_ROMUSB_GLB_STATUS); 3613d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale done &= 2; 362c9517e5893db03ca8bd32b8783b39af58176947cDhananjay Phadke if (++timeout >= NETXEN_MAX_ROM_WAIT_USEC) { 363c9517e5893db03ca8bd32b8783b39af58176947cDhananjay Phadke dev_err(&adapter->pdev->dev, 364c9517e5893db03ca8bd32b8783b39af58176947cDhananjay Phadke "Timeout reached waiting for rom done"); 3653d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale return -EIO; 3663d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale } 367c9517e5893db03ca8bd32b8783b39af58176947cDhananjay Phadke udelay(1); 3683d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale } 3693d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale return 0; 3703d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale} 3713d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale 372993fb90c5b1727342362c43ed4e29c26682f54f7Adrian Bunkstatic int do_rom_fast_read(struct netxen_adapter *adapter, 373993fb90c5b1727342362c43ed4e29c26682f54f7Adrian Bunk int addr, int *valp) 3743d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale{ 375f98a9f693b5f4919d9c4085a2fd8d67c7e152f3eDhananjay Phadke NXWR32(adapter, NETXEN_ROMUSB_ROM_ADDRESS, addr); 376f98a9f693b5f4919d9c4085a2fd8d67c7e152f3eDhananjay Phadke NXWR32(adapter, NETXEN_ROMUSB_ROM_DUMMY_BYTE_CNT, 0); 377f98a9f693b5f4919d9c4085a2fd8d67c7e152f3eDhananjay Phadke NXWR32(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 3); 378f98a9f693b5f4919d9c4085a2fd8d67c7e152f3eDhananjay Phadke NXWR32(adapter, NETXEN_ROMUSB_ROM_INSTR_OPCODE, 0xb); 3793d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale if (netxen_wait_rom_done(adapter)) { 3803d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale printk("Error waiting for rom done\n"); 3813d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale return -EIO; 3823d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale } 3833d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale /* reset abyte_cnt and dummy_byte_cnt */ 384f98a9f693b5f4919d9c4085a2fd8d67c7e152f3eDhananjay Phadke NXWR32(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 0); 38527c915a4d843b90eb4065298969578d15e5e6ab0Dhananjay Phadke udelay(10); 386f98a9f693b5f4919d9c4085a2fd8d67c7e152f3eDhananjay Phadke NXWR32(adapter, NETXEN_ROMUSB_ROM_DUMMY_BYTE_CNT, 0); 3873d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale 388f98a9f693b5f4919d9c4085a2fd8d67c7e152f3eDhananjay Phadke *valp = NXRD32(adapter, NETXEN_ROMUSB_ROM_RDATA); 3893d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale return 0; 3903d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale} 3913d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale 392993fb90c5b1727342362c43ed4e29c26682f54f7Adrian Bunkstatic int do_rom_fast_read_words(struct netxen_adapter *adapter, int addr, 393993fb90c5b1727342362c43ed4e29c26682f54f7Adrian Bunk u8 *bytes, size_t size) 39427d2ab54bdfaffdbdc1a81100dc53c6479c9db35Amit S. Kale{ 39527d2ab54bdfaffdbdc1a81100dc53c6479c9db35Amit S. Kale int addridx; 39627d2ab54bdfaffdbdc1a81100dc53c6479c9db35Amit S. Kale int ret = 0; 39727d2ab54bdfaffdbdc1a81100dc53c6479c9db35Amit S. Kale 39827d2ab54bdfaffdbdc1a81100dc53c6479c9db35Amit S. Kale for (addridx = addr; addridx < (addr + size); addridx += 4) { 399f305f789bb96ee6e35e71f58324b72abb7bd0b13Al Viro int v; 400f305f789bb96ee6e35e71f58324b72abb7bd0b13Al Viro ret = do_rom_fast_read(adapter, addridx, &v); 40127d2ab54bdfaffdbdc1a81100dc53c6479c9db35Amit S. Kale if (ret != 0) 40227d2ab54bdfaffdbdc1a81100dc53c6479c9db35Amit S. Kale break; 403f305f789bb96ee6e35e71f58324b72abb7bd0b13Al Viro *(__le32 *)bytes = cpu_to_le32(v); 40427d2ab54bdfaffdbdc1a81100dc53c6479c9db35Amit S. Kale bytes += 4; 40527d2ab54bdfaffdbdc1a81100dc53c6479c9db35Amit S. Kale } 40627d2ab54bdfaffdbdc1a81100dc53c6479c9db35Amit S. Kale 40727d2ab54bdfaffdbdc1a81100dc53c6479c9db35Amit S. Kale return ret; 40827d2ab54bdfaffdbdc1a81100dc53c6479c9db35Amit S. Kale} 40927d2ab54bdfaffdbdc1a81100dc53c6479c9db35Amit S. Kale 41027d2ab54bdfaffdbdc1a81100dc53c6479c9db35Amit S. Kaleint 4114790654c71b250018ecc234f6b9f1ed96a55572dJeff Garziknetxen_rom_fast_read_words(struct netxen_adapter *adapter, int addr, 41227d2ab54bdfaffdbdc1a81100dc53c6479c9db35Amit S. Kale u8 *bytes, size_t size) 41327d2ab54bdfaffdbdc1a81100dc53c6479c9db35Amit S. Kale{ 41427d2ab54bdfaffdbdc1a81100dc53c6479c9db35Amit S. Kale int ret; 41527d2ab54bdfaffdbdc1a81100dc53c6479c9db35Amit S. Kale 416c9517e5893db03ca8bd32b8783b39af58176947cDhananjay Phadke ret = netxen_rom_lock(adapter); 41727d2ab54bdfaffdbdc1a81100dc53c6479c9db35Amit S. Kale if (ret < 0) 41827d2ab54bdfaffdbdc1a81100dc53c6479c9db35Amit S. Kale return ret; 41927d2ab54bdfaffdbdc1a81100dc53c6479c9db35Amit S. Kale 42027d2ab54bdfaffdbdc1a81100dc53c6479c9db35Amit S. Kale ret = do_rom_fast_read_words(adapter, addr, bytes, size); 42127d2ab54bdfaffdbdc1a81100dc53c6479c9db35Amit S. Kale 42227d2ab54bdfaffdbdc1a81100dc53c6479c9db35Amit S. Kale netxen_rom_unlock(adapter); 42327d2ab54bdfaffdbdc1a81100dc53c6479c9db35Amit S. Kale return ret; 42427d2ab54bdfaffdbdc1a81100dc53c6479c9db35Amit S. Kale} 42527d2ab54bdfaffdbdc1a81100dc53c6479c9db35Amit S. Kale 4263d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kaleint netxen_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp) 4273d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale{ 4283d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale int ret; 4293d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale 430c9517e5893db03ca8bd32b8783b39af58176947cDhananjay Phadke if (netxen_rom_lock(adapter) != 0) 4313d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale return -EIO; 4323d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale 4333d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale ret = do_rom_fast_read(adapter, addr, valp); 434cb8011ad53e0855ef088e0e5a4bcb98fa90c70b6Amit S. Kale netxen_rom_unlock(adapter); 435cb8011ad53e0855ef088e0e5a4bcb98fa90c70b6Amit S. Kale return ret; 436cb8011ad53e0855ef088e0e5a4bcb98fa90c70b6Amit S. Kale} 437cb8011ad53e0855ef088e0e5a4bcb98fa90c70b6Amit S. Kale 4383d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale#define NETXEN_BOARDTYPE 0x4008 4393d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale#define NETXEN_BOARDNUM 0x400c 4403d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale#define NETXEN_CHIPNUM 0x4010 4413d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale 4420be367bd5d10634c0836f57a684432fee935d929Amit Kumar Salechaint netxen_pinit_from_rom(struct netxen_adapter *adapter) 4433d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale{ 444dcd56fdbaeae1008044687b973c4a3e852e8a726Dhananjay Phadke int addr, val; 44527c915a4d843b90eb4065298969578d15e5e6ab0Dhananjay Phadke int i, n, init_delay = 0; 4463d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale struct crb_addr_pair *buf; 44727c915a4d843b90eb4065298969578d15e5e6ab0Dhananjay Phadke unsigned offset; 448e0e20a1a0822aa64335c05013f0966de6a8fc2c6Linsys Contractor Mithlesh Thukral u32 off; 4493d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale 4503d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale /* resetall */ 451c9517e5893db03ca8bd32b8783b39af58176947cDhananjay Phadke netxen_rom_lock(adapter); 452f98a9f693b5f4919d9c4085a2fd8d67c7e152f3eDhananjay Phadke NXWR32(adapter, NETXEN_ROMUSB_GLB_SW_RESET, 0xffffffff); 45327c915a4d843b90eb4065298969578d15e5e6ab0Dhananjay Phadke netxen_rom_unlock(adapter); 4543d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale 4552956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { 4562956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke if (netxen_rom_fast_read(adapter, 0, &n) != 0 || 45727c915a4d843b90eb4065298969578d15e5e6ab0Dhananjay Phadke (n != 0xcafecafe) || 4582956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke netxen_rom_fast_read(adapter, 4, &n) != 0) { 4592956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke printk(KERN_ERR "%s: ERROR Reading crb_init area: " 4602956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke "n: %08x\n", netxen_nic_driver_name, n); 4613d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale return -EIO; 4623d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale } 4632956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke offset = n & 0xffffU; 4642956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke n = (n >> 16) & 0xffffU; 4652956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke } else { 4662956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke if (netxen_rom_fast_read(adapter, 0, &n) != 0 || 4672956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke !(n & 0x80000000)) { 4682956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke printk(KERN_ERR "%s: ERROR Reading crb_init area: " 4692956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke "n: %08x\n", netxen_nic_driver_name, n); 4702956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke return -EIO; 4713d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale } 4722956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke offset = 1; 4732956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke n &= ~0x80000000; 4742956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke } 4752956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke 4760be367bd5d10634c0836f57a684432fee935d929Amit Kumar Salecha if (n >= 1024) { 4772956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke printk(KERN_ERR "%s:n=0x%x Error! NetXen card flash not" 4782956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke " initialized.\n", __func__, n); 4792956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke return -EIO; 4802956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke } 4813d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale 4822956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke buf = kcalloc(n, sizeof(struct crb_addr_pair), GFP_KERNEL); 4832956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke if (buf == NULL) { 4842956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke printk("%s: netxen_pinit_from_rom: Unable to calloc memory.\n", 4852956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke netxen_nic_driver_name); 4862956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke return -ENOMEM; 4872956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke } 4880be367bd5d10634c0836f57a684432fee935d929Amit Kumar Salecha 4892956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke for (i = 0; i < n; i++) { 4902956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke if (netxen_rom_fast_read(adapter, 8*i + 4*offset, &val) != 0 || 491584dbe9475313e117abf9d2af88164edfd429c9aDaniel Marjamäki netxen_rom_fast_read(adapter, 8*i + 4*offset + 4, &addr) != 0) { 492584dbe9475313e117abf9d2af88164edfd429c9aDaniel Marjamäki kfree(buf); 4932956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke return -EIO; 494584dbe9475313e117abf9d2af88164edfd429c9aDaniel Marjamäki } 4952956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke 4962956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke buf[i].addr = addr; 4972956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke buf[i].data = val; 4982956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke 4992956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke } 5000be367bd5d10634c0836f57a684432fee935d929Amit Kumar Salecha 5012956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke for (i = 0; i < n; i++) { 5022956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke 5032956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke off = netxen_decode_crb_addr(buf[i].addr); 5042956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke if (off == NETXEN_ADDR_ERROR) { 5052956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke printk(KERN_ERR"CRB init value out of range %x\n", 5061fcca1a5fc81689d191b7132318970c969b4b635Amit S. Kale buf[i].addr); 5072956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke continue; 5082956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke } 5092956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke off += NETXEN_PCI_CRBSPACE; 5100be367bd5d10634c0836f57a684432fee935d929Amit Kumar Salecha 5110be367bd5d10634c0836f57a684432fee935d929Amit Kumar Salecha if (off & 1) 5120be367bd5d10634c0836f57a684432fee935d929Amit Kumar Salecha continue; 5130be367bd5d10634c0836f57a684432fee935d929Amit Kumar Salecha 5142956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke /* skipping cold reboot MAGIC */ 5152956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke if (off == NETXEN_CAM_RAM(0x1fc)) 5162956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke continue; 5172956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke 5182956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { 5198bee0a91dd2f472d51dc107288c988ae0a0f371aDhananjay Phadke if (off == (NETXEN_CRB_I2C0 + 0x1c)) 5208bee0a91dd2f472d51dc107288c988ae0a0f371aDhananjay Phadke continue; 5212956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke /* do not reset PCI */ 5222956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke if (off == (ROMUSB_GLB + 0xbc)) 5231fcca1a5fc81689d191b7132318970c969b4b635Amit S. Kale continue; 52427c915a4d843b90eb4065298969578d15e5e6ab0Dhananjay Phadke if (off == (ROMUSB_GLB + 0xa8)) 52527c915a4d843b90eb4065298969578d15e5e6ab0Dhananjay Phadke continue; 52627c915a4d843b90eb4065298969578d15e5e6ab0Dhananjay Phadke if (off == (ROMUSB_GLB + 0xc8)) /* core clock */ 52727c915a4d843b90eb4065298969578d15e5e6ab0Dhananjay Phadke continue; 52827c915a4d843b90eb4065298969578d15e5e6ab0Dhananjay Phadke if (off == (ROMUSB_GLB + 0x24)) /* MN clock */ 52927c915a4d843b90eb4065298969578d15e5e6ab0Dhananjay Phadke continue; 53027c915a4d843b90eb4065298969578d15e5e6ab0Dhananjay Phadke if (off == (ROMUSB_GLB + 0x1c)) /* MS clock */ 53127c915a4d843b90eb4065298969578d15e5e6ab0Dhananjay Phadke continue; 532e7473f12be7712aafe6df163222f26caadee1175Amit Kumar Salecha if ((off & 0x0ff00000) == NETXEN_CRB_DDR_NET) 533e7473f12be7712aafe6df163222f26caadee1175Amit Kumar Salecha continue; 5340be367bd5d10634c0836f57a684432fee935d929Amit Kumar Salecha if (off == (NETXEN_CRB_PEG_NET_1 + 0x18) && 5350be367bd5d10634c0836f57a684432fee935d929Amit Kumar Salecha !NX_IS_REVISION_P3P(adapter->ahw.revision_id)) 5362956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke buf[i].data = 0x1020; 5372956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke /* skip the function enable register */ 5382956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke if (off == NETXEN_PCIE_REG(PCIE_SETUP_FUNCTION)) 5393d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale continue; 5402956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke if (off == NETXEN_PCIE_REG(PCIE_SETUP_FUNCTION2)) 5412956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke continue; 5422956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke if ((off & 0x0ff00000) == NETXEN_CRB_SMB) 5432956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke continue; 5442956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke } 5453d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale 54627c915a4d843b90eb4065298969578d15e5e6ab0Dhananjay Phadke init_delay = 1; 5472956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke /* After writing this register, HW needs time for CRB */ 5482956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke /* to quiet down (else crb_window returns 0xffffffff) */ 5492956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke if (off == NETXEN_ROMUSB_GLB_SW_RESET) { 55027c915a4d843b90eb4065298969578d15e5e6ab0Dhananjay Phadke init_delay = 1000; 5512956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) { 5523d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale /* hold xdma in reset also */ 553cb8011ad53e0855ef088e0e5a4bcb98fa90c70b6Amit S. Kale buf[i].data = NETXEN_NIC_XDMA_RESET; 55427c915a4d843b90eb4065298969578d15e5e6ab0Dhananjay Phadke buf[i].data = 0x8000ff; 5553d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale } 5562956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke } 5573d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale 558f98a9f693b5f4919d9c4085a2fd8d67c7e152f3eDhananjay Phadke NXWR32(adapter, off, buf[i].data); 5593d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale 56027c915a4d843b90eb4065298969578d15e5e6ab0Dhananjay Phadke msleep(init_delay); 5612956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke } 5622956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke kfree(buf); 5633d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale 5642956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke /* disable_peg_cache_all */ 5653d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale 5662956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke /* unreset_net_cache */ 5672956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) { 568f98a9f693b5f4919d9c4085a2fd8d67c7e152f3eDhananjay Phadke val = NXRD32(adapter, NETXEN_ROMUSB_GLB_SW_RESET); 569f98a9f693b5f4919d9c4085a2fd8d67c7e152f3eDhananjay Phadke NXWR32(adapter, NETXEN_ROMUSB_GLB_SW_RESET, (val & 0xffffff0f)); 5703d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale } 5712956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke 5722956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke /* p2dn replyCount */ 573f98a9f693b5f4919d9c4085a2fd8d67c7e152f3eDhananjay Phadke NXWR32(adapter, NETXEN_CRB_PEG_NET_D + 0xec, 0x1e); 5742956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke /* disable_peg_cache 0 */ 575f98a9f693b5f4919d9c4085a2fd8d67c7e152f3eDhananjay Phadke NXWR32(adapter, NETXEN_CRB_PEG_NET_D + 0x4c, 8); 5762956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke /* disable_peg_cache 1 */ 577f98a9f693b5f4919d9c4085a2fd8d67c7e152f3eDhananjay Phadke NXWR32(adapter, NETXEN_CRB_PEG_NET_I + 0x4c, 8); 5782956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke 5792956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke /* peg_clr_all */ 5802956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke 5812956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke /* peg_clr 0 */ 582f98a9f693b5f4919d9c4085a2fd8d67c7e152f3eDhananjay Phadke NXWR32(adapter, NETXEN_CRB_PEG_NET_0 + 0x8, 0); 583f98a9f693b5f4919d9c4085a2fd8d67c7e152f3eDhananjay Phadke NXWR32(adapter, NETXEN_CRB_PEG_NET_0 + 0xc, 0); 5842956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke /* peg_clr 1 */ 585f98a9f693b5f4919d9c4085a2fd8d67c7e152f3eDhananjay Phadke NXWR32(adapter, NETXEN_CRB_PEG_NET_1 + 0x8, 0); 586f98a9f693b5f4919d9c4085a2fd8d67c7e152f3eDhananjay Phadke NXWR32(adapter, NETXEN_CRB_PEG_NET_1 + 0xc, 0); 5872956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke /* peg_clr 2 */ 588f98a9f693b5f4919d9c4085a2fd8d67c7e152f3eDhananjay Phadke NXWR32(adapter, NETXEN_CRB_PEG_NET_2 + 0x8, 0); 589f98a9f693b5f4919d9c4085a2fd8d67c7e152f3eDhananjay Phadke NXWR32(adapter, NETXEN_CRB_PEG_NET_2 + 0xc, 0); 5902956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke /* peg_clr 3 */ 591f98a9f693b5f4919d9c4085a2fd8d67c7e152f3eDhananjay Phadke NXWR32(adapter, NETXEN_CRB_PEG_NET_3 + 0x8, 0); 592f98a9f693b5f4919d9c4085a2fd8d67c7e152f3eDhananjay Phadke NXWR32(adapter, NETXEN_CRB_PEG_NET_3 + 0xc, 0); 5933d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale return 0; 5943d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale} 5953d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale 596f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salechastatic struct uni_table_desc *nx_get_table_desc(const u8 *unirom, int section) 597f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha{ 598f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha uint32_t i; 599f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha struct uni_table_desc *directory = (struct uni_table_desc *) &unirom[0]; 600f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha __le32 entries = cpu_to_le32(directory->num_entries); 601f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha 602f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha for (i = 0; i < entries; i++) { 603f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha 604f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha __le32 offs = cpu_to_le32(directory->findex) + 605f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha (i * cpu_to_le32(directory->entry_size)); 606f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha __le32 tab_type = cpu_to_le32(*((u32 *)&unirom[offs] + 8)); 607f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha 608f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha if (tab_type == section) 609f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha return (struct uni_table_desc *) &unirom[offs]; 610f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha } 611f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha 612f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha return NULL; 613f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha} 614f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha 61510c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia#define QLCNIC_FILEHEADER_SIZE (14 * 4) 61610c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia 617f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salechastatic int 61810c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundianetxen_nic_validate_header(struct netxen_adapter *adapter) 61910c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia { 620f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha const u8 *unirom = adapter->fw->data; 62110c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia struct uni_table_desc *directory = (struct uni_table_desc *) &unirom[0]; 62210c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia u32 fw_file_size = adapter->fw->size; 62310c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia u32 tab_size; 624f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha __le32 entries; 62510c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia __le32 entry_size; 62610c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia 62710c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia if (fw_file_size < QLCNIC_FILEHEADER_SIZE) 62810c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia return -EINVAL; 62910c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia 63010c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia entries = cpu_to_le32(directory->num_entries); 63110c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia entry_size = cpu_to_le32(directory->entry_size); 63210c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia tab_size = cpu_to_le32(directory->findex) + (entries * entry_size); 63310c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia 63410c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia if (fw_file_size < tab_size) 63510c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia return -EINVAL; 63610c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia 63710c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia return 0; 63810c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia} 63910c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia 64010c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundiastatic int 64110c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundianetxen_nic_validate_bootld(struct netxen_adapter *adapter) 64210c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia{ 64310c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia struct uni_table_desc *tab_desc; 64410c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia struct uni_data_desc *descr; 64510c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia const u8 *unirom = adapter->fw->data; 64610c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia __le32 idx = cpu_to_le32(*((int *)&unirom[adapter->file_prd_off] + 64710c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia NX_UNI_BOOTLD_IDX_OFF)); 64810c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia u32 offs; 64910c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia u32 tab_size; 65010c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia u32 data_size; 65110c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia 65210c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia tab_desc = nx_get_table_desc(unirom, NX_UNI_DIR_SECT_BOOTLD); 65310c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia 65410c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia if (!tab_desc) 65510c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia return -EINVAL; 65610c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia 65710c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia tab_size = cpu_to_le32(tab_desc->findex) + 65810c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia (cpu_to_le32(tab_desc->entry_size) * (idx + 1)); 65910c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia 66010c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia if (adapter->fw->size < tab_size) 66110c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia return -EINVAL; 66210c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia 66310c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia offs = cpu_to_le32(tab_desc->findex) + 66410c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia (cpu_to_le32(tab_desc->entry_size) * (idx)); 66510c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia descr = (struct uni_data_desc *)&unirom[offs]; 66610c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia 66710c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia data_size = cpu_to_le32(descr->findex) + cpu_to_le32(descr->size); 66810c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia 66910c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia if (adapter->fw->size < data_size) 67010c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia return -EINVAL; 67110c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia 67210c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia return 0; 67310c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia} 67410c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia 67510c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundiastatic int 67610c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundianetxen_nic_validate_fw(struct netxen_adapter *adapter) 67710c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia{ 67810c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia struct uni_table_desc *tab_desc; 67910c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia struct uni_data_desc *descr; 68010c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia const u8 *unirom = adapter->fw->data; 68110c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia __le32 idx = cpu_to_le32(*((int *)&unirom[adapter->file_prd_off] + 68210c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia NX_UNI_FIRMWARE_IDX_OFF)); 68310c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia u32 offs; 68410c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia u32 tab_size; 68510c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia u32 data_size; 68610c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia 68710c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia tab_desc = nx_get_table_desc(unirom, NX_UNI_DIR_SECT_FW); 68810c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia 68910c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia if (!tab_desc) 69010c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia return -EINVAL; 691f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha 69210c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia tab_size = cpu_to_le32(tab_desc->findex) + 69310c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia (cpu_to_le32(tab_desc->entry_size) * (idx + 1)); 69410c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia 69510c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia if (adapter->fw->size < tab_size) 69610c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia return -EINVAL; 69710c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia 69810c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia offs = cpu_to_le32(tab_desc->findex) + 69910c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia (cpu_to_le32(tab_desc->entry_size) * (idx)); 70010c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia descr = (struct uni_data_desc *)&unirom[offs]; 70110c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia data_size = cpu_to_le32(descr->findex) + cpu_to_le32(descr->size); 70210c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia 70310c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia if (adapter->fw->size < data_size) 70410c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia return -EINVAL; 70510c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia 70610c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia return 0; 70710c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia} 70810c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia 70910c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia 71010c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundiastatic int 71110c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundianetxen_nic_validate_product_offs(struct netxen_adapter *adapter) 71210c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia{ 71310c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia struct uni_table_desc *ptab_descr; 71410c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia const u8 *unirom = adapter->fw->data; 715634d7df89a93a52561f598bf9512f4cf72946954Dhananjay Phadke int mn_present = (NX_IS_REVISION_P2(adapter->ahw.revision_id)) ? 716634d7df89a93a52561f598bf9512f4cf72946954Dhananjay Phadke 1 : netxen_p3_has_mn(adapter); 71710c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia __le32 entries; 71810c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia __le32 entry_size; 71910c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia u32 tab_size; 72010c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia u32 i; 721634d7df89a93a52561f598bf9512f4cf72946954Dhananjay Phadke 722f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha ptab_descr = nx_get_table_desc(unirom, NX_UNI_DIR_SECT_PRODUCT_TBL); 723f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha if (ptab_descr == NULL) 72410c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia return -EINVAL; 725f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha 726f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha entries = cpu_to_le32(ptab_descr->num_entries); 72710c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia entry_size = cpu_to_le32(ptab_descr->entry_size); 72810c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia tab_size = cpu_to_le32(ptab_descr->findex) + (entries * entry_size); 72910c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia 73010c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia if (adapter->fw->size < tab_size) 73110c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia return -EINVAL; 732f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha 733634d7df89a93a52561f598bf9512f4cf72946954Dhananjay Phadkenomn: 734f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha for (i = 0; i < entries; i++) { 735f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha 736f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha __le32 flags, file_chiprev, offs; 737f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha u8 chiprev = adapter->ahw.revision_id; 738f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha uint32_t flagbit; 739f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha 740f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha offs = cpu_to_le32(ptab_descr->findex) + 741f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha (i * cpu_to_le32(ptab_descr->entry_size)); 742f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha flags = cpu_to_le32(*((int *)&unirom[offs] + NX_UNI_FLAGS_OFF)); 743f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha file_chiprev = cpu_to_le32(*((int *)&unirom[offs] + 744f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha NX_UNI_CHIP_REV_OFF)); 745f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha 746f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha flagbit = mn_present ? 1 : 2; 747f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha 748f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha if ((chiprev == file_chiprev) && 749f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha ((1ULL << flagbit) & flags)) { 750f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha adapter->file_prd_off = offs; 751f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha return 0; 752f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha } 753f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha } 754f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha 755634d7df89a93a52561f598bf9512f4cf72946954Dhananjay Phadke if (mn_present && NX_IS_REVISION_P3(adapter->ahw.revision_id)) { 756634d7df89a93a52561f598bf9512f4cf72946954Dhananjay Phadke mn_present = 0; 757634d7df89a93a52561f598bf9512f4cf72946954Dhananjay Phadke goto nomn; 758634d7df89a93a52561f598bf9512f4cf72946954Dhananjay Phadke } 759634d7df89a93a52561f598bf9512f4cf72946954Dhananjay Phadke 76010c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia return -EINVAL; 761f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha} 762f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha 76310c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundiastatic int 76410c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundianetxen_nic_validate_unified_romimage(struct netxen_adapter *adapter) 76510c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia{ 76610c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia if (netxen_nic_validate_header(adapter)) { 76710c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia dev_err(&adapter->pdev->dev, 76810c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia "unified image: header validation failed\n"); 76910c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia return -EINVAL; 77010c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia } 77110c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia 77210c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia if (netxen_nic_validate_product_offs(adapter)) { 77310c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia dev_err(&adapter->pdev->dev, 77410c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia "unified image: product validation failed\n"); 77510c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia return -EINVAL; 77610c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia } 77710c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia 77810c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia if (netxen_nic_validate_bootld(adapter)) { 77910c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia dev_err(&adapter->pdev->dev, 78010c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia "unified image: bootld validation failed\n"); 78110c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia return -EINVAL; 78210c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia } 78310c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia 78410c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia if (netxen_nic_validate_fw(adapter)) { 78510c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia dev_err(&adapter->pdev->dev, 78610c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia "unified image: firmware validation failed\n"); 78710c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia return -EINVAL; 78810c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia } 78910c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia 79010c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia return 0; 79110c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia} 792f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha 793f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salechastatic struct uni_data_desc *nx_get_data_desc(struct netxen_adapter *adapter, 794f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha u32 section, u32 idx_offset) 795f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha{ 796f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha const u8 *unirom = adapter->fw->data; 797f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha int idx = cpu_to_le32(*((int *)&unirom[adapter->file_prd_off] + 798f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha idx_offset)); 799f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha struct uni_table_desc *tab_desc; 800f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha __le32 offs; 801f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha 802f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha tab_desc = nx_get_table_desc(unirom, section); 803f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha 804f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha if (tab_desc == NULL) 805f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha return NULL; 806f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha 807f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha offs = cpu_to_le32(tab_desc->findex) + 808f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha (cpu_to_le32(tab_desc->entry_size) * idx); 809f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha 810f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha return (struct uni_data_desc *)&unirom[offs]; 811f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha} 812f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha 813f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salechastatic u8 * 814f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salechanx_get_bootld_offs(struct netxen_adapter *adapter) 815f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha{ 816f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha u32 offs = NETXEN_BOOTLD_START; 817f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha 818f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha if (adapter->fw_type == NX_UNIFIED_ROMIMAGE) 819f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha offs = cpu_to_le32((nx_get_data_desc(adapter, 820f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha NX_UNI_DIR_SECT_BOOTLD, 821f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha NX_UNI_BOOTLD_IDX_OFF))->findex); 822f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha 823f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha return (u8 *)&adapter->fw->data[offs]; 824f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha} 825f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha 826f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salechastatic u8 * 827f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salechanx_get_fw_offs(struct netxen_adapter *adapter) 828f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha{ 829f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha u32 offs = NETXEN_IMAGE_START; 830f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha 831f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha if (adapter->fw_type == NX_UNIFIED_ROMIMAGE) 832f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha offs = cpu_to_le32((nx_get_data_desc(adapter, 833f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha NX_UNI_DIR_SECT_FW, 834f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha NX_UNI_FIRMWARE_IDX_OFF))->findex); 835f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha 836f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha return (u8 *)&adapter->fw->data[offs]; 837f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha} 838f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha 839f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salechastatic __le32 840f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salechanx_get_fw_size(struct netxen_adapter *adapter) 841f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha{ 842f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha if (adapter->fw_type == NX_UNIFIED_ROMIMAGE) 843f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha return cpu_to_le32((nx_get_data_desc(adapter, 844f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha NX_UNI_DIR_SECT_FW, 845f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha NX_UNI_FIRMWARE_IDX_OFF))->size); 846f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha else 847f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha return cpu_to_le32( 848f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha *(u32 *)&adapter->fw->data[NX_FW_SIZE_OFFSET]); 849f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha} 850f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha 851f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salechastatic __le32 852f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salechanx_get_fw_version(struct netxen_adapter *adapter) 853f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha{ 854f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha struct uni_data_desc *fw_data_desc; 855f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha const struct firmware *fw = adapter->fw; 856f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha __le32 major, minor, sub; 857f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha const u8 *ver_str; 858f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha int i, ret = 0; 859f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha 860f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha if (adapter->fw_type == NX_UNIFIED_ROMIMAGE) { 861f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha 862f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha fw_data_desc = nx_get_data_desc(adapter, 863f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha NX_UNI_DIR_SECT_FW, NX_UNI_FIRMWARE_IDX_OFF); 864f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha ver_str = fw->data + cpu_to_le32(fw_data_desc->findex) + 865f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha cpu_to_le32(fw_data_desc->size) - 17; 866f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha 867f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha for (i = 0; i < 12; i++) { 868f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha if (!strncmp(&ver_str[i], "REV=", 4)) { 869f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha ret = sscanf(&ver_str[i+4], "%u.%u.%u ", 870f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha &major, &minor, &sub); 871f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha break; 872f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha } 873f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha } 874f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha 875f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha if (ret != 3) 876f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha return 0; 877f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha 878f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha return major + (minor << 8) + (sub << 16); 879f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha 880f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha } else 881f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha return cpu_to_le32(*(u32 *)&fw->data[NX_FW_VERSION_OFFSET]); 882f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha} 883f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha 884f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salechastatic __le32 885f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salechanx_get_bios_version(struct netxen_adapter *adapter) 886f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha{ 887f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha const struct firmware *fw = adapter->fw; 888f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha __le32 bios_ver, prd_off = adapter->file_prd_off; 889f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha 890f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha if (adapter->fw_type == NX_UNIFIED_ROMIMAGE) { 891f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha bios_ver = cpu_to_le32(*((u32 *) (&fw->data[prd_off]) 892f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha + NX_UNI_BIOS_VERSION_OFF)); 893bb2792e0383793d5135ba777e93f0a918371394bAmit Kumar Salecha return (bios_ver << 16) + ((bios_ver >> 8) & 0xff00) + 894f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha (bios_ver >> 24); 895f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha } else 896f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha return cpu_to_le32(*(u32 *)&fw->data[NX_BIOS_VERSION_OFFSET]); 897f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha 898f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha} 899f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha 900f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadkeint 90167c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadkenetxen_need_fw_reset(struct netxen_adapter *adapter) 90267c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadke{ 90367c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadke u32 count, old_count; 90467c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadke u32 val, version, major, minor, build; 90567c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadke int i, timeout; 90667c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadke u8 fw_type; 90767c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadke 90867c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadke /* NX2031 firmware doesn't support heartbit */ 90967c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadke if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) 91067c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadke return 1; 91167c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadke 9126a808c6c02fb9f0ffa24ac7cca6cfc323cf98b21Amit Kumar Salecha if (adapter->need_fw_reset) 9136a808c6c02fb9f0ffa24ac7cca6cfc323cf98b21Amit Kumar Salecha return 1; 9146a808c6c02fb9f0ffa24ac7cca6cfc323cf98b21Amit Kumar Salecha 91567c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadke /* last attempt had failed */ 91667c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadke if (NXRD32(adapter, CRB_CMDPEG_STATE) == PHAN_INITIALIZE_FAILED) 91767c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadke return 1; 91867c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadke 919581e8ae49ea3a70b438991e388ded2dcbdbd2162Amit Kumar Salecha old_count = NXRD32(adapter, NETXEN_PEG_ALIVE_COUNTER); 92067c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadke 92167c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadke for (i = 0; i < 10; i++) { 92267c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadke 92367c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadke timeout = msleep_interruptible(200); 92467c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadke if (timeout) { 92567c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadke NXWR32(adapter, CRB_CMDPEG_STATE, 92667c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadke PHAN_INITIALIZE_FAILED); 92767c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadke return -EINTR; 92867c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadke } 92967c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadke 93067c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadke count = NXRD32(adapter, NETXEN_PEG_ALIVE_COUNTER); 93167c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadke if (count != old_count) 93267c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadke break; 93367c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadke } 93467c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadke 93567c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadke /* firmware is dead */ 93667c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadke if (count == old_count) 93767c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadke return 1; 93867c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadke 93967c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadke /* check if we have got newer or different file firmware */ 94067c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadke if (adapter->fw) { 94167c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadke 942f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha val = nx_get_fw_version(adapter); 94367c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadke 94467c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadke version = NETXEN_DECODE_VERSION(val); 94567c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadke 94667c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadke major = NXRD32(adapter, NETXEN_FW_VERSION_MAJOR); 94767c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadke minor = NXRD32(adapter, NETXEN_FW_VERSION_MINOR); 94867c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadke build = NXRD32(adapter, NETXEN_FW_VERSION_SUB); 94967c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadke 95067c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadke if (version > NETXEN_VERSION_CODE(major, minor, build)) 95167c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadke return 1; 95267c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadke 953f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha if (version == NETXEN_VERSION_CODE(major, minor, build) && 954f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha adapter->fw_type != NX_UNIFIED_ROMIMAGE) { 95567c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadke 95667c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadke val = NXRD32(adapter, NETXEN_MIU_MN_CONTROL); 95767c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadke fw_type = (val & 0x4) ? 95867c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadke NX_P3_CT_ROMIMAGE : NX_P3_MN_ROMIMAGE; 95967c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadke 96067c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadke if (adapter->fw_type != fw_type) 96167c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadke return 1; 96267c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadke } 96367c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadke } 96467c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadke 96567c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadke return 0; 96667c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadke} 96767c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadke 968e933d0198d399842f075c2c8af0f38630e7e4beeAmit Kumar Salecha#define NETXEN_MIN_P3_FW_SUPP NETXEN_VERSION_CODE(4, 0, 505) 969e933d0198d399842f075c2c8af0f38630e7e4beeAmit Kumar Salecha 970e933d0198d399842f075c2c8af0f38630e7e4beeAmit Kumar Salechaint 971e933d0198d399842f075c2c8af0f38630e7e4beeAmit Kumar Salechanetxen_check_flash_fw_compatibility(struct netxen_adapter *adapter) 972e933d0198d399842f075c2c8af0f38630e7e4beeAmit Kumar Salecha{ 973e933d0198d399842f075c2c8af0f38630e7e4beeAmit Kumar Salecha u32 flash_fw_ver, min_fw_ver; 974e933d0198d399842f075c2c8af0f38630e7e4beeAmit Kumar Salecha 975e933d0198d399842f075c2c8af0f38630e7e4beeAmit Kumar Salecha if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) 976e933d0198d399842f075c2c8af0f38630e7e4beeAmit Kumar Salecha return 0; 977e933d0198d399842f075c2c8af0f38630e7e4beeAmit Kumar Salecha 978e933d0198d399842f075c2c8af0f38630e7e4beeAmit Kumar Salecha if (netxen_rom_fast_read(adapter, 979e933d0198d399842f075c2c8af0f38630e7e4beeAmit Kumar Salecha NX_FW_VERSION_OFFSET, (int *)&flash_fw_ver)) { 980e933d0198d399842f075c2c8af0f38630e7e4beeAmit Kumar Salecha dev_err(&adapter->pdev->dev, "Unable to read flash fw" 981e933d0198d399842f075c2c8af0f38630e7e4beeAmit Kumar Salecha "version\n"); 982e933d0198d399842f075c2c8af0f38630e7e4beeAmit Kumar Salecha return -EIO; 983e933d0198d399842f075c2c8af0f38630e7e4beeAmit Kumar Salecha } 984e933d0198d399842f075c2c8af0f38630e7e4beeAmit Kumar Salecha 985e933d0198d399842f075c2c8af0f38630e7e4beeAmit Kumar Salecha flash_fw_ver = NETXEN_DECODE_VERSION(flash_fw_ver); 986e933d0198d399842f075c2c8af0f38630e7e4beeAmit Kumar Salecha min_fw_ver = NETXEN_MIN_P3_FW_SUPP; 987e933d0198d399842f075c2c8af0f38630e7e4beeAmit Kumar Salecha if (flash_fw_ver >= min_fw_ver) 988e933d0198d399842f075c2c8af0f38630e7e4beeAmit Kumar Salecha return 0; 989e933d0198d399842f075c2c8af0f38630e7e4beeAmit Kumar Salecha 990e933d0198d399842f075c2c8af0f38630e7e4beeAmit Kumar Salecha dev_info(&adapter->pdev->dev, "Flash fw[%d.%d.%d] is < min fw supported" 991e933d0198d399842f075c2c8af0f38630e7e4beeAmit Kumar Salecha "[4.0.505]. Please update firmware on flash\n", 992e933d0198d399842f075c2c8af0f38630e7e4beeAmit Kumar Salecha _major(flash_fw_ver), _minor(flash_fw_ver), 993e933d0198d399842f075c2c8af0f38630e7e4beeAmit Kumar Salecha _build(flash_fw_ver)); 994e933d0198d399842f075c2c8af0f38630e7e4beeAmit Kumar Salecha return -EINVAL; 995e933d0198d399842f075c2c8af0f38630e7e4beeAmit Kumar Salecha} 996e933d0198d399842f075c2c8af0f38630e7e4beeAmit Kumar Salecha 99767c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadkestatic char *fw_name[] = { 9987e8e5d9718744b817bfea6f020586d7035cc89f4Dhananjay Phadke NX_P2_MN_ROMIMAGE_NAME, 9997e8e5d9718744b817bfea6f020586d7035cc89f4Dhananjay Phadke NX_P3_CT_ROMIMAGE_NAME, 10007e8e5d9718744b817bfea6f020586d7035cc89f4Dhananjay Phadke NX_P3_MN_ROMIMAGE_NAME, 10017e8e5d9718744b817bfea6f020586d7035cc89f4Dhananjay Phadke NX_UNIFIED_ROMIMAGE_NAME, 10027e8e5d9718744b817bfea6f020586d7035cc89f4Dhananjay Phadke NX_FLASH_ROMIMAGE_NAME, 100367c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadke}; 100467c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadke 100567c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadkeint 1006f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadkenetxen_load_firmware(struct netxen_adapter *adapter) 1007f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke{ 1008f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke u64 *ptr64; 1009f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke u32 i, flashaddr, size; 1010f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke const struct firmware *fw = adapter->fw; 101167c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadke struct pci_dev *pdev = adapter->pdev; 101267c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadke 101367c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadke dev_info(&pdev->dev, "loading firmware from %s\n", 101467c38fc61af930fa03b042932b6b14fbf8126222Dhananjay Phadke fw_name[adapter->fw_type]); 1015f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke 1016f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) 1017f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke NXWR32(adapter, NETXEN_ROMUSB_GLB_CAS_RST, 1); 1018f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke 1019f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke if (fw) { 1020f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke __le64 data; 1021f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke 1022f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke size = (NETXEN_IMAGE_START - NETXEN_BOOTLD_START) / 8; 1023f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke 1024f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha ptr64 = (u64 *)nx_get_bootld_offs(adapter); 1025f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke flashaddr = NETXEN_BOOTLD_START; 1026f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke 1027f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke for (i = 0; i < size; i++) { 1028f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke data = cpu_to_le64(ptr64[i]); 1029f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha 1030f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha if (adapter->pci_mem_write(adapter, flashaddr, data)) 10311f5e055db369a5d1c74174571585a4ec2e6c40fbAmit Kumar Salecha return -EIO; 10321f5e055db369a5d1c74174571585a4ec2e6c40fbAmit Kumar Salecha 1033f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke flashaddr += 8; 1034f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke } 1035f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke 1036f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha size = (__force u32)nx_get_fw_size(adapter) / 8; 1037f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke 1038f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha ptr64 = (u64 *)nx_get_fw_offs(adapter); 1039f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke flashaddr = NETXEN_IMAGE_START; 1040f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke 1041f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke for (i = 0; i < size; i++) { 1042f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke data = cpu_to_le64(ptr64[i]); 1043f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke 1044f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke if (adapter->pci_mem_write(adapter, 10451f5e055db369a5d1c74174571585a4ec2e6c40fbAmit Kumar Salecha flashaddr, data)) 1046f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke return -EIO; 1047f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke 1048f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke flashaddr += 8; 1049f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke } 1050e270299a2f7a3040fe598113f74c2a7d5f63b582Amit Kumar Salecha 1051e270299a2f7a3040fe598113f74c2a7d5f63b582Amit Kumar Salecha size = (__force u32)nx_get_fw_size(adapter) % 8; 1052e270299a2f7a3040fe598113f74c2a7d5f63b582Amit Kumar Salecha if (size) { 1053e270299a2f7a3040fe598113f74c2a7d5f63b582Amit Kumar Salecha data = cpu_to_le64(ptr64[i]); 1054e270299a2f7a3040fe598113f74c2a7d5f63b582Amit Kumar Salecha 1055e270299a2f7a3040fe598113f74c2a7d5f63b582Amit Kumar Salecha if (adapter->pci_mem_write(adapter, 1056e270299a2f7a3040fe598113f74c2a7d5f63b582Amit Kumar Salecha flashaddr, data)) 1057e270299a2f7a3040fe598113f74c2a7d5f63b582Amit Kumar Salecha return -EIO; 1058e270299a2f7a3040fe598113f74c2a7d5f63b582Amit Kumar Salecha } 1059e270299a2f7a3040fe598113f74c2a7d5f63b582Amit Kumar Salecha 1060f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke } else { 1061f78c0850d2ebe7a44a4b0263480a2f1a36a92218Amit Kumar Salecha u64 data; 1062f78c0850d2ebe7a44a4b0263480a2f1a36a92218Amit Kumar Salecha u32 hi, lo; 1063f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke 1064f78c0850d2ebe7a44a4b0263480a2f1a36a92218Amit Kumar Salecha size = (NETXEN_IMAGE_START - NETXEN_BOOTLD_START) / 8; 1065f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke flashaddr = NETXEN_BOOTLD_START; 1066f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke 1067f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke for (i = 0; i < size; i++) { 1068f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke if (netxen_rom_fast_read(adapter, 10691f5e055db369a5d1c74174571585a4ec2e6c40fbAmit Kumar Salecha flashaddr, (int *)&lo) != 0) 1070f78c0850d2ebe7a44a4b0263480a2f1a36a92218Amit Kumar Salecha return -EIO; 1071f78c0850d2ebe7a44a4b0263480a2f1a36a92218Amit Kumar Salecha if (netxen_rom_fast_read(adapter, 10721f5e055db369a5d1c74174571585a4ec2e6c40fbAmit Kumar Salecha flashaddr + 4, (int *)&hi) != 0) 1073f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke return -EIO; 1074f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke 1075f78c0850d2ebe7a44a4b0263480a2f1a36a92218Amit Kumar Salecha /* hi, lo are already in host endian byteorder */ 1076f78c0850d2ebe7a44a4b0263480a2f1a36a92218Amit Kumar Salecha data = (((u64)hi << 32) | lo); 1077f78c0850d2ebe7a44a4b0263480a2f1a36a92218Amit Kumar Salecha 1078f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke if (adapter->pci_mem_write(adapter, 10791f5e055db369a5d1c74174571585a4ec2e6c40fbAmit Kumar Salecha flashaddr, data)) 1080f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke return -EIO; 1081f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke 1082f78c0850d2ebe7a44a4b0263480a2f1a36a92218Amit Kumar Salecha flashaddr += 8; 1083f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke } 1084f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke } 1085f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke msleep(1); 1086f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke 10870be367bd5d10634c0836f57a684432fee935d929Amit Kumar Salecha if (NX_IS_REVISION_P3P(adapter->ahw.revision_id)) { 10880be367bd5d10634c0836f57a684432fee935d929Amit Kumar Salecha NXWR32(adapter, NETXEN_CRB_PEG_NET_0 + 0x18, 0x1020); 10890be367bd5d10634c0836f57a684432fee935d929Amit Kumar Salecha NXWR32(adapter, NETXEN_ROMUSB_GLB_SW_RESET, 0x80001e); 10900be367bd5d10634c0836f57a684432fee935d929Amit Kumar Salecha } else if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) 1091f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke NXWR32(adapter, NETXEN_ROMUSB_GLB_SW_RESET, 0x80001d); 1092f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke else { 1093f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke NXWR32(adapter, NETXEN_ROMUSB_GLB_CHIP_CLK_CTRL, 0x3fff); 1094f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke NXWR32(adapter, NETXEN_ROMUSB_GLB_CAS_RST, 0); 1095f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke } 1096f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke 1097f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke return 0; 1098f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke} 1099f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke 1100f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadkestatic int 1101f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salechanetxen_validate_firmware(struct netxen_adapter *adapter) 1102f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke{ 1103f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke __le32 val; 1104e933d0198d399842f075c2c8af0f38630e7e4beeAmit Kumar Salecha __le32 flash_fw_ver; 1105e933d0198d399842f075c2c8af0f38630e7e4beeAmit Kumar Salecha u32 file_fw_ver, min_ver, bios; 1106f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke struct pci_dev *pdev = adapter->pdev; 1107f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke const struct firmware *fw = adapter->fw; 1108f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha u8 fw_type = adapter->fw_type; 1109e933d0198d399842f075c2c8af0f38630e7e4beeAmit Kumar Salecha u32 crbinit_fix_fw; 1110f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke 1111f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha if (fw_type == NX_UNIFIED_ROMIMAGE) { 111210c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia if (netxen_nic_validate_unified_romimage(adapter)) 1113f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha return -EINVAL; 1114f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha } else { 1115f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha val = cpu_to_le32(*(u32 *)&fw->data[NX_FW_MAGIC_OFFSET]); 1116f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha if ((__force u32)val != NETXEN_BDINFO_MAGIC) 1117f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha return -EINVAL; 1118f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke 111910c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia if (fw->size < NX_FW_MIN_SIZE) 112010c0f2a852a529eacf2f223bbaef47832224a521Rajesh K Borundia return -EINVAL; 1121f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha } 1122f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha 1123f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha val = nx_get_fw_version(adapter); 1124f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke 1125f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) 1126e933d0198d399842f075c2c8af0f38630e7e4beeAmit Kumar Salecha min_ver = NETXEN_MIN_P3_FW_SUPP; 1127f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke else 1128f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke min_ver = NETXEN_VERSION_CODE(3, 4, 216); 1129f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke 1130e933d0198d399842f075c2c8af0f38630e7e4beeAmit Kumar Salecha file_fw_ver = NETXEN_DECODE_VERSION(val); 1131f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke 1132e933d0198d399842f075c2c8af0f38630e7e4beeAmit Kumar Salecha if ((_major(file_fw_ver) > _NETXEN_NIC_LINUX_MAJOR) || 1133e933d0198d399842f075c2c8af0f38630e7e4beeAmit Kumar Salecha (file_fw_ver < min_ver)) { 1134f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke dev_err(&pdev->dev, 1135f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke "%s: firmware version %d.%d.%d unsupported\n", 1136e933d0198d399842f075c2c8af0f38630e7e4beeAmit Kumar Salecha fw_name[fw_type], _major(file_fw_ver), _minor(file_fw_ver), 1137e933d0198d399842f075c2c8af0f38630e7e4beeAmit Kumar Salecha _build(file_fw_ver)); 1138f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke return -EINVAL; 1139f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke } 1140f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke 1141f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha val = nx_get_bios_version(adapter); 1142f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke netxen_rom_fast_read(adapter, NX_BIOS_VERSION_OFFSET, (int *)&bios); 1143f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke if ((__force u32)val != bios) { 1144f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke dev_err(&pdev->dev, "%s: firmware bios is incompatible\n", 1145f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha fw_name[fw_type]); 1146f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke return -EINVAL; 1147f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke } 1148f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke 1149f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke if (netxen_rom_fast_read(adapter, 1150e933d0198d399842f075c2c8af0f38630e7e4beeAmit Kumar Salecha NX_FW_VERSION_OFFSET, (int *)&flash_fw_ver)) { 1151e933d0198d399842f075c2c8af0f38630e7e4beeAmit Kumar Salecha dev_err(&pdev->dev, "Unable to read flash fw version\n"); 1152f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke return -EIO; 1153e933d0198d399842f075c2c8af0f38630e7e4beeAmit Kumar Salecha } 1154e933d0198d399842f075c2c8af0f38630e7e4beeAmit Kumar Salecha flash_fw_ver = NETXEN_DECODE_VERSION(flash_fw_ver); 1155e933d0198d399842f075c2c8af0f38630e7e4beeAmit Kumar Salecha 1156e933d0198d399842f075c2c8af0f38630e7e4beeAmit Kumar Salecha /* New fw from file is not allowed, if fw on flash is < 4.0.554 */ 1157e933d0198d399842f075c2c8af0f38630e7e4beeAmit Kumar Salecha crbinit_fix_fw = NETXEN_VERSION_CODE(4, 0, 554); 1158e933d0198d399842f075c2c8af0f38630e7e4beeAmit Kumar Salecha if (file_fw_ver >= crbinit_fix_fw && flash_fw_ver < crbinit_fix_fw && 1159e933d0198d399842f075c2c8af0f38630e7e4beeAmit Kumar Salecha NX_IS_REVISION_P3(adapter->ahw.revision_id)) { 1160e933d0198d399842f075c2c8af0f38630e7e4beeAmit Kumar Salecha dev_err(&pdev->dev, "Incompatibility detected between driver " 1161e933d0198d399842f075c2c8af0f38630e7e4beeAmit Kumar Salecha "and firmware version on flash. This configuration " 1162e933d0198d399842f075c2c8af0f38630e7e4beeAmit Kumar Salecha "is not recommended. Please update the firmware on " 1163e933d0198d399842f075c2c8af0f38630e7e4beeAmit Kumar Salecha "flash immediately\n"); 1164f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke return -EINVAL; 116598e31bb00983a5b6d638a31e4ff77e5ca1ccf93eDhananjay Phadke } 1166f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke 1167e933d0198d399842f075c2c8af0f38630e7e4beeAmit Kumar Salecha /* check if flashed firmware is newer only for no-mn and P2 case*/ 1168e933d0198d399842f075c2c8af0f38630e7e4beeAmit Kumar Salecha if (!netxen_p3_has_mn(adapter) || 1169e933d0198d399842f075c2c8af0f38630e7e4beeAmit Kumar Salecha NX_IS_REVISION_P2(adapter->ahw.revision_id)) { 1170e933d0198d399842f075c2c8af0f38630e7e4beeAmit Kumar Salecha if (flash_fw_ver > file_fw_ver) { 1171e933d0198d399842f075c2c8af0f38630e7e4beeAmit Kumar Salecha dev_info(&pdev->dev, "%s: firmware is older than flash\n", 1172e933d0198d399842f075c2c8af0f38630e7e4beeAmit Kumar Salecha fw_name[fw_type]); 1173e933d0198d399842f075c2c8af0f38630e7e4beeAmit Kumar Salecha return -EINVAL; 1174e933d0198d399842f075c2c8af0f38630e7e4beeAmit Kumar Salecha } 1175e933d0198d399842f075c2c8af0f38630e7e4beeAmit Kumar Salecha } 1176e933d0198d399842f075c2c8af0f38630e7e4beeAmit Kumar Salecha 1177f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke NXWR32(adapter, NETXEN_CAM_RAM(0x1fc), NETXEN_BDINFO_MAGIC); 1178f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke return 0; 1179f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke} 1180f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke 1181f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salechastatic void 1182f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salechanx_get_next_fwtype(struct netxen_adapter *adapter) 1183f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha{ 1184f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha u8 fw_type; 1185f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha 1186f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha switch (adapter->fw_type) { 1187f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha case NX_UNKNOWN_ROMIMAGE: 1188f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha fw_type = NX_UNIFIED_ROMIMAGE; 1189f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha break; 1190f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha 1191f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha case NX_UNIFIED_ROMIMAGE: 1192f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha if (NX_IS_REVISION_P3P(adapter->ahw.revision_id)) 1193f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha fw_type = NX_FLASH_ROMIMAGE; 1194f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha else if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) 1195f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha fw_type = NX_P2_MN_ROMIMAGE; 1196f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha else if (netxen_p3_has_mn(adapter)) 1197f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha fw_type = NX_P3_MN_ROMIMAGE; 1198f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha else 1199f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha fw_type = NX_P3_CT_ROMIMAGE; 1200f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha break; 1201f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha 1202f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha case NX_P3_MN_ROMIMAGE: 1203f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha fw_type = NX_P3_CT_ROMIMAGE; 1204f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha break; 1205f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha 1206f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha case NX_P2_MN_ROMIMAGE: 1207f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha case NX_P3_CT_ROMIMAGE: 1208f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha default: 1209f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha fw_type = NX_FLASH_ROMIMAGE; 1210f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha break; 1211f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha } 1212f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha 1213f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha adapter->fw_type = fw_type; 1214f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha} 1215f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha 12166598b169b856793f8f9b80a3f3c5a48f5eaf40e3Dhananjay Phadkestatic int 12176598b169b856793f8f9b80a3f3c5a48f5eaf40e3Dhananjay Phadkenetxen_p3_has_mn(struct netxen_adapter *adapter) 1218f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke{ 1219f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke u32 capability, flashed_ver; 1220f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke capability = 0; 1221f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke 1222634d7df89a93a52561f598bf9512f4cf72946954Dhananjay Phadke /* NX2031 always had MN */ 1223634d7df89a93a52561f598bf9512f4cf72946954Dhananjay Phadke if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) 1224634d7df89a93a52561f598bf9512f4cf72946954Dhananjay Phadke return 1; 1225634d7df89a93a52561f598bf9512f4cf72946954Dhananjay Phadke 1226f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke netxen_rom_fast_read(adapter, 1227f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke NX_FW_VERSION_OFFSET, (int *)&flashed_ver); 122898e31bb00983a5b6d638a31e4ff77e5ca1ccf93eDhananjay Phadke flashed_ver = NETXEN_DECODE_VERSION(flashed_ver); 122998e31bb00983a5b6d638a31e4ff77e5ca1ccf93eDhananjay Phadke 1230f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke if (flashed_ver >= NETXEN_VERSION_CODE(4, 0, 220)) { 12316598b169b856793f8f9b80a3f3c5a48f5eaf40e3Dhananjay Phadke 1232f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke capability = NXRD32(adapter, NX_PEG_TUNE_CAPABILITY); 12336598b169b856793f8f9b80a3f3c5a48f5eaf40e3Dhananjay Phadke if (capability & NX_PEG_TUNE_MN_PRESENT) 12346598b169b856793f8f9b80a3f3c5a48f5eaf40e3Dhananjay Phadke return 1; 12356598b169b856793f8f9b80a3f3c5a48f5eaf40e3Dhananjay Phadke } 12366598b169b856793f8f9b80a3f3c5a48f5eaf40e3Dhananjay Phadke return 0; 12376598b169b856793f8f9b80a3f3c5a48f5eaf40e3Dhananjay Phadke} 12386598b169b856793f8f9b80a3f3c5a48f5eaf40e3Dhananjay Phadke 12396598b169b856793f8f9b80a3f3c5a48f5eaf40e3Dhananjay Phadkevoid netxen_request_firmware(struct netxen_adapter *adapter) 12406598b169b856793f8f9b80a3f3c5a48f5eaf40e3Dhananjay Phadke{ 12416598b169b856793f8f9b80a3f3c5a48f5eaf40e3Dhananjay Phadke struct pci_dev *pdev = adapter->pdev; 12426598b169b856793f8f9b80a3f3c5a48f5eaf40e3Dhananjay Phadke int rc = 0; 12436598b169b856793f8f9b80a3f3c5a48f5eaf40e3Dhananjay Phadke 1244f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha adapter->fw_type = NX_UNKNOWN_ROMIMAGE; 1245f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke 1246f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salechanext: 1247f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha nx_get_next_fwtype(adapter); 1248f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke 1249f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha if (adapter->fw_type == NX_FLASH_ROMIMAGE) { 1250f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke adapter->fw = NULL; 1251f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha } else { 1252f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha rc = request_firmware(&adapter->fw, 1253f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha fw_name[adapter->fw_type], &pdev->dev); 1254f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha if (rc != 0) 1255f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha goto next; 1256f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha 1257f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha rc = netxen_validate_firmware(adapter); 1258f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha if (rc != 0) { 1259f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha release_firmware(adapter->fw); 1260f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke msleep(1); 1261f50330f90b9aa42b7058650ce66b85f1b443ab11Amit Kumar Salecha goto next; 1262f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke } 1263f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke } 1264f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke} 1265f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke 1266f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke 1267f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadkevoid 1268f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadkenetxen_release_firmware(struct netxen_adapter *adapter) 1269f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke{ 1270f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke if (adapter->fw) 1271f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke release_firmware(adapter->fw); 1272db4cfd8a6149e778befb2ff6e6f91cdc6394cbe6Dhananjay Phadke adapter->fw = NULL; 1273f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke} 1274f7185c71234434d48b96f9a0387737df1759a4afDhananjay Phadke 127583ac51fa747c3a74372417629fcad4b110857b77Dhananjay Phadkeint netxen_init_dummy_dma(struct netxen_adapter *adapter) 1276ed25ffa16434724f5ed825aa48734c7f3aefa203Amit S. Kale{ 127783ac51fa747c3a74372417629fcad4b110857b77Dhananjay Phadke u64 addr; 127883ac51fa747c3a74372417629fcad4b110857b77Dhananjay Phadke u32 hi, lo; 1279ed25ffa16434724f5ed825aa48734c7f3aefa203Amit S. Kale 128083ac51fa747c3a74372417629fcad4b110857b77Dhananjay Phadke if (!NX_IS_REVISION_P2(adapter->ahw.revision_id)) 128183ac51fa747c3a74372417629fcad4b110857b77Dhananjay Phadke return 0; 128283ac51fa747c3a74372417629fcad4b110857b77Dhananjay Phadke 128383ac51fa747c3a74372417629fcad4b110857b77Dhananjay Phadke adapter->dummy_dma.addr = pci_alloc_consistent(adapter->pdev, 1284ed25ffa16434724f5ed825aa48734c7f3aefa203Amit S. Kale NETXEN_HOST_DUMMY_DMA_SIZE, 1285ed25ffa16434724f5ed825aa48734c7f3aefa203Amit S. Kale &adapter->dummy_dma.phys_addr); 1286ed25ffa16434724f5ed825aa48734c7f3aefa203Amit S. Kale if (adapter->dummy_dma.addr == NULL) { 128783ac51fa747c3a74372417629fcad4b110857b77Dhananjay Phadke dev_err(&adapter->pdev->dev, 128883ac51fa747c3a74372417629fcad4b110857b77Dhananjay Phadke "ERROR: Could not allocate dummy DMA memory\n"); 1289ed25ffa16434724f5ed825aa48734c7f3aefa203Amit S. Kale return -ENOMEM; 1290ed25ffa16434724f5ed825aa48734c7f3aefa203Amit S. Kale } 1291ed25ffa16434724f5ed825aa48734c7f3aefa203Amit S. Kale 1292ed25ffa16434724f5ed825aa48734c7f3aefa203Amit S. Kale addr = (uint64_t) adapter->dummy_dma.phys_addr; 1293ed25ffa16434724f5ed825aa48734c7f3aefa203Amit S. Kale hi = (addr >> 32) & 0xffffffff; 1294ed25ffa16434724f5ed825aa48734c7f3aefa203Amit S. Kale lo = addr & 0xffffffff; 1295ed25ffa16434724f5ed825aa48734c7f3aefa203Amit S. Kale 1296f98a9f693b5f4919d9c4085a2fd8d67c7e152f3eDhananjay Phadke NXWR32(adapter, CRB_HOST_DUMMY_BUF_ADDR_HI, hi); 1297f98a9f693b5f4919d9c4085a2fd8d67c7e152f3eDhananjay Phadke NXWR32(adapter, CRB_HOST_DUMMY_BUF_ADDR_LO, lo); 1298ed25ffa16434724f5ed825aa48734c7f3aefa203Amit S. Kale 1299ed25ffa16434724f5ed825aa48734c7f3aefa203Amit S. Kale return 0; 1300ed25ffa16434724f5ed825aa48734c7f3aefa203Amit S. Kale} 1301ed25ffa16434724f5ed825aa48734c7f3aefa203Amit S. Kale 130283ac51fa747c3a74372417629fcad4b110857b77Dhananjay Phadke/* 130383ac51fa747c3a74372417629fcad4b110857b77Dhananjay Phadke * NetXen DMA watchdog control: 130483ac51fa747c3a74372417629fcad4b110857b77Dhananjay Phadke * 130583ac51fa747c3a74372417629fcad4b110857b77Dhananjay Phadke * Bit 0 : enabled => R/O: 1 watchdog active, 0 inactive 130683ac51fa747c3a74372417629fcad4b110857b77Dhananjay Phadke * Bit 1 : disable_request => 1 req disable dma watchdog 130783ac51fa747c3a74372417629fcad4b110857b77Dhananjay Phadke * Bit 2 : enable_request => 1 req enable dma watchdog 130883ac51fa747c3a74372417629fcad4b110857b77Dhananjay Phadke * Bit 3-31 : unused 130983ac51fa747c3a74372417629fcad4b110857b77Dhananjay Phadke */ 131083ac51fa747c3a74372417629fcad4b110857b77Dhananjay Phadkevoid netxen_free_dummy_dma(struct netxen_adapter *adapter) 1311ed25ffa16434724f5ed825aa48734c7f3aefa203Amit S. Kale{ 131215eef1e1b718667981da92d2fa18283f181c117cDhananjay Phadke int i = 100; 131383ac51fa747c3a74372417629fcad4b110857b77Dhananjay Phadke u32 ctrl; 131483ac51fa747c3a74372417629fcad4b110857b77Dhananjay Phadke 131583ac51fa747c3a74372417629fcad4b110857b77Dhananjay Phadke if (!NX_IS_REVISION_P2(adapter->ahw.revision_id)) 131683ac51fa747c3a74372417629fcad4b110857b77Dhananjay Phadke return; 131715eef1e1b718667981da92d2fa18283f181c117cDhananjay Phadke 131815eef1e1b718667981da92d2fa18283f181c117cDhananjay Phadke if (!adapter->dummy_dma.addr) 131915eef1e1b718667981da92d2fa18283f181c117cDhananjay Phadke return; 1320439b454edf551f5a6eb49de6b868015724d275abDhananjay Phadke 132183ac51fa747c3a74372417629fcad4b110857b77Dhananjay Phadke ctrl = NXRD32(adapter, NETXEN_DMA_WATCHDOG_CTRL); 132283ac51fa747c3a74372417629fcad4b110857b77Dhananjay Phadke if ((ctrl & 0x1) != 0) { 132383ac51fa747c3a74372417629fcad4b110857b77Dhananjay Phadke NXWR32(adapter, NETXEN_DMA_WATCHDOG_CTRL, (ctrl | 0x2)); 132483ac51fa747c3a74372417629fcad4b110857b77Dhananjay Phadke 132583ac51fa747c3a74372417629fcad4b110857b77Dhananjay Phadke while ((ctrl & 0x1) != 0) { 132683ac51fa747c3a74372417629fcad4b110857b77Dhananjay Phadke 1327439b454edf551f5a6eb49de6b868015724d275abDhananjay Phadke msleep(50); 132883ac51fa747c3a74372417629fcad4b110857b77Dhananjay Phadke 132983ac51fa747c3a74372417629fcad4b110857b77Dhananjay Phadke ctrl = NXRD32(adapter, NETXEN_DMA_WATCHDOG_CTRL); 133083ac51fa747c3a74372417629fcad4b110857b77Dhananjay Phadke 133183ac51fa747c3a74372417629fcad4b110857b77Dhananjay Phadke if (--i == 0) 1332439b454edf551f5a6eb49de6b868015724d275abDhananjay Phadke break; 13336403eab143205a45a5493166ff8bf7e3646f4a77Joe Perches } 133415eef1e1b718667981da92d2fa18283f181c117cDhananjay Phadke } 1335439b454edf551f5a6eb49de6b868015724d275abDhananjay Phadke 133615eef1e1b718667981da92d2fa18283f181c117cDhananjay Phadke if (i) { 133715eef1e1b718667981da92d2fa18283f181c117cDhananjay Phadke pci_free_consistent(adapter->pdev, 133815eef1e1b718667981da92d2fa18283f181c117cDhananjay Phadke NETXEN_HOST_DUMMY_DMA_SIZE, 133915eef1e1b718667981da92d2fa18283f181c117cDhananjay Phadke adapter->dummy_dma.addr, 134015eef1e1b718667981da92d2fa18283f181c117cDhananjay Phadke adapter->dummy_dma.phys_addr); 134115eef1e1b718667981da92d2fa18283f181c117cDhananjay Phadke adapter->dummy_dma.addr = NULL; 134283ac51fa747c3a74372417629fcad4b110857b77Dhananjay Phadke } else 134383ac51fa747c3a74372417629fcad4b110857b77Dhananjay Phadke dev_err(&adapter->pdev->dev, "dma_watchdog_shutdown failed\n"); 1344ed25ffa16434724f5ed825aa48734c7f3aefa203Amit S. Kale} 1345ed25ffa16434724f5ed825aa48734c7f3aefa203Amit S. Kale 134696acb6eb8effe7c2549909e2ee49f4130f2c167dDhananjay Phadkeint netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val) 13473d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale{ 13483d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale u32 val = 0; 13492956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke int retries = 60; 13503d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale 135196f2ebd2e10417da151202c750d8664767a2194bDhananjay Phadke if (pegtune_val) 135296f2ebd2e10417da151202c750d8664767a2194bDhananjay Phadke return 0; 135396f2ebd2e10417da151202c750d8664767a2194bDhananjay Phadke 135496f2ebd2e10417da151202c750d8664767a2194bDhananjay Phadke do { 135596f2ebd2e10417da151202c750d8664767a2194bDhananjay Phadke val = NXRD32(adapter, CRB_CMDPEG_STATE); 135696acb6eb8effe7c2549909e2ee49f4130f2c167dDhananjay Phadke 135796f2ebd2e10417da151202c750d8664767a2194bDhananjay Phadke switch (val) { 135896f2ebd2e10417da151202c750d8664767a2194bDhananjay Phadke case PHAN_INITIALIZE_COMPLETE: 135996f2ebd2e10417da151202c750d8664767a2194bDhananjay Phadke case PHAN_INITIALIZE_ACK: 136096f2ebd2e10417da151202c750d8664767a2194bDhananjay Phadke return 0; 136196f2ebd2e10417da151202c750d8664767a2194bDhananjay Phadke case PHAN_INITIALIZE_FAILED: 136296f2ebd2e10417da151202c750d8664767a2194bDhananjay Phadke goto out_err; 136396f2ebd2e10417da151202c750d8664767a2194bDhananjay Phadke default: 136496f2ebd2e10417da151202c750d8664767a2194bDhananjay Phadke break; 136596f2ebd2e10417da151202c750d8664767a2194bDhananjay Phadke } 136696acb6eb8effe7c2549909e2ee49f4130f2c167dDhananjay Phadke 136796f2ebd2e10417da151202c750d8664767a2194bDhananjay Phadke msleep(500); 13682956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke 136996f2ebd2e10417da151202c750d8664767a2194bDhananjay Phadke } while (--retries); 13702956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke 137196f2ebd2e10417da151202c750d8664767a2194bDhananjay Phadke NXWR32(adapter, CRB_CMDPEG_STATE, PHAN_INITIALIZE_FAILED); 137296acb6eb8effe7c2549909e2ee49f4130f2c167dDhananjay Phadke 137396f2ebd2e10417da151202c750d8664767a2194bDhananjay Phadkeout_err: 137496f2ebd2e10417da151202c750d8664767a2194bDhananjay Phadke dev_warn(&adapter->pdev->dev, "firmware init failed\n"); 137596f2ebd2e10417da151202c750d8664767a2194bDhananjay Phadke return -EIO; 13763d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale} 13773d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale 137856a007871a6689db80e19f63fe6dc3692daa2a6fDhananjay Phadkestatic int 137956a007871a6689db80e19f63fe6dc3692daa2a6fDhananjay Phadkenetxen_receive_peg_ready(struct netxen_adapter *adapter) 13802956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke{ 13812956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke u32 val = 0; 13822956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke int retries = 2000; 13832956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke 13842956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke do { 1385f98a9f693b5f4919d9c4085a2fd8d67c7e152f3eDhananjay Phadke val = NXRD32(adapter, CRB_RCVPEG_STATE); 13862956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke 13872956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke if (val == PHAN_PEG_RCV_INITIALIZED) 13882956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke return 0; 13892956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke 13902956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke msleep(10); 13912956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke 13922956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke } while (--retries); 13932956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke 13942956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke if (!retries) { 13952956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke printk(KERN_ERR "Receive Peg initialization not " 13962956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke "complete, state: 0x%x.\n", val); 13972956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke return -EIO; 13982956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke } 13992956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke 14002956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke return 0; 14012956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke} 14022956640d4aaaecd42bd8ba800cc8c33bfe206b7eDhananjay Phadke 140356a007871a6689db80e19f63fe6dc3692daa2a6fDhananjay Phadkeint netxen_init_firmware(struct netxen_adapter *adapter) 140456a007871a6689db80e19f63fe6dc3692daa2a6fDhananjay Phadke{ 140556a007871a6689db80e19f63fe6dc3692daa2a6fDhananjay Phadke int err; 140656a007871a6689db80e19f63fe6dc3692daa2a6fDhananjay Phadke 140756a007871a6689db80e19f63fe6dc3692daa2a6fDhananjay Phadke err = netxen_receive_peg_ready(adapter); 140856a007871a6689db80e19f63fe6dc3692daa2a6fDhananjay Phadke if (err) 140956a007871a6689db80e19f63fe6dc3692daa2a6fDhananjay Phadke return err; 141056a007871a6689db80e19f63fe6dc3692daa2a6fDhananjay Phadke 1411f98a9f693b5f4919d9c4085a2fd8d67c7e152f3eDhananjay Phadke NXWR32(adapter, CRB_NIC_CAPABILITIES_HOST, INTR_SCHEME_PERPORT); 1412f98a9f693b5f4919d9c4085a2fd8d67c7e152f3eDhananjay Phadke NXWR32(adapter, CRB_MPORT_MODE, MPORT_MULTI_FUNCTION_MODE); 1413f98a9f693b5f4919d9c4085a2fd8d67c7e152f3eDhananjay Phadke NXWR32(adapter, CRB_CMDPEG_STATE, PHAN_INITIALIZE_ACK); 141456a007871a6689db80e19f63fe6dc3692daa2a6fDhananjay Phadke 1415f8e21f8fe2253e2ed5b9189b9dd5ff7e51af307cAmit Kumar Salecha if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) 1416f8e21f8fe2253e2ed5b9189b9dd5ff7e51af307cAmit Kumar Salecha NXWR32(adapter, CRB_NIC_MSI_MODE_HOST, MSI_MODE_MULTIFUNC); 1417f8e21f8fe2253e2ed5b9189b9dd5ff7e51af307cAmit Kumar Salecha 141856a007871a6689db80e19f63fe6dc3692daa2a6fDhananjay Phadke return err; 141956a007871a6689db80e19f63fe6dc3692daa2a6fDhananjay Phadke} 142056a007871a6689db80e19f63fe6dc3692daa2a6fDhananjay Phadke 14213bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadkestatic void 14223bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadkenetxen_handle_linkevent(struct netxen_adapter *adapter, nx_fw_msg_t *msg) 14233bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke{ 14243bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke u32 cable_OUI; 14253bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke u16 cable_len; 14263bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke u16 link_speed; 14273bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke u8 link_status, module, duplex, autoneg; 14283bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke struct net_device *netdev = adapter->netdev; 14293bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke 14303bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke adapter->has_link_events = 1; 14313bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke 14323bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke cable_OUI = msg->body[1] & 0xffffffff; 14333bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke cable_len = (msg->body[1] >> 32) & 0xffff; 14343bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke link_speed = (msg->body[1] >> 48) & 0xffff; 14353bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke 14363bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke link_status = msg->body[2] & 0xff; 14373bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke duplex = (msg->body[2] >> 16) & 0xff; 14383bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke autoneg = (msg->body[2] >> 24) & 0xff; 14393bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke 14403bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke module = (msg->body[2] >> 8) & 0xff; 14413bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke if (module == LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLE) { 14423bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke printk(KERN_INFO "%s: unsupported cable: OUI 0x%x, length %d\n", 14433bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke netdev->name, cable_OUI, cable_len); 14443bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke } else if (module == LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLELEN) { 14453bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke printk(KERN_INFO "%s: unsupported cable length %d\n", 14463bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke netdev->name, cable_len); 14473bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke } 14483bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke 14493bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke netxen_advert_link_change(adapter, link_status); 14503bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke 14513bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke /* update link parameters */ 14523bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke if (duplex == LINKEVENT_FULL_DUPLEX) 14533bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke adapter->link_duplex = DUPLEX_FULL; 14543bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke else 14553bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke adapter->link_duplex = DUPLEX_HALF; 14563bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke adapter->module_type = module; 14573bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke adapter->link_autoneg = autoneg; 14583bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke adapter->link_speed = link_speed; 14593bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke} 14603bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke 14613bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadkestatic void 14623bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadkenetxen_handle_fw_message(int desc_cnt, int index, 14633bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke struct nx_host_sds_ring *sds_ring) 14643bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke{ 14653bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke nx_fw_msg_t msg; 14663bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke struct status_desc *desc; 14673bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke int i = 0, opcode; 14683bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke 14693bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke while (desc_cnt > 0 && i < 8) { 14703bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke desc = &sds_ring->desc_head[index]; 14713bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke msg.words[i++] = le64_to_cpu(desc->status_desc_data[0]); 14723bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke msg.words[i++] = le64_to_cpu(desc->status_desc_data[1]); 14733bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke 14743bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke index = get_next_index(index, sds_ring->num_desc); 14753bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke desc_cnt--; 14763bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke } 14773bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke 14783bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke opcode = netxen_get_nic_msg_opcode(msg.body[0]); 14793bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke switch (opcode) { 14803bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke case NX_NIC_C2H_OPCODE_GET_LINKEVENT_RESPONSE: 14813bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke netxen_handle_linkevent(sds_ring->adapter, &msg); 14823bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke break; 14833bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke default: 14843bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke break; 14853bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke } 14863bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke} 14873bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke 1488d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadkestatic int 1489d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadkenetxen_alloc_rx_skb(struct netxen_adapter *adapter, 1490d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke struct nx_host_rds_ring *rds_ring, 1491d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke struct netxen_rx_buffer *buffer) 1492d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke{ 1493d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke struct sk_buff *skb; 1494d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke dma_addr_t dma; 1495d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke struct pci_dev *pdev = adapter->pdev; 1496d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke 1497d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke buffer->skb = dev_alloc_skb(rds_ring->skb_size); 1498d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke if (!buffer->skb) 1499d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke return 1; 1500d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke 1501d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke skb = buffer->skb; 1502d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke 1503d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke if (!adapter->ahw.cut_through) 1504d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke skb_reserve(skb, 2); 1505d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke 1506d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke dma = pci_map_single(pdev, skb->data, 1507d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke rds_ring->dma_size, PCI_DMA_FROMDEVICE); 1508d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke 1509d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke if (pci_dma_mapping_error(pdev, dma)) { 1510d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke dev_kfree_skb_any(skb); 1511d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke buffer->skb = NULL; 1512d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke return 1; 1513d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke } 1514d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke 1515d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke buffer->skb = skb; 1516d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke buffer->dma = dma; 1517d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke buffer->state = NETXEN_BUFFER_BUSY; 1518d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke 1519d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke return 0; 1520d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke} 1521d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke 1522d9e651bc06690c5a5326e8d019fa7668409bc819Dhananjay Phadkestatic struct sk_buff *netxen_process_rxbuf(struct netxen_adapter *adapter, 1523d9e651bc06690c5a5326e8d019fa7668409bc819Dhananjay Phadke struct nx_host_rds_ring *rds_ring, u16 index, u16 cksum) 1524d9e651bc06690c5a5326e8d019fa7668409bc819Dhananjay Phadke{ 1525d9e651bc06690c5a5326e8d019fa7668409bc819Dhananjay Phadke struct netxen_rx_buffer *buffer; 1526d9e651bc06690c5a5326e8d019fa7668409bc819Dhananjay Phadke struct sk_buff *skb; 1527d9e651bc06690c5a5326e8d019fa7668409bc819Dhananjay Phadke 1528d9e651bc06690c5a5326e8d019fa7668409bc819Dhananjay Phadke buffer = &rds_ring->rx_buf_arr[index]; 1529d9e651bc06690c5a5326e8d019fa7668409bc819Dhananjay Phadke 1530d9e651bc06690c5a5326e8d019fa7668409bc819Dhananjay Phadke pci_unmap_single(adapter->pdev, buffer->dma, rds_ring->dma_size, 1531d9e651bc06690c5a5326e8d019fa7668409bc819Dhananjay Phadke PCI_DMA_FROMDEVICE); 1532d9e651bc06690c5a5326e8d019fa7668409bc819Dhananjay Phadke 1533d9e651bc06690c5a5326e8d019fa7668409bc819Dhananjay Phadke skb = buffer->skb; 1534d9e651bc06690c5a5326e8d019fa7668409bc819Dhananjay Phadke if (!skb) 1535d9e651bc06690c5a5326e8d019fa7668409bc819Dhananjay Phadke goto no_skb; 1536d9e651bc06690c5a5326e8d019fa7668409bc819Dhananjay Phadke 1537066413dac420c8225e3ef7f0f76c3255448782d3Michał Mirosław if (likely((adapter->netdev->features & NETIF_F_RXCSUM) 1538066413dac420c8225e3ef7f0f76c3255448782d3Michał Mirosław && cksum == STATUS_CKSUM_OK)) { 1539d9e651bc06690c5a5326e8d019fa7668409bc819Dhananjay Phadke adapter->stats.csummed++; 1540d9e651bc06690c5a5326e8d019fa7668409bc819Dhananjay Phadke skb->ip_summed = CHECKSUM_UNNECESSARY; 1541d9e651bc06690c5a5326e8d019fa7668409bc819Dhananjay Phadke } else 1542d9e651bc06690c5a5326e8d019fa7668409bc819Dhananjay Phadke skb->ip_summed = CHECKSUM_NONE; 1543d9e651bc06690c5a5326e8d019fa7668409bc819Dhananjay Phadke 1544d9e651bc06690c5a5326e8d019fa7668409bc819Dhananjay Phadke skb->dev = adapter->netdev; 1545d9e651bc06690c5a5326e8d019fa7668409bc819Dhananjay Phadke 1546d9e651bc06690c5a5326e8d019fa7668409bc819Dhananjay Phadke buffer->skb = NULL; 1547d9e651bc06690c5a5326e8d019fa7668409bc819Dhananjay Phadkeno_skb: 1548d9e651bc06690c5a5326e8d019fa7668409bc819Dhananjay Phadke buffer->state = NETXEN_BUFFER_FREE; 1549d9e651bc06690c5a5326e8d019fa7668409bc819Dhananjay Phadke return skb; 1550d9e651bc06690c5a5326e8d019fa7668409bc819Dhananjay Phadke} 1551d9e651bc06690c5a5326e8d019fa7668409bc819Dhananjay Phadke 1552d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadkestatic struct netxen_rx_buffer * 15539b3ef55c6ddbe8c7b76707eae9a77d874fe2cec0Dhananjay Phadkenetxen_process_rcv(struct netxen_adapter *adapter, 1554c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke struct nx_host_sds_ring *sds_ring, 1555c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke int ring, u64 sts_data0) 15563d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale{ 15573176ff3ee71bddbd1d68e6a9e28dbcf0a2960c95Mithlesh Thukral struct net_device *netdev = adapter->netdev; 1558becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadke struct netxen_recv_context *recv_ctx = &adapter->recv_ctx; 15593d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale struct netxen_rx_buffer *buffer; 15603d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale struct sk_buff *skb; 1561c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke struct nx_host_rds_ring *rds_ring; 1562c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke int index, length, cksum, pkt_offset; 15633d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale 1564c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke if (unlikely(ring >= adapter->max_rds_rings)) 1565c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke return NULL; 1566c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke 1567c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke rds_ring = &recv_ctx->rds_rings[ring]; 1568c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke 1569c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke index = netxen_get_sts_refhandle(sts_data0); 1570c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke if (unlikely(index >= rds_ring->num_desc)) 1571d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke return NULL; 1572438627c77b877e445a4b918a50ff910a5ea2a12dDhananjay Phadke 157348bfd1e0fc66b27254ec742b014e689ef218e76cDhananjay Phadke buffer = &rds_ring->rx_buf_arr[index]; 15743d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale 1575c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke length = netxen_get_sts_totallength(sts_data0); 1576c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke cksum = netxen_get_sts_status(sts_data0); 1577c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke pkt_offset = netxen_get_sts_pkt_offset(sts_data0); 1578c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke 1579d9e651bc06690c5a5326e8d019fa7668409bc819Dhananjay Phadke skb = netxen_process_rxbuf(adapter, rds_ring, index, cksum); 1580d9e651bc06690c5a5326e8d019fa7668409bc819Dhananjay Phadke if (!skb) 1581d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke return buffer; 1582200eef20db6de7535438c9af9becc8169c6cb6c0Dhananjay Phadke 15839b3ef55c6ddbe8c7b76707eae9a77d874fe2cec0Dhananjay Phadke if (length > rds_ring->skb_size) 15849b3ef55c6ddbe8c7b76707eae9a77d874fe2cec0Dhananjay Phadke skb_put(skb, rds_ring->skb_size); 15859b3ef55c6ddbe8c7b76707eae9a77d874fe2cec0Dhananjay Phadke else 15869b3ef55c6ddbe8c7b76707eae9a77d874fe2cec0Dhananjay Phadke skb_put(skb, length); 1587d9e651bc06690c5a5326e8d019fa7668409bc819Dhananjay Phadke 15889b3ef55c6ddbe8c7b76707eae9a77d874fe2cec0Dhananjay Phadke 15899b3ef55c6ddbe8c7b76707eae9a77d874fe2cec0Dhananjay Phadke if (pkt_offset) 15909b3ef55c6ddbe8c7b76707eae9a77d874fe2cec0Dhananjay Phadke skb_pull(skb, pkt_offset); 1591ed25ffa16434724f5ed825aa48734c7f3aefa203Amit S. Kale 15923d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale skb->protocol = eth_type_trans(skb, netdev); 15933d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale 1594a92e9e65f0068a291a677c627a747fae1f230284Amit Kumar Salecha napi_gro_receive(&sds_ring->napi, skb); 1595d9e651bc06690c5a5326e8d019fa7668409bc819Dhananjay Phadke 15961bb482f8a46000f77577948ff1c350275bba7dc9Narender Kumar adapter->stats.rx_pkts++; 15970ddc110c6fef34c554999448cdffe9c174a15fc9Dhananjay Phadke adapter->stats.rxbytes += length; 1598d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke 1599d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke return buffer; 16003d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale} 16013d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale 1602c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke#define TCP_HDR_SIZE 20 1603c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke#define TCP_TS_OPTION_SIZE 12 1604c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke#define TCP_TS_HDR_SIZE (TCP_HDR_SIZE + TCP_TS_OPTION_SIZE) 1605c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke 1606c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadkestatic struct netxen_rx_buffer * 1607c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadkenetxen_process_lro(struct netxen_adapter *adapter, 1608c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke struct nx_host_sds_ring *sds_ring, 1609c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke int ring, u64 sts_data0, u64 sts_data1) 1610c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke{ 1611c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke struct net_device *netdev = adapter->netdev; 1612c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke struct netxen_recv_context *recv_ctx = &adapter->recv_ctx; 1613c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke struct netxen_rx_buffer *buffer; 1614c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke struct sk_buff *skb; 1615c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke struct nx_host_rds_ring *rds_ring; 1616c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke struct iphdr *iph; 1617c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke struct tcphdr *th; 1618c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke bool push, timestamp; 1619c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke int l2_hdr_offset, l4_hdr_offset; 1620c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke int index; 1621c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke u16 lro_length, length, data_offset; 1622c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke u32 seq_number; 1623a7ffa289445edf73c7797eac1dfa645a9784015aRajesh Borundia u8 vhdr_len = 0; 1624c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke 1625c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke if (unlikely(ring > adapter->max_rds_rings)) 1626c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke return NULL; 1627c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke 1628c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke rds_ring = &recv_ctx->rds_rings[ring]; 1629c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke 1630c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke index = netxen_get_lro_sts_refhandle(sts_data0); 1631c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke if (unlikely(index > rds_ring->num_desc)) 1632c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke return NULL; 1633c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke 1634c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke buffer = &rds_ring->rx_buf_arr[index]; 1635c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke 1636c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke timestamp = netxen_get_lro_sts_timestamp(sts_data0); 1637c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke lro_length = netxen_get_lro_sts_length(sts_data0); 1638c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke l2_hdr_offset = netxen_get_lro_sts_l2_hdr_offset(sts_data0); 1639c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke l4_hdr_offset = netxen_get_lro_sts_l4_hdr_offset(sts_data0); 1640c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke push = netxen_get_lro_sts_push_flag(sts_data0); 1641c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke seq_number = netxen_get_lro_sts_seq_number(sts_data1); 1642c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke 1643c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke skb = netxen_process_rxbuf(adapter, rds_ring, index, STATUS_CKSUM_OK); 1644c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke if (!skb) 1645c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke return buffer; 1646c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke 1647c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke if (timestamp) 1648c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke data_offset = l4_hdr_offset + TCP_TS_HDR_SIZE; 1649c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke else 1650c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke data_offset = l4_hdr_offset + TCP_HDR_SIZE; 1651c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke 1652c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke skb_put(skb, lro_length + data_offset); 1653c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke 1654c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke skb_pull(skb, l2_hdr_offset); 1655c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke skb->protocol = eth_type_trans(skb, netdev); 1656c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke 165757569d0e12eaf31717e295960cd2a26f626c8e5bRajesh Borundia if (skb->protocol == htons(ETH_P_8021Q)) 165857569d0e12eaf31717e295960cd2a26f626c8e5bRajesh Borundia vhdr_len = VLAN_HLEN; 165957569d0e12eaf31717e295960cd2a26f626c8e5bRajesh Borundia iph = (struct iphdr *)(skb->data + vhdr_len); 166057569d0e12eaf31717e295960cd2a26f626c8e5bRajesh Borundia th = (struct tcphdr *)((skb->data + vhdr_len) + (iph->ihl << 2)); 1661c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke 1662c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke length = (iph->ihl << 2) + (th->doff << 2) + lro_length; 1663c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke iph->tot_len = htons(length); 1664c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke iph->check = 0; 1665c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl); 1666c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke th->psh = push; 1667c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke th->seq = htonl(seq_number); 1668c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke 16691bb482f8a46000f77577948ff1c350275bba7dc9Narender Kumar length = skb->len; 16701bb482f8a46000f77577948ff1c350275bba7dc9Narender Kumar 1671c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke netif_receive_skb(skb); 1672c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke 16731bb482f8a46000f77577948ff1c350275bba7dc9Narender Kumar adapter->stats.lro_pkts++; 16741bb482f8a46000f77577948ff1c350275bba7dc9Narender Kumar adapter->stats.rxbytes += length; 16751bb482f8a46000f77577948ff1c350275bba7dc9Narender Kumar 1676c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke return buffer; 1677c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke} 1678c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke 1679d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke#define netxen_merge_rx_buffers(list, head) \ 1680d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke do { list_splice_tail_init(list, head); } while (0); 1681d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke 1682becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadkeint 1683d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadkenetxen_process_rcv_ring(struct nx_host_sds_ring *sds_ring, int max) 16843d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale{ 1685d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke struct netxen_adapter *adapter = sds_ring->adapter; 1686d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke 1687d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke struct list_head *cur; 1688d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke 16890ddc110c6fef34c554999448cdffe9c174a15fc9Dhananjay Phadke struct status_desc *desc; 1690d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke struct netxen_rx_buffer *rxbuf; 1691d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke 1692d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke u32 consumer = sds_ring->consumer; 1693d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke 16949b3ef55c6ddbe8c7b76707eae9a77d874fe2cec0Dhananjay Phadke int count = 0; 1695c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke u64 sts_data0, sts_data1; 1696c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke int opcode, ring = 0, desc_cnt; 16973d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale 16983d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale while (count < max) { 1699d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke desc = &sds_ring->desc_head[consumer]; 1700c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke sts_data0 = le64_to_cpu(desc->status_desc_data[0]); 17010ddc110c6fef34c554999448cdffe9c174a15fc9Dhananjay Phadke 1702c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke if (!(sts_data0 & STATUS_OWNER_HOST)) 17033d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale break; 1704d9e651bc06690c5a5326e8d019fa7668409bc819Dhananjay Phadke 1705c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke desc_cnt = netxen_get_sts_desc_cnt(sts_data0); 17063bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke 1707c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke opcode = netxen_get_sts_opcode(sts_data0); 1708d9e651bc06690c5a5326e8d019fa7668409bc819Dhananjay Phadke 17093bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke switch (opcode) { 17103bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke case NETXEN_NIC_RXPKT_DESC: 17113bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke case NETXEN_OLD_RXPKT_DESC: 17126598b169b856793f8f9b80a3f3c5a48f5eaf40e3Dhananjay Phadke case NETXEN_NIC_SYN_OFFLOAD: 1713c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke ring = netxen_get_sts_type(sts_data0); 1714c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke rxbuf = netxen_process_rcv(adapter, sds_ring, 1715c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke ring, sts_data0); 1716c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke break; 1717c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke case NETXEN_NIC_LRO_DESC: 1718c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke ring = netxen_get_lro_sts_type(sts_data0); 1719c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke sts_data1 = le64_to_cpu(desc->status_desc_data[1]); 1720c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke rxbuf = netxen_process_lro(adapter, sds_ring, 1721c1c00ab8626298ac784ea344bf10e94b5bd9bcb5Dhananjay Phadke ring, sts_data0, sts_data1); 17223bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke break; 17233bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke case NETXEN_NIC_RESPONSE_DESC: 17243bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke netxen_handle_fw_message(desc_cnt, consumer, sds_ring); 17253bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke default: 17263bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke goto skip; 17273bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke } 17283bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke 17293bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke WARN_ON(desc_cnt > 1); 17303bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke 1731d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke if (rxbuf) 1732d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke list_add_tail(&rxbuf->list, &sds_ring->free_list[ring]); 1733d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke 17343bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadkeskip: 17353bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke for (; desc_cnt > 0; desc_cnt--) { 17363bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke desc = &sds_ring->desc_head[consumer]; 17373bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke desc->status_desc_data[0] = 17383bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke cpu_to_le64(STATUS_OWNER_PHANTOM); 17393bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke consumer = get_next_index(consumer, sds_ring->num_desc); 17403bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1Dhananjay Phadke } 17413d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale count++; 17423d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale } 17430ddc110c6fef34c554999448cdffe9c174a15fc9Dhananjay Phadke 1744d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke for (ring = 0; ring < adapter->max_rds_rings; ring++) { 1745d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke struct nx_host_rds_ring *rds_ring = 1746d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke &adapter->recv_ctx.rds_rings[ring]; 1747d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke 1748d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke if (!list_empty(&sds_ring->free_list[ring])) { 1749d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke list_for_each(cur, &sds_ring->free_list[ring]) { 1750d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke rxbuf = list_entry(cur, 1751d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke struct netxen_rx_buffer, list); 1752d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke netxen_alloc_rx_skb(adapter, rds_ring, rxbuf); 1753d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke } 1754d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke spin_lock(&rds_ring->lock); 1755d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke netxen_merge_rx_buffers(&sds_ring->free_list[ring], 1756d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke &rds_ring->free_list); 1757d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke spin_unlock(&rds_ring->lock); 1758d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke } 1759d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke 1760d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke netxen_post_rx_buffers_nodb(adapter, rds_ring); 1761d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke } 17623d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale 17633d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale if (count) { 1764d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke sds_ring->consumer = consumer; 1765195c5f9829407857cba86f083caec6302b1fd8e1Amit Kumar Salecha NXWRIO(adapter, sds_ring->crb_sts_consumer, consumer); 17663d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale } 17673d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale 17683d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale return count; 17693d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale} 17703d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale 17713d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale/* Process Command status ring */ 177205aaa02d799e8e9548d57ac92fcb05e783027341Dhananjay Phadkeint netxen_process_cmd_ring(struct netxen_adapter *adapter) 17733d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale{ 1774d877f1e344f5515988d9dcd6db5d4285911778a3Dhananjay Phadke u32 sw_consumer, hw_consumer; 1775ba53e6b4878e07411826312c59bfe49561594b6eDhananjay Phadke int count = 0, i; 17763d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale struct netxen_cmd_buffer *buffer; 1777ba53e6b4878e07411826312c59bfe49561594b6eDhananjay Phadke struct pci_dev *pdev = adapter->pdev; 1778ba53e6b4878e07411826312c59bfe49561594b6eDhananjay Phadke struct net_device *netdev = adapter->netdev; 17793d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale struct netxen_skb_frag *frag; 1780ba53e6b4878e07411826312c59bfe49561594b6eDhananjay Phadke int done = 0; 17814ea528a151549df795c984649d75860ea40390bdDhananjay Phadke struct nx_host_tx_ring *tx_ring = adapter->tx_ring; 17823d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale 1783d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke if (!spin_trylock(&adapter->tx_clean_lock)) 1784d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke return 1; 1785d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke 1786d877f1e344f5515988d9dcd6db5d4285911778a3Dhananjay Phadke sw_consumer = tx_ring->sw_consumer; 1787d877f1e344f5515988d9dcd6db5d4285911778a3Dhananjay Phadke hw_consumer = le32_to_cpu(*(tx_ring->hw_consumer)); 17883d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale 1789d877f1e344f5515988d9dcd6db5d4285911778a3Dhananjay Phadke while (sw_consumer != hw_consumer) { 1790d877f1e344f5515988d9dcd6db5d4285911778a3Dhananjay Phadke buffer = &tx_ring->cmd_buf_arr[sw_consumer]; 179153a01e00f8c78bc5875e09aca7749ea54bb09798dhananjay@netxen.com if (buffer->skb) { 179253a01e00f8c78bc5875e09aca7749ea54bb09798dhananjay@netxen.com frag = &buffer->frag_array[0]; 17933d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale pci_unmap_single(pdev, frag->dma, frag->length, 17943d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale PCI_DMA_TODEVICE); 179596acb6eb8effe7c2549909e2ee49f4130f2c167dDhananjay Phadke frag->dma = 0ULL; 17963d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale for (i = 1; i < buffer->frag_count; i++) { 17973d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale frag++; /* Get the next frag */ 17983d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale pci_unmap_page(pdev, frag->dma, frag->length, 17993d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale PCI_DMA_TODEVICE); 180096acb6eb8effe7c2549909e2ee49f4130f2c167dDhananjay Phadke frag->dma = 0ULL; 18013d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale } 18023d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale 1803ba53e6b4878e07411826312c59bfe49561594b6eDhananjay Phadke adapter->stats.xmitfinished++; 180453a01e00f8c78bc5875e09aca7749ea54bb09798dhananjay@netxen.com dev_kfree_skb_any(buffer->skb); 180553a01e00f8c78bc5875e09aca7749ea54bb09798dhananjay@netxen.com buffer->skb = NULL; 18063d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale } 18073d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale 1808d877f1e344f5515988d9dcd6db5d4285911778a3Dhananjay Phadke sw_consumer = get_next_index(sw_consumer, tx_ring->num_desc); 1809ba53e6b4878e07411826312c59bfe49561594b6eDhananjay Phadke if (++count >= MAX_STATUS_HANDLE) 1810ba53e6b4878e07411826312c59bfe49561594b6eDhananjay Phadke break; 18113d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale } 18123d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale 181322527864ed7ee6c50f3c4d4b03c83c963caf5c0bDhananjay Phadke if (count && netif_running(netdev)) { 1814cb2107be43d2fc5eadec58b92b54bf32c00bfff3Dhananjay Phadke tx_ring->sw_consumer = sw_consumer; 1815cb2107be43d2fc5eadec58b92b54bf32c00bfff3Dhananjay Phadke 1816ba53e6b4878e07411826312c59bfe49561594b6eDhananjay Phadke smp_mb(); 1817cb2107be43d2fc5eadec58b92b54bf32c00bfff3Dhananjay Phadke 18187a9905e64272c8021a8cfaf6015dd0fb8eeeb378Rajesh Borundia if (netif_queue_stopped(netdev) && netif_carrier_ok(netdev)) 18197a9905e64272c8021a8cfaf6015dd0fb8eeeb378Rajesh Borundia if (netxen_tx_avail(tx_ring) > TX_STOP_THRESH) 1820cb2107be43d2fc5eadec58b92b54bf32c00bfff3Dhananjay Phadke netif_wake_queue(netdev); 18217a9905e64272c8021a8cfaf6015dd0fb8eeeb378Rajesh Borundia adapter->tx_timeo_cnt = 0; 18223d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale } 1823ed25ffa16434724f5ed825aa48734c7f3aefa203Amit S. Kale /* 1824ed25ffa16434724f5ed825aa48734c7f3aefa203Amit S. Kale * If everything is freed up to consumer then check if the ring is full 1825ed25ffa16434724f5ed825aa48734c7f3aefa203Amit S. Kale * If the ring is full then check if more needs to be freed and 1826ed25ffa16434724f5ed825aa48734c7f3aefa203Amit S. Kale * schedule the call back again. 1827ed25ffa16434724f5ed825aa48734c7f3aefa203Amit S. Kale * 1828ed25ffa16434724f5ed825aa48734c7f3aefa203Amit S. Kale * This happens when there are 2 CPUs. One could be freeing and the 1829ed25ffa16434724f5ed825aa48734c7f3aefa203Amit S. Kale * other filling it. If the ring is full when we get out of here and 1830ed25ffa16434724f5ed825aa48734c7f3aefa203Amit S. Kale * the card has already interrupted the host then the host can miss the 1831ed25ffa16434724f5ed825aa48734c7f3aefa203Amit S. Kale * interrupt. 1832ed25ffa16434724f5ed825aa48734c7f3aefa203Amit S. Kale * 1833ed25ffa16434724f5ed825aa48734c7f3aefa203Amit S. Kale * There is still a possible race condition and the host could miss an 1834ed25ffa16434724f5ed825aa48734c7f3aefa203Amit S. Kale * interrupt. The card has to take care of this. 1835ed25ffa16434724f5ed825aa48734c7f3aefa203Amit S. Kale */ 1836d877f1e344f5515988d9dcd6db5d4285911778a3Dhananjay Phadke hw_consumer = le32_to_cpu(*(tx_ring->hw_consumer)); 1837d877f1e344f5515988d9dcd6db5d4285911778a3Dhananjay Phadke done = (sw_consumer == hw_consumer); 1838d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke spin_unlock(&adapter->tx_clean_lock); 18393d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale 1840807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return done; 18413d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale} 18423d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale 1843becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadkevoid 1844d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadkenetxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ringid, 1845d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke struct nx_host_rds_ring *rds_ring) 18463d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale{ 18473d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale struct rcv_desc *pdesc; 18483d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale struct netxen_rx_buffer *buffer; 1849d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke int producer, count = 0; 1850ed25ffa16434724f5ed825aa48734c7f3aefa203Amit S. Kale netxen_ctx_msg msg = 0; 1851d9e651bc06690c5a5326e8d019fa7668409bc819Dhananjay Phadke struct list_head *head; 18523d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale 185348bfd1e0fc66b27254ec742b014e689ef218e76cDhananjay Phadke producer = rds_ring->producer; 1854d9e651bc06690c5a5326e8d019fa7668409bc819Dhananjay Phadke 1855d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke head = &rds_ring->free_list; 1856d9e651bc06690c5a5326e8d019fa7668409bc819Dhananjay Phadke while (!list_empty(head)) { 1857d9e651bc06690c5a5326e8d019fa7668409bc819Dhananjay Phadke 1858d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke buffer = list_entry(head->next, struct netxen_rx_buffer, list); 18596f70340698333f14b1d9c9e913c5de8f66b72c55Dhananjay Phadke 1860d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke if (!buffer->skb) { 1861d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke if (netxen_alloc_rx_skb(adapter, rds_ring, buffer)) 1862d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke break; 18636f70340698333f14b1d9c9e913c5de8f66b72c55Dhananjay Phadke } 18646f70340698333f14b1d9c9e913c5de8f66b72c55Dhananjay Phadke 18656f70340698333f14b1d9c9e913c5de8f66b72c55Dhananjay Phadke count++; 1866d9e651bc06690c5a5326e8d019fa7668409bc819Dhananjay Phadke list_del(&buffer->list); 1867d9e651bc06690c5a5326e8d019fa7668409bc819Dhananjay Phadke 1868ed25ffa16434724f5ed825aa48734c7f3aefa203Amit S. Kale /* make a rcv descriptor */ 18696f70340698333f14b1d9c9e913c5de8f66b72c55Dhananjay Phadke pdesc = &rds_ring->desc_head[producer]; 1870d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke pdesc->addr_buffer = cpu_to_le64(buffer->dma); 1871ed33ebe464d973ab656cfc9ff0ca40a4c1e38238Amit S. Kale pdesc->reference_handle = cpu_to_le16(buffer->ref_handle); 187248bfd1e0fc66b27254ec742b014e689ef218e76cDhananjay Phadke pdesc->buffer_length = cpu_to_le32(rds_ring->dma_size); 18736f70340698333f14b1d9c9e913c5de8f66b72c55Dhananjay Phadke 1874438627c77b877e445a4b918a50ff910a5ea2a12dDhananjay Phadke producer = get_next_index(producer, rds_ring->num_desc); 1875ed25ffa16434724f5ed825aa48734c7f3aefa203Amit S. Kale } 18769b3ef55c6ddbe8c7b76707eae9a77d874fe2cec0Dhananjay Phadke 1877ed25ffa16434724f5ed825aa48734c7f3aefa203Amit S. Kale if (count) { 187848bfd1e0fc66b27254ec742b014e689ef218e76cDhananjay Phadke rds_ring->producer = producer; 1879195c5f9829407857cba86f083caec6302b1fd8e1Amit Kumar Salecha NXWRIO(adapter, rds_ring->crb_rcv_producer, 1880438627c77b877e445a4b918a50ff910a5ea2a12dDhananjay Phadke (producer-1) & (rds_ring->num_desc-1)); 188148bfd1e0fc66b27254ec742b014e689ef218e76cDhananjay Phadke 18824f96b988e8d404b8b32aefed27503b4538949a3cDhananjay Phadke if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) { 1883ed25ffa16434724f5ed825aa48734c7f3aefa203Amit S. Kale /* 1884ed25ffa16434724f5ed825aa48734c7f3aefa203Amit S. Kale * Write a doorbell msg to tell phanmon of change in 1885ed25ffa16434724f5ed825aa48734c7f3aefa203Amit S. Kale * receive ring producer 188648bfd1e0fc66b27254ec742b014e689ef218e76cDhananjay Phadke * Only for firmware version < 4.0.0 1887ed25ffa16434724f5ed825aa48734c7f3aefa203Amit S. Kale */ 1888ed25ffa16434724f5ed825aa48734c7f3aefa203Amit S. Kale netxen_set_msg_peg_id(msg, NETXEN_RCV_PEG_DB_ID); 1889ed25ffa16434724f5ed825aa48734c7f3aefa203Amit S. Kale netxen_set_msg_privid(msg); 1890ed25ffa16434724f5ed825aa48734c7f3aefa203Amit S. Kale netxen_set_msg_count(msg, 1891438627c77b877e445a4b918a50ff910a5ea2a12dDhananjay Phadke ((producer - 1) & 1892438627c77b877e445a4b918a50ff910a5ea2a12dDhananjay Phadke (rds_ring->num_desc - 1))); 18933176ff3ee71bddbd1d68e6a9e28dbcf0a2960c95Mithlesh Thukral netxen_set_msg_ctxid(msg, adapter->portnum); 1894ed25ffa16434724f5ed825aa48734c7f3aefa203Amit S. Kale netxen_set_msg_opcode(msg, NETXEN_RCV_PRODUCER(ringid)); 1895f03b0ebd8e7132bd9adb41348070813feb280300Dhananjay Phadke NXWRIO(adapter, DB_NORMALIZE(adapter, 1896f03b0ebd8e7132bd9adb41348070813feb280300Dhananjay Phadke NETXEN_RCV_PRODUCER_OFFSET), msg); 189748bfd1e0fc66b27254ec742b014e689ef218e76cDhananjay Phadke } 1898ed25ffa16434724f5ed825aa48734c7f3aefa203Amit S. Kale } 1899ed25ffa16434724f5ed825aa48734c7f3aefa203Amit S. Kale} 1900ed25ffa16434724f5ed825aa48734c7f3aefa203Amit S. Kale 1901becf46a012db667c562bbbe589c14e100b62e5a4Dhananjay Phadkestatic void 1902d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadkenetxen_post_rx_buffers_nodb(struct netxen_adapter *adapter, 1903d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke struct nx_host_rds_ring *rds_ring) 1904ed25ffa16434724f5ed825aa48734c7f3aefa203Amit S. Kale{ 1905ed25ffa16434724f5ed825aa48734c7f3aefa203Amit S. Kale struct rcv_desc *pdesc; 1906ed25ffa16434724f5ed825aa48734c7f3aefa203Amit S. Kale struct netxen_rx_buffer *buffer; 1907d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke int producer, count = 0; 1908d9e651bc06690c5a5326e8d019fa7668409bc819Dhananjay Phadke struct list_head *head; 1909ed25ffa16434724f5ed825aa48734c7f3aefa203Amit S. Kale 1910d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke if (!spin_trylock(&rds_ring->lock)) 1911d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke return; 1912d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke 19132227bae22becb88b75ede022c7bb991aabfb50bbAmit Kumar Salecha producer = rds_ring->producer; 19142227bae22becb88b75ede022c7bb991aabfb50bbAmit Kumar Salecha 1915d9e651bc06690c5a5326e8d019fa7668409bc819Dhananjay Phadke head = &rds_ring->free_list; 1916d9e651bc06690c5a5326e8d019fa7668409bc819Dhananjay Phadke while (!list_empty(head)) { 1917d9e651bc06690c5a5326e8d019fa7668409bc819Dhananjay Phadke 1918d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke buffer = list_entry(head->next, struct netxen_rx_buffer, list); 19196f70340698333f14b1d9c9e913c5de8f66b72c55Dhananjay Phadke 1920d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke if (!buffer->skb) { 1921d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke if (netxen_alloc_rx_skb(adapter, rds_ring, buffer)) 1922d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke break; 19236f70340698333f14b1d9c9e913c5de8f66b72c55Dhananjay Phadke } 19246f70340698333f14b1d9c9e913c5de8f66b72c55Dhananjay Phadke 19256f70340698333f14b1d9c9e913c5de8f66b72c55Dhananjay Phadke count++; 1926d9e651bc06690c5a5326e8d019fa7668409bc819Dhananjay Phadke list_del(&buffer->list); 1927d9e651bc06690c5a5326e8d019fa7668409bc819Dhananjay Phadke 19283d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale /* make a rcv descriptor */ 19296f70340698333f14b1d9c9e913c5de8f66b72c55Dhananjay Phadke pdesc = &rds_ring->desc_head[producer]; 1930ed33ebe464d973ab656cfc9ff0ca40a4c1e38238Amit S. Kale pdesc->reference_handle = cpu_to_le16(buffer->ref_handle); 193148bfd1e0fc66b27254ec742b014e689ef218e76cDhananjay Phadke pdesc->buffer_length = cpu_to_le32(rds_ring->dma_size); 19323d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale pdesc->addr_buffer = cpu_to_le64(buffer->dma); 19336f70340698333f14b1d9c9e913c5de8f66b72c55Dhananjay Phadke 1934438627c77b877e445a4b918a50ff910a5ea2a12dDhananjay Phadke producer = get_next_index(producer, rds_ring->num_desc); 19353d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale } 19363d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale 19373d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale if (count) { 193848bfd1e0fc66b27254ec742b014e689ef218e76cDhananjay Phadke rds_ring->producer = producer; 1939195c5f9829407857cba86f083caec6302b1fd8e1Amit Kumar Salecha NXWRIO(adapter, rds_ring->crb_rcv_producer, 1940438627c77b877e445a4b918a50ff910a5ea2a12dDhananjay Phadke (producer - 1) & (rds_ring->num_desc - 1)); 19413d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale } 1942d8b100c5da003b6f8c410453e1e6e74ced8d1cc1Dhananjay Phadke spin_unlock(&rds_ring->lock); 19433d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale} 19443d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale 19453d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kalevoid netxen_nic_clear_stats(struct netxen_adapter *adapter) 19463d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale{ 19473d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale memset(&adapter->stats, 0, sizeof(adapter->stats)); 19483d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale} 19493d396eb17e9f8c5f59314078b45b88647591378dAmit S. Kale 1950