📄 skge.c
字号:
* those three depending on kernel version used: * <linux/bios32.h> * <linux/init.h> * <asm/uaccess.h> * <net/checksum.h> * * "h/skerror.h" * "h/skdebug.h" * "h/sktypes.h" * "h/lm80.h" * "h/xmac_ii.h" * * "h/skdrv2nd.h" * "h/skqueue.h" * "h/skgehwt.h" * "h/sktimer.h" * "h/ski2c.h" * "h/skgepnmi.h" * "h/skvpd.h" * "h/skgehw.h" * "h/skgeinit.h" * "h/skaddr.h" * "h/skgesirq.h" * "h/skcsum.h" * "h/skrlmt.h" * ******************************************************************************/#include "h/skversion.h"#include <linux/module.h>#include <linux/init.h>#ifdef CONFIG_PROC_FS#include <linux/proc_fs.h>#endif#include "h/skdrv1st.h"#include "h/skdrv2nd.h"#include "../probe.h" //NP/******************************************************************************* * * Defines * ******************************************************************************//* for debuging on x86 only *//* #define BREAKPOINT() asm(" int $3"); *//* use the transmit hw checksum driver functionality */#define USE_SK_TX_CHECKSUM/* use the receive hw checksum driver functionality *///#define USE_SK_RX_CHECKSUM/* use the scatter-gather functionality with sendfile() */#define SK_ZEROCOPY/* use of a transmit complete interrupt */#define USE_TX_COMPLETE/* * threshold for copying small receive frames * set to 0 to avoid copying, set to 9001 to copy all frames */#define SK_COPY_THRESHOLD 0 /* NP AWM, SOS22: was 50, needs testing *//* number of adapters that can be configured via command line params */#define SK_MAX_CARD_PARAM 16/* * use those defines for a compile-in version of the driver instead * of command line parameters */// #define LINK_SPEED_A {"Auto", }// #define LINK_SPEED_B {"Auto", }// #define AUTO_NEG_A {"Sense", }// #define AUTO_NEG_B {"Sense", }// #define DUP_CAP_A {"Both", }// #define DUP_CAP_B {"Both", }// #define FLOW_CTRL_A {"SymOrRem", }// #define FLOW_CTRL_B {"SymOrRem", }// #define ROLE_A {"Auto", }// #define ROLE_B {"Auto", }// #define PREF_PORT {"A", }// #define CON_TYPE {"Auto", }// #define RLMT_MODE {"CheckLinkState", }#define DEV_KFREE_SKB_IRQ(skb) dev_kfree_skb_irq(skb)#if 0#define DEV_KFREE_SKB(skb) dev_kfree_skb(skb)#define DEV_KFREE_SKB_ANY(skb) dev_kfree_skb_any(skb)#else/* in NP these are nops */#define DEV_KFREE_SKB(skb) NP_dev_kfree_skb(skb)#define DEV_KFREE_SKB_ANY(skb) NP_dev_kfree_skb(skb)#endif /* !0 *//* Set blink mode*/#define OEM_CONFIG_VALUE ( SK_ACT_LED_BLINK | \ SK_DUP_LED_NORMAL | \ SK_LED_LINK100_ON)/* Isr return value */#define SkIsrRetVar irqreturn_t#define SkIsrRetNone IRQ_NONE#define SkIsrRetHandled IRQ_HANDLED/******************************************************************************* * * Local Function Prototypes * ******************************************************************************/static void FreeResources(struct SK_NET_DEVICE *dev);static int SkGeBoardInit(struct SK_NET_DEVICE *dev, SK_AC *pAC);static SK_BOOL BoardAllocMem(SK_AC *pAC);static void BoardFreeMem(SK_AC *pAC);static void BoardInitMem(SK_AC *pAC);static void SetupRing(SK_AC*, void*, uintptr_t, RXD**, RXD**, RXD**, int*, SK_BOOL);static SkIsrRetVar SkGeIsr(int irq, void *dev_id, struct pt_regs *ptregs);static SkIsrRetVar SkGeIsrOnePort(int irq, void *dev_id, struct pt_regs *ptregs);static int SkGeOpen(struct SK_NET_DEVICE *dev);static int SkGeClose(struct SK_NET_DEVICE *dev);static int SkGeXmit(struct sk_buff *skb, struct SK_NET_DEVICE *dev);static int SkGeSetMacAddr(struct SK_NET_DEVICE *dev, void *p);static void SkGeSetRxMode(struct SK_NET_DEVICE *dev);static struct net_device_stats *SkGeStats(struct SK_NET_DEVICE *dev);static int SkGeIoctl(struct SK_NET_DEVICE *dev, struct ifreq *rq, int cmd);static void GetConfiguration(SK_AC*);static void ProductStr(SK_AC*);static int XmitFrame(SK_AC*, TX_PORT*, struct sk_buff*);static void FreeTxDescriptors(SK_AC*pAC, TX_PORT*);static void FillRxRing(SK_AC*, RX_PORT*);static SK_BOOL FillRxDescriptor(SK_AC*, RX_PORT*);static void ReceiveIrq(SK_AC*, RX_PORT*, SK_BOOL);static void ClearAndStartRx(SK_AC*, int);static void ClearTxIrq(SK_AC*, int, int);static void ClearRxRing(SK_AC*, RX_PORT*);static void ClearTxRing(SK_AC*, TX_PORT*);static int SkGeChangeMtu(struct SK_NET_DEVICE *dev, int new_mtu);static void PortReInitBmu(SK_AC*, int);static int SkGeIocMib(DEV_NET*, unsigned int, int);static void SkXmEnableTimestamp(SK_AC *pAC, SK_IOC IoC, int Port);static int SkGeInitPCI(SK_AC *pAC);static void StartDrvCleanupTimer(SK_AC *pAC);static void StopDrvCleanupTimer(SK_AC *pAC);static int XmitFrameSG(SK_AC*, TX_PORT*, struct sk_buff*);/******************************************************************************* * * Extern Function Prototypes * ******************************************************************************/#ifdef CONFIG_PROC_FSstatic const char SK_Root_Dir_entry[] = "sk98lin";static struct proc_dir_entry *pSkRootDir;extern int sk_proc_read( char *buffer, char **buffer_location, off_t offset, int buffer_length, int *eof, void *data);#endifextern void SkDimEnableModerationIfNeeded(SK_AC *pAC); extern void SkDimDisplayModerationSettings(SK_AC *pAC);extern void SkDimStartModerationTimer(SK_AC *pAC);extern void SkDimModerate(SK_AC *pAC);#ifdef DEBUGstatic void DumpMsg(struct sk_buff*, char*);static void DumpData(char*, int);static void DumpLong(char*, int);#endif/* global variables *********************************************************/static const char *BootString = BOOT_STRING;struct SK_NET_DEVICE *SkGeRootDev = NULL;static int probed __initdata = 0;/* local variables **********************************************************/static uintptr_t TxQueueAddr[SK_MAX_MACS][2] = {{0x680, 0x600},{0x780, 0x700}};static uintptr_t RxQueueAddr[SK_MAX_MACS] = {0x400, 0x480};#ifdef CONFIG_PROC_FSstatic struct proc_dir_entry *pSkRootDir;#endif/***************************************************************************** * * skge_probe - find all SK-98xx adapters * * Description: * This function scans the PCI bus for SK-98xx adapters. Resources for * each adapter are allocated and the adapter is brought into Init 1 * state. * * Returns: * 0, if everything is ok * !=0, on error */static int __init skge_probe (void){ int boards_found = 0; int vendor_flag = SK_FALSE; SK_AC *pAC; DEV_NET *pNet = NULL; struct pci_dev *pdev = NULL; struct SK_NET_DEVICE *dev = NULL; SK_BOOL DeviceFound = SK_FALSE; SK_BOOL BootStringCount = SK_FALSE; int retval;#ifdef CONFIG_PROC_FS int proc_root_initialized = 0; struct proc_dir_entry *pProcFile;#endif if (probed) return -ENODEV; probed++; while((pdev = pci_find_class(PCI_CLASS_NETWORK_ETHERNET << 8, pdev))) { if (pci_enable_device(pdev)) { continue; } dev = NULL; pNet = NULL; SK_PCI_ISCOMPLIANT(vendor_flag, pdev); if (!vendor_flag) continue; /* Configure DMA attributes. */ if (pci_set_dma_mask(pdev, (u64) 0xffffffffffffffffULL) && pci_set_dma_mask(pdev, (u64) 0xffffffff)) continue; if ((dev = alloc_etherdev(sizeof(DEV_NET))) == NULL) { printk(KERN_ERR "Unable to allocate etherdev " "structure!\n"); break; } pNet = dev->priv; pNet->pAC = kmalloc(sizeof(SK_AC), GFP_KERNEL); if (pNet->pAC == NULL) { free_netdev(dev); printk(KERN_ERR "Unable to allocate adapter " "structure!\n"); break; } /* Print message */ if (!BootStringCount) { /* set display flag to TRUE so that */ /* we only display this string ONCE */ BootStringCount = SK_TRUE; printk("%s\n", BootString); } memset(pNet->pAC, 0, sizeof(SK_AC)); pAC = pNet->pAC; pAC->PciDev = pdev; pAC->PciDevId = pdev->device; pAC->dev[0] = dev; pAC->dev[1] = dev; sprintf(pAC->Name, "SysKonnect SK-98xx"); pAC->CheckQueue = SK_FALSE; pNet->Mtu = 1500; pNet->Up = 0; dev->irq = pdev->irq; retval = SkGeInitPCI(pAC); if (retval) { printk("SKGE: PCI setup failed: %i\n", retval); free_netdev(dev); continue; } SET_MODULE_OWNER(dev); dev->open = &SkGeOpen; dev->stop = &SkGeClose; dev->hard_start_xmit = &SkGeXmit; dev->get_stats = &SkGeStats; dev->set_multicast_list = &SkGeSetRxMode; dev->set_mac_address = &SkGeSetMacAddr; dev->do_ioctl = &SkGeIoctl; dev->change_mtu = &SkGeChangeMtu; dev->flags &= ~IFF_RUNNING; SET_NETDEV_DEV(dev, &pdev->dev);#ifdef SK_ZEROCOPY#ifdef USE_SK_TX_CHECKSUM if (pAC->ChipsetType) { /* Use only if yukon hardware */ /* SK and ZEROCOPY - fly baby... */ dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; }#endif#endif pAC->Index = boards_found; if (SkGeBoardInit(dev, pAC)) { free_netdev(dev); FreeResources(dev); kfree(dev); continue; } if (register_netdev(dev)) { printk(KERN_ERR "SKGE: Could not register device.\n"); FreeResources(dev); free_netdev(dev); continue; } /* Print adapter specific string from vpd */ ProductStr(pAC); printk("%s: %s\n", dev->name, pAC->DeviceStr); /* Print configuration settings */ printk(" PrefPort:%c RlmtMode:%s\n", 'A' + pAC->Rlmt.Net[0].Port[pAC->Rlmt.Net[0].PrefPort]-> PortNumber, (pAC->RlmtMode==0) ? "Check Link State" : ((pAC->RlmtMode==1) ? "Check Link State" : ((pAC->RlmtMode==3) ? "Check Local Port" : ((pAC->RlmtMode==7) ? "Check Segmentation" : ((pAC->RlmtMode==17) ? "Dual Check Link State" :"Error") )))); SkGeYellowLED(pAC, pAC->IoBase, 1); memcpy((caddr_t) &dev->dev_addr, (caddr_t) &pAC->Addr.Net[0].CurrentMacAddress, 6); /* First adapter... Create proc and print message */#ifdef CONFIG_PROC_FS if (!DeviceFound) { DeviceFound = SK_TRUE; SK_MEMCPY(&SK_Root_Dir_entry, BootString, sizeof(SK_Root_Dir_entry) - 1); /*Create proc (directory)*/ if(!proc_root_initialized) { pSkRootDir = create_proc_entry(SK_Root_Dir_entry, S_IFDIR | S_IWUSR | S_IRUGO | S_IXUGO, proc_net); pSkRootDir->owner = THIS_MODULE; proc_root_initialized = 1; } } /* Create proc file */ pProcFile = create_proc_entry(dev->name, S_IFREG | S_IXUSR | S_IWGRP | S_IROTH, pSkRootDir); pProcFile->read_proc = sk_proc_read; pProcFile->write_proc = NULL; pProcFile->nlink = 1; pProcFile->size = sizeof(dev->name + 1); pProcFile->data = (void *)pProcFile; pProcFile->owner = THIS_MODULE;#endif pNet->PortNr = 0; pNet->NetNr = 0;#ifdef SK_ZEROCOPY#ifdef USE_SK_TX_CHECKSUM if (pAC->ChipsetType) { /* SG and ZEROCOPY - fly baby... */ dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; }#endif#endif boards_found++; /* More then one port found */ if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) { if ((dev = alloc_etherdev(sizeof(DEV_NET))) == 0) { printk(KERN_ERR "Unable to allocate etherdev " "structure!\n"); break; } pAC->dev[1] = dev; pNet = dev->priv; pNet->PortNr = 1; pNet->NetNr = 1; pNet->pAC = pAC; pNet->Mtu = 1500; pNet->Up = 0; dev->open = &SkGeOpen; dev->stop = &SkGeClose; dev->hard_start_xmit = &SkGeXmit; dev->get_stats = &SkGeStats; dev->set_multicast_list = &SkGeSetRxMode; dev->set_mac_address = &SkGeSetMacAddr; dev->do_ioctl = &SkGeIoctl; dev->change_mtu = &SkGeChangeMtu; dev->flags &= ~IFF_RUNNING;#ifdef SK_ZEROCOPY#ifdef USE_SK_TX_CHECKSUM if (pAC->ChipsetType) { /* SG and ZEROCOPY - fly baby... */ dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; }#endif#endif if (register_netdev(dev)) { printk(KERN_ERR "SKGE: Could not register device.\n"); free_netdev(dev); pAC->dev[1] = pAC->dev[0]; } else {#ifdef CONFIG_PROC_FS pProcFile = create_proc_entry(dev->name, S_IFREG | S_IXUSR | S_IWGRP | S_IROTH, pSkRootDir); pProcFile->read_proc = sk_proc_read;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -