📄 ga.c
字号:
#undef __NO_VERSION__/*******************************************************************************h** Name: ga.c** Description: This is the source code for the Linux Network OS* Specific Module**h*******************************************************************************/#include "nsmtypes.h"#include "ga622t.h"#include "hsm.h"#include "nsm.h"/* Default initialisation of load time parameters */UINT MaxTxDesc=100;UINT MaxRxDesc=100;UINT SetAutoNeg=1;UINT RxBufSize=2048;UINT MediaSpeed=1000;UINT NCBit=0;UINT DuplexMode=FULL_DUPLEX;UINT CacheLineSz=512;UINT TxDrth = 200; UINT RxDrth = 0;UINT TxFlth = 2;UINT PauseCounterVal = 40000;#ifdef PRIORITY_QUEUESUINT MaxPrio=8;#elseUINT MaxPrio=1;#endif#if defined(MODULE)MODULE_DESCRIPTION("NETGEAR GA622T Gigabit UTP Adapter driver");MODULE_PARM(options, "1-" __MODULE_STRING(8) "i");/* Load time parameters */MODULE_PARM(MaxTxDesc, "i");MODULE_PARM(MaxRxDesc, "i");MODULE_PARM(RxBufSize, "i");MODULE_PARM(MediaSpeed, "i");MODULE_PARM(SetAutoNeg, "i");MODULE_PARM(NCBit, "i");MODULE_PARM(DuplexMode, "i");MODULE_PARM(CacheLineSz, "i");MODULE_PARM(TxDrth, "i");MODULE_PARM(RxDrth, "i");MODULE_PARM(TxFlth, "i");MODULE_PARM(PauseCounterVal, "i");#endif/* List of the various instances of the GA622T */struct device *DevList = NULL;UCHAR AdapterOpen (struct device *dev);void AdapterClose (struct device *dev);/*******************************************************************************f** Name: DrvProbe** Description This routine enumerates Drv ethernet devices on the PCI * bus, and registers each device found.** Parameters: dev: Pointer to the device structure ** Return Value: OK or -ENODEV **f*******************************************************************************/intDrvProbe (struct device *dev){ int DevCount=0; struct pci_dev *pPciDev=NULL; UINT iobase; UINT membase; AdapterContext *pNsc; NsmContext *pNsm; /* Check for PCI BIOS being present, return ENODEV if not present */ if (! pci_present()) {#ifdef FAILURE_MESSAGES printk("\nPCI bios not present"); #endif /* No such device */ return -ENODEV; } /* Find the instances of the device present, and for each instance of the device do the following */ while ( (pPciDev = pci_find_device (PCI_VENDOR_ID_NS, PCI_DEVICE_ID_83820, pPciDev) ) != NULL) { /* Get the IOBASE, MEMBASE address */ iobase = (UINT) pPciDev->base_address[0]; membase = (UINT)pPciDev->base_address[1]; iobase &= PCI_BASE_ADDRESS_IO_MASK; membase &= PCI_BASE_ADDRESS_MEM_MASK;#ifdef IOMAPPED_IO /* Check if a range of ports is already locked by other drivers */ if (check_region(iobase,PCI_IO_SIZE)) { #ifdef FAILURE_MESSAGES printk ("check_region failed : IO region already in use\n");#endif continue; }#endif /* Allocate space for the device structure, name the device, and also for the private data structure, in this case, the NsmContext. Add the device to the ethernet device list and register the network device. */ dev = init_etherdev(dev, sizeof(NsmContext)); if (dev == NULL) { #ifdef FAILURE_MESSAGES printk (KERN_ERR "%s: Failed to create device struct\n",DRV_NAME);#endif break; } printk(KERN_INFO "\nNETGEAR GA622T Gigabit UTP Adapter : %s\n",dev->name); /* Get the pointer to the NsmContext */ pNsm = (NsmContext *)dev->priv; pNsm->dev = dev; /* Get the pointer to the adapter context */ pNsc = &pNsm->AdpCtxt ; /* Allocate the structure to hold the enet_statistics */ /* This is reqd here because an ifconfig done can request the statistcs even before an open is done */ pNsm->pAdapterStats = (struct enet_statistics *) kmalloc(sizeof(struct enet_statistics), GFP_KERNEL); /* Check if the allocation was successful */ if(pNsm->pAdapterStats == NULL) {#ifdef FAILURE_MESSAGES printk(KERN_INFO "Allocation of Statistics struct failed\n");#endif unregister_netdev(dev); kfree(dev); break; } pNsc->pNsmContext = (void *)pNsm; /* initialize the device data like iobase, irq, and the entry points for the driver in the device structure */ pNsc->CacheLineSize = CacheLineSz; pNsc->MaxPktSize = RxBufSize;#ifdef MEMMAPPED_IO dev->base_addr = (ULONG) membase; /* Memory mapped IO */ pNsc->RegAddr = (UCHAR *)ioremap(membase, PCI_MEM_SIZE);#elif IOMAPPED_IO dev->base_addr = (ULONG) iobase; pNsc->RegAddr = (UCHAR *)dev->base_addr;#endif dev->irq = pPciDev->irq; dev->open = DrvOpen; dev->stop = DrvClose; dev->get_stats = DrvGetStatistics; dev->do_ioctl = DrvIoctl; dev->hard_start_xmit = DrvSend; dev->set_multicast_list = DrvSetMulticastList; dev->set_mac_address = DrvSetMacAddress; /* Change the mtu function in the device structure as ether_setup sets it to a function which can accepts MTUs of size less than 1500, so change it to a function which can change the MTU to any value less than 65280 and greater than 68. */ dev->change_mtu = ChangeMtu; #ifdef IOMAPPED_IO /* reserve IO region, this locks the ports for later use */ request_region (iobase, PCI_IO_SIZE, dev->name);#endif /* Chain the device */ pNsm->next = (void *)DevList; DevList = dev; /* Install interrupt vector and register the interrupt service routine */ if((AdapterOpen(dev)) != OK) { #ifdef FAILURE_MESSAGES printk (KERN_ERR "%s: AdapterOpen Failed \n", DRV_NAME); #endif kfree(pNsm->pAdapterStats); unregister_netdev(dev); kfree(dev); break; } /* Update Counters for the number of devices found */ DevCount++; dev=NULL; /* pPciDev = NULL; */ } if(DevCount == 0) {#ifdef FAILURE_MESSAGES printk (KERN_ERR "No device of NETGEAR present\n");#endif return -ENODEV; } return 0;}/*******************************************************************************f** Name: DrvOpen** Description: DrvOpen opens and initializes a device. This is * typically called when an ifconfig is done for this * interface.** Parameters: dev: Pointer to the device structure ** Return Value: OK or -EAGAIN **f*******************************************************************************/STATIC intDrvOpen (struct device *dev){#if 0 UINT stat; NsmContext *pNsm; AdapterContext *pNsc; UINT i; /* Get the pointer to the allocated private data structure, NsmContext, from the device structure */ pNsm = (NsmContext *)dev->priv; /* Get the pointer to the AdapterContext structure from the NsmContext */ pNsc = &pNsm->AdpCtxt; for(i=0; i< MAX_PRI_QUEUE; i++) { pNsc->RxQueueSz[i] = MaxRxDesc; pNsc->TxQueueSz[i] = MaxTxDesc; } pNsc->TxDrth = TxDrth; pNsc->RxDrth = RxDrth; pNsc->TxFlth = TxFlth; pNsc->PauseCounterVal = PauseCounterVal; pNsc->RxFFLO = 2; pNsc->RxFFHI = 8; pNsc->RxSTLO = 2; pNsc->RxSTHI = 8; /* Initialize fields which would indicate the capabilities of the hardware, such as the, checksum offload */ HsmInitContext(pNsc); /* Find out the capabilities of the OS and indicate whether the above capabilties are supported by the OS. */ pNsc->OsPrio = MaxPrio; pNsc->PhysCapabilities &= ~(VLAN_TAG_INSERTION_GEN_ON | BIG_ENDIAN | TX_CHKSUM_OFFLOAD_ON_GEN ); if(SetAutoNeg == 0) { pNsc->PhysCapabilities &= ~AUTO_NEG_ON; pNsc->InfMediaSpeed = MediaSpeed; pNsc->InfDuplexMode = DuplexMode; } pNsc->NcBit = NCBit; /* Allocate the Tx and Rx lists, based on the number of priority levels supported. Call the HsmInitialise routine of the HSM, this will also setup transmit & receive control. This will set up descriptor lists for each level of priorities on both send and receive side. */ if ( (stat = HsmInitialize(pNsc) ) == FAILURE ) {#ifdef FAILURE_MESSAGES printk (KERN_ERR "%s: HsmInitialize Failed \n", DRV_NAME);#endif return -EAGAIN; } /* Now set the Mac address in the device structure */ NsmCopy((char *)pNsc->PermMacAddr, (char *)dev->dev_addr, MAC_ADDR_LEN); /* Install interrupt vector and register the interrupt service routine */ if(request_irq (dev->irq, DrvIsr, SA_SHIRQ, dev->name, dev) != OK) {#ifdef FAILURE_MESSAGES printk (KERN_ERR "%s: request_irq Failed \n", DRV_NAME);#endif HsmUnInitialize(pNsc); return -EAGAIN; } /* Reset the adapter */ if( ( stat =HsmReset(pNsc, 0) ) == FAILURE) {#ifdef FAILURE_MESSAGES printk (KERN_ERR "%s: Resetting the adapter, failed \n", DRV_NAME);#endif free_irq (dev->irq, dev); HsmUnInitialize(pNsc); return -EAGAIN; } /* Call HsmOpen call to open the adapter */ if( ( stat =HsmOpen(pNsc) ) == FAILURE) {#ifdef FAILURE_MESSAGES printk (KERN_ERR "%s: Opening the adapter, failed \n", DRV_NAME);#endif free_irq (dev->irq, dev); HsmUnInitialize(pNsc); return -EAGAIN; } HsmRxFilter(pNsc, (ACCEPT_PERFECT_MATCH_ON | ACCEPT_ALL_BROADCAST_ON)); /* Mark the start flag in the device structure */ dev->start = DEV_STARTED; dev->tbusy = 0; dev->interrupt = 0; /* Set the transmit queue length in the device structure */ dev->tx_queue_len = (MaxTxDesc*MaxPrio); pNsm->status |= NSM_OPEN; printk("\nExiting DrvOpen"); #endif /* Increment module reference count, MOD_INC_USE_COUNT */ MOD_INC_USE_COUNT; return OK;}UCHAR AdapterOpen (struct device *dev){ UINT stat; NsmContext *pNsm; AdapterContext *pNsc; UINT dp_val; UINT i; #ifdef FT_DBG static UINT CallCount=0; printk("The DrvOpen call No : %d",CallCount++);#endif /* Get the pointer to the allocated private data structure, NsmContext, from the device structure */ pNsm = (NsmContext *)dev->priv; /* Get the pointer to the AdapterContext structure from the NsmContext */ pNsc = &pNsm->AdpCtxt; for(i=0; i< MAX_PRI_QUEUE; i++) { pNsc->RxQueueSz[i] = MaxRxDesc; pNsc->TxQueueSz[i] = MaxTxDesc; } pNsc->TxDrth = 200; pNsc->RxDrth = 0; pNsc->TxFlth = 2; pNsc->PauseCounterVal = 40000; pNsc->RxFFLO = 2; pNsc->RxFFHI = 8; pNsc->RxSTLO = 2; pNsc->RxSTHI = 8; /* Initialize fields which would indicate the capabilities of the hardware, such as the, checksum offload */ HsmInitContext(pNsc);#ifdef NSCDEBUG printk(KERN_INFO "HsmInitContext called\n");#endif /* Find out the capabilities of the OS and indicate whether the above capabilties are supported by the OS. */ if(MaxPrio > 8) MaxPrio = 8; pNsc->OsPrio = MaxPrio; pNsc->PhysCapabilities &= ~(VLAN_TAG_INSERTION_GEN_ON | BIG_ENDIAN | TX_CHKSUM_OFFLOAD_ON_GEN ); //SET_RX_CHKSUM_OFFLOAD_ON ); if(SetAutoNeg == 0) { pNsc->PhysCapabilities &= ~AUTO_NEG_ON; /* MKC revisit */ pNsc->InfMediaSpeed = MediaSpeed; } pNsc->NcBit = NCBit;#if 0 pNsc->PhysCapabilities |= (RX_UDP_CHKSUM_DISCARD_ON | RX_TCP_CHKSUM_DISCARD_ON | RX_IP_CHKSUM_DISCARD_ON); #endif /* Allocate the Tx and Rx lists, based on the number of priority levels supported. Call the HsmInitialise routine of the HSM, this will also setup transmit & receive control. This will set up descriptor lists for each level of priorities on both send and receive side. */ if ( (stat = HsmInitialize(pNsc) ) == FAILURE ) {#ifdef FAILURE_MESSAGES printk (KERN_ERR "%s: HsmInitialize Failed \n", DRV_NAME);#endif return -EAGAIN; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -