【Atheros】网卡驱动速率调整算法概述
我做网卡驱动,最主要的内容就是设计和改进速率调整算法,随着802.11协议簇的新标准越来越多,速率越来越高,调制编码方式也越来越多,一般来说,速率越高越可能丢包,速率越低越稳定,这是整体状况,但不是必然的规律,所以,只用固定的速率来发送显然是不合适的,这就需要速率调整算法来自己调节,信号比较好的时候,就用高速率来发送,信道状况不好了,就换用低速率来发,atheros驱动中提供了两种可选的速率调整算法,ath9k和minstrel,其中minstrel要好一些,后面我会分别根据源码解读minstrel和ath9k这两种算法,这一篇文章,只介绍一个重要的结构体,从而引出速率调整算法的任务。
接触过网络编程的朋友都不会对socket感到陌生,在数据链路层,有一个与之对应的结构体,叫做sk_buff,一般记作skb,skb中有一个域叫做control_buffer,也就是skb->cb,是一个48字节长度的内存区域,这个区域的设计,是为了协议栈中各个层存储一些私有的数据,数据包在不同层之间传递时,比如从网络层传输到链路层之后,这个域的数据就没有用了,可以放心地被链路层写入新的数据,链路层在把这个数据包交给物理层去发送的时候,需要指定一些参数,比如这个数据包要用20MHz还是40MHz去发送,用哪个速率去发送,如果发送失败了需要重传的话,最多重传多少次等等的信息,这些信息就存储在skb->cb中,存储的格式,是按照下面这个结构体来存的:
struct ieee80211_tx_info {
/* common information */
u32 flags;
u8 band; u8 antenna_sel_tx; u16 ack_frame_id; union {
struct {
union {
/* rate control */
struct {
struct ieee80211_tx_rate rates[
IEEE80211_TX_MAX_RATES];
s8 rts_cts_rate_idx;
};
/* only needed before rate control */
unsigned long jiffies;
};
/* NB: vif can be NULL for injected frames */
struct ieee80211_vif *vif;
struct ieee80211_key_conf *hw_key;
struct ieee80211_sta *sta;
} control;
struct {
struct ieee80211_tx_rate rates[IEEE80211_TX_MAX_RATES];
u8 ampdu_ack_len;
int ack_signal;
u8 ampdu_len;
/* 15 bytes free */
} status;
struct {
struct ieee80211_tx_rate driver_rates[
IEEE80211_TX_MAX_RATES];
void *rate_driver_data[
IEEE80211_TX_INFO_RATE_DRIVER_DATA_SIZE / sizeof(void *)];
};
void *driver_data[
IEEE80211_TX_INFO_DRIVER_DATA_SIZE / sizeof(void *)];
};
};
其中,很多字段的意义不需要操心,只需要关注其中union的一部分(标红的union),这段内存区域可以通过control和status等方式访问,这个control和status就是我们关注的重点!
他们的核心又是同样的一个字段:我标红的ieee80211_tx_rate:
struct ieee80211_tx_rate {
s8 idx;
u8 count;
u8 flags;
} __packed;
这个结构体代表一个速率,看字段名就很明显了:速率号、发送次数和一个标志位(标识带宽、SGI/LGI等),网卡可能会支持多速率重传,就是先用某个速率发送,如果几次都失败了就换第二个速率发,因此,底层在发包过程中,需要一个ieee80211_tx_rate的数组,速率调整算法的任务,就是把前面结构体中的这个字段填充好交给底层:
struct ieee80211_tx_rate rates[IEEE80211_TX_MAX_RATES];
回到前面那个结构体tx_info,它拥有一个union,主要包括control和status两个部分,control部分是在发送过程中被使用的,速率调整算法会:
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
struct ieee80211_tx_rate *rates = tx_info->control.rates; rates[].idx=0; rates[].count=2; rates[].flags=zzz0;
rates[].idx=1; rates[].count=4; rates[].flags=zzz1;
rates[].idx=2; rates[].count=8; rates[].flags=zzz2;
这样,我就指定了,发送时数据包依次使用0、1、2这三个速率最多发送2、4、8次,直到发送成功为止。那么发送完成之后,我们需要知道发送到底成功了没有,最后是哪个速率发送成功的等信息。所以这个结构体又会被底层返回给我们,此时,我们可以通过status访问之前设置的这些数据,只是每一项的count域被底层重写了,之前是表示每个速率的最大发送次数是多少,现在变成了每个速率的实际发送次数是多少。
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
struct ieee80211_tx_rate *rates = tx_info->status.rates; // rates[0].count == 4
// rates[1].count == 1
// rates[2].count == 0
这就代表速率0发了4次,最终都失败了,速率1发了1次就成功了,当然速率2没有用到,发了0次。
所以速率调整算法的任务就是在发送过程中把tx_info->control.rates填充好,等发送结束后根据tx_info->status.rates来做速率的调整。
【Atheros】网卡驱动速率调整算法概述的更多相关文章
- 【Atheros】Ath9k速率调整算法源码走读
上一篇文章介绍了驱动中minstrel_ht速率调整算法,atheros中提供了可选的的两种速率调整算法,分别是ath9k和minstrel,这两个算法分别位于: drivers\net\wirele ...
- 【Atheros】minstrel速率调整算法源码走读
先说几个辅助的宏,因为内核不支持浮点运算,当然还有实现需要,minstrel对很多浮点值做了缩放: /* scaled fraction values */ #define MINSTREL_SCAL ...
- k-近邻算法概述
2.1 k-近邻算法概述 k-近邻算法采用测量不同特征值之间的距离方法进行分类. 优点:精度高.对异常值不敏感.无数据输入假定. 确定:计算复杂度高.空间复杂度高. 适用数据范围:数值型和标称型. 工 ...
- 目标反射回波检测算法及其FPGA实现 之一:算法概述
目标反射回波检测算法及其FPGA实现之一:算法概述 前段时间,接触了一个声呐目标反射回波检测的项目.声呐接收机要实现的核心功能是在含有大量噪声的反射回波中,识别出发射机发出的激励信号的回波.我会分几篇 ...
- JS数据结构与算法-概述
JS数据结构与算法概述 数据结构: 计算机存储, 组织数据的方式, 就像锅碗瓢盆 算法: 一系列解决问题的清晰指令, 就像食谱 两者关系: 程序 = 数据结构 + 算法 邂逅数据结构与算法 什么是数据 ...
- TF-IDF算法(1)—算法概述
假设现在有一篇很长的文章,要从中提取出它的关键字,完全不人工干预,那么怎么做到呢?又有如如何判断两篇文章的相似性的这类问题,这是在数据挖掘,信息检索中经常遇到的问题,然而TF-IDF算法就可以解决.这 ...
- PS 图像调整算法——黑白
这个算法是参考自 阿发伯 的博客: http://blog.csdn.net/maozefa 黑白调整 Photoshop CS的图像黑白调整功能,是通过对红.黄.绿.青.蓝和洋红等6种颜色的比例调节 ...
- PS 图像调整算法——饱和度调整
算法参考自 阿发伯 的博客. http://blog.csdn.net/maozefa 饱和度调整 图像的饱和度调整有很多方法,最简单的就是判断每个象素的R.G.B值是否大于或小于128,大于加上调整 ...
- PS 图像调整算法——亮度调整
这个算法是参考自 阿发伯 的博客,在此对 阿发伯 表示感谢, http://blog.csdn.net/maozefa 亮度调整 非线性亮度调整: 对于R,G,B三个通道,每个通道增加相同的增量. 线 ...
随机推荐
- RS-232
RS-232 锁定 同义词 rs232一般指RS-232 本词条由“科普中国”百科科学词条编写与应用工作项目 审核 . 个人计算机上的通讯接口之一,由电子工业协会(Electronic Industr ...
- cocurrent包countdownlatch 倒计时门栓
latch 英[lætʃ]美[lætʃ]n. 门闩; 弹簧锁; 锁是每个类的成员变量,它是这个类的固有属性,当然要声明为成员变量. 成员变量的初始化是通过对象的构造函数的. 锁是每个类的成员变量,它是 ...
- iOS GCD 拾遗
GCD里就有三种queue(分派队列)来处理. 1. Main queue:(主队列) 顾名思义,运行在主线程,由dispatch_get_main_queue获得.和ui相关的就要使用Main Qu ...
- windows上的docker容器内安装vim
Reading package lists... Done Building dependency tree Reading state information... Done E: Unable t ...
- 新人补钙系列教程之:AS3 位运算符
ECMAScript 整数有两种类型,即有符号整数(允许用正数和负数)和无符号整数(只允许用正数).在 ECMAScript 中,所有整数字面量默认都是有符号整数,这意味着什么呢? 有符号整数使用 3 ...
- 前端存储之Web Sql Database
前言 在上一篇前端存储之indexedDB中说到,我们项目组要搞一个前后端分离的项目,要求在前端实现存储,我们首先找到了indexedDB,而我们研究了一段时间的indexedDB后,发现它并不是很适 ...
- MySql中文乱码问题(3)
MySql的client是在dos界面上,然而dos界面默认的字符集编码方式是:GBK (1).MySql字符转换原理图 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi ...
- hibernate学习系列-----(1)开发环境搭建
其实一两个月前就在了解hibernate方面的知识了,但一直以来,都没有好好的总结,而且一直使用的是myeclipse,感觉有些傻瓜式的操作就可以搭建起hibernate的开发环境,但这样一点都不好, ...
- mysql double 乘法 缺失精度
CREATE TABLE tmp_decimal( id BIGINT auto_increment PRIMARY KEY , amount DOUBLE ); 创建测试表 插入测试数据 INSER ...
- 如何安装Android模拟器到VM虚拟机
1 像普通安装一样找到ISO镜像文件,该镜像文件名称为"android-x86-2.2-generic.iso",该镜像文件可以从谷歌官网得到 http://code.google ...