從硬體操作到核心來談網絡卡驅動

2021-06-18 14:17:20 字數 4683 閱讀 4568

dm9000任務:

1、把上層傳下來的資料

sk_buff

,抽取有效資料通過

dm9000

轉為二進位制傳送出去;

2、接收來自其他裝置的二進位制資料,通過

dm9000

得到這些資料,然後封裝為

sk_buff

格式,然後提交給上一層。

我們需要對網絡卡驅動做的主要任務:

1、網絡卡初始化,然網絡卡執行起來;

2、註冊接收中斷函式,中斷處理函式負責接收來自其他裝置資料,以及當傳送完成也會產生中斷等。

ndev->netdev_ops->ndo_start_xmit

來完成包交付給網絡卡。

首先第一件事網絡卡初始化要做什麼事情?

1、讓網絡卡能執行起來;

對於網絡卡主要初始化工作是在開啟函式。

dm9000_open

dm9000_reset(db);

dm9000_init_dm9000(dev);

在看著兩個函式之前,先了解一下dm9000

底層操作:

對於硬體操作,由於dm9000

內部存在很多暫存器,我們是通過處理器引出的位址線來操作這款晶元,相當於儲存晶元一樣。所以我們呢可以相當把那些暫存器當做晶元記憶體,起始位址根據位址引腳得出:

我們6410

的靜態儲存區域是從

0x10000000

開始的,根據

dm9000的cs

引腳接到

csn1

即第二bank

區,故起始位址是

0x18000000

。在這個位址開始的就是

dm9000

的暫存器。

了解一下dm9000

的暫存器功能:

用於復位:

ncr (

00h):網路控制暫存器(

network control register )

nsr (

01h):網路狀態暫存器(

network status register 

)用於傳送接收設定:

tcr(

02h):傳送控制暫存器(

tx control register)

rcr(

05h):接收控制暫存器(

rx control register 

)bptr(

08h):背壓門限暫存器(

back pressure threshold register

)模式設定:

