Focus on the Linux kernel
阿新 • • 發佈:2018-12-30
通常網絡卡驅動程式碼量比較大,但是都離不開發送與接收,掌握好骨幹也就好理解與除錯了。
資料傳送 :
傳送函式:xxx_start_xmit()
上層封裝好了sk_buff丟進kernel後,buf儲存在skb->data中,通 過 xxx_start_xmit(),傳送出去。
下面的例項是通過寫入某個裝置節點發送出去,當然這個裝置肯定是串列埠或者sdio等傳輸裝置,
也可以直接呼叫寫入函式將buf送出去。
比如sdio的寫入:
sdio_memcpy_toio(xxx->func, addr, buf, sizeof(buf));
net_device_ops結構體的填充,在裡實現了open與傳送等操作:
static const struct net_device_ops xxx_netdev_ops = { .ndo_open = xxx_net_open, .ndo_stop = xxx_net_stop, .ndo_start_xmit = xxx_start_xmit, .ndo_get_stats = xxx_get_stats, .ndo_tx_timeout = xxx_tx_timeout, }; static int xxx_start_xmit(struct sk_buff *skb, struct net_device *dev){ --------- nwrite = filep->f_op->write(filep, skb->data, skb->len, &filep->f_pos); set_fs(old_fs); if (nwrite == skb->len) { priv->stats.tx_packets++; priv->stats.tx_bytes +=skb->len; priv->netdev->trans_start = jiffies; } ----------- }
資料接收:
目前我所看到的接收觸發都是在中斷(低速串列埠與sdio card)裡面讀取到buf後非同步呼叫netif_rx()提交到網路棧,
對於sdio card的接收資料是host端接收到中斷後呼叫到card裡面的中斷處理函式而讀取buf的。另外一種就是軟中斷來接收,
比如usb與高速串列埠的資料接收。
netif_rx()是標準的網絡卡上交sk_buff資料流,通常網絡卡驅動程式碼量很大當你找不到接收函式時,搜netif_rx()是最 好的 選擇。
下面接收處理函式:首先分配skb資料空間,再將讀取的buf存入skb中,再呼叫netif_rx(),資料報入網路棧。
static int xxx_submit_skb(void *data) { -------- skb = netdev_alloc_skb(ndev, pkt_len + NET_IP_ALIGN); /* NET_IP_ALIGN is 2 */ if (!skb) { printk(KERN_INFO "error: out of memory for rx'd frame\n"); priv->stats.rx_dropped++; ret = -ENOMEM; goto error; } skb_reserve(skb, NET_IP_ALIGN); memcpy((skb_put(skb, pkt_len), pkt_len),buf,sizeof(buf); skb->dev = priv->netdev; skb->protocol = eth_type_trans(skb, priv->netdev); priv->stats.rx_packets++; priv->stats.rx_bytes += pkt_len; ret = netif_rx(skb); if (ret != 0) printk(KERN_INFO "%s: netif_rx error\n", __func__); -------- }