蟹さんのWiFiチップには以下のようなものがある。
製品 | Version |
---|---|
8188C | 0x1000 |
8192C | 0x1001 |
8192D | 0x1002 |
8188E | 0x1003 |
8812E | 0x1004 |
8192E | 0x1005 |
8881A | 0x1006 |
8814A | 0x1007 |
8723B | 0x1008 |
auの蟹さんは8196C+8192DRでdocomoの蟹さんは8196E+8196CEです。
これらのチップは8051が入ったチップでfirmwareのダウンロードが必要となる。
Host Controle Interface(HCI)はUSB,PCIe,SDIOがある。RL8196CなどのSOCとはPCIeで接続されている。
SOC | ARCHITECTURE |
---|---|
RTL8196C | RLX4181 |
RTL8196D | RLX5281 |
RTL8196E | RLX4181 |
RTL8197D | RLX5281 |
RTL8197F | MIPS 24K |
RTL8198 | RLX5281 |
RTL8881AM | RLX5281 |
GPLで公開されているコードはLinux専用のものとそれをECOSなどにポートしたものがある。ECOSにポートしたもののソースファイルは以下のようになっている。
path: ecos-3.0/packages/devs/eth/rltk/819x/wlan/v3_3/src/rtl8192cd
ファイル名 | ECOS | 内容 |
---|---|---|
1x_kmsm_aes.c | ○ | AES |
1x_kmsm_hmac.c | ○ | HMAC |
1x_md5c.c | MD5 | |
1x_rc4.c | RC4 | |
8188e_hw.c | ○ | RTL8188E |
8192cd_11h.c | ○ | |
8192cd_a4_sta.c | a4 sta functions | |
8192cd_aes.c | ○ | Software AES encryption/descryption routines |
8192cd_br_ext.c | ○ | bridge extention functions |
8192cd_cfg80211.c | ||
8192cd_comapi.c | API-compatible handling routines | |
8192cd_dfs.c | ○ | Handling routines for DFS (Dynamic Frequency Selection) functions |
8192cd_dfs_det.c | Handling routines for DFS DET functions | |
8192cd_dmem.c | ○ | D-MEM supporting module for RTL8190 802.11N wireless NIC on RTL865x platform |
8192cd_eeprom.c | Routines to read and write eeprom | |
8192cd_host.c | ○ | Routines to handle host CPU related functions |
8192cd_hw.c | ○ | Routines to access hardware |
8192cd_ioctl.c | ○ | io-control handling routines |
8192cd_led.c | ○ | Handling routines for LED lightening functions |
8192cd_mib.c | ○ | SNMP MIB module |
8192cd_mp.c | ○ | MP routines |
8192cd_net80211.c | API-compatible handling routines | |
8192cd_osdep.c | ○ | Routines to handle OS dependent jobs and interfaces |
8192cd_p2p.c | ○ | P2P support ; WIFI-DRIECT |
8192cd_proc.c | ○ | Handle routines for proc file system |
8192cd_psk.c | ○ | WPA PSK handling routines |
8192cd_psk_hapd.c | WPA PSK handling routines | |
8192cd_rx.c | ○ | RX handle routines |
8192cd_security.c | ○ | Handle routines to communicate with AUTH daemon (802.1x authenticator) |
8192cd_sme.c | ○ | Handling routines for 802.11 SME (Station Management Entity) |
8192cd_sta_control.c | a4 sta functions | |
8192cd_tkip.c | ○ | Software TKIP encryption/descryption routines |
8192cd_tx.c | ○ | TX handle routines |
8192cd_util.c | ○ | Utility routines |
8192d_hw.c | RTL8192D | |
8812_hw.c | RTL8812 | |
8812_vht_gen.c | ||
Beamforming.c | ||
EdcaTurboCheck.c | ||
Hal8188EPwrSeq.c | ○ | This file includes all kinds of Power Action event for RTL8188E and corresponding hardware configurtions which are released from HW SD. |
Hal8192CDMOutSrc.c | ○ | This file is for 92CE/92CU outsource dynamic mechanism for partner. |
Hal8723BPwrSeq.c | This file includes all kinds of Power Action event for RTL8723B and corresponding hardware configurtions which are released from HW SD. | |
Hal8812PwrSeq.c | This file includes all kinds of Power Action event for RTL8812 and corresponding hardware configurtions which are released from HW SD. | |
Hal8821APwrSeq.c | This file includes all kinds of Power Action event for RTL8188E and corresponding hardware configurtions which are released from HW SD. | |
HalDMOutSrc.c | ○ | This file is for common outsource dynamic mechanism for partner. |
HalPwrSeqCmd.c | ○ | Implement HW Power sequence configuration CMD handling routine for Realtek devices. |
RateAdaptive.c | ○ | Implement Rate Adaptive functions for common operations. |
romeperf.c | Performance Profiling routines | |
rtl8672_port.c | ||
rtw_android.c | ||
sha256.c | SHA-256 hash implementation and interface functions |
firmwareは./data_92d/rtl8192dfw_n.binなどになり、このファイルをbin2c.plというスクリプトでテキストにしてコード中に取り込むようです。
ドライバーでのWPAのサポート(INCLUDE_WPA_PSK)があるので、8192cd_tx.cと8192cd_rx.cでカーネルのEthernetレイヤーとつながっている。
AESの暗号化の処理は8192cd_aes.cにあるaesccmp_encrypt,aesccmp_decryptで行っている模様。
3つのバージョンがディレクトリを分けて入っていた。どれが使われているかはecos.dbで指定されている。
Linuxの高速パケット処理(FASTPATH)の対応コードもある。
通常のWIFIチップはAP,STATIONの両方のモードで使える。ドライバーは別々になっているか同一のケースがある。
WiFiのドライバーはそれ単体では完結しておらずユーザランドのプログラムとnl80211やhostapdのプロトコルで接続され、処理を行っている。
クライアント接続(STATION)での処理はプリシェアードキーの確認処理(PSK)、送信データの暗号化、受信データの復号化になる。また送受信の電波の設定も必要になる。
SSIDの一覧はビーコンパケットを集めるとできるので、ドライバーレイヤーより高い処理になるのかもしれない。
ECOSのIPスタックはFreeBSDのコードを使ってるようだ。
蟹さんはRTL8196などのLexra(MIPS 1)のプロダクトと後期にMIPS 24Kのプロダクトも出していたのでソースツリーにはMIPS用(msdk)とLexra用(rsdk)が含まれていた。
LinuxやECOS以外にも__DRAYTEK_OS__や__OSK__でもビルドされているように見えるが、何を意味しているかや実際動くのかは不明。
これ以外もWlanHALなどのディレクトリにファイルがある。
RTL8195Aの定義もある。RTL8195AはWiFi内蔵のSOCでmbedのサポートもあるARMアーキテクチャのamebaと言われるチップです。mbed環境はおそらくFreeRTOSなのではないかと思われる。
ECOS対応はドライバーコードを修正してLINUXとの差を以下のコードで調整しているようです。
ecos-3.0/packages/devs/eth/rltk/819x/wlan/v3_3/src/if_819x_wlan.c
ecos-3.0/packages/devs/eth/rltk/819x/wlan/v3_3/src/8192cd_ecos.c
ecos-3.0/packages/devs/eth/rltk/819x/wrapper/v3_0/src/*
とりあえずgithubにあったソースをビルド試してみました。ccなどはLinux用のtoolchainをFreeBSDのLinuxエミュレーションで使い、make,tclshはpkgでインストールした/usr/local/bin/にディレクトリを掘って、シンボリックリンクしてPATHを通してbashやperlのスクリプトはパスを書き換えて、あとこまごまと修正してビルド通りました。yuicompresserを使っていたのでopenjdk8をインストールしました。
msdk-elf-gcc -Wall -Wpointer-arith -Wstrict-prototypes -Wundef -Wno-write-strings -EL -mips32 -mips32r2 -msoft-float -g -Os -ffunction-sections -fdata-sections -fno-exceptions -G0 -minterlink-mips16 -D__ECOS -fno-pic -mno-abicalls -DEMBEDDED -I./ -I/usr/home/hiroki/kani/ecos_http/rtk/ecos-work/97f-8812br-16M-gw_install/include -DCOMPRESSED_KERNEL -G 0 -D__LITTLE_ENDIAN__ -DCONFIG_RTL_8197F -include /usr/home/hiroki/kani/ecos_http/rtk/ecos-work/97f-8812br-16M-gw_install/include/pkgconf/system.h -include /usr/home/hiroki/kani/ecos_http/rtk/ecos-work/97f-8812br-16M-gw_install/include/cyg/hal/bspcpu.h -DLZMA_COMPRESS -c -o LzmaDecode.o LzmaDecode.c
msdk-elf-gcc -EL -msoft-float -fno-pic -mno-abicalls -Os -fomit-frame-pointer -c vmlinux_img.c -o vmlinux_img.o
msdk-elf-objcopy --add-section .vmlinux=vmlinux_img.gz vmlinux_img.o
msdk-elf-ld -static -nostdlib -EL -G 0 -T ld.script -o memload-partial start.o hfload.o read_memory.o vsprintf.o prom_printf.o string.o ctype.o misc.o cache-mips32.o LzmaDecode.o vmlinux_img.o
msdk-elf-nm memload-partial | grep -v '\(compiled\)\|\(\.o$\)\|\( [aU] \)\|\(\.\.ng$\)\|\(LASH[RL]DI\)' | sort > system.map
cp memload-partial memload-full
msdk-elf-objcopy -Obinary memload-full nfjrom
./cvimg signature nfjrom ecos.bin 0x80500000 20000 cs6c
Generate image successfully, length=1760258, checksum=0xaac4
==============================================
Summary ==>
Image loading addr :0x80500000
Image decompress end addr :0x80469d84
Available size :0x0009627c
make[4]: Leaving directory '/usr/home/hiroki/kani/ecos_http/rtk/ecos-work/AP/rtkload'
make[3]: Leaving directory '/usr/home/hiroki/kani/ecos_http/rtk/ecos-work/AP'
./AP/tools/mgbin -c -o fw-97f-8812br-16M-gw.bin ./AP/rtkload/ecos.bin
Merge KERNEL => fw-97f-8812br-16M-gw.bin ok, size=1760274.
chmod +x trx
./trx -f 0x0002 -o bcmhead_upgrade_file.bin fw-97f-8812br-16M-gw.bin
sed 's/HDR0/RTK0/' bcmhead_upgrade_file.bin > RTK0_MAGIC_upgradefile.bin
make[2]: Leaving directory '/usr/home/hiroki/kani/ecos_http/rtk/ecos-work'
make[1]: Leaving directory '/usr/home/hiroki/kani/ecos_http/rtk/ecos-work'
上記のツリーは設定してある、8197f(mips 24k) + 8812でしかコンパイル通ららないようです。
ECOS用のソースの関数は以下の通りです。
static cyg_uint32 rltk819x_wlan_isr(cyg_vector_t vector, cyg_addrword_t data)
static void rltk819x_wlan_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
static bool rltk819x_wlan_init(struct cyg_netdevtab_entry *tab)
static bool rltk819x_wlan_wds_init(struct cyg_netdevtab_entry *tab)
static bool rltk819x_wlan_mesh_init(struct cyg_netdevtab_entry *tab)
static bool rltk819x_wlan_vap_init(struct cyg_netdevtab_entry *tab)
static bool rltk819x_wlan_pwlan_init(struct cyg_netdevtab_entry *tab)
static bool rltk819x_wlan_vxd_init(struct cyg_netdevtab_entry *tab)
static void rltk819x_wlan_start(struct eth_drv_sc *sc, unsigned char *enaddr, int flags)
static void rltk819x_wlan_stop(struct eth_drv_sc *sc)
void assign_diff_AC(unsigned char* pMib, unsigned char* pVal)
static int rltk819x_wlan_control(struct eth_drv_sc *sc, unsigned long key, void *data,
static int rltk819x_wlan_can_send(struct eth_drv_sc *sc)
static void rltk819x_wlan_send(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len,
static void rltk819x_wlan_recv(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list,
static void rltk819x_wlan_deliver(struct eth_drv_sc *sc)
static void rltk819x_wlan_poll(struct eth_drv_sc *sc)
static int rltk819x_wlan_int_vector(struct eth_drv_sc *sc)
int rltk819x_send_wlan(struct eth_drv_sc *sc, unsigned char *data, int size)
int rltk819x_send_wlan_mesh(struct eth_drv_sc *sc, unsigned char *data, int size)
void set_ecos_pr_fun(pr_fun *pr)
void *rltk_wlan_init(int wlan_idx)
void *rltk_wlan_vxd_init(int wlan_idx)
void *rltk_wlan_vap_init(int wlan_idx, int vap_idx)
void interrupt_dsr(struct net_device *dev)
int can_xmit(struct net_device *dev)
struct sk_buff *copy_skb(struct sk_buff *skb)
struct net_device *rltk_get_wds_net_device(int wlan_idx, int wds_num)
struct net_device *rltk_get_mesh_net_device(int wlan_idx, int mesh_num)
void passthru_wlan_show()
void passthru_wlan_write()
struct net_device *rltk_get_pwlan_net_device(int dev_num, int device_num)
void rtl8192cd_wlan_cmd_dispatch(char *name, int argc, char *argv[])
int encode_ssid_str(const char *source,char *dest )
void silence_stainfo(void)
static void init_local_pool(void)
void *alloc_local(int size)
int mac_hash(unsigned char *da)
struct net_device * getDevByMac(unsigned char * mac)
void dump_fst_fdb()
void addfdbentry(unsigned char *mac,struct net_device *dev)
int rtl_CheckPassthruFrame(unsigned char* data)
static inline struct ethhdr *eth_hdr(const struct mbuf *m)
void enable_dnstrap(int en)
int get_interface_ip(char *interface_name)
inline int br_dns_packet_recap(struct mbuf *m)
inline int br_dns_filter_enter(struct mbuf *m)
int is_dns_packet(struct sk_buff *skb)
int is_dns_packet(struct sk_buff *skb)
void wrapper_up(struct sk_buff *skb)
void wrapper_que_up(struct sk_buff *skb, struct net_device *root_dev)
void wrapper_que_retrieve(struct net_device *dev)
int wrapper_que_len(struct net_device *dev)
void wrapper_free_tx_queue(struct net_device *dev)
void wrapper_deliver(Rltk819x_t *info, struct eth_drv_sg *sg_list, int sg_len)
struct net_device *alloc_etherdev(int sizeof_priv)
void wrapper_init(void)
void wrapper_binding(Rltk819x_t *info, void *dev)
int wrapper_isr(Rltk819x_t *info)
void wrapper_dsr(Rltk819x_t *info)
void wrapper_free_tx(struct net_device *dev, unsigned long key)
void wrapper_que_free_tx_pkt(struct net_device *root_dev, struct sk_buff *skb)
void wrapper_start(Rltk819x_t *info)
void wrapper_stop(Rltk819x_t *info)
int wrapper_can_send(Rltk819x_t *info)
void wrapper_tx(Rltk819x_t *info, struct eth_drv_sg *sg_list, int sg_len,
static struct net_device *wrapper_find_netdev(char *name)
struct net_device_stats *wrapper_get_stats(char *ifname)
void shutdown_netdev(void)
int rtk_atoi(char *s)
void suspend_check_cmd_dispatch(int argc, char *argv[])
static void suspend_check_timer_fn(void *arg)
void suspend_check_init(void)
int rtl_isWanDevDecideByIfp(struct ifnet *ifp)
struct net_device * rtl_getDevByIfp(struct ifnet *ifp)
struct net_device * rtl_getDevByName(char *name)
rltk819x_wlan_init() - if_819x_wlan.c ->
rltk_wlan_init() - 8192cd_ecos.c ->
rtl8192cd_init_one() - 8192cd_osdep.c
rltk819x_wlan_start() - if_819x_wlan.c ->
wrapper_start() - wrapper.c ->
(((struct net_device *)info->dev)->open)((struct net_device *)info->dev);
rtl8192cd_open() - 8192cd_osdep.c ->
rtl8192cd_init_hw_PCI() - 8192cd_hw.c ->
Load_92D_Firmware() - 8192d_hw.c
設定はrltk819x_wlan_control()の中では構造体などに値を設定しているだけのように見えます。
rltk819x_wlan_control() - if_819x_wlan.c
送信はwrapper_tx()でskbに変換しているようです。
rltk819x_wlan_send() - if_819x_wlan.c ->
wrapper_tx() - wrapper.c ->
(dev->hard_start_xmit)(skb, dev);
rtl8192cd_start_xmit() - 8192cd_tx.c ->
__rtl8192cd_start_xmit() - 8192cd_tx.c
受信は割り込みで処理されて一旦eCosに渡ってから、rltk819x_wlan_recv()が呼ばれるようです。wrapper_deliver()でskbからmbufに変換しているようです。RTLPKG_DEVS_ETH_RLTK_819X_RX_ZERO_COPYが定義されているとsbkをそのままmbufにしますが、定義されてない場合はmemcpy()するようです。
rltk819x_wlan_recv() - if_819x_wlan.c ->
wrapper_deliver() - wrapper.c ->
割り込み処理は以下のようになっています。
rltk819x_wlan_isr() - if_819x_wlan.c ->
wrapper_isr() - wrapper.c ->
(((struct net_device *)info->dev)->isr)((struct net_device *)info->dev)
rtl8192cd_interrupt() - rtl8192cd/8192cd_osdep.c ->
__rtl8192cd_interrupt() - rtl8192cd/8192cd_osdep.c ->
rtl8192cd_rx_isr() - rtl8192cd/8192cd_rx.c
割り込み処理は二つに分かれていてisrルーチンがCYG_ISR_CALL_DSRを返すと、dsrルーチンが後で呼ばれ、CYG_ISR_HANDLEDだと呼ばれないようです。
毎度突っ込みどころ満載なので、気がついたところを書いておきたいと思います。
こんなコードがあります。
# ifdef __ECOS
if (SUCCESS==rtl_isWlanPassthruFrame(pskb->data))
# else
if (SUCCESS==rtl_isPassthruFrame(pskb->data))
# endif
実態はここにあります。
# ifdef __ECOS
INT32 rtl_isWlanPassthruFrame(UINT8 *data)
# else
INT32 rtl_isPassthruFrame(UINT8 *data)
# endif
{
ECOSへの移植なのになぜ関数名を変える必要があるのでしょうか?
# ifdef __ECOS
int ecos_send_wlan(struct net_device *dev, unsigned char *data, int size)
{
省略
}
# ifdef __ECOS
int ecos_send_wlan_mesh(struct net_device *dev, unsigned char *data, int size)
{
省略
}
# endif
# endif
二つ目のifdefは意味ありません。
/*
* Software TKIP encryption/descryption routines
*
* $Id: 8192cd_tkip.c,v 1.4.4.2 2010/09/30 05:27:28 button Exp $
ファイルをコピーして作ってコメントがそのままになっています。
# ifdef CONFIG_PHY_WLAN_EAT_40MHZ
ClkSel = XTAL_CLK_SEL_40M;
# else
# ifdef CONFIG_WLAN_HAL_8881A
if(GET_CHIP_VER(priv) == VERSION_8881A)
ClkSel = XTAL_CLK_SEL_40M;
else
# endif
ClkSel = XTAL_CLK_SEL_25M;
# endif //CONFIG_PHY_EAT_40MHZ
コメントのマクロが間違っています。どっちもあるのでどっちが正しいかも分かりません。
# ifdef INCLUDE_WPA_PSK
INCLUDEはなんか違うような気がします。マクロは良く分からない略称がいろいろあります。
# if 0
487行もあります。
8192cd_psk_hapd.cは8192cd_psk.cがあまりにぐちゃぐちゃになったので、もともとのファイルを別に作ったのではないかと思われます。
結構ぐちゃぐちゃです。DKM
FreeBSDのこれらのデバイスのサポートコードはdev/rtwnになります。
参考
いろいろよいWIFIの技術説明がありました。