madwifi驱动阅读
该程序有好几个目录
ath: 物理网卡的控制函数,例如发送等
ath_rate: 速率控制的相关代码
hal: 硬件抽象层的相关库,不公开源代码
net80211: 802.11相关的代码,与物理层独立,完成诸如scan、wap、VAP等功能。
Ieee80211_wireless.c
static const iw_handler ieee80211_handlers[] = {
(iw_handler) ieee80211_ioctl_siwrate, /* SIOCSIWRATE */
(iw_handler) ieee80211_ioctl_giwrate, /* SIOCGIWRATE */
模块的入口函数:if_ath_pci.c /module_init(init_ath_pci);
static int __init
init_ath_pci(void)
{
printk(KERN_INFO “%s: %s\n”, dev_info, version);
if (pci_register_driver(&ath_pci_drv_id) < 0) {
printk(“ath_pci: No devices found, driver not installed.\n”);
return (-ENODEV);
}
#ifdef CONFIG_SYSCTL
ath_sysctl_register();
#endif
return (0);
}
module_init(init_ath_pci);
初始化会调用 ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)函数,进一步加载ath无线网卡:
if (ath_attach(vdevice, dev) != 0)
goto bad4;
If_ath.c (ath)文件实现ath_attach函数,该函数的实现非常复杂,关键的代码如下:
ath_attach(u_int16_t devid, struct net_device *dev)
{
……………
ah = _ath_hal_attach(devid, sc, NULL, (void *) dev->mem_start, &status);
可能是探测与硬件相关的东西,不能显示更进一步的代码:
………………..
dev->hard_start_xmit = ath_hardstart;
dev->do_ioctl = ath_ioctl;
ieee80211_ifattach(ic); 该函数在Ieee80211.c文件中实现
ic->ic_vap_create = ath_vap_create;
ic->ic_vap_delete = ath_vap_delete;
重点需要掌握ath与80211目录的关联,ath_vap_create是做什么的。
static struct ieee80211vap *
ath_vap_create(struct ieee80211com *ic, const char *name, int unit,
int opmode, int flags, struct net_device *mdev)
{
……………………
ieee80211_vap_setup(ic, dev, name, unit, opmode, flags);
………….
(void) ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status);
Ieee80211_wireless.c
ieee80211_vap_setup(struct ieee80211com *ic, struct net_device *dev, const char *name, int unit, int opmode, int flags)->
调用下面的函数,实现ioctl函数,
ieee80211_ioctl_vattach(struct ieee80211vap *vap)
{
struct net_device *dev = vap->iv_dev;
dev->do_ioctl = ieee80211_ioctl;
这里就存在两次对dev->do_ioctl赋值的情况,一次是在ath_attach函数中,一次在
ieee80211_ioctl_vattach函数中,怀疑第二次是不是就将第一次的覆盖了。
ieee80211_ioctl函数就有很多的子函数用以实现不同的功能,以设置和获取速率为例:
ieee80211_ioctl_siwrate(struct net_device *dev, struct iw_request_info *info, struct iw_param *rrq, char *extra)
获取速率的ioctl函数的实现
ieee80211_ioctl_giwrate(struct net_device *dev, struct iw_request_info *info, struct iw_param *rrq, char *extra)
{
struct ieee80211vap *vap = dev->priv;
struct ifmediareq imr;
int rate;
memset(&imr, 0, sizeof(imr));
vap->iv_media.ifm_status(vap->iv_dev, &imr);
rrq->fixed = IFM_SUBTYPE(vap->iv_media.ifm_media) != IFM_AUTO;
/* media status will have the current xmit rate if available */
rate = ieee80211_media2rate(imr.ifm_active); //这个函数的意思是将速率编号转换为实际的速率
if (rate == -1) /* IFM_AUTO */
rate = 0; //如果是auto,那么就返回0
rrq->value = 1000000 * (rate / 2);
return 0;
}
有关于速率的东西都在ifm_active变量中,这个变量包含了很多的属性,包括速率、模式等等,在if_media.h文件中
#define IFM_IEEE80211_DS1 5 /* Direct Sequence 1Mbps */
#define IFM_IEEE80211_DS2 6 /* Direct Sequence 2Mbps */
#define IFM_IEEE80211_DS5 7 /* Direct Sequence 5.5Mbps */
#define IFM_IEEE80211_DS11 8 /* Direct Sequence 11Mbps */
函数ieee80211com_media_status实现获得ifm_active变量
ieee80211com_media_status(struct net_device *dev, struct ifmediareq *imr)
{
struct ieee80211com *ic = dev->priv; /*XXX*/
imr->ifm_status = IFM_AVALID;
if (!TAILQ_EMPTY(&ic->ic_vaps))
imr->ifm_status |= IFM_ACTIVE;
imr->ifm_active = media_status(ic->ic_opmode, ic->ic_curchan);
}
通过上述分析,发现ifm_active变量的获得实际上是ieee80211com *ic结构体获得的。
数据发送过程分析:
static int
ath_hardstart(struct sk_buff *skb, struct net_device *dev)-> ath_tx_start(struct net_device *dev, struct ieee80211_node *ni, struct ath_buf *bf, struct sk_buff *skb, int nextfraglen)
{
……….
ath_rate_findrate(sc, an, shortPreamble, skb->len, &rix, &try0, &txrate); //有关速率控制的东西
………
ath_hal_setuptxdesc(ah, ds
, pktlen /* packet length */
, hdrlen /* header length */
, atype /* Atheros packet type */
, MIN(ni->ni_txpower, 60)/* txpower */
, txrate, try0 /* series 0 rate/tries */
, keyix /* key cache index */
, antenna /* antenna mode */
, flags /* flags */
, ctsrate /* rts/cts rate */
, ctsduration /* rts/cts duration */
, icvlen /* comp icv len */
, ivlen /* comp iv len */
, comp /* comp scheme */
); //与硬件相关的函数
if (try0 != ATH_TXMAXTRY)
ath_rate_setupxtxdesc(sc, an, ds, shortPreamble, skb->len, rix); //速率控制的描述符
}
» 本文来自:橙叶WLAN » 《atheros madwifi驱动分析》
No comments:
Post a Comment