⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 acenic_np.c

📁 该软件根据网络数据生成NetFlow记录。NetFlow可用于网络规划、负载均衡、安全监控等
💻 C
📖 第 1 页 / 共 5 页
字号:
/*******************************************************************************                                                                             **   Copyright 2005 University of Cambridge Computer Laboratory.               **                                                                             **   This file is part of Nprobe.                                              **                                                                             **   Nprobe 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.                                       **                                                                             **   Nprobe 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 Nprobe; if not, write to the Free Software                     **   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA **                                                                             *******************************************************************************//* * acenic.c: Linux driver for the Alteon AceNIC Gigabit Ethernet card *           and other Tigon based cards. * * Copyright 1998-2000 by Jes Sorensen, <jes@linuxcare.com>. * * Thanks to Alteon and 3Com for providing hardware and documentation * enabling me to write this driver. * * A mailing list for discussing the use of this driver has been * setup, please subscribe to the lists if you have any questions * about the driver. Send mail to linux-acenic-help@sunsite.auc.dk to * see how to subscribe. * * 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. * * Additional credits: *   Pete Wyckoff <wyckoff@ca.sandia.gov>: Initial Linux/Alpha and trace *       dump support. The trace dump support has not been *       integrated yet however. *   Troy Benjegerdes: Big Endian (PPC) patches. *   Nate Stahl: Better out of memory handling and stats support. *   Aman Singla: Nasty race between interrupt handler and tx code dealing *                with 'testing the tx_ret_csm and setting tx_full' *   David S. Miller <davem@redhat.com>: conversion to new PCI dma mapping *                                       infrastructure and Sparc support *   Pierrick Pinasseau (CERN): For lending me an Ultra 5 to test the *                              driver under Linux/Sparc64 *   Matt Domsch <Matt_Domsch@dell.com>: Detect Alteon 1000baseT cards *   Chip Salzenberg <chip@valinux.com>: Fix race condition between tx *                                       handler and close() cleanup. *   Ken Aaker <kdaaker@rchland.vnet.ibm.com>: Correct check for whether *                                       memory mapped IO is enabled to *                                       make the driver work on RS/6000. *   Takayoshi Kouchi <kouchi@hpc.bs1.fc.nec.co.jp>: Identifying problem *                                       where the driver would disable *                                       bus master mode if it had to disable *                                       write and invalidate. *   Stephen Hack <stephen_hack@hp.com>: Fixed ace_set_mac_addr for little *                                       endian systems. *   Val Henson <vhenson@esscom.com>:    Reset Jumbo skb producer and *                                       rx producer index when *                                       flushing the Jumbo ring. *   Hans Grobler <grobh@sun.ac.za>:     Memory leak fixes in the *                                       driver init path. */#include <linux/config.h>#include <linux/module.h>#include <linux/version.h>#include <linux/types.h>#include <linux/errno.h>#include <linux/ioport.h>#include <linux/pci.h>#include <linux/kernel.h>#include <linux/netdevice.h>#include <linux/etherdevice.h>#include <linux/skbuff.h>#include <linux/init.h>#include <linux/delay.h>#include <linux/mm.h>#include <linux/sockios.h>#ifdef SIOCETHTOOL#include <linux/ethtool.h>#endif#include <net/sock.h>#include <net/ip.h>#include <asm/system.h>#include <asm/io.h>#include <asm/irq.h>#include <asm/byteorder.h>#include <asm/uaccess.h>#include "probe.h"//#define NP_dev_kfree_skb(skb) dev_kfree_skb(skb)//#define NP_dev_alloc_skb(sz) alloc_skb(sz, GFP_ATOMIC)//#define NP_netif_rx(skb) netif_rx(skb)#undef INDEX_DEBUG#ifdef CONFIG_ACENIC_OMIT_TIGON_I#define ACE_IS_TIGON_I(ap)	0#else#define ACE_IS_TIGON_I(ap)	(ap->version == 1)#endif#ifndef PCI_VENDOR_ID_ALTEON#define PCI_VENDOR_ID_ALTEON		0x12ae	#endif#ifndef PCI_DEVICE_ID_ALTEON_ACENIC_FIBRE#define PCI_DEVICE_ID_ALTEON_ACENIC_FIBRE  0x0001#define PCI_DEVICE_ID_ALTEON_ACENIC_COPPER 0x0002#endif#ifndef PCI_DEVICE_ID_3COM_3C985#define PCI_DEVICE_ID_3COM_3C985	0x0001#endif#ifndef PCI_VENDOR_ID_NETGEAR#define PCI_VENDOR_ID_NETGEAR		0x1385#define PCI_DEVICE_ID_NETGEAR_GA620	0x620a#endif#ifndef PCI_DEVICE_ID_NETGEAR_GA620T#define PCI_DEVICE_ID_NETGEAR_GA620T	0x630a#endif/* * Farallon used the DEC vendor ID by mistake and they seem not * to care - stinky! */#ifndef PCI_DEVICE_ID_FARALLON_PN9000SX#define PCI_DEVICE_ID_FARALLON_PN9000SX	0x1a#endif#ifndef PCI_VENDOR_ID_SGI#define PCI_VENDOR_ID_SGI		0x10a9#endif#ifndef PCI_DEVICE_ID_SGI_ACENIC#define PCI_DEVICE_ID_SGI_ACENIC	0x0009#endif#if LINUX_VERSION_CODE >= 0x20400static struct pci_device_id acenic_pci_tbl[] __initdata = {	{ PCI_VENDOR_ID_ALTEON, PCI_DEVICE_ID_ALTEON_ACENIC_FIBRE,	  PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_NETWORK_ETHERNET << 8, 0xffff00, },	{ PCI_VENDOR_ID_ALTEON, PCI_DEVICE_ID_ALTEON_ACENIC_COPPER,	  PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_NETWORK_ETHERNET << 8, 0xffff00, },	{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C985,	  PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_NETWORK_ETHERNET << 8, 0xffff00, },	{ PCI_VENDOR_ID_NETGEAR, PCI_DEVICE_ID_NETGEAR_GA620,	  PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_NETWORK_ETHERNET << 8, 0xffff00, },	{ PCI_VENDOR_ID_NETGEAR, PCI_DEVICE_ID_NETGEAR_GA620T,	  PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_NETWORK_ETHERNET << 8, 0xffff00, },	/*	 * Farallon used the DEC vendor ID on their cards incorrectly.	 */	{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_FARALLON_PN9000SX,	  PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_NETWORK_ETHERNET << 8, 0xffff00, },	{ PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_ACENIC,	  PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_NETWORK_ETHERNET << 8, 0xffff00, },	{ }};MODULE_DEVICE_TABLE(pci, acenic_pci_tbl);#endif#ifndef wmb#define wmb()	mb()#endif#ifndef __exit#define __exit#endif#ifndef __devinit#define __devinit	__init#endif#ifndef SMP_CACHE_BYTES#define SMP_CACHE_BYTES	L1_CACHE_BYTES#endif#if (BITS_PER_LONG == 64)#define ACE_64BIT_PTR	1#endif#ifndef SET_MODULE_OWNER#define SET_MODULE_OWNER(dev)		{do{} while(0);}#define ACE_MOD_INC_USE_COUNT		MOD_INC_USE_COUNT#define ACE_MOD_DEC_USE_COUNT		MOD_DEC_USE_COUNT#else#define ACE_MOD_INC_USE_COUNT		{do{} while(0);}#define ACE_MOD_DEC_USE_COUNT		{do{} while(0);}#endif#if (LINUX_VERSION_CODE < 0x02030d)#define pci_resource_start(dev, bar)	dev->base_address[bar]#elif (LINUX_VERSION_CODE < 0x02032c)#define pci_resource_start(dev, bar)	dev->resource[bar].start#endif#if (LINUX_VERSION_CODE < 0x02030e)#define net_device device#endif#if (LINUX_VERSION_CODE < 0x02032a)typedef u32 dma_addr_t;static inline void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,					 dma_addr_t *dma_handle){	void *virt_ptr;	virt_ptr = kmalloc(size, GFP_KERNEL);	if (!virt_ptr)		return NULL;	*dma_handle = virt_to_bus(virt_ptr);	return virt_ptr;}#define pci_free_consistent(cookie, size, ptr, dma_ptr)	kfree(ptr)#define pci_map_single(cookie, address, size, dir)	virt_to_bus(address)#define pci_unmap_single(cookie, address, size, dir)#endif#if (LINUX_VERSION_CODE < 0x02032b)/* * SoftNet * * For pre-softnet kernels we need to tell the upper layer not to * re-enter start_xmit() while we are in there. However softnet * guarantees not to enter while we are in there so there is no need * to do the netif_stop_queue() dance unless the transmit queue really * gets stuck. This should also improve performance according to tests * done by Aman Singla. */#define dev_kfree_skb_irq(a)			dev_kfree_skb(a)#define netif_wake_queue(dev)			clear_bit(0, &dev->tbusy)#define netif_stop_queue(dev)			set_bit(0, &dev->tbusy)#define late_stop_netif_stop_queue(dev)		{do{} while(0);}#define early_stop_netif_stop_queue(dev)	test_and_set_bit(0,&dev->tbusy)#define early_stop_netif_wake_queue(dev)	netif_wake_queue(dev)static inline void netif_start_queue(struct net_device *dev){	dev->tbusy = 0;	dev->interrupt = 0;	dev->start = 1;}#define ace_mark_net_bh()			mark_bh(NET_BH)#define netif_queue_stopped(dev)		dev->tbusy#define netif_running(dev)			dev->start#define ace_if_down(dev)			{do{dev->start = 0;} while(0);}#define tasklet_struct				tq_structstatic inline void tasklet_schedule(struct tasklet_struct *tasklet){	queue_task(tasklet, &tq_immediate);	mark_bh(IMMEDIATE_BH);}static inline void tasklet_init(struct tasklet_struct *tasklet,				void (*func)(unsigned long),				unsigned long data){	tasklet->next = NULL;	tasklet->sync = 0;	tasklet->routine = (void (*)(void *))func;	tasklet->data = (void *)data;}#define tasklet_kill(tasklet)			{do{} while(0);}#else#define late_stop_netif_stop_queue(dev)		netif_stop_queue(dev)#define early_stop_netif_stop_queue(dev)	0#define early_stop_netif_wake_queue(dev)	{do{} while(0);}#define ace_mark_net_bh()			{do{} while(0);}#define ace_if_down(dev)			{do{} while(0);}#endif#if (LINUX_VERSION_CODE >= 0x02031b)#define NEW_NETINIT#define ACE_PROBE_ARG				void#else#define ACE_PROBE_ARG				struct net_device *dev#endif#define ACE_MAX_MOD_PARMS	8#define BOARD_IDX_STATIC	0#define BOARD_IDX_OVERFLOW	-1#include "acenic_np.h"/* * These must be defined before the firmware is included. */#define MAX_TEXT_LEN	96*1024#define MAX_RODATA_LEN	8*1024#define MAX_DATA_LEN	2*1024#include "acenic_firmware.h"/* * This driver currently supports Tigon I and Tigon II based cards * including the Alteon AceNIC, the 3Com 3C985[B] and NetGear * GA620. The driver should also work on the SGI, DEC and Farallon * versions of the card, however I have not been able to test that * myself. * * This card is really neat, it supports receive hardware checksumming * and jumbo frames (up to 9000 bytes) and does a lot of work in the * firmware. Also the programming interface is quite neat, except for * the parts dealing with the i2c eeprom on the card ;-) * * Using jumbo frames: * * To enable jumbo frames, simply specify an mtu between 1500 and 9000 * bytes to ifconfig. Jumbo frames can be enabled or disabled at any time * by running `ifconfig eth<X> mtu <MTU>' with <X> being the Ethernet * interface number and <MTU> being the MTU value. * * Module parameters: * * When compiled as a loadable module, the driver allows for a number * of module parameters to be specified. The driver supports the * following module parameters: * *  trace=<val> - Firmware trace level. This requires special traced *                firmware to replace the firmware supplied with *                the driver - for debugging purposes only. * *  link=<val>  - Link state. Normally you want to use the default link *                parameters set by the driver. This can be used to *                override these in case your switch doesn't negotiate *                the link properly. Valid values are: *         0x0001 - Force half duplex link. *         0x0002 - Do not negotiate line speed with the other end. *         0x0010 - 10Mbit/sec link. *         0x0020 - 100Mbit/sec link. *         0x0040 - 1000Mbit/sec link. *         0x0100 - Do not negotiate flow control. *         0x0200 - Enable RX flow control Y *         0x0400 - Enable TX flow control Y (Tigon II NICs only). *                Default value is 0x0270, ie. enable link+flow *                control negotiation. Negotiating the highest *                possible link speed with RX flow control enabled. * *                When disabling link speed negotiation, only one link *                speed is allowed to be specified! * *  tx_coal_tick=<val> - number of coalescing clock ticks (us) allowed *                to wait for more packets to arive before *                interrupting the host, from the time the first *                packet arrives. * *  rx_coal_tick=<val> - number of coalescing clock ticks (us) allowed *                to wait for more packets to arive in the transmit ring, *                before interrupting the host, after transmitting the *                first packet in the ring. * *  max_tx_desc=<val> - maximum number of transmit descriptors *                (packets) transmitted before interrupting the host. * *  max_rx_desc=<val> - maximum number of receive descriptors *                (packets) received before interrupting the host. * *  tx_ratio=<val> - 7 bit value (0 - 63) specifying the split in 64th *                increments of the NIC's on board memory to be used for *                transmit and receive buffers. For the 1MB NIC app. 800KB *                is available, on the 1/2MB NIC app. 300KB is available. *                68KB will always be available as a minimum for both *                directions. The default value is a 50/50 split. *  dis_pci_mem_inval=<val> - disable PCI memory write and invalidate *                operations, default (1) is to always disable this as *                that is what Alteon does on NT. I have not been able *                to measure any real performance differences with *                this on my systems. Set <val>=0 if you want to *                enable these operations. * * If you use more than one NIC, specify the parameters for the * individual NICs with a comma, ie. trace=0,0x00001fff,0 you want to * run tracing on NIC #2 but not on NIC #1 and #3. * * TODO: * * - Proper multicast support. * - NIC dump support. * - More tuning parameters. * * The mini ring is not used under Linux and I am not sure it makes sense * to actually use it. * * New interrupt handler strategy: * * The old interrupt handler worked using the traditional method of * replacing an skbuff with a new one when a packet arrives. However * the rx rings do not need to contain a static number of buffer * descriptors, thus it makes sense to move the memory allocation out * of the main interrupt handler and do it in a bottom half handler * and only allocate new buffers when the number of buffers in the * ring is below a certain threshold. In order to avoid starving the * NIC under heavy load it is however necessary to force allocation * when hitting a minimum threshold. The strategy for alloction is as * follows: * *     RX_LOW_BUF_THRES    - allocate buffers in the bottom half *     RX_PANIC_LOW_THRES  - we are very low on buffers, allocate *                           the buffers in the interrupt handler *     RX_RING_THRES       - maximum number of buffers in the rx ring *     RX_MINI_THRES       - maximum number of buffers in the mini ring *     RX_JUMBO_THRES      - maximum number of buffers in the jumbo ring * * One advantagous side effect of this allocation approach is that the * entire rx processing can be done without holding any spin lock * since the rx rings and registers are totally independant of the tx * ring and its registers.  This of course includes the kmalloc's of * new skb's. Thus start_xmit can run in parallel with rx processing * and the memory allocation on SMP systems. * * Note that running the skb reallocation in a bottom half opens up * another can of races which needs to be handled properly. In * particular it can happen that the interrupt handler tries to run * the reallocation while the bottom half is either running on another * CPU or was interrupted on the same CPU. To get around this the * driver uses bitops to prevent the reallocation routines from being * reentered. * * TX handling can also be done without holding any spin lock, wheee * this is fun! since tx_ret_csm is only written to by the interrupt * handler. The case to be aware of is when shutting down the device * and cleaning up where it is necessary to make sure that * start_xmit() is not running while this is happening. Well DaveM * informs me that this case is already protected against ... bye bye * Mr. Spin Lock, it was nice to know you. * * TX interrupts are now partly disabled so the NIC will only generate * TX interrupts for the number of coal ticks, not for the number of * TX packets in the queue. This should reduce the number of TX only, * ie. when no RX processing is done, interrupts seen. *//* * Threshold values for RX buffer allocation - the low water marks for * when to start refilling the rings are set to 75% of the ring * sizes. It seems to make sense to refill the rings entirely from the * intrrupt handler once it gets below the panic threshold, that way * we don't risk that the refilling is moved to another CPU when the * one running the interrupt handler just got the slab code hot in its * cache. */#define RX_RING_SIZE		128#define RX_MINI_SIZE		128#define RX_JUMBO_SIZE		48#define RX_PANIC_STD_THRES	16#define RX_PANIC_STD_REFILL	(3*RX_PANIC_STD_THRES)/2#define RX_LOW_STD_THRES	(3*RX_RING_SIZE)/4#define RX_PANIC_MINI_THRES	12

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -