"); //-->
static int dm9013_open(struct net_device *dev)
{
board_info_t *db = (board_info_t *)dev->priv;
//priv 指向私有数据
if (request_irq(dev->irq,&dm9013_interrupt,SA_SHIRQ,dev->name,dev))
return -EAGAIN;
//申请中断号
/* Initilize DM9013 board */
dm9013_init(dev);
//总线模式选择,根据硬件设计
switch(db->io_mode)
{
case DM9013_BYTE_MODE:
db->MoveData = &dm9013_move8bit;
break;
case DM9013_WORD_MODE:
db->MoveData = &dm9013_move16bit;
break;
case DM9013_DWORD_MODE:
db->MoveData = &dm9013_move32bit;
break;
}
//初始化系统变量
/* Init driver variable */
db->reset_counter = 0;
db->reset_tx_timeout = 0;
db->cont_rx_pkt_cnt = 0;
//设置定时器
/* set and active a timer process */
init_timer(&db->timer);
db->timer.expires = DM9013_TIMER_WUT;
db->timer.data = (unsigned long)dev;
db->timer.function = &dm9013_timer;
add_timer(&db->timer);
//启动网络接口的发送队列
netif_start_queue(dev);
return 0;
}
相关API Linux 驱动原型
/**
* netif_start_queue - allow transmit
* @dev: network device
*
* Allow upper layers to call the device hard_start_xmit routine.
*/
static inline void netif_start_queue(struct net_device *dev)
{
clear_bit(__LINK_STATE_XOFF, &dev->state);
}
使用定时器的一般流程为:
(1)timer、编写function;
(2)为timer的expires、data、function赋值;
(3)调用add_timer将timer加入列表;
(4)在定时器到期时,function被执行;
(5)在程序中涉及timer控制的地方适当地调用del_timer、mod_timer删除timer或修改timer的expires。
struct timer_list {
struct list_head entry;
unsigned long expires;
void (*function)(unsigned long);
unsigned long data;
struct tvec_base *base;
#ifdef CONFIG_TIMER_STATS
void *start_site;
char start_comm[16];
int start_pid;
#endif
};
static void dm9013_init(struct net_device *dev)
{
board_info_t *db = (board_info_t *)dev->priv;
DM9013_DBUG(0, "dm9013_init()", 0);
spin_lock_init(&db->lock);
/* switch reset */
iow(db, DM9013_SCR,DM9013_SCR_ResetSwitch);
wait_bit_clear(DM9013_SCR,6); //系统清除10us后重启交换核
/* software reset */
iow(db, DM9013_NCR, NCR_Reset);
wait_bit_clear(DM9013_NCR,0); //软重启,系统清除状态10us后
/* I/O mode */
db->io_mode = ior(db, DM9013_ISR) >> 6; /* ISR bit7:6 keeps I/O mode */
/* DM9003 is 2 port mode */
/* DM9013 is 2 port mode or 3 port mode */
if (pe.id_val==DM9003_ID)
db->port_mode= 2;
else
db->port_mode= (ior(db, DM9013_MONITOR2)&(1<<6)) ? 2:3; //'CHECK_STR_V105.1'
/* Set PHY */
db->op_mode = media_mode;
dm9013_set_PHY_mode(db);
IC_Notice(db);
//设置网络状态及流控寄存器
/* Program operating register */
iow(db, DM9013_NCR, 0x20); /* reg.01 cleared by write 1 */
iow(db, DM9013_FCR, 0x20); /* RX Flow Control Enable */
#ifdef CHECKSUM
printk("<DM9013>Enable checksum offload \n");
/* TX checksum enable */
iow(db, DM9013_TCCR, TCCR_UDP_Chksum|TCCR_TCP_Chksum|TCCR_IP_Chksum);
/* RX checksum enable */
iow(db, DM9013_RCSR, RCSR_RX_Chksum_enable);
#endif
/* switch config */
/* If using EEPROM sets switch functions,
don't execute dm9013_switch_config() function */
if (db->HasEEPROM)
iow(db, DM9013_EPCR, (1<<5));/* reload EEPROM */
else
dm9013_switch_config(db);
//设置多播地址
/* Set address filter table */
dm9013_hash_table(dev);
/* Activate DM9000A/DM9010 */
iow(db, DM9013_RXCR, RXCR_RxEnable);
//中断使能
dm9013_enable_interrupt(db);/* Enable TX/RX interrupt mask */
//系统变量初始化
/* Init Driver variable */
db->tx_pkt_cnt = 0;
netif_carrier_on(dev);
}
/**
网络设备默认具备载波信号存在,驱动程序可通过动作函数来显式地改变状态。比如:
void netif_carrier_on (struct net_device *dev);如果驱动程序没有侦测到设备上的载波信号,那么将执行
netif_carrier_off(struct net_device *dev);动作,并告诉内核,一旦侦测到载波信号,那么将执行
void netif_carrier_on动作函数,也可用int netif_carrier_ok(struct net_device *dev);。
* netif_carrier_on - set carrier
* @dev: network device
*
* Device has detected that carrier.
*/
void netif_carrier_on(struct net_device *dev)
{
if (test_and_clear_bit(__LINK_STATE_NOCARRIER, &dev->state)) {
linkwatch_fire_event(dev);
if (netif_running(dev))
__netdev_watchdog_up(dev);
}
}
*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。