[RK3399] SDIO 接口 Wifi 驅動流程分析 (AP6354)

https://blog.csdn.net/mmmccc000/article/details/73322637

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,提供無線接入服務,允許其它無線設備接入,提供數據訪問,一般的無線路由/網橋工作在該模式下。AP和AP之間允許相互連接。 
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 記憶卡。

SDIO(Secure 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 具有傳輸數據快,兼容SD、MMC接口等特點。

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

SDIO 總線

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

SDIO 命令

SDIO總線上都是HOST端發起請求,然後DEVICE端迴應請求。 
SDIO 命令由6個字節組成。

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

SDIO的每次操作都是由HOST在CMD線上發起一個CMD,對於有的CMD,DEVICE需要返回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. 根據 接口類型 usb、sdio、pcie 選擇不同的操作 
———————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的驅動會根據讀取到的vid,pid進行驅動匹配;其中正基系列的模塊會根據後面從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 爲 0V,sdio其他五根線與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單線模式方法如下


 
  1. &sdio {

  2. ...

  3. bus-width = <1>;

  4. ...

  5. };

  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

使用 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 接口的可以考慮 提到sdio的clk 啓用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的外圍供電是否發生變更

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章