ath9k驅動代碼主要數據結構概覽。
(1)在ath9k的驅動中,幾乎是最頂層的數據結構是ath_softc,這個數據結構幾乎隨處可見。ath_softc是硬件與MAC層進行交互的中間載體,很多有用的
網絡參數都可以從ath_softc中得到,對於進一步的網卡驅動開發,收集網絡數據等很有幫助。
定義位置:drivers/net/wireless/ath/ath9k/ath9k.h 具體定義如下:
struct ath_softc { struct ieee80211_hw *hw; //保存硬件信息 struct device *dev; //當前工作的設備 u32 chan_bw; // 信道帶寬 int chan_idx; // 信道序號 int chan_is_ht; // 是否使用high_throughput模式 即綠野模式 struct survey_info *cur_survey; struct survey_info survey[ATH9K_NUM_CHANNELS]; struct tasklet_struct intr_tq; struct tasklet_struct bcon_tasklet; //結構體定義在 include <linux/interrupt.h> 用於中斷管理 struct ath_hw *sc_ah; //hw的包裝結構體 void __iomem *mem; //內存區域 int irq; spinlock_t sc_serial_rw; spinlock_t sc_pm_lock; spinlock_t sc_pcu_lock; //進行數據讀取,或者處理skb時需要的鎖 struct mutex mutex; struct work_struct paprd_work; struct work_struct hw_check_work; struct work_struct hw_reset_work; //執行不同工作的工作隊列 以后在代碼中具體解釋 struct completion paprd_complete; unsigned int hw_busy_count; u32 intrstatus; u32 sc_flags; /* SC_OP_* */ u16 ps_flags; /* PS_* */ u16 curtxpow; bool ps_enabled; bool ps_idle; short nbcnvifs; short nvifs; unsigned long ps_usecount; struct ath_config config; struct ath_rx rx; struct ath_tx tx; struct ath_beacon beacon; struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS]; //當前支持的帶寬 #ifdef CONFIG_MAC80211_LEDS const char *led_default_trigger; struct list_head leds; #endif struct ath9k_hw_cal_data caldata; int last_rssi; #ifdef CONFIG_ATH9K_DEBUGFS struct ath9k_debug debug; spinlock_t nodes_lock; struct list_head nodes; /* basically, stations */ unsigned int tx_complete_poll_work_seen; #endif struct ath_beacon_config cur_beacon_conf; struct delayed_work tx_complete_work; struct delayed_work hw_pll_work; struct ath_btcoex btcoex; struct ath_mci_coex mci_coex; struct ath_descdma txsdma; struct ath_ant_comb ant_comb; u8 ant_tx, ant_rx; };
在ath_softc中的一些數據結構是值得注意的,ieee80211_hw, ath_rx,ath_tx,ath_beacon,ath_debug。這些結構體在網卡編碼中經常使用,現在逐一
對其分析解釋。
(2)ath9k_debug。在Linux運行過程中,會建立一個虛擬的文件操作系統 /proc,通過/proc可以訪問內核內部數據結構、改變內核設置的機制,對
於OpenWrt操作系統來說,內核與外部shell之間的交互是通過讀寫/sys/kernel/debug/ieee80211/phy0/ath9k/目錄下的文件實現的。ath9k_debug中定義
的數據結構承接了外部參數輸入和內核數據的導出。如果先要改變內核運行時的參數,可以在此結構中定義新的數據變量,然后通過實現新的file_operations達到
參數的讀入和內核數據的導出的目的。總之,想要在代碼中增加需要的數據結構,定義好后,放一個對象在這個結構體中,就可以安心使用了,當然具體的操作
方法,會在以后的博客中再具體說明。
ath_debug定義在 drivers/net/wireless/ath/ath9k/debug.h 中。
struct ath9k_debug { struct dentry *debugfs_phy; u32 regidx; struct ath_stats stats; spinlock_t samp_lock; struct ath_dbg_bb_mac_samp bb_mac_samp[ATH_DBG_MAX_SAMPLES]; u8 sampidx; u8 tsidx; u8 rsidx; // 以上是系統自定義的變量 // 下面是個人開發需要所增加的變量,其中的結構體變量的定義也在debug.h中 bool first_into; unsigned long mcs_tx_time; struct inject_settings *setting; struct list_head recv_tp_list; struct realtime_var rtv; struct list_head xmit_bw_list; struct list_head rx_infos_list; struct list_head frame_list; unsigned int frame_maxnum; };
(3)ath_rx_status這個數據結構,。此結構提供的信息對於分析信道狀況、統計單幀的信息都很有幫助,而且信息的粒度足夠小了。這個數據結構
定義了網卡接收到一個skb時網卡的狀態,數據幀的狀態等信息,具體見代碼注釋,沒注釋的就是我也沒看懂的各位誰知道的請留言,多謝賜教。
格式:結構體:成員變量--含義 比如 ath_rx_status:rs_rate--標記速率類型。
結構體定義在:drivers/net/wireless/ath/ath9k/mac.h
struct ath_rx_status { u32 rs_tstamp; // 接收的時間戳 u16 rs_datalen; u8 rs_status; // 標記出錯類型 CRC or PHY u8 rs_phyerr; // PHY Error 有很多類型,這個變量可以使這些類型對應的某一個或幾個 int8_t rs_rssi; // 當前數據幀的信號接收強度 u8 rs_keyix; u8 rs_rate; // 標記當前速率是否是HT模式 如果是 則rs_rate = 0x80 u8 rs_antenna; // 接收天線編號 u8 rs_more; // 標記當前數據幀是否是分片之一 int8_t rs_rssi_ctl[3]; // 候選RSSI集合,與diversity和combining有關 int8_t rs_rssi_ext[3]; u8 rs_isaggr; // 是否是聚合幀的一部分 u8 rs_moreaggr; // 是否是聚合幀中的最后一個數據幀 u8 rs_num_delims; u8 rs_flags; bool is_mybeacon; // 是否是屬於自己的beacon幀 u32 evm0; u32 evm1; u32 evm2; u32 evm3; u32 evm4; };
(4)ath_atx_tid是發送端MAC層非常重要的一個數據結構。塊確認機制、重傳、窗口管理、發送隊列的管理和實現都依賴或者設計到ath_atx_tid。
具體使用方法會在后續的發送端詳解中依次說明,現在看一下其中的成員變量及含義。
此數據結構定義在drivers/net/wireless/ath/ath9k/ath9k.h。
struct ath_atx_tid { struct list_head list; struct sk_buff_head buf_q; struct ath_node *an; struct ath_atx_ac *ac; unsigned long tx_buf[BITS_TO_LONGS(ATH_TID_MAX_BUFS)]; //類似於Bitmap,標記窗口內已發送的數據幀 int buf_pending; int bar_index; // Block Ack Request的索引 u16 seq_start; // 當前發送序號的開始 u16 seq_next; // 下一次發送序號的開始 u16 baw_size; // Block Ack Window 的大小 一般為128 int tidno; //標記當前傳輸的數據的類型:媒體數據或者是文本數據等等 int baw_head; /* first un-acked tx buffer */ int baw_tail; /* next unused tx buffer slot */ int sched; int paused; u8 state; // 發送狀態,正在發送,發送完畢,或出錯 };
未完待續。
