📄 ga.c
字号:
* Return Value: OK or -EOPNOTSUPP **f****************************************************************************/int DrvIoctl( struct device *dev, struct ifreq *rq, int cmd ){ /* Get the data for the ioctl from the ifreq structure */ void *data = &(rq->ifr_data); /* Get the pointer to the AdapterContext */ AdapterContext *pNsc = &((NsmContext *)(dev->priv))->AdpCtxt; /* Depending on the cmd perform the following */ switch( cmd ) { /* For setting interface address(dev->dev_addr) */ case SIOCSIFADDR: /* Set the MAC address in the device structure and also the AdapterContext, with the one obtained from the data */ NsmCopy((const void *)data, (void *)dev->dev_addr, MAC_ADDR_LEN); NsmCopy((const void *)data, (void *)pNsc->CurrMacAddr, MAC_ADDR_LEN); HsmSetMacAddress(pNsc, pNsc->CurrMacAddr); break; /* The ioctl implementation for sockets, defines 16 ioctls cmds as private to the interface, SIOCSDEVPRIVATE, SIOCSDEVPRIVATE+ 1,.. & so on */ case SIOCDEVPRIVATE: break; default: return -EOPNOTSUPP; } return OK;}/*******************************************************************************f** Name: DrvGetStatistics ** Description: This is the routine used to get the statistical information* regarding the transmission and reception of packets.** Parameters: dev: This is a pointer to the device structure** Return Value: Pointer to the statistics structure **f****************************************************************************/struct enet_statistics *DrvGetStatistics(struct device *dev){ /* Get the pointer to the NsmContext and thereby to the AdapterContext, from the device structure */ NsmContext *pNsm = (NsmContext *)dev->priv; AdapterContext *pNsc = &(pNsm->AdpCtxt); struct enet_statistics *pAdpStats = pNsm->pAdapterStats; /* Update the fields in the StatInfo structure (MacStats) in the AdapterContext, by reading the current values from the MIB registers of the adapter */ if(HsmGetStatistics(pNsc) == FAILURE) { return NULL; } /* Get the statistics from the adapter context structure & set the values of the statistics in the enet_statistics structure */ pAdpStats->rx_packets = pNsc->MacStats.rxOkCount; pAdpStats->rx_errors = pNsc->MacStats.rxErrorCount; pAdpStats->rx_dropped = pNsc->MacStats.rxDroppedCount; pAdpStats->rx_crc_errors = pNsc->MacStats.rxCrcErrorCount; pAdpStats->rx_frame_errors = pNsc->MacStats.rxFaeCount; pAdpStats->rx_missed_errors = pNsc->MacStats.rxNoBufferCount; pAdpStats->tx_errors = pNsc->MacStats.txErrorCount; pAdpStats->tx_packets = pNsc->MacStats.txOkCount; pAdpStats->tx_dropped = pNsc->MacStats.txDroppedCount; pAdpStats->tx_carrier_errors = pNsc->MacStats.txCrsLostCount; pAdpStats->tx_aborted_errors = pNsc->MacStats.txAbortCount; pAdpStats->tx_fifo_errors = pNsc->MacStats.txUnderrunCount; pAdpStats->collisions = pNsc->MacStats.txTotCollisionCount; pAdpStats->rx_length_errors = 0; pAdpStats->rx_over_errors = 0; pAdpStats->rx_fifo_errors = 0; pAdpStats->tx_heartbeat_errors = 0; pAdpStats->tx_window_errors = 0; return pAdpStats;}/*******************************************************************************f** Name: init_module ** Description: init_module initializes the driver module. This routine * is called to initialize the driver when the module in * installed into a running kernel via insmod.** Parameters: None ** Return Value: OK or ENODEV **f****************************************************************************/intinit_module (void){#ifdef _DUMP struct module *mlist = &__this_module; printk("module %s is loaded at %p\n",mlist->name, &((char *)mlist)[mlist->size_of_struct]);#endif return DrvProbe (NULL);}/*******************************************************************************f** Name: cleanup_module ** Description: cleanup_module initializes the driver module. This routine * is called to initialize the driver when the module in * installed into a running kernel via insmod.** Parameters: None ** Return Value: None **f****************************************************************************/voidcleanup_module (void){ struct device *cur_dev; struct device *pDev; /* Traverse through the list of device structures */ cur_dev= DevList; while (cur_dev) { /* Get the next device structure in the list */ pDev = (struct device *) (((NsmContext *)cur_dev->priv)->next); AdapterClose(cur_dev); /* Unregister the instance of the network device, corresponding to this device structure */ unregister_netdev (cur_dev); /* Release the IO region held by this instance of the device */ release_region(cur_dev->base_addr, PCI_IO_SIZE); kfree(((NsmContext *)cur_dev->priv)->pAdapterStats); kfree(cur_dev); /* Update the cur_dev to point to the next device in the list */ cur_dev = pDev; }}/*******************************************************************************f** Name: NsmTxCompleted ** Description: This is called by HSM to indicate that transmission is * complete for a sublist of HsmTCBs in the HsmTCB list, * which is indicated by sending the first and the TCB, next * to the last TCB in list.** Parameters: pNsc: Pointer to the AdapterContext structure** TcbFirst: Pointer to the first HsmTCB in the list for * which transmit completion has happened** TcbLast: Pointer to the HsmTCB which is the next from * the last TCB in the list for which transmit completion has * happened* ** Return Value: None **f****************************************************************************/void NsmTxCompleted(AdapterContext *pNsc, HsmTCB *TcbFirst, HsmTCB *TcbLast){ HsmTCB *tcb; tcb = TcbFirst; /* Free up the data buffer associated with the indicated HsmTCBs */ do { if((struct sk_buff *)tcb->pOsCtrlBlk) { kfree_skb((struct sk_buff *)tcb->pOsCtrlBlk); tcb->pOsCtrlBlk = NULL; } tcb = tcb->pNext; }while(tcb != TcbLast);}/*******************************************************************************f** Name: NsmRxPackets ** Description: This is called by the HSM, to send the received packets in * a particular priority, over to the upper layers** Parameters: pNsc: Pointer to the AdapterContext structure** RcbStart: Pointer to the first HsmRCB in the list for * which receive completion has happened* * RcbEnd: Pointer to the HsmRCB which is the next from * the last RCB in the list for which receive completion has * happened** Priority: Priority queue on which the packet was obtained** Return Value: None**f****************************************************************************/STATIC VOID NsmRxPackets (AdapterContext *pNsc, HsmRCB *RcbStart, HsmRCB *RcbEnd, UCHAR Priority) { HsmRCB *rcb; HsmRCB *CurrRCB; HsmRCB *StartRCB; HsmRCB *TempRcb; struct sk_buff *NewSkb; struct sk_buff *skb_new; struct sk_buff *skb; UINT RemainingRCBs = 0; struct device *dev; UINT status=OK; UINT BufSizeReqd; /* Get the pointer to the NsmContext */ NsmContext *pNsm = (NsmContext *)pNsc->pNsmContext; /* Get the start of the list of HsmRCBs for which Rx complete has happened */ rcb = RcbStart; /* Traverse through the HsmRCB list and for each RCB from RcbStart to RcbEnd */ while ( rcb != RcbEnd ) { /* check for jumbo frames by checking the More flag in HsmRCB, if it's a jumbo packet */ if(rcb->More) { /* Get the start of the HsmRCB list */ StartRCB = rcb; /* Initialise the variable to update the size of the jumbo packet received */ BufSizeReqd = 0; /* For all the HsmRCBs into which this packet has spanned, do the following */ while( rcb->More) { /* Calculate the size of the entire packet by adding the PktSize in the individual HsmRCBs, constituting the packet */ BufSizeReqd += rcb->PktSize; /* Get the next HsmRCB in the RCB list */ rcb = rcb->pNext; } CurrRCB = StartRCB; /* Update with the size of the last fragment of the packet */ BufSizeReqd += rcb->PktSize; rcb = rcb->pNext; /* Allocate a new sk_buff to hold the complete jumbo packet, thereby one having a data buffer of enough size */ NewSkb = alloc_skb(BufSizeReqd + HEAD_SPACE, GFP_ATOMIC); if( NewSkb == NULL) {#ifdef FAILURE_MESSAGES printk("The allocation of the sk_buff of size %d for the jumbo packet FAILED\n", BufSizeReqd);#endif /* Update statisitics */ pNsc->MacStats.rxErrorCount++; pNsc->MacStats.rxDroppedCount++; continue; }#ifdef PRIORITY_QUEUES /* Set the priority field of the new sk_buff */ NewSkb->priority = Priority;#else NewSkb->priority = 0;#endif /* Reserve some space at the beginning of the buffer */ skb_reserve(NewSkb, HEAD_SPACE); dev = ( (struct sk_buff *) rcb->pOsCtrlBlk)->dev; /* Traverse through the HsmRCB list to copy the entire jumbo packet into the newly allocated sk_buff */ while(CurrRCB != rcb) { memcpy( NewSkb->tail, ((struct sk_buff *)CurrRCB->pOsCtrlBlk)->data, CurrRCB->PktSize); skb_put(NewSkb, CurrRCB->PktSize); CurrRCB->Status = RCB_FREE; CurrRCB = CurrRCB->pNext; } /* If checksum offloading is supported ie if it is already done in hardware then indicate it in the skbuff */#ifdef CHECKSUM NewSkb->ip_summed = CHECKSUM_UNNECESSARY; #else NewSkb->ip_summed = CHECKSUM_NONE; #endif NewSkb->dev = dev; NewSkb->protocol = eth_type_trans(NewSkb,dev); /* Send the new sk_buff up */ netif_rx(NewSkb); } else { /* Through the HsmRCB, get the pointer to the OsCtrlBlk ( sk_buff ) */ skb = (struct sk_buff *)rcb->pOsCtrlBlk; /* Clone this sk_buff */ skb_new = skb_clone(skb, GFP_ATOMIC); if( skb_new == NULL) { printk(KERN_ERR "NsmRxPackets : The cloning failed\n"); TempRcb = rcb; /* Find out the number of packets remaining, which are now going to be dropped*/ while((TempRcb != RcbEnd) && TempRcb) { while(TempRcb->More) TempRcb = TempRcb->pNext; RemainingRCBs++; TempRcb = TempRcb->pNext; } /* Update statistics */ pNsc->MacStats.rxErrorCount += RemainingRCBs; pNsc->MacStats.rxDroppedCount += RemainingRCBs; status = ERROR; break; } rcb->Status = DUPED; skb_put(skb_new,rcb->PktSize); dev = skb_new->dev = skb->dev; skb_new->protocol = eth_type_trans(skb_new,dev);#ifdef CHECKSUM skb_new->ip_summed = CHECKSUM_UNNECESSARY; #else skb_new->ip_summed = CHECKSUM_NONE; #endif /* If checksum offloading is supported ie if it is already done in hardware then indicate it in the skbuff */#ifdef PRIORITY_QUEUES /* Set the priority field of the new sk_buff */ skb_new->priority = Priority;#else skb_new->priority = 0;#endif netif_rx(skb_new); /* Get the next HsmRCB in the RCB list */ rcb = rcb->pNext; } } /* Set the time for the last receive */ pNsm->dev->last_rx = jiffies;}/*******************************************************************************f** Name: NsmMallocContiguous ** Description: This is called by HSM to allocate a contiguous chunk of * memory, the virtual & physical addresses of the start of * the chunk of memory, is set in the Addrstruct structure. * The byte alignment required is given by the Alignment * parameter.** Parameters: pNsm: Pointer to the NsmContext * * pAddrstruct: Pointer to the Addrstruct structure, where the * virtual and physical addresses need to be put** BitAlignment: The alignment factor, to which the memory * allocated needs to be aligned** Cached: Cached/Non-Cached memory** Return Value: SUCCESS or FAILURE **f****************************************************************************/UCHAR NsmMallocContiguous(VOID *pNsm,AddrStruct *pAddrStruct, USHORT BitAlignment, UINT Cached){ VOID *pMem; UINT AlignedMem; USHORT Alignment = BitAlignment/8;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -