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 共...