新闻  |   论坛  |   博客  |   在线研讨会
DM9003 驱动学习(四)Linux driver 02
0750long | 2009-05-26 18:51:15    阅读:2638   发布文章

DM9003 驱动学习(四)Linux driver 02

 

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);
 }
}

*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论
登录后参与讨论
推荐文章
最近访客