上一次講的cs8900_receive函數是在中斷處理函數中調用的,也就是當中斷到來,如果判斷出是資料接收情況,則通過這個函數進行資料接收。那麼如果中斷是由於其他事件觸發的呢,當然就需要其他代碼了,不過那些代碼並不難,大家自己看就是了。 中斷的內容講完後,cs8900_start函數也算告一段落,我們回到最初的cs8900_init函數中。在cs8900_start之後的就是cs8900_stop了:ndev->stop = cs8900_stop;這個函數基本上是open的反操作:關閉網卡、釋放中斷、停止隊列。所以為一個網卡寫驅動,主要是讀懂它的手冊,這樣你才知道哪個寄存器做什麼,它的工作方式等。留一個作業吧,結合手冊和下面代碼,理解cs8900網卡的關閉方式: cs8900_write (dev,PP_BusCTL,0); cs8900_write (dev,PP_TestCTL,0); cs8900_write (dev,PP_SelfCTL,0); cs8900_write (dev,PP_LineCTL,0); cs8900_write (dev,PP_BufCFG,0); cs8900_write (dev,PP_TxCFG,0); cs8900_write (dev,PP_RxCTL,0); cs8900_write (dev,PP_RxCFG,0); 釋放中斷和申請中斷又是一對,只管調用就是了:free_irq (dev->irq,dev); 還記得在cs8900_start函數中調用了netif_start_queue嗎?那麼在關閉網卡後調用netif_stop_queue 就是了。 如果按代碼順序講,該介紹cs8900_send_start了,不過這個函數比較重要,我們放在下一節單獨介紹。我們先看它後面的代碼: ndev->get_stats = cs8900_get_stats; ndev->set_multicast_list = cs8900_set_receive_mode; ndev->tx_timeout = cs8900_transmit_timeout; 我們的cs8900網卡只實現了這些函數。根據網卡的不同,你可能需要自己完成更多的函數。不過就get_stats、set_multicast_list和tx_timeout來說,它們完成的任務是相同的,分別是擷取統計資訊、處理多播網包、逾時處理。 先看一下cs8900是如何擷取統計資訊的: static struct net_device_stats *cs8900_get_stats (struct net_device *dev){ cs8900_t *priv = (cs8900_t *) dev->priv; return (&priv->
stats);} stats是一個net_device_stats結構,其實說簡單點,你只要返回stats結構就可以了,它裡面記錄了你需要的資訊。net_device_stats結構在netdevice.h檔案中。 struct net_device_stats{ unsigned long rx_packets; /* total packets received */ unsigned long tx_packets; /* total packets transmitted */ unsigned long rx_bytes; /* total bytes received */ unsigned long tx_bytes; /* total bytes transmitted */ unsigned long rx_errors; /* bad packets received */ unsigned long tx_errors; /* packet transmit problems */ unsigned long rx_dropped; /* no space in linux buffers */ unsigned long tx_dropped; /* no space available in linux */ unsigned long multicast; /* multicast packets received */ unsigned long collisions; /* detailed rx_errors: */ unsigned long rx_length_errors; unsigned long rx_over_errors; /* receiver ring buff overflow */ unsigned long rx_crc_errors; /* recved pkt with crc error */ unsigned long rx_frame_errors; /* recv'd frame alignment error */ unsigned long rx_fifo_errors; /* recv'r fifo overrun */ unsigned long rx_missed_errors; /* receiver missed packet */ /* detailed tx_errors */ unsigned long tx_aborted_errors; unsigned long tx_carrier_errors; unsigned long tx_fifo_errors; unsigned long tx_heartbeat_errors; unsigned long tx_window_errors; /* for cslip etc */ unsigned long rx_compressed; unsigned long tx_compressed;}; cs8900_get_stats這個函數雖然簡單,但是很實用。cs8900_set_receive_mode函數設定網卡模式,需要配合手冊來閱讀。出現的新函數(cs8900_set和cs8900_clear)實際上就是cs8900_write,就是通過與(&)或(|)運算,實用set和clear字樣,會使函數非常易讀。 一句話總結:對網卡的控制需要熟讀硬體手冊。