LAN9221网卡驱动分析----发送数据---理解记录

LAN9221网卡驱动中,以字对齐往网卡缓存发数据,当网卡中TX_FIFO空间余量小于1600个字节时,通知上层停止发送队列,余量大于3200的时候网卡触发中断继续发送数据。

static int smsc911x_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)

freespace = smsc911x_reg_read(pdata, TX_FIFO_INF) & TX_FIFO_INF_TDFREE_;//读TX_FIFO_INF寄存器获取低十六位,得到TX_FIFO中剩余空间的大小。

/* Word alignment adjustment */
tx_cmd_a = (u32)((ulong)skb->data & 0x03) << 16; //skb->data低两位给Data Start Offset,在网卡缓存中空几个字节使数据字对齐
tx_cmd_a |= TX_CMD_A_FIRST_SEG_ | TX_CMD_A_LAST_SEG_;
tx_cmd_a |= (unsigned int)skb->len;

tx_cmd_b = ((unsigned int)skb->len) << 16;  //虽然skb->len是32位的数据,但skb->len的最大值为1536,小于11位
tx_cmd_b |= (unsigned int)skb->len;  //所以这里的两次复制,只是把套接字的长度给了Command_B的Packte Tag和Packte Length,用包的长度作为包的唯一标示
smsc911x_reg_write(pdata, TX_DATA_FIFO, tx_cmd_a);
smsc911x_reg_write(pdata, TX_DATA_FIFO, tx_cmd_b); //写入command A和command B

 

bufp = (ulong)skb->data & (~0x3);  //数据发送指针前移3个ulong,使包字对齐,并且强制转换成ulong型,减一就跳过四个字节
wrsz = (u32)skb->len + 3; //根据上一句的数据发送指针前移了3个ulong
wrsz += (u32)((ulong)skb->data & 0x3);??
wrsz >>= 2;  //以字为单位将数据发给网卡,计算发送的次数??

smsc911x_tx_writefifo(pdata, (unsigned int *)bufp, wrsz); //按字发送数据给网卡

if (freespace < TX_FIFO_LOW_THRESHOLD) {  //剩余空间小于1600B时,通知上层暂停发送数据
netif_stop_queue(dev);
temp = smsc911x_reg_read(pdata, FIFO_INT);
temp &= 0x00FFFFFF;
temp |= 0x32000000;  //设置当TX_FIFO剩余空间大于3200B的时候触发中断
smsc911x_reg_write(pdata, FIFO_INT, temp);

posted @ 2015-05-19 09:33  polo2013  阅读(90)  评论(0)    收藏  举报