netxen_nic_hw.c
来自「linux 内核源代码」· C语言 代码 · 共 1,201 行 · 第 1/3 页
C
1,201 行
/* * Copyright (C) 2003 - 2006 NetXen, Inc. * All rights reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * MA 02111-1307, USA. * * The full GNU General Public License is included in this distribution * in the file called LICENSE. * * Contact Information: * info@netxen.com * NetXen, * 3965 Freedom Circle, Fourth floor, * Santa Clara, CA 95054 * * * Source file for NIC routines to access the Phantom hardware * */#include "netxen_nic.h"#include "netxen_nic_hw.h"#define DEFINE_GLOBAL_RECV_CRB#include "netxen_nic_phan_reg.h"#include <net/ip.h>struct netxen_recv_crb recv_crb_registers[] = { /* * Instance 0. */ { /* rcv_desc_crb: */ { { /* crb_rcv_producer_offset: */ NETXEN_NIC_REG(0x100), /* crb_rcv_consumer_offset: */ NETXEN_NIC_REG(0x104), /* crb_gloablrcv_ring: */ NETXEN_NIC_REG(0x108), /* crb_rcv_ring_size */ NETXEN_NIC_REG(0x10c), }, /* Jumbo frames */ { /* crb_rcv_producer_offset: */ NETXEN_NIC_REG(0x110), /* crb_rcv_consumer_offset: */ NETXEN_NIC_REG(0x114), /* crb_gloablrcv_ring: */ NETXEN_NIC_REG(0x118), /* crb_rcv_ring_size */ NETXEN_NIC_REG(0x11c), }, /* LRO */ { /* crb_rcv_producer_offset: */ NETXEN_NIC_REG(0x120), /* crb_rcv_consumer_offset: */ NETXEN_NIC_REG(0x124), /* crb_gloablrcv_ring: */ NETXEN_NIC_REG(0x128), /* crb_rcv_ring_size */ NETXEN_NIC_REG(0x12c), } }, /* crb_rcvstatus_ring: */ NETXEN_NIC_REG(0x130), /* crb_rcv_status_producer: */ NETXEN_NIC_REG(0x134), /* crb_rcv_status_consumer: */ NETXEN_NIC_REG(0x138), /* crb_rcvpeg_state: */ NETXEN_NIC_REG(0x13c), /* crb_status_ring_size */ NETXEN_NIC_REG(0x140), }, /* * Instance 1, */ { /* rcv_desc_crb: */ { { /* crb_rcv_producer_offset: */ NETXEN_NIC_REG(0x144), /* crb_rcv_consumer_offset: */ NETXEN_NIC_REG(0x148), /* crb_globalrcv_ring: */ NETXEN_NIC_REG(0x14c), /* crb_rcv_ring_size */ NETXEN_NIC_REG(0x150), }, /* Jumbo frames */ { /* crb_rcv_producer_offset: */ NETXEN_NIC_REG(0x154), /* crb_rcv_consumer_offset: */ NETXEN_NIC_REG(0x158), /* crb_globalrcv_ring: */ NETXEN_NIC_REG(0x15c), /* crb_rcv_ring_size */ NETXEN_NIC_REG(0x160), }, /* LRO */ { /* crb_rcv_producer_offset: */ NETXEN_NIC_REG(0x164), /* crb_rcv_consumer_offset: */ NETXEN_NIC_REG(0x168), /* crb_globalrcv_ring: */ NETXEN_NIC_REG(0x16c), /* crb_rcv_ring_size */ NETXEN_NIC_REG(0x170), } }, /* crb_rcvstatus_ring: */ NETXEN_NIC_REG(0x174), /* crb_rcv_status_producer: */ NETXEN_NIC_REG(0x178), /* crb_rcv_status_consumer: */ NETXEN_NIC_REG(0x17c), /* crb_rcvpeg_state: */ NETXEN_NIC_REG(0x180), /* crb_status_ring_size */ NETXEN_NIC_REG(0x184), }, /* * Instance 2, */ { { { /* crb_rcv_producer_offset: */ NETXEN_NIC_REG(0x1d8), /* crb_rcv_consumer_offset: */ NETXEN_NIC_REG(0x1dc), /* crb_gloablrcv_ring: */ NETXEN_NIC_REG(0x1f0), /* crb_rcv_ring_size */ NETXEN_NIC_REG(0x1f4), }, /* Jumbo frames */ { /* crb_rcv_producer_offset: */ NETXEN_NIC_REG(0x1f8), /* crb_rcv_consumer_offset: */ NETXEN_NIC_REG(0x1fc), /* crb_gloablrcv_ring: */ NETXEN_NIC_REG(0x200), /* crb_rcv_ring_size */ NETXEN_NIC_REG(0x204), }, /* LRO */ { /* crb_rcv_producer_offset: */ NETXEN_NIC_REG(0x208), /* crb_rcv_consumer_offset: */ NETXEN_NIC_REG(0x20c), /* crb_gloablrcv_ring: */ NETXEN_NIC_REG(0x210), /* crb_rcv_ring_size */ NETXEN_NIC_REG(0x214), } }, /* crb_rcvstatus_ring: */ NETXEN_NIC_REG(0x218), /* crb_rcv_status_producer: */ NETXEN_NIC_REG(0x21c), /* crb_rcv_status_consumer: */ NETXEN_NIC_REG(0x220), /* crb_rcvpeg_state: */ NETXEN_NIC_REG(0x224), /* crb_status_ring_size */ NETXEN_NIC_REG(0x228), }, /* * Instance 3, */ { { { /* crb_rcv_producer_offset: */ NETXEN_NIC_REG(0x22c), /* crb_rcv_consumer_offset: */ NETXEN_NIC_REG(0x230), /* crb_gloablrcv_ring: */ NETXEN_NIC_REG(0x234), /* crb_rcv_ring_size */ NETXEN_NIC_REG(0x238), }, /* Jumbo frames */ { /* crb_rcv_producer_offset: */ NETXEN_NIC_REG(0x23c), /* crb_rcv_consumer_offset: */ NETXEN_NIC_REG(0x240), /* crb_gloablrcv_ring: */ NETXEN_NIC_REG(0x244), /* crb_rcv_ring_size */ NETXEN_NIC_REG(0x248), }, /* LRO */ { /* crb_rcv_producer_offset: */ NETXEN_NIC_REG(0x24c), /* crb_rcv_consumer_offset: */ NETXEN_NIC_REG(0x250), /* crb_gloablrcv_ring: */ NETXEN_NIC_REG(0x254), /* crb_rcv_ring_size */ NETXEN_NIC_REG(0x258), } }, /* crb_rcvstatus_ring: */ NETXEN_NIC_REG(0x25c), /* crb_rcv_status_producer: */ NETXEN_NIC_REG(0x260), /* crb_rcv_status_consumer: */ NETXEN_NIC_REG(0x264), /* crb_rcvpeg_state: */ NETXEN_NIC_REG(0x268), /* crb_status_ring_size */ NETXEN_NIC_REG(0x26c), },};u64 ctx_addr_sig_regs[][3] = { {NETXEN_NIC_REG(0x188), NETXEN_NIC_REG(0x18c), NETXEN_NIC_REG(0x1c0)}, {NETXEN_NIC_REG(0x190), NETXEN_NIC_REG(0x194), NETXEN_NIC_REG(0x1c4)}, {NETXEN_NIC_REG(0x198), NETXEN_NIC_REG(0x19c), NETXEN_NIC_REG(0x1c8)}, {NETXEN_NIC_REG(0x1a0), NETXEN_NIC_REG(0x1a4), NETXEN_NIC_REG(0x1cc)}};/* PCI Windowing for DDR regions. */#define ADDR_IN_RANGE(addr, low, high) \ (((addr) <= (high)) && ((addr) >= (low)))#define NETXEN_FLASH_BASE (NETXEN_BOOTLD_START)#define NETXEN_PHANTOM_MEM_BASE (NETXEN_FLASH_BASE)#define NETXEN_MAX_MTU 8000 + NETXEN_ENET_HEADER_SIZE + NETXEN_ETH_FCS_SIZE#define NETXEN_MIN_MTU 64#define NETXEN_ETH_FCS_SIZE 4#define NETXEN_ENET_HEADER_SIZE 14#define NETXEN_WINDOW_ONE 0x2000000 /*CRB Window: bit 25 of CRB address */#define NETXEN_FIRMWARE_LEN ((16 * 1024) / 4)#define NETXEN_NIU_HDRSIZE (0x1 << 6)#define NETXEN_NIU_TLRSIZE (0x1 << 5)#define lower32(x) ((u32)((x) & 0xffffffff))#define upper32(x) \ ((u32)(((unsigned long long)(x) >> 32) & 0xffffffff))#define NETXEN_NIC_ZERO_PAUSE_ADDR 0ULL#define NETXEN_NIC_UNIT_PAUSE_ADDR 0x200ULL#define NETXEN_NIC_EPG_PAUSE_ADDR1 0x2200010000c28001ULL#define NETXEN_NIC_EPG_PAUSE_ADDR2 0x0100088866554433ULL#define NETXEN_NIC_WINDOW_MARGIN 0x100000unsigned long netxen_nic_pci_set_window(struct netxen_adapter *adapter, unsigned long long addr);void netxen_free_hw_resources(struct netxen_adapter *adapter);int netxen_nic_set_mac(struct net_device *netdev, void *p){ struct netxen_adapter *adapter = netdev_priv(netdev); struct sockaddr *addr = p; if (netif_running(netdev)) return -EBUSY; if (!is_valid_ether_addr(addr->sa_data)) return -EADDRNOTAVAIL; DPRINTK(INFO, "valid ether addr\n"); memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); if (adapter->macaddr_set) adapter->macaddr_set(adapter, addr->sa_data); return 0;}/* * netxen_nic_set_multi - Multicast */void netxen_nic_set_multi(struct net_device *netdev){ struct netxen_adapter *adapter = netdev_priv(netdev); struct dev_mc_list *mc_ptr; mc_ptr = netdev->mc_list; if (netdev->flags & IFF_PROMISC) { if (adapter->set_promisc) adapter->set_promisc(adapter, NETXEN_NIU_PROMISC_MODE); } else { if (adapter->unset_promisc) adapter->unset_promisc(adapter, NETXEN_NIU_NON_PROMISC_MODE); }}/* * netxen_nic_change_mtu - Change the Maximum Transfer Unit * @returns 0 on success, negative on failure */int netxen_nic_change_mtu(struct net_device *netdev, int mtu){ struct netxen_adapter *adapter = netdev_priv(netdev); int eff_mtu = mtu + NETXEN_ENET_HEADER_SIZE + NETXEN_ETH_FCS_SIZE; if ((eff_mtu > NETXEN_MAX_MTU) || (eff_mtu < NETXEN_MIN_MTU)) { printk(KERN_ERR "%s: %s %d is not supported.\n", netxen_nic_driver_name, netdev->name, mtu); return -EINVAL; } if (adapter->set_mtu) adapter->set_mtu(adapter, mtu); netdev->mtu = mtu; return 0;}/* * check if the firmware has been downloaded and ready to run and * setup the address for the descriptors in the adapter */int netxen_nic_hw_resources(struct netxen_adapter *adapter){ struct netxen_hardware_context *hw = &adapter->ahw; u32 state = 0; void *addr; int loops = 0, err = 0; int ctx, ring; struct netxen_recv_context *recv_ctx; struct netxen_rcv_desc_ctx *rcv_desc; int func_id = adapter->portnum; DPRINTK(INFO, "crb_base: %lx %x", NETXEN_PCI_CRBSPACE, PCI_OFFSET_SECOND_RANGE(adapter, NETXEN_PCI_CRBSPACE)); DPRINTK(INFO, "cam base: %lx %x", NETXEN_CRB_CAM, pci_base_offset(adapter, NETXEN_CRB_CAM)); DPRINTK(INFO, "cam RAM: %lx %x", NETXEN_CAM_RAM_BASE, pci_base_offset(adapter, NETXEN_CAM_RAM_BASE)); for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) { DPRINTK(INFO, "Command Peg ready..waiting for rcv peg\n"); loops = 0; state = 0; /* Window 1 call */ state = readl(NETXEN_CRB_NORMALIZE(adapter, recv_crb_registers[ctx]. crb_rcvpeg_state)); while (state != PHAN_PEG_RCV_INITIALIZED && loops < 20) { msleep(1); /* Window 1 call */ state = readl(NETXEN_CRB_NORMALIZE(adapter, recv_crb_registers [ctx]. crb_rcvpeg_state)); loops++; } if (loops >= 20) { printk(KERN_ERR "Rcv Peg initialization not complete:" "%x.\n", state); err = -EIO; return err; } } adapter->intr_scheme = readl( NETXEN_CRB_NORMALIZE(adapter, CRB_NIC_CAPABILITIES_FW)); printk(KERN_NOTICE "%s: FW capabilities:0x%x\n", netxen_nic_driver_name, adapter->intr_scheme); DPRINTK(INFO, "Receive Peg ready too. starting stuff\n"); addr = netxen_alloc(adapter->ahw.pdev,
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?