smcr(

2fh):特殊模式控制暫存器(

special mode control register

中斷設定:

imr(

ffh):中斷遮蔽暫存器(

interrupt mask register

)isr(

feh):中斷狀態暫存器(

interrupt status register

)phy設定:

gpcr(

1fh):

gpio

控制暫存器(

general purpose control register

)gpr(

1fh):

gpio

暫存器(

general purpose register

)讀寫暫存器:

mrcmdx(

f0h----

用於接下來的讀取工作是否有效;

mrcmd(

f2h---

用於讀取資料,從

dm9000 rx sram讀取

;mwcmd(

f8h---

用於傳送資料,直接先存放到

dm9000 tx sram中;

txpll(

fch):傳送資料報長度暫存器低半位元組(

tx packet length low byte register)

txplh(

fdh):傳送資料報長度暫存器高半位元組(

tx packet length high byte register)

判斷傳送完成是否(在傳送完之後判斷是否無誤傳送完成):

tcr(

02h):傳送控制暫存器(

tx control register)

tsr_i(03h):資料報指標1的傳送狀態暫存器1(tx status register i)

tsr_ii(04h):資料報指標2的傳送狀態暫存器2(tx status register ii)

首先看核心如何初始化dm9000:

dm9000_reset:

軟體復位:

writeb(dm9000_ncr, db->io_addr); //時能

phy

udelay(200);

writeb(ncr_rst, db->io_data); //復位

udelay(200);

dm9000_init_dm9000:

1、iow(db, dm9000_gpr, 0);/* reg_1f bit0 activate phyxcer */

iow(db, dm9000_gpcr, gpcr_gep_cntl);/* let gpio0 output */

iow(db, dm9000_gpr, 0);/* enable phy */

上面說的很明白,第一句啟用phy,

第二句讓

gpio0

輸出,第三句時能

phy。所以

phy要通過晶元

gp輸出來啟用時能的。

2、if (db->wake_supported)

ncr |= ncr_wakeen;

iow(db, dm9000_ncr, ncr);

設定dm9000

支援睡眠功能,如果該晶元支援。

3、iow(db, dm9000_tcr, 0);       /* tx polling clear */

iow(db, dm9000_bptr, 0x3f);/* less 3kb, 200us */

iow(db, dm9000_fcr, 0xff);/* flow control */

iow(db, dm9000_smcr, 0);        /* special mode */

設定傳送接收暫存器,暫存器相關功能看

,我也半懂。

4、iow(db, dm9000_imr, imr);

時能接收傳送中斷位;

到這裡dm9000

就可以工作了。

總結一下:

軟體復位-->

使能phy---->

設定傳送接收暫存器

----->

時能傳送接收中斷。

另外可以參考:

往暫存器讀寫東西:

static u8   ior(board_info_t * db, int reg)

static void  iow(board_info_t * db, int reg, int value)

最後來看看核心如何實現讀寫操作的:

1、傳送操作:

首先得到上層資料,然後通過dm9000

操作傳送出去。

上層呼叫dm9000_start_xmit(struct sk_buff *skb, struct net_device *dev)

函式:

1、讀取

dm9000_mwcmd

暫存器的內容,通過

db->outblk

傳送出去(

dm9000_outblk_16bit)[

通過 dm9000_mwcmd命令寫到

tx sram那裡]

,如果是第乙個包,那麼就直接傳送傳送包的長度。如果是第二個包的

話,說明還有乙個包在傳送中,那麼就需要把報的長度和ip_summed

就暫停傳送

netif_stop_queue

,直到第乙個包發

完產生中斷呼叫dm9000_interrupt

函式的時候,再呼叫

dm9000_tx_done

函式把剛才沒法送的傳送出去,最後釋放

dev_kfree_skb(skb);

如果接收的話,首先產生中斷dm9000_interrupt

,讀取中斷狀態知道是接收資料,呼叫

dm9000_rx

函式,然後通過

dm9000_mrcmdx

從讀取第乙個位元組(驗證位元組),由於

dm9000

讀取的這個第乙個位元組必須是

0x00,0x01,

不是的話表示出錯。讀完之後就可以開始讀取資料,通過

dm9000_mrcmd

命令從dm9000

的rx sram

快取讀取資料了,使用讀取函式

(db->inblk)(db->io_data, &rxhdr, sizeof(rxhdr));

,然後就是檢驗資料大小和資料準確性,緊接著就是封裝為

sk_buff

格式了:

dev_alloc_skb

分配sk_buff,(db->inblk)(db->io_data, rdptr, rxlen)

讀取資料長度,最後提交給上一層

skb->protocol = eth_type_trans(skb, dev)。

mac去除dmg密碼操作到程式設計

由於使用osx 系統,經常會訪問到 二 開啟選單欄裡的轉換 三 選擇有密碼的dmg 四 輸入名字,選擇儲存位置,五 轉換前會叫你輸入原來 的密碼xclient.info 六 已經生成 七 雙擊 開啟時,已經沒有密碼了 那麼問題來了,這裡有一百個dmg,這樣操作會不會太累 所以我們得用命令或者指令碼,...

從硬體了解定址

學習linux核心,記憶體管理是必學的,但是和自己以前設計解碼電路的定址完全不同,所以對抽象後位址對映不能很好地理解,雖然很多書都有介紹,但是領悟的還是有缺陷。所以這次以intel微處理器為例子,去了解硬體是怎麼定址的,然後在轉到linux系統怎麼抽象的。80x86常見的工作模式有,實模式和保護模式...

經驗 MacVim基本操作到安裝 配置

本渣渣想入門macvim顯得高階一點。一頓亂操作打算記錄一下共享給網路。macvim官網 高階一點學習vim可以參考learn vimscript the hard way 首先在安裝前還是要先熟悉一下macvim的基本操作。因為到時候安裝還是很快的,可能會手足無措。macvim基本操作 vim 共...