以下為這個驅動程式的撰寫重點 :
- 驅動程式的進入點, 則依照Linux驅動程式的標準寫法, 若是PCI bus則在初始化時依照PCI client驅程式的登錄方式, 若是SoC則依照platform driver的登錄方式。以下是一個範例說明:
static struct platform_driver victor_mac_driver = {
.driver.name = DRV_NAME,
.probe = victor_mac_probe,
.remove = victor_mac_remove,
};
static int __init victor_mac_module_init(void)
{
printk("%s \n",__FUNCTION__);
return platform_driver_register(&victor_mac_driver);
}
module_init(victor_mac_module_init);
- 當你登錄完畢後則會進入probe的進入點, 在這裏我們需要初始化ethernet device driver。而在probe callback function中會做以下幾件事:
- 取得硬體資源 (memory & IRQ no), 並且將其做ioremap以取得virtual address
- 初始化硬體, 並註冊interrupt service routine
- allocate ethernet device structure, register a ethernet device
static const struct net_device_ops victor_netdev_mac_ops = {
.ndo_init = victor_mac_init,
.ndo_open = victor_mac_open,
.ndo_stop = victor_mac_stop,
.ndo_start_xmit = victor_mac_start_xmit,
.ndo_get_stats = victor_mac_get_stats,
.ndo_set_multicast_list = victor_mac_set_mcast_list,
.ndo_do_ioctl = victor_mac_ioctl,
.ndo_change_mtu = eth_change_mtu,
.ndo_set_mac_address = eth_mac_addr,
.ndo_validate_addr = eth_validate_addr,
};
struct net_device *ndev;
struct resource *res;
ndev = alloc_etherdev(sizeof(victor_gmac_priv_t));
res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
ndev->netdev_ops = (struct net_device_ops *)&victor_netdev_mac_ops;
retval = register_netdev(ndev);
而以上在註冊ethernet device driver時會有幾個call back function需要給予撰寫, 其說明如下:
ndo_init
這是在註冊ethernet driver時馬上會被呼叫的call back function, 在此可以做一些初始化的動作
ndo_open
當使用者up該網路介面時會呼叫這個call back function, 通常會在此啓動該ethernet的硬體動作
ndo_stop
當使用者down該網路介面時會呼叫這個call back function, 通常會在此停止該ethernet的硬體動作
ndo_start_xmit
這是網路最後要將資料在硬體線路傳輸, 在這裏該driver不用對內容做任何更動, 而source MAC address通常是由硬體自動填入, 另外有一個很重要的事, 就是網路傳輸由開始者 (TCP or UDP) allocate skb_buff來儲存資料, 而在ethernet driver在送至硬體時需要free該skb_buff, 若沒有做這個動作將會由系統的記憶體越來越少
ndo_get_stats
由此來取得系統所定統計資料, 統計資籵必須由driver自行記錄, 並非由系統協助記錄
ndo_set_multicast_list
設定multicast MAC位址,驅動程式必須將這些位址設至硬體
ndo_do_ioctl
這是對於該元件的ioctl,通常一些運用程式會使用,如bridge程式就會使用,又如設定phy時也會使用。
ndo_change_mtu
設定網路的mtu值,通常是不會更動。
ndo_set_mac_address
設定該網路介面的MAC位址,通常MAC位址都是在初始化時讀取設定在硬體中,所以不會是任意更改,因為MAC位址是全世界上有所管制的,必須是唯一性。
ndo_validate_addr
設定validate MAC address
撰寫好以上各個call back function之後就是interrupt service routine, 而在interrupt service routine中就是要處理收和送的資料, 這部分和IC硬體有很大的關連, 隨著硬體而有所不同, 所以必須要好好地研讀硬體的軟體說明書.
沒有留言:
張貼留言