📄 smctr.c
字号:
/* 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 + -