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

📄 e1000_main.c

📁 COPE the first practical network coding scheme which is developped on click
💻 C
📖 第 1 页 / 共 5 页
字号:
/***************************************************************************** Name:        e1000_open** Description: This routine is the open call for the interface.**               This is a Linux required routine.** Author:      IntelCorporation** Born on Date:    07/11/99** Arguments:   *       NONE** Returns:*        It returns 0 on success *         -EAGAIN on failure** Modification log:* Date      Who  Description* --------  ---  -------------------------------------------------------- *****************************************************************************/static inte1000_open(device_t * dev){    bd_config_t *bdp;    PADAPTER_STRUCT Adapter = 0;    int ret_val;    printk("v0 e1000 Alignment: %p %p\n", 	   &(Adapter->FirstTxDescriptor), &(Adapter->NumRxDescriptors));    bdp = dev->priv;    Adapter = bdp->bddp;    if (e1000_debug_level >= 1)        printk("open: SOR, bdp = 0x%p\n", bdp);    /* make sure we have not already opened this interface */    if(bdp->flags & BOARD_OPEN)        return -EBUSY;        if (e1000_init(bdp)) {        return -ENOMEM;    }    if (e1000_runtime_init(bdp)) {        return -ENOMEM;    }    Adapter->AdapterStopped = FALSE;   #ifdef IANS_BASE_VLAN_TAGGING    /* on a close a global reset is issued to the hardware,      * so VLAN settings are lost and need to be re-set on open */    if((IANS_BD_TAGGING_MODE)ANS_PRIVATE_DATA_FIELD(bdp)->tag_mode != IANS_BD_TAGGING_NONE)        bd_ans_hw_EnableVLAN(bdp);#endif           if (request_irq(dev->irq, &e1000_intr, SA_SHIRQ, "e1000", dev)) {        if (e1000_debug_level >= 1)            printk("open: request_irq failed");        return (-EAGAIN);    }    /* Check to see if promiscuous mode needs to be turned on */    if (dev->flags & IFF_PROMISC) {        /* turn  promisc mode on */        ret_val = e1000_set_promisc(bdp, B_TRUE);        bdp->flags |= PROMISCUOUS;    } else {        /* turn  promisc mode off */        ret_val = e1000_set_promisc(bdp, B_FALSE);        bdp->flags &= ~PROMISCUOUS;    }#ifdef MODULE    /* up the mod use count used by the system */    MOD_INC_USE_COUNT;#endif    /* setup and start the watchdog timer */    init_timer(&bdp->timer_id);    /* set the timer value for 2 sec( i.e. 200 10msec tics )      * jiffies are mesured in tics and is equiv. to LBOLTS in Unix     */    bdp->timer_id.expires = bdp->timer_val = jiffies + 200;    bdp->timer_id.data = (ulong_t) dev;    bdp->timer_id.function = (void *) &e1000_watchdog;    /* start the timer */    add_timer(&bdp->timer_id);    /* set the device flags */    netif_start_queue(dev);    /* enable interrupts */    e1000EnableInterrupt(Adapter);    /* init the basic stats stuff */    ClearHwStatsCounters(Adapter);    bdp->flags |= BOARD_OPEN;    return (0);}/***************************************************************************** Name:        e1000_close** Description: This routine is an entry point into the driver.**               This is a Linux required routine.** Author:      IntelCorporation** Born on Date:    07/11/99** Arguments:   *         device_t pointer** Returns:*        It returns 0 and can not fail.** Modification log:* Date      Who  Description* --------  ---  -------------------------------------------------------- *****************************************************************************/static inte1000_close(device_t * dev){    bd_config_t *bdp;    PADAPTER_STRUCT Adapter;    ushort_t status;    int j;    bdp = dev->priv;    Adapter = bdp->bddp;    /* set the device to not started */    netif_stop_queue(dev);    /* stop the hardware */    /* Disable all possible interrupts */    E1000_WRITE_REG(Imc, (0xffffffff));    status = E1000_READ_REG(Icr);    /* Reset the chip */    AdapterStop(Adapter);    /* kill the timer */    del_timer(&bdp->timer_id);    /* free the irq back to the system */    if (e1000_debug_level >= 1)        printk("E1000: close: free_irq\n");    free_irq(dev->irq, dev);    /*     * Free up the transmit descriptor area      */    if (e1000_debug_level >= 2)        printk("--Cleanup, free tx descriptor area\n");    free_contig(bdp->base_tx_tbds);    bdp->base_tx_tbds = NULL;    if(Adapter->TxSkBuffs)      free_contig(Adapter->TxSkBuffs);    /*      *  Free up the RX_SW_PACKET area also free any allocated      *  receive buffers     */    if (e1000_debug_level >= 2)        printk("--Cleanup, free rx packet area + skbuffs\n");    if(Adapter->RxSkBuffs){        for (j = 0; j < Adapter->NumRxDescriptors; j++) {            if (Adapter->RxSkBuffs[j]){                if (e1000_debug_level >= 2)                    printk(" -- kfree_skb\n");                dev_kfree_skb(Adapter->RxSkBuffs[j]);                Adapter->RxSkBuffs[j] = 0;            }        }        free_contig(Adapter->RxSkBuffs);    }    /*     * Free the receive descriptor area      */    if (e1000_debug_level >= 2)        printk("--Cleanup, free rx descriptor area\n");    /* free_contig( Adapter->e1000_rbd_data ); */    free_contig(bdp->base_rx_rbds);    bdp->base_rx_rbds = NULL;        bdp->flags &= ~BOARD_OPEN;#ifdef MODULE    /* adjust the mod use count */    MOD_DEC_USE_COUNT;#endif    return (0);}/* * the send a packet, may poke at e1000 to force it to start tx */  static inte1000_xmit_frame_aux(struct sk_buff *skb, device_t * dev, int poke){    bd_config_t *bdp;    PADAPTER_STRUCT Adapter;    int lock_flag;    int ret;    bdp = dev->priv;    Adapter = (PADAPTER_STRUCT) bdp->bddp;    if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) {      return 1;    }    if (e1000_debug_level >= 3)        printk("e1000_tx_frame\n");    /* call the transmit routine */#ifdef CLICK_POLLING    if(SendBuffer(skb, bdp, poke, dev->polling)){#else    if(SendBuffer(skb, bdp, poke, 0)){#endif      ret = 0;    } else {#ifdef IANS      if(bdp->iANSdata->iANS_status == IANS_COMMUNICATION_UP) {        ans_notify(dev, IANS_IND_XMIT_QUEUE_FULL);      }#endif      ret = 1;    }    if(bdp->tx_out_res == 0)      clear_bit(0, (void*)&dev->tbusy);    return (ret);}/***************************************************************************** Name:        e1000_xmit_frame** Description: This routine is called to transmit a frame.*** Author:      IntelCorporation** Born on Date:    07/11/99** Arguments:   *         sb_buff   pointer*         device_t pointer** Returns:*        It returns B_FALSE on success*         B_TRUE on failure** Modification log:* Date      Who  Description* --------  ---  -------------------------------------------------------- *****************************************************************************/static inte1000_xmit_frame(struct sk_buff *skb, device_t * dev){  return e1000_xmit_frame_aux(skb, dev, 1);}/***************************************************************************** Name:       SendBuffer** Description: This routine physically sends the packet to the nic controller.*** Author:      IntelCorporation** Born on Date:    07/11/99** Arguments:   *         TX_SW_PACKET   pointer*         bd_config_t      pointer** Returns:*        It returns B_TRUE always and can not fail.** Modification log:* Date      Who  Description* --------  ---  -------------------------------------------------------- *****************************************************************************/static UINTSendBuffer(struct sk_buff *skb, bd_config_t * bdp, int poke, int polling){    PADAPTER_STRUCT Adapter;    PE1000_TRANSMIT_DESCRIPTOR CurrentTxDescriptor, nxt;    // net_device_stats_t *stats;    int di;    Adapter = bdp->bddp;    // stats = &bdp->net_stats;    CurrentTxDescriptor = Adapter->NextAvailTxDescriptor;    /* Don't use the last descriptor! */    if (CurrentTxDescriptor == Adapter->LastTxDescriptor)      nxt = Adapter->FirstTxDescriptor;    else      nxt = CurrentTxDescriptor + 1;    if(nxt == Adapter->OldestUsedTxDescriptor){      printk("e1000: out of descs in Sendbuffer\n");      return(0);    }    di = CurrentTxDescriptor - Adapter->FirstTxDescriptor;    if(Adapter->TxSkBuffs[di])      printk("e1000 oops di %d TxSkBuffs[di] %x\n",             di,             (di >= 0 && di < 80) ? Adapter->TxSkBuffs[di] : 0);    Adapter->TxSkBuffs[di] = skb;    CurrentTxDescriptor->BufferAddress = virt_to_bus(skb->data);        CurrentTxDescriptor->Lower.DwordData = skb->len;    /* zero out the status field in the descriptor. */    CurrentTxDescriptor->Upper.DwordData = 0;#ifdef IANS    if(bdp->iANSdata->iANS_status == IANS_COMMUNICATION_UP) {        if(bd_ans_os_Transmit(bdp, CurrentTxDescriptor, &skb)==BD_ANS_FAILURE) {            dev_kfree_skb(skb);            return B_FALSE;        }    }#endif     Adapter->NextAvailTxDescriptor = nxt;    CurrentTxDescriptor->Lower.DwordData |=      (E1000_TXD_CMD_EOP | E1000_TXD_CMD_IFCS);#if 1    /*     * If there is a valid value for the transmit interrupt delay, set up the     * delay in the descriptor field     */    if (Adapter->TxIntDelay)      CurrentTxDescriptor->Lower.DwordData |= E1000_TXD_CMD_IDE;#else    /*     * Ask for a transmit complete interrupt every 60 packets. RTM     * This seems to be broken -- sometimes the tx complete     * interrupts never happen -- sending waits until a receive     * packet arrives. RTM Dec 22 2000.     */    if(polling==0 && Adapter->TxIntDelay){      static int dctr;      if(dctr++ > 60){        dctr = 0;        /* Don't delay for this packet! */      } else {        /* Delay tx complete interrupt for most packets. */        CurrentTxDescriptor->Lower.DwordData |= E1000_TXD_CMD_IDE;      }    }#endif    /* Set the RS or the RPS bit by looking at the ReportTxEarly setting */    if (Adapter->ReportTxEarly == 1)        CurrentTxDescriptor->Lower.DwordData |= E1000_TXD_CMD_RS;    else        CurrentTxDescriptor->Lower.DwordData |= E1000_TXD_CMD_RPS;    if (poke)      /* Advance the Transmit Descriptor Tail (Tdt), this tells the        * E1000 that this frame is available to transmit.        */      E1000_WRITE_REG(Tdt, (((unsigned long) Adapter->NextAvailTxDescriptor -                             (unsigned long) Adapter->FirstTxDescriptor) >> 4));    /* Could we queue another packet? */    if (Adapter->NextAvailTxDescriptor == Adapter->LastTxDescriptor)      nxt = Adapter->FirstTxDescriptor;    else      nxt = Adapter->NextAvailTxDescriptor + 1;    if(nxt == Adapter->OldestUsedTxDescriptor)      bdp->tx_out_res = 1;    return(1);}/***************************************************************************** Name:        e1000_get_stats** Description: This routine is called when the OS wants the nic stats returned*

⌨️ 快捷键说明

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