2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

蟹さんのWiFiコード

Last updated at Posted at 2020-02-07

蟹さんの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 Software TKIP encryption/descryption routines
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用のソースの関数は以下の通りです。

if_819x_wlan.c
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)
8192cd_ecos.c
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)
wrapper.c
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だと呼ばれないようです。

毎度突っ込みどころ満載なので、気がついたところを書いておきたいと思います。

こんなコードがあります。

8192cd_rx.c
# ifdef __ECOS
        if (SUCCESS==rtl_isWlanPassthruFrame(pskb->data))
# else
        if (SUCCESS==rtl_isPassthruFrame(pskb->data))
# endif

実態はここにあります。

8192cd_util.c
# ifdef __ECOS
INT32 rtl_isWlanPassthruFrame(UINT8 *data)
# else
INT32 rtl_isPassthruFrame(UINT8 *data)
# endif
{

ECOSへの移植なのになぜ関数名を変える必要があるのでしょうか?

8192cd_psk.c
# 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は意味ありません。

8192cd_11h.c
/*
 *  Software TKIP encryption/descryption routines
 *
 *  $Id: 8192cd_tkip.c,v 1.4.4.2 2010/09/30 05:27:28 button Exp $

ファイルをコピーして作ってコメントがそのままになっています。

8192cd_hw.c
# 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の技術説明がありました。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?