https://blog.csdn.net/dearsq/article/details/53318887

[Android6.0][RK3399] SDIO 介面 Wifi 驅動流程分析 (AP6354)



Platform: RockChip
OS: Android 6.0
Kernel: 4.4
WiFi/BT/FM
模組: AP6354

前面的基本概念搜羅於網路;
後面的驅動流程分析是根據 RockChip 3399 Kernel 部分來進行分析的。

本博客唯一地址:http://blog.csdn.net/dearsq/article/details/53318887
歡迎轉載,轉載請注明作者 Younix~ 謝謝~

基本概念

Wifi

wifi 英文全稱是 WIreless-FIdelity,翻譯成中文就是無線保真,英文簡稱WiFi

WLAN

wlan 英文全名:Wireless Local Area Networks, 無線區域網路。

關係

wifi 是實現 wlan 的一種技術。

STA 模式 和 AP 模式

AP模式: Access Point,提供無線接入服務,允許其它無線設備接入,提供資料訪問,一般的無線路由/橋接器工作在該模式下。APAP之間允許相互連接。
Sta模式: Station, 類似於無線終端,sta本身並不接受無線的接入,它可以連接到AP,一般無線網卡即工作在該模式。

無線接入過程的三個階段

STA(工作站)啟動初始化、開始正式使用AP傳送資料幀前,要經過三個階段才能夠接入(802.11MAC層負責用戶端與AP之間的通訊,功能包括掃描、接入、認證、加密、漫遊和同步等功能):
1)掃描階段(SCAN
2)認證階段 (Authentication)
3
)關聯(Association

 

更詳細的 wifi 相關介紹可以參考這篇文章 WiFi基礎知識解析

後面介紹 Wifi 的介面 SDIO 的基本概念。

SD MMC

SD (Secure Digital) MMC (Multimedia Card)
MMC
是較早的一種記憶卡標準,目前已經被 SD 標準取代
SD 是一種 flash memory card 的標準,也就是一般常見的 SD 記憶卡。

SDIOSecure Digital I/O

SDIO 就是 SD I/O 介面的意思。
更具體的說,SD 本來是記憶卡的標準,但是現在也可以把 SD 拿來插上一些週邊介面使用,這樣的技術便是 SDIO

SDIO 通過 SD I/O 管腳來連接外部的週邊 device 傳輸資料。這些週邊設備,我們稱為 SDIO 卡,常見的有:

  • Wi-Fi card(無線網路卡)
  • CMOS sensor card(照相模組)
  • GPS card
  • GSM/GPRS modem card
  • Bluetooth card
  • Radio/TV card

SDIO 卡 和 SD 卡 的區別

SD卡使用的是SD卡協定,而SDIO卡使用的是SDIO協定!
協定不一樣,初始化/讀寫方式也不一樣!

SDIO-Wifi 模組

SDIO-Wifi 模組是基於 SDIO 介面的符合 wifi 無線網路標準的嵌入式模組,內置無線網路通訊協定IEEE802.11協定棧以及TCP/IP協定棧,能夠實現用戶主平臺資料通過SDIO口到無線網路之間的轉換。
SDIO 具有傳輸資料快,相容SDMMC介面等特點。

對於SDIO介面的wifi,首先,它是一個sdio的卡的設備,然後具備了wifi的功能。
所以,註冊的時候還是先以sdio的卡的設備去註冊的。然後檢測到卡之後就要驅動他的wifi功能

SDIO 匯流排

SDIO匯流排 和 USB匯流排 類似,SDIO也有兩端,其中一端是HOST端,另一端是device端。所有的通信都是由HOST端 發送 命令 開始的,Device端只要能解析命令,就可以相互通信。
CLK信號:HOSTDEVICE的 時鐘信號,每個時鐘週期傳輸一個命令。
CMD信號:雙向 的信號,用於傳送 命令 和 反應。
DAT0-DAT3 信號:四條用於傳送的資料線。
VDD信號:電源信號。
VSS1VSS2:電源地信號。

SDIO 命令

SDIO匯流排上都是HOST端發起請求,然後DEVICE端回應請求。
SDIO 命令由6個位元組組成。

a – Command:用於開始傳輸的命令,是由HOST端發往DEVICE端的。其中命令是通過CMD信號線傳送的。
b – Response:回應是DEVICE返回的HOST的命令,作為Command的回應。也是通過CMD線傳送的。
c – Data:資料是雙向的傳送的。可以設置為1線模式,也可以設置為4線模式。資料是通過DAT0-DAT3信號線傳輸的。

SDIO的每次操作都是由HOSTCMD線上發起一個CMD,對於有的CMDDEVICE需要返回Response,有的則不需要。
對於讀命令,首先HOST會向DEVICE發送命令,緊接著DEVICE會返回一個握手信號,此時,當HOST收到回應的握手信號後,會將資料放在4位元的資料線上,在傳送資料的同時會跟隨著CRC校驗碼。當整個讀傳送完畢後,HOST會再次發送一個命令,通知DEVICE操作完畢,DEVICE同時會返回一個響應。
對於寫命令,首先HOST會向DEVICE發送命令,緊接著DEVICE會返回一個握手信號,此時,當HOST收到回應的握手信號後,會將資料放在4位元的資料線上,在傳送資料的同時會跟隨著CRC校驗碼。當整個寫傳送完畢後,HOST會再次發送一個命令,通知DEVICE操作完畢,DEVICE同時會返回一個響應。

WIFI 模組解析和啟動流程

對於 Wifi 模組的 Android 上層的分析,這篇文章講的非常不錯:
http://blog.csdn.net/ylyuanlu/article/details/7711433
這篇文章將下圖藍色的和綠色的部分講的非常詳細。

 

我這個板子上所採用的 WiFi 模組是 AP6354, 它是一個 Wifi / BT4.0 / FM 三合一模組。介面是 SDIO
本文主要分析 Kernel Driver 部分。所以先從 SDIO 介面的驅動來切入。

SDIO 介面驅動

SDIO 介面的 wifi,首先,它是一個 sdio 卡 設備,然後具備了 wifi 的功能,所以 SDIO 介面的 WiFi 驅動就是在 wifi 驅動 外面套上了一個 SDIO 驅動 的外殼。

SDIO 驅動部分代碼結構如下

 

drivers/mmc 下有 mmc卡、sd卡、sdio 卡驅動。

SDIO驅動仍然符合設備驅動的分層與分離思想。

設備驅動層(wifi 設備):
|

核心層(向上向下提供介面)
|
主機驅動層(實現 SDIO 驅動)

我們主要關心 core 目錄(CORE 層),其中是媒體卡的通用代碼。包括 core.c host.c stdio.c
CORE 層完成了
1. 不同協定和規範的實現
2. HOST 層的驅動提供了介面函數
3. 完成了 SDIO 匯流排註冊
4. 對應 ops 操作
5. 以及支持 mmc 的代碼

host 目錄(HOST 層)是根據不通平臺而編寫的 host 驅動。

WIFI 驅動流程分析

rockchip_wifi_init_module_rkwifi //創建了一個內核執行緒 wifi_init_thread
—wifi_init_thread //->
——dhd_module_init
———dhd_wifi_platform_register_drv //
查找設備,註冊 wifi 驅動,註冊成功調用後面的 bcmdhd_wifi_plat_dev_drv_probe
————wifi_ctrlfunc_register_drv
————|—bus_find_device //
查找 wifi 設備
————|—platform_driver_register(&wifi_platform_dev_driver) //註冊 wifi 驅動
————bcmdhd_wifi_plat_dev_drv_probe //->
—————dhd_wifi_platform_load //
兩個操作
——————wl_android_init //1. wlan 初始化
——————dhd_wifi_platform_load_sdio //2. 根據 介面類別型 usbsdiopcie 選擇不同的操作
———————dhd_bus_register // 註冊成功就調用 dhd_sdio.dhdsdio_probe
————————bcmsdh_register(&dhd_sdio)
————————|—bcmsdh_register_client_driver
————————|——sdio_register_driver(&bcmsdh_sdmmc_driver) //
註冊成功調用 bcmsdh_sdmmc_probe
————————|———bcmsdh_sdmmc_probe //->
————————|———sdioh_probe
————————dhdsdio_probe

參考文章
在全志平臺調試博通的wifi驅動(類似ap6212
wifi 詳解(三)

調試問題

調試步驟

1.確保配置無誤

 

dts檔的配置wifi部分是在net/rfkill-wlan.c中進行配置;先通過內核開機記錄確認相關配置是否有正常解析,如果解析過程出現異常,確認是所配置的gpio是否存在衝突;

2.檢查供電是否正常

確認wifi的供電控制是否受控
Echo 0 > /sys/class/rkwifi/power //wifi模組掉電
Echo 1 > /sys/class/rkwifi/power//wifi模組上電
如果執行上面命令對模組進行上下電,而 實際測量對應管腳不受控,可以通過io 命令讀取對應的寄存器,確認是否寫入,如果正確寫入但是實際測量不受控請檢查硬體部分;

3. 掃描模組初始化模組

檢查內核中是否配置
CONFIG_WIFI_LOAD_DRIVER_WHEN_KERNEL_BOOTUP=y
調測wifi時請把該巨集配置為 n
執行 echo 1 > /sys/class/rkwifi/driver 命令會調用模組的驅動的初始化操作,初始化成功後看到wlan0 節點;

如何判斷是否識別到模組
* Usb介面的模組:出現如下 log

* SDIO
介面的模組
對於sdio介面的模組,執行” echo 1 > /sys/class/rkwifi/driver”命令 ,正常情況下 sdio_clk sdio_cmd 能夠測量到相關波形,內核列印上能夠看到如下列印,如果沒有測量到波形也沒有看到如下列印,根據配置文檔檢查是否正確配置sdio;


Wifi驅動會根據掃描到的sdio模組的vid pid 進行驅動匹配,rtl的驅動會根據讀取到的vidpid進行驅動匹配;其中正基系列的模組會根據後面從data資料線上讀取到F1 function 讀取的數值進行 驅動與固件匹配(正基目前的驅動相容所有sdio介面正基模組,根據F1 function 讀取的值 匹配固件);
如果能夠掃描模組但是初始化過程看到data fifo error,檢查下 sdio介面電平是否一致;方法如下:
echo 1 > /sys/class/rkwifi/power
測量 VDDIO sdio_clk sdio_cmd sdio_data0~sdio_data3 的電壓;正常情況下 sdio_clk 0Vsdio其他五根線與vddio電壓一致;
如果電壓不一致:312x平臺確認下 sdio介面的內部上下拉是否禁掉,參看文檔RK Kernel 3.10平臺WiFi BT不工作異常排查.pdf Part C;其他平臺考慮加外部上拉(clk絕對不要加外部上拉)
同時測量執行echo 1 > /sys/class/rkwifi/driver 時 外部晶體是否有起振,如果掃描時沒有起振檢查下硬體;同時建議測量外部晶體頻偏,頻偏比較大情況下,會出現能掃描到模組但是初始化失敗;除檢查晶振外,正基系列還需要外部32k,測量32k的峰峰值(峰峰值>=0.7*VDDIO && 峰峰值 <= 1*VDDIO);【注:頻偏和峰峰值一定要測量檢查,頻偏過大峰峰值不對會影響wifi(掃描連接熱點)和藍牙(掃描連接設備))】
電壓一致情況下,晶振頻偏和32k的峰峰值沒有問題(正基系列的要考慮晶振頻偏與32k峰峰值,具體結合自己電路實際情況)但是初始化依然出問題;
考慮降低sdio_clk ,重新測試;如果降低clk可以,考慮硬體上走線;
如果降低clk依然不行,考慮使用sdio單線模式方法如下

&sdio {

        ...

        bus-width = <1>;

        ...

};

  •  
  •  
  •  
  •  
  •  

使用 sdio 單線模式。如果單線模式可以而使用4線模式不行,檢查硬體上sdio_data0~sdio_data3 四根線的線序是否弄錯;
如果降低clk,使用單線模式均不可以檢查下是否是使用最新的sdk代碼和最新的wifi驅動(ftp伺服器上有相關patch);
上述檢查均無結果,check 圖紙 是否周圍器件有貼錯器件;

4.檢查模組能否處於工作狀態

netcfg wlan0 up busybox ifconfig wlan0 up //執行完成後檢查 wlan0 是否處於up狀態;如果沒有處於up狀態;做如下檢查確認
1 確認相關固件是否存在(正基系列,通過看內核日誌可以看到),固件不存在考慮到ftp下載固件;此時如果還報其他錯誤從兩個方面排查1 上電時序,2檢查sdio部分走線;
2 嘗試使用原始最新的sdk代碼做測試;(有客戶出現過,上層做了相關修改導致wifi初始化成功,但是執行netcfg wlan0 up 報告無法識別 ioctl 命令等奇怪錯誤,原生sdk生成的sysytem.img 沒有問題)
執行iwlist wlan0 scanning ,測試掃描熱點是否正常(3368平臺下執行iwlist 命令有問題,忽略此步驟)

5. 確認Android層是否能夠打開

述檢查各個步驟可以工作,而通過上層settings介面打開失敗;以下幾個方面排查
1 dts中的wifi_type配置是否正確;cat /sys/class/rkwifi/chip 確認 下 列印的結果和你的模組是否匹配
2 確認 wpa_supplicant 相關服務是否生成,libhardware_leacy 啟動的wpa服務是否正確;
3 抓取logcat 日誌上傳readmine

吞吐率問題

  1. pcb檢查,一定要讓模組原廠檢查確認 pcb是否存在問題
  2. RF指標確認是否ok
  3. 天線是否做過匹配
  4. Sdio 介面的可以考慮 提到sdioclk 啟用sdio3.0【前提 平臺支援 sdio3.0 ,模組支援sdio3.0

其他問題

無法連接熱點

1.無法連接熱點,正基系列模組檢查確認晶振頻偏和32k峰峰值;
rtl模組考慮驅動配置是否正確,是否匹配;
2.檢查確認p2p wlan0 mac位址是否一致如果檢查是否有調用rockchip_wifi_mac_addr讀取mac地址,如果有考慮直接在該函數中return -1
3.檢查確認是否有做RF指標測試以及天線匹配測試
4.上述檢查沒有問題,做如下測試 (首先用給手機連接所測試的熱點做確認)
1 連接無加密熱點 2 連接加密熱點 測試能否連接成功,並記錄對應的logcat 日誌與內核日誌(開機到打開wifi以及連接熱點的整個過程)

softap 無法打開(正基系列的)

1.查看打開熱點時的內核日誌,確認下 下載固件是否正確 ,正基系列的模組 softap 下載的固件一般是帶ap尾碼結尾的;
2.固件下載沒有問題 ,考慮使用原始的sdk代碼做測試

P2P 問題

P2p 無法打開:確認是否有p2p節點,有p2p節點的檢查確認mac地址是否與wlan0 一樣,如果一樣按照熱點問題中的step 2 處理;
第一次開機能夠打開,重啟後無法打開:考慮檢查上電時序,目前遇到都是rtl的模組出現過,問題在於chipen 腳不受控,建議做成受控,在重啟時對chipen腳下電;可以通過如下方法實現net/rfkill-wlan.c中的rfkill_wlan_driver 中增加shutdown函數 在該函數中對chip_en 下電;
休眠喚醒出現wifi無法打開
1 對比檢查休眠喚醒前後 sdio iomux 是否發生變更
2 對比 休眠前後以及休眠中 wifi的週邊供電是否發生變更

    全站熱搜

    立你斯 發表在 痞客邦 留言(0) 人氣()