Linuxの Broadcom BCM43430 デバイスドライバのソースコード読んでみました。
準備
- https://wireless.wiki.kernel.org/en/users/drivers/brcm80211 にある内容を読んでみました。
- BroadcomのWi-FIドライバはsoftmac用のbrcmsmac と fullmac用のbrcmfmacの2種類があります。
- BCM43430はbrcmfmacなのでFullMACなドライバです。
- BCM43430は Linux 4.1 以降でサポートされています。
- SDIOの場合NVRAMファイルと呼ばれるファイルをロードする必要があります。
- fullmacドライバの機能
Integrated with cfg80211
Most of Mac functionality is performed on chip
support for SDIO, USB and PCIe
SoftAP
P2P
TDLS
- BCM43430を追加した時のcommitを見ると、以前のチップと同じ様に動くので、BCM4343特有の変更はあまりないようです。
ソースコード
SDIOの初期化からファームウェアダウンロードまで
probeからファームウェアのダウンロードまでを追ってみた。
下記のSDIOの情報を登録する、
drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
/* devices we support, null terminated */
static const struct sdio_device_id brcmf_sdmmc_ids[] = {
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43143),
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43241),
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4329),
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4330),
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4334),
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43340),
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43341),
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43362),
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4335_4339),
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4339),
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43430),
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4345),
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4354),
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4356),
{ /* end: all zeroes */ }
};
MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids);
drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
static struct sdio_driver brcmf_sdmmc_driver = {
.probe = brcmf_ops_sdio_probe,
.remove = brcmf_ops_sdio_remove,
.name = KBUILD_MODNAME,
.id_table = brcmf_sdmmc_ids,
.drv = {
.owner = THIS_MODULE,
#ifdef CONFIG_PM_SLEEP
.pm = &brcmf_sdio_pm_ops,
#endif /* CONFIG_PM_SLEEP */
},
};
- kernelのSDホストドライバで、SDIOと判断し、brcmf_sdmmc_idsのIDと一致するIDを持つSDIOでバイスであるなら、brcmf_ops_sdio_probe()を実行する。
- brcmf_ops_sdio_probe()からbrcmf_sdiod_probe()を呼ぶ。
- brcmf_sdiod_probe()でSDIOブロックサイズの設定、SDIOファンクション0の設定をして、brcmf_sdio_probe()を呼ぶ
- brcmf_sdio_probe()から、brcmf_fw_get_firmwares()を呼び、そのコールバックbrcmf_sdio_firmware_callback()の中でファームウェアをダウンロードする。