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

📄 smctr.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
        /* Re-Initialize adapter's internal registers */        smctr_reset_adapter(dev);        if((err = smctr_init_card_real(dev)))	{                printk(KERN_ERR "%s: Initialization of card failed (%d)\n",                        dev->name, err);                return (-EINVAL);        }        smctr_enable_bic_int(dev);        if((err = smctr_issue_enable_int_cmd(dev, TRC_INTERRUPT_ENABLE_MASK)))                return (err);        smctr_disable_16bit(dev);        return (0);}static int smctr_init_card_real(struct net_device *dev){        struct net_local *tp = netdev_priv(dev);        int err = 0;        if(smctr_debug > 10)                printk(KERN_DEBUG "%s: smctr_init_card_real\n", dev->name);        tp->sh_mem_used = 0;        tp->num_acbs    = NUM_OF_ACBS;        /* Range Check Max Packet Size */        if(tp->max_packet_size < 256)                tp->max_packet_size = 256;        else        {                if(tp->max_packet_size > NON_MAC_TX_BUFFER_MEMORY)                        tp->max_packet_size = NON_MAC_TX_BUFFER_MEMORY;        }        tp->num_of_tx_buffs = (NON_MAC_TX_BUFFER_MEMORY                / tp->max_packet_size) - 1;        if(tp->num_of_tx_buffs > NUM_NON_MAC_TX_FCBS)                tp->num_of_tx_buffs = NUM_NON_MAC_TX_FCBS;        else        {                if(tp->num_of_tx_buffs == 0)                        tp->num_of_tx_buffs = 1;        }        /* Tx queue constants */        tp->num_tx_fcbs        [BUG_QUEUE]     = NUM_BUG_TX_FCBS;        tp->num_tx_bdbs        [BUG_QUEUE]     = NUM_BUG_TX_BDBS;        tp->tx_buff_size       [BUG_QUEUE]     = BUG_TX_BUFFER_MEMORY;        tp->tx_buff_used       [BUG_QUEUE]     = 0;        tp->tx_queue_status    [BUG_QUEUE]     = NOT_TRANSMITING;        tp->num_tx_fcbs        [MAC_QUEUE]     = NUM_MAC_TX_FCBS;        tp->num_tx_bdbs        [MAC_QUEUE]     = NUM_MAC_TX_BDBS;        tp->tx_buff_size       [MAC_QUEUE]     = MAC_TX_BUFFER_MEMORY;        tp->tx_buff_used       [MAC_QUEUE]     = 0;        tp->tx_queue_status    [MAC_QUEUE]     = NOT_TRANSMITING;        tp->num_tx_fcbs        [NON_MAC_QUEUE] = NUM_NON_MAC_TX_FCBS;        tp->num_tx_bdbs        [NON_MAC_QUEUE] = NUM_NON_MAC_TX_BDBS;        tp->tx_buff_size       [NON_MAC_QUEUE] = NON_MAC_TX_BUFFER_MEMORY;        tp->tx_buff_used       [NON_MAC_QUEUE] = 0;        tp->tx_queue_status    [NON_MAC_QUEUE] = NOT_TRANSMITING;        /* Receive Queue Constants */        tp->num_rx_fcbs[MAC_QUEUE] = NUM_MAC_RX_FCBS;        tp->num_rx_bdbs[MAC_QUEUE] = NUM_MAC_RX_BDBS;        if(tp->extra_info & CHIP_REV_MASK)                tp->num_rx_fcbs[NON_MAC_QUEUE] = 78;    /* 825 Rev. XE */        else                tp->num_rx_fcbs[NON_MAC_QUEUE] = 7;     /* 825 Rev. XD */        tp->num_rx_bdbs[NON_MAC_QUEUE] = smctr_get_num_rx_bdbs(dev);        smctr_alloc_shared_memory(dev);        smctr_init_shared_memory(dev);        if((err = smctr_issue_init_timers_cmd(dev)))                return (err);        if((err = smctr_issue_init_txrx_cmd(dev)))	{                printk(KERN_ERR "%s: Hardware failure\n", dev->name);                return (err);        }        return (0);}static int smctr_init_rx_bdbs(struct net_device *dev){        struct net_local *tp = netdev_priv(dev);        unsigned int i, j;        BDBlock *bdb;        __u16 *buf;        if(smctr_debug > 10)                printk(KERN_DEBUG "%s: smctr_init_rx_bdbs\n", dev->name);        for(i = 0; i < NUM_RX_QS_USED; i++)        {                bdb = tp->rx_bdb_head[i];                buf = tp->rx_buff_head[i];                bdb->info = (BDB_CHAIN_END | BDB_NO_WARNING);                bdb->buffer_length = RX_DATA_BUFFER_SIZE;                bdb->next_ptr = (BDBlock *)(((char *)bdb) + sizeof(BDBlock));                bdb->data_block_ptr = buf;                bdb->trc_next_ptr = TRC_POINTER(bdb->next_ptr);                if(i == NON_MAC_QUEUE)                        bdb->trc_data_block_ptr = RX_BUFF_TRC_POINTER(buf);                else                        bdb->trc_data_block_ptr = TRC_POINTER(buf);                for(j = 1; j < tp->num_rx_bdbs[i]; j++)                {                        bdb->next_ptr->back_ptr = bdb;                        bdb = bdb->next_ptr;                        buf = (__u16 *)((char *)buf + RX_DATA_BUFFER_SIZE);                        bdb->info = (BDB_NOT_CHAIN_END | BDB_NO_WARNING);                        bdb->buffer_length = RX_DATA_BUFFER_SIZE;                        bdb->next_ptr = (BDBlock *)(((char *)bdb) + sizeof(BDBlock));                        bdb->data_block_ptr = buf;                        bdb->trc_next_ptr = TRC_POINTER(bdb->next_ptr);                        if(i == NON_MAC_QUEUE)                                bdb->trc_data_block_ptr = RX_BUFF_TRC_POINTER(buf);                        else                                bdb->trc_data_block_ptr = TRC_POINTER(buf);                }                bdb->next_ptr           = tp->rx_bdb_head[i];                bdb->trc_next_ptr       = TRC_POINTER(tp->rx_bdb_head[i]);                tp->rx_bdb_head[i]->back_ptr    = bdb;                tp->rx_bdb_curr[i]              = tp->rx_bdb_head[i]->next_ptr;        }        return (0);}static int smctr_init_rx_fcbs(struct net_device *dev){        struct net_local *tp = netdev_priv(dev);        unsigned int i, j;        FCBlock *fcb;        for(i = 0; i < NUM_RX_QS_USED; i++)        {                fcb               = tp->rx_fcb_head[i];                fcb->frame_status = 0;                fcb->frame_length = 0;                fcb->info         = FCB_CHAIN_END;                fcb->next_ptr     = (FCBlock *)(((char*)fcb) + sizeof(FCBlock));                if(i == NON_MAC_QUEUE)                        fcb->trc_next_ptr = RX_FCB_TRC_POINTER(fcb->next_ptr);                else                        fcb->trc_next_ptr = TRC_POINTER(fcb->next_ptr);                for(j = 1; j < tp->num_rx_fcbs[i]; j++)                {                        fcb->next_ptr->back_ptr = fcb;                        fcb                     = fcb->next_ptr;                        fcb->frame_status       = 0;                        fcb->frame_length       = 0;                        fcb->info               = FCB_WARNING;                        fcb->next_ptr                                = (FCBlock *)(((char *)fcb) + sizeof(FCBlock));                        if(i == NON_MAC_QUEUE)                                fcb->trc_next_ptr                                        = RX_FCB_TRC_POINTER(fcb->next_ptr);                        else                                fcb->trc_next_ptr                                        = TRC_POINTER(fcb->next_ptr);                }                fcb->next_ptr = tp->rx_fcb_head[i];                if(i == NON_MAC_QUEUE)                        fcb->trc_next_ptr = RX_FCB_TRC_POINTER(fcb->next_ptr);                else                        fcb->trc_next_ptr = TRC_POINTER(fcb->next_ptr);                tp->rx_fcb_head[i]->back_ptr    = fcb;                tp->rx_fcb_curr[i]              = tp->rx_fcb_head[i]->next_ptr;        }        return(0);}static int smctr_init_shared_memory(struct net_device *dev){        struct net_local *tp = netdev_priv(dev);        unsigned int i;        __u32 *iscpb;        if(smctr_debug > 10)                printk(KERN_DEBUG "%s: smctr_init_shared_memory\n", dev->name);        smctr_set_page(dev, (__u8 *)(unsigned int)tp->iscpb_ptr);        /* Initialize Initial System Configuration Point. (ISCP) */        iscpb = (__u32 *)PAGE_POINTER(&tp->iscpb_ptr->trc_scgb_ptr);        *iscpb = (__u32)(SWAP_WORDS(TRC_POINTER(tp->scgb_ptr)));        smctr_set_page(dev, (__u8 *)tp->ram_access);        /* Initialize System Configuration Pointers. (SCP) */        tp->scgb_ptr->config = (SCGB_ADDRESS_POINTER_FORMAT                | SCGB_MULTI_WORD_CONTROL | SCGB_DATA_FORMAT                | SCGB_BURST_LENGTH);        tp->scgb_ptr->trc_sclb_ptr      = TRC_POINTER(tp->sclb_ptr);        tp->scgb_ptr->trc_acb_ptr       = TRC_POINTER(tp->acb_head);        tp->scgb_ptr->trc_isb_ptr       = TRC_POINTER(tp->isb_ptr);        tp->scgb_ptr->isbsiz            = (sizeof(ISBlock)) - 2;        /* Initialize System Control Block. (SCB) */        tp->sclb_ptr->valid_command    = SCLB_VALID | SCLB_CMD_NOP;        tp->sclb_ptr->iack_code        = 0;        tp->sclb_ptr->resume_control   = 0;        tp->sclb_ptr->int_mask_control = 0;        tp->sclb_ptr->int_mask_state   = 0;        /* Initialize Interrupt Status Block. (ISB) */        for(i = 0; i < NUM_OF_INTERRUPTS; i++)        {                tp->isb_ptr->IStatus[i].IType = 0xf0;                tp->isb_ptr->IStatus[i].ISubtype = 0;        }        tp->current_isb_index = 0;        /* Initialize Action Command Block. (ACB) */        smctr_init_acbs(dev);        /* Initialize transmit FCB's and BDB's. */        smctr_link_tx_fcbs_to_bdbs(dev);        smctr_init_tx_bdbs(dev);        smctr_init_tx_fcbs(dev);        /* Initialize receive FCB's and BDB's. */        smctr_init_rx_bdbs(dev);        smctr_init_rx_fcbs(dev);        return (0);}static int smctr_init_tx_bdbs(struct net_device *dev){        struct net_local *tp = netdev_priv(dev);        unsigned int i, j;        BDBlock *bdb;        for(i = 0; i < NUM_TX_QS_USED; i++)        {                bdb = tp->tx_bdb_head[i];                bdb->info = (BDB_NOT_CHAIN_END | BDB_NO_WARNING);                bdb->next_ptr = (BDBlock *)(((char *)bdb) + sizeof(BDBlock));                bdb->trc_next_ptr = TRC_POINTER(bdb->next_ptr);                for(j = 1; j < tp->num_tx_bdbs[i]; j++)                {                        bdb->next_ptr->back_ptr = bdb;                        bdb = bdb->next_ptr;                        bdb->info = (BDB_NOT_CHAIN_END | BDB_NO_WARNING);                        bdb->next_ptr                                = (BDBlock *)(((char *)bdb) + sizeof( BDBlock));                        bdb->trc_next_ptr = TRC_POINTER(bdb->next_ptr);                }                bdb->next_ptr = tp->tx_bdb_head[i];                bdb->trc_next_ptr = TRC_POINTER(tp->tx_bdb_head[i]);                tp->tx_bdb_head[i]->back_ptr = bdb;        }        return (0);}static int smctr_init_tx_fcbs(struct net_device *dev){        struct net_local *tp = netdev_priv(dev);        unsigned int i, j;        FCBlock *fcb;        for(i = 0; i < NUM_TX_QS_USED; i++)        {                fcb               = tp->tx_fcb_head[i];                fcb->frame_status = 0;                fcb->frame_length = 0;                fcb->info         = FCB_CHAIN_END;                fcb->next_ptr = (FCBlock *)(((char *)fcb) + sizeof(FCBlock));                fcb->trc_next_ptr = TRC_POINTER(fcb->next_ptr);                for(j = 1; j < tp->num_tx_fcbs[i]; j++)                {                        fcb->next_ptr->back_ptr = fcb;                        fcb                     = fcb->next_ptr;                        fcb->frame_status       = 0;                        fcb->frame_length       = 0;                        fcb->info               = FCB_CHAIN_END;                        fcb->next_ptr                                = (FCBlock *)(((char *)fcb) + sizeof(FCBlock));                        fcb->trc_next_ptr = TRC_POINTER(fcb->next_ptr);                }                fcb->next_ptr           = tp->tx_fcb_head[i];                fcb->trc_next_ptr       = TRC_POINTER(tp->tx_fcb_head[i]);                tp->tx_fcb_head[i]->back_ptr    = fcb;                tp->tx_fcb_end[i]               = tp->tx_fcb_head[i]->next_ptr;                tp->tx_fcb_curr[i]              = tp->tx_fcb_head[i]->next_ptr;                tp->num_tx_fcbs_used[i]         = 0;        }        return (0);}static int smctr_internal_self_test(struct net_device *dev){        struct net_local *tp = netdev_priv(dev);        int err;        if((err = smctr_issue_test_internal_rom_cmd(dev)))                return (err);        if((err = smctr_wait_cmd(dev)))                return (err);        if(tp->acb_head->cmd_done_status & 0xff)                return (-1);        if((err = smctr_issue_test_hic_cmd(dev)))                return (err);        if((err = smctr_wait_cmd(dev)))                return (err);        if(tp->acb_head->cmd_done_status & 0xff)                return (-1);        if((err = smctr_issue_test_mac_reg_cmd(dev)))                return (err);        if((err = smctr_wait_cmd(dev)))                return (err);        if(tp->acb_head->cmd_done_status & 0xff)                return (-1);        return (0);}/* * The typical workload of the driver: Handle the network interface interrupts. */static irqreturn_t smctr_interrupt(int irq, void *dev_id, struct pt_regs *regs){        struct net_device *dev = dev_id;        struct net_local *tp;        int ioaddr;        __u16 interrupt_unmask_bits = 0, interrupt_ack_code = 0xff00;        __u16 err1, err = NOT_MY_INTERRUPT;        __u8 isb_type, isb_subtype;        __u16 isb_index;        if(dev == NULL)        {                printk(KERN_CRIT "%s: irq %d for unknown device.\n", dev->name, irq);                return IRQ_NONE;        }        ioaddr = dev->base_addr;        tp = netdev_priv(dev);                if(tp->status == NOT_INITIALIZED)                return IRQ_NONE;        spin_lock(&tp->lock);                smctr_disable_bic_int(dev);        smctr_enable_16bit(dev);        smctr_clear_int(dev);        /* First read the LSB */        while((tp->isb_ptr->IStatus[tp->current_isb_index].IType & 0xf0) == 0)        {                isb_index       = tp->current_isb_index;                isb_type        = tp->isb_ptr->IStatus[isb_index].IType;                isb_subtype     = tp->isb_ptr->IStatus[isb_index].ISubtype;                (tp->current_isb_index)++;                if(tp->current_isb_index == NUM_OF_INTERRUPTS)                        tp->current_isb_index = 0;                i

⌨️ 快捷键说明

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