FreeBSDのieee80211comを読む


[Linuxのsoftmacとdriverのinterfaceを調査した](http://qiita.com/eggman/items/2345a240d6ffbd84e586)ので、BSDについても同様のぶぶんを調査してみました。
ieee80211comはNetBSD/OpenBSD/FreeBSDのkernelに含まれるnet80211で利用される構造体です。
ieee80211comは巨大な構造体なのですが、その中の一部にdriverとのinterface関数が含まれます。

# FreeBSDのwirelessの構成図
* net80211はMACのMLME処理（接続、切断、SCANなど)などを行うブロックでnetとdriverの間に位置する。
![freebsd_wireles.png](https://qiita-image-store.s3.amazonaws.com/0/42120/71b47b7b-9ef6-3da2-b8f0-6ffc1495dc6b.png)


#　ソースコード
* FreeBSD-current の net80211 を見ました
* https://github.com/freebsd/freebsd/tree/master/sys/net80211
* https://github.com/freebsd/freebsd/blob/master/sys/net80211/ieee80211_var.h

# ieee80211com の ドライバとのインターフェース部分
* ドライバとのinterface関数（ic_で始まる関数）について、必須と考えられるものについて調べました。
* ieee80211_var.hでstruct ieee80211comが宣言されています。
* icはiee80211のiとcomのcみたいです。
* プロトタイプがANSIじゃないのは違和感があります。

## ic_vap_create
* virtual ap の作成。
* virtual ap の意味がよく分からない。おそらくBSSの構築と対応しており、APの開始、STAでの接続などを包括的に取り扱うと思われる。

```c
	/* virtual ap create/delete */
	struct ieee80211vap*	(*ic_vap_create)(struct ieee80211com *,
				    const char [IFNAMSIZ], int,
				    enum ieee80211_opmode, int,
				    const uint8_t [IEEE80211_ADDR_LEN],
				    const uint8_t [IEEE80211_ADDR_LEN]);
```

## ic_vap_delete
* virtual ap の削除

```c
	void			(*ic_vap_delete)(struct ieee80211vap *);
```

## ic_parent
* デバイスの開始・停止をする
* ic->ic_softc->sc_running などの状態を見て開始、停止をする。

```c
	/* start/stop device */
	void			(*ic_parent)(struct ieee80211com *);
```

## ic_getradiocaps
* radio capabilitiesの取得

```c
	/* return hardware/radio capabilities */
	void			(*ic_getradiocaps)(struct ieee80211com *,
				    int, int *, struct ieee80211_channel []);
```

## ic_transmit
* データの送信
* 送信完了はドライバからieee80211_tx_complete()を呼ぶ。

```c
	/* regular transmit */
	int			(*ic_transmit)(struct ieee80211com *,
				    struct mbuf *);
```


## ic_send_mgmt
* マネージメントフレームの送信
* FullMACの場合はこのメソッドを用いて、ドライバ内でマネージメントフレームの送信と同等の処理をする。
* SoftMACでマネージメントフレームを生成する場合はic_raw_xmitを使うようです。

```c
	/* send/recv 802.11 management frame */
	int			(*ic_send_mgmt)(struct ieee80211_node *,
				     int, int);
```


## ic_raw_xmit
* 生フレームの送信

```c
	/* send raw 802.11 frame */
	int			(*ic_raw_xmit)(struct ieee80211_node *,
				    struct mbuf *,
				    const struct ieee80211_bpf_params *);
```

## ic_update_mcast
* マルチキャスト受信設定

```c
	/* handle multicast state changes */
	void			(*ic_update_mcast)(struct ieee80211com *);
```

## ic_scan_start
* スキャンの開始

```c
	/* scanning support */
	void			(*ic_scan_start)(struct ieee80211com *);
```


## ic_scan_end
* スキャンの終了

```c
	void			(*ic_scan_end)(struct ieee80211com *);
```

## ic_set_channel
* スキャンのチャンネル設定

```c
	void			(*ic_set_channel)(struct ieee80211com *);
```

## ic_ampdu_enable
* 802.11n AMPDUの有効

```c
	/* check if A-MPDU should be enabled this station+ac */
	int			(*ic_ampdu_enable)(struct ieee80211_node *,
				    struct ieee80211_tx_ampdu *);
```

## ic_update_chw
* チャンネル幅の設定

```c
	/* The channel width has changed (20<->2040) */
	void			(*ic_update_chw)(struct ieee80211com *);
```


## ic_wme.wme_update
* WMEの設定

```c
	int	(*wme_update)(struct ieee80211com *);
```

# 参考
* BSDのnet80211についてはmanと「[Porting the BSD net80211 wireless stack to the Mac OS X kernel](http://cnds.eecs.jacobs-university.de/archive/bsc-2011-pvaibhav.pdf)」を読むのが良いです。