📄 velocity_main.c
字号:
/* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. * * This software may be redistributed and/or modified under * the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or * 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. * * * File: velocity_main.c * * Purpose: Functions for Linux drver interfaces. * * Author: Chuang Liang-Shing, AJ Jiang * * Date: Jan 24, 2003 * */#undef __NO_VERSION__#if !defined(__VELOCITY_H__)#include "velocity.h"#endifstatic int velocity_nics = 0;static PVELOCITY_INFO pVelocity3_Infos = NULL;static int msglevel = MSG_LEVEL_INFO;#ifdef VELOCITY_ETHTOOL_IOCTL_SUPPORTstatic int velocity_ethtool_ioctl(struct net_device* dev, struct ifreq* ifr);#endif#ifdef SIOCGMIIPHYstatic int velocity_mii_ioctl(struct net_device* dev, struct ifreq* ifr, int cmd);#endif/* Define module options*/MODULE_AUTHOR("VIA Networking Technologies, Inc.");MODULE_LICENSE("GPL");MODULE_DESCRIPTION("VIA Networking Velocity Family Gigabit Ethernet Adapter Driver");#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)#define VELOCITY_PARAM(N,D) \ static int N[MAX_UINTS]=OPTION_DEFAULT;\ module_param_array(N, int, NULL, 0);\ MODULE_PARM_DESC(N, D);#else#define VELOCITY_PARAM(N,D) \ static const int N[MAX_UINTS]=OPTION_DEFAULT;\ MODULE_PARM(N, "1-" __MODULE_STRING(MAX_UINTS) "i");\ MODULE_PARM_DESC(N, D);#endif#define RX_DESC_MIN 64#define RX_DESC_MAX 255#define RX_DESC_DEF 64VELOCITY_PARAM(RxDescriptors,"Number of receive descriptors");#define TX_DESC_MIN 16#define TX_DESC_MAX 256#define TX_DESC_DEF 64VELOCITY_PARAM(TxDescriptors,"Number of transmit descriptors");#define VLAN_ID_MIN 0#define VLAN_ID_MAX 4094#define VLAN_ID_DEF 0/* VID_setting[] is used for setting the VID of NIC. 0: default VID. 1-4094: other VIDs.*/VELOCITY_PARAM(VID_setting,"802.1Q VLAN ID");#define RX_THRESH_MIN 0#define RX_THRESH_MAX 3#define RX_THRESH_DEF 0/* rx_thresh[] is used for controlling the receive fifo threshold. 0: indicate the rxfifo threshold is 128 bytes. 1: indicate the rxfifo threshold is 512 bytes. 2: indicate the rxfifo threshold is 1024 bytes. 3: indicate the rxfifo threshold is store & forward.*/VELOCITY_PARAM(rx_thresh,"Receive fifo threshold");#define DMA_LENGTH_MIN 0#define DMA_LENGTH_MAX 7#define DMA_LENGTH_DEF 6 // [1.18] Change DMA default to S&F/* DMA_length[] is used for controlling the DMA length 0: 8 DWORDs 1: 16 DWORDs 2: 32 DWORDs 3: 64 DWORDs 4: 128 DWORDs 5: 256 DWORDs 6: SF(flush till emply) 7: SF(flush till emply)*/VELOCITY_PARAM(DMA_length,"DMA length");#define TAGGING_DEF 0/* enable_tagging[] is used for enabling 802.1Q VID tagging. 0: disable VID seeting(default). 1: enable VID setting.*/VELOCITY_PARAM(enable_tagging,"Enable 802.1Q tagging");#define IP_ALIG_DEF 0/* IP_byte_align[] is used for IP header DWORD byte aligned 0: indicate the IP header won't be DWORD byte aligned.(Default) . 1: indicate the IP header will be DWORD byte aligned. In some enviroment, the IP header should be DWORD byte aligned, or the packet will be droped when we receive it. (eg: IPVS)*/VELOCITY_PARAM(IP_byte_align,"Enable IP header dword aligned");#ifdef VELOCITY_TX_CSUM_SUPPORT#define TX_CSUM_DEF 1/* txcsum_offload[] is used for setting the checksum offload ability of NIC. (We only support RX checksum offload now) 0: disable csum_offload[checksum offload 1: enable checksum offload. (Default)*/VELOCITY_PARAM(txcsum_offload,"Enable transmit packet checksum offload");#endif#define FLOW_CNTL_DEF 1#define FLOW_CNTL_MIN 1#define FLOW_CNTL_MAX 5/* flow_control[] is used for setting the flow control ability of NIC. 1: hardware deafult - AUTO (default). Use Hardware default value in ANAR. 2: enable TX flow control. 3: enable RX flow control. 4: enable RX/TX flow control. 5: disable*/VELOCITY_PARAM(flow_control,"Enable flow control ability");#define MED_LNK_DEF 0#define MED_LNK_MIN 0#define MED_LNK_MAX 4/* speed_duplex[] is used for setting the speed and duplex mode of NIC. 0: indicate autonegotiation for both speed and duplex mode 1: indicate 100Mbps half duplex mode 2: indicate 100Mbps full duplex mode 3: indicate 10Mbps half duplex mode 4: indicate 10Mbps full duplex mode Note: if EEPROM have been set to the force mode, this option is ignored by driver.*/VELOCITY_PARAM(speed_duplex,"Setting the speed and duplex mode");#define VAL_PKT_LEN_DEF 0/* ValPktLen[] is used for setting the checksum offload ability of NIC. 0: Receive frame with invalid layer 2 length (Default) 1: Drop frame with invalid layer 2 length*/VELOCITY_PARAM(ValPktLen,"Receiving or Drop invalid 802.3 frame");#define WOL_OPT_DEF 0#define WOL_OPT_MIN 0#define WOL_OPT_MAX 7/* wol_opts[] is used for controlling wake on lan behavior. 0: Wake up if recevied a magic packet. (Default) 1: Wake up if link status is on/off. 2: Wake up if recevied an arp packet. 4: Wake up if recevied any unicast packet. Those value can be sumed up to support more than one option.*/VELOCITY_PARAM(wol_opts,"Wake On Lan options");#define INT_WORKS_DEF 32#define INT_WORKS_MIN 10#define INT_WORKS_MAX 64VELOCITY_PARAM(int_works,"Number of packets per interrupt services");// EnableMRDPL[] is used for setting the Memory-Read-Multiple ability of NIC// 0: Disable (default)// 1: Enable#define MRDPL_DEF 0VELOCITY_PARAM(EnableMRDPL,"Memory-Read-Multiple ability");static int velocity_found1(struct pci_dev *pcid, const struct pci_device_id *ent);static void velocity_print_info(PVELOCITY_INFO pInfo);static int velocity_open(struct net_device *dev);static int velocity_change_mtu(struct net_device *dev,int mtu);static int velocity_xmit(struct sk_buff *skb, struct net_device *dev);static irqreturn_t velocity_intr(int irq, void *dev_instance, struct pt_regs *regs);static void velocity_set_multi(struct net_device *dev);static struct net_device_stats *velocity_get_stats(struct net_device *dev);static int velocity_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);static int velocity_close(struct net_device *dev);static int velocity_rx_srv(PVELOCITY_INFO pInfo,int status);static BOOL velocity_receive_frame(PVELOCITY_INFO ,int idx);static BOOL velocity_alloc_rx_buf(PVELOCITY_INFO, int idx);static void velocity_init_adapter(PVELOCITY_INFO pInfo, VELOCITY_INIT_TYPE);static void velocity_init_pci(PVELOCITY_INFO pInfo);static void velocity_free_tx_buf(PVELOCITY_INFO pInfo, PVELOCITY_TD_INFO, PTX_DESC pTD);#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,9)#ifdef CONFIG_PMstatic int velocity_notify_reboot(struct notifier_block *, unsigned long event, void *ptr);#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,11)static int velocity_suspend(struct pci_dev *pcid, pm_message_t state);#elsestatic int velocity_suspend(struct pci_dev *pcid, u32 state);#endifstatic int velocity_resume(struct pci_dev *pcid);struct notifier_block velocity_notifier = { notifier_call: velocity_notify_reboot, next: NULL, priority: 0};static int velocity_netdev_event(struct notifier_block *nb, unsigned long notification, void *ptr);static struct notifier_block velocity_inetaddr_notifier = { notifier_call: velocity_netdev_event, };#endif //CONFIG_PM#endif //LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,9)static CHIP_INFO chip_info_table[] = { {CHIP_TYPE_VT6110, "VIA Networking Velocity Family Gigabit Ethernet Adapter", 256, 4, 0x00FFFFFFUL}, {0, NULL}};static struct pci_device_id velocity_id_table[] __devinitdata = { {0x1106, 0x3119, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (unsigned long)&chip_info_table[0]}, {0,}};static char* get_product_name(int chip_id){ int i; for (i=0; chip_info_table[i].name!=NULL; i++) if (chip_info_table[i].chip_id==chip_id) break; return chip_info_table[i].name;}static void __devexit velocity_remove1(struct pci_dev *pcid){ PVELOCITY_INFO pInfo = pci_get_drvdata(pcid); PVELOCITY_INFO ptr; struct net_device* dev = pInfo->dev; if (pInfo == NULL) return; for (ptr=pVelocity3_Infos; ptr && (ptr!=pInfo); ptr=ptr->next) do {} while (0); if (ptr == pInfo) { if (ptr == pVelocity3_Infos) pVelocity3_Infos = ptr->next; else ptr->prev->next = ptr->next; } else { VELOCITY_PRT(msglevel, MSG_LEVEL_ERR, KERN_ERR "info struct not found\n"); return; }#ifdef CONFIG_PROC_FS velocity_free_proc_entry(pInfo); velocity_free_proc_fs(pInfo);#endif if (dev) unregister_netdev(dev); /*if (pInfo->pMacRegs) iounmap(pInfo->pMacRegs);*/ if (pInfo->hw.hw_addr) iounmap(pInfo->hw.hw_addr); pci_disable_device(pcid);#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) pci_release_regions(pcid); free_netdev(dev);#else if (pInfo->hw.ioaddr) release_region(pInfo->hw.ioaddr, pInfo->hw.io_size); kfree(dev);#endif pci_set_drvdata(pcid, NULL);}static voidvelocity_set_int_opt( int* opt, int val, int min, int max, int def, char* name ){ if (val == -1) *opt = def; else if (val<min || val>max) { VELOCITY_PRT(msglevel, MSG_LEVEL_INFO, KERN_NOTICE "the value of parameter %s is invalid, the valid range is (%d-%d)\n", name, min, max); *opt = def; } else { VELOCITY_PRT(msglevel, MSG_LEVEL_INFO, KERN_INFO "set value of parameter %s to %d\n", name, val); *opt = val; }}static voidvelocity_set_bool_opt(PU32 opt, int val, BOOL def, U32 flag, char* name){ (*opt) &= (~flag); if (val == -1) *opt |= (def ? flag : 0); else if (val<0 || val>1) { printk(KERN_NOTICE "the value of parameter %s is invalid, the valid range is (0-1)\n", name); *opt |= (def ? flag : 0); } else { printk(KERN_INFO "set parameter %s to %s\n", name , val ? "TRUE" : "FALSE"); *opt |= (val ? flag : 0); }}static voidvelocity_get_options (POPTIONS pOpts, int index){ velocity_set_int_opt(&pOpts->rx_thresh,rx_thresh[index], RX_THRESH_MIN, RX_THRESH_MAX, RX_THRESH_DEF,"rx_thresh"); velocity_set_int_opt(&pOpts->DMA_length,DMA_length[index], DMA_LENGTH_MIN, DMA_LENGTH_MAX, DMA_LENGTH_DEF,"DMA_length"); velocity_set_int_opt(&pOpts->nRxDescs,RxDescriptors[index], RX_DESC_MIN, RX_DESC_MAX, RX_DESC_DEF, "RxDescriptors"); velocity_set_int_opt(&pOpts->nTxDescs,TxDescriptors[index], TX_DESC_MIN, TX_DESC_MAX, TX_DESC_DEF, "TxDescriptors"); velocity_set_int_opt(&pOpts->vid,VID_setting[index], VLAN_ID_MIN, VLAN_ID_MAX, VLAN_ID_DEF,"VID_setting"); velocity_set_bool_opt(&pOpts->flags,enable_tagging[index], TAGGING_DEF,VELOCITY_FLAGS_TAGGING, "enable_tagging");#ifdef VELOCITY_TX_CSUM_SUPPORT velocity_set_bool_opt(&pOpts->flags, txcsum_offload[index], TX_CSUM_DEF, VELOCITY_FLAGS_TX_CSUM, "txcsum_offload");#endif velocity_set_int_opt(&pOpts->flow_cntl,flow_control[index], FLOW_CNTL_MIN,FLOW_CNTL_MAX, FLOW_CNTL_DEF, "flow_control"); velocity_set_bool_opt(&pOpts->flags,IP_byte_align[index], IP_ALIG_DEF, VELOCITY_FLAGS_IP_ALIGN, "IP_byte_align"); velocity_set_bool_opt(&pOpts->flags,ValPktLen[index], VAL_PKT_LEN_DEF, VELOCITY_FLAGS_VAL_PKT_LEN, "ValPktLen"); velocity_set_int_opt((int*) &pOpts->spd_dpx,speed_duplex[index], MED_LNK_MIN, MED_LNK_MAX, MED_LNK_DEF,"Media link mode"); velocity_set_int_opt((int*) &pOpts->wol_opts,wol_opts[index], WOL_OPT_MIN, WOL_OPT_MAX, WOL_OPT_DEF,"Wake On Lan options"); velocity_set_int_opt((int*) &pOpts->int_works,int_works[index], INT_WORKS_MIN, INT_WORKS_MAX, INT_WORKS_DEF,"Interrupt service works"); velocity_set_bool_opt(&pOpts->flags,EnableMRDPL[index], MRDPL_DEF, VELOCITY_FLAGS_MRDPL, "EnableMRDPL"); pOpts->nRxDescs = (pOpts->nRxDescs & ~3);}//// Initialiation of adapter//static voidvelocity_init_adapter ( PVELOCITY_INFO pInfo, VELOCITY_INIT_TYPE InitType ){ struct net_device *dev = pInfo->dev; int i; mac_wol_reset(&pInfo->hw); switch (InitType) { case VELOCITY_INIT_RESET: case VELOCITY_INIT_WOL: netif_stop_queue(dev); velocity_init_register_reset(&pInfo->hw);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -