日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

mac80211解析之发送速率控制

發(fā)布時間:2025/4/5 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mac80211解析之发送速率控制 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

mac80211的模塊初始化的時候,也初始化了minstrel,minstrel是調(diào)用速率控制函數(shù)模快,通過tx.c中的ieee80211_tx_h_rate_ctrl句柄填充結構體ieee80211_tx_info的速率變量ieee80211_tx_rate。

模塊初始化后調(diào)用了ieee80211_rate_control_register進行速率控制注冊,注冊了定義好的速率控制操作結構體mac80211_minstrel_ht,內(nèi)容如下:

?

static const struct rate_control_ops mac80211_minstrel_ht = {.name = "minstrel_ht",.tx_status = minstrel_ht_tx_status,.get_rate = minstrel_ht_get_rate,.rate_init = minstrel_ht_rate_init,.rate_update = minstrel_ht_rate_update,.alloc_sta = minstrel_ht_alloc_sta,.free_sta = minstrel_ht_free_sta,.alloc = minstrel_ht_alloc,.free = minstrel_ht_free, #ifdef CPTCFG_MAC80211_DEBUGFS.add_sta_debugfs = minstrel_ht_add_sta_debugfs,.remove_sta_debugfs = minstrel_ht_remove_sta_debugfs, #endif.get_expected_throughput = minstrel_ht_get_expected_throughput, };


其中minstrel_ht_get_rate函數(shù),這個函數(shù)在高速率控制函數(shù)rc80211_minstrel_ht.c文件中,內(nèi)容如下:

static void minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,struct ieee80211_tx_rate_control *txrc) {const struct mcs_group *sample_group;struct ieee80211_tx_info *info = IEEE80211_SKB_CB(txrc->skb);struct ieee80211_tx_rate *rate = &info->status.rates[0];struct minstrel_ht_sta_priv *msp = priv_sta;struct minstrel_ht_sta *mi = &msp->ht;struct minstrel_priv *mp = priv;int sample_idx;if (rate_control_send_low(sta, priv_sta, txrc))return;if (!msp->is_ht)return mac80211_minstrel.get_rate(priv, sta, &msp->legacy, txrc);info->flags |= mi->tx_flags;minstrel_ht_check_cck_shortpreamble(mp, mi, txrc->short_preamble);#ifdef CPTCFG_MAC80211_DEBUGFSif (mp->fixed_rate_idx != -1)return; #endif/* Don't use EAPOL frames for sampling on non-mrr hw */if (mp->hw->max_rates == 1 &&(info->control.flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO))sample_idx = -1;elsesample_idx = minstrel_get_sample_rate(mp, mi);mi->total_packets++;/* wraparound */if (mi->total_packets == ~0) {mi->total_packets = 0;mi->sample_packets = 0;}if (sample_idx < 0)return;sample_group = &minstrel_mcs_groups[sample_idx / MCS_GROUP_RATES];info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE;rate->count = 1;if (sample_idx / MCS_GROUP_RATES == MINSTREL_CCK_GROUP) {int idx = sample_idx % ARRAY_SIZE(mp->cck_rates);rate->idx = mp->cck_rates[idx];rate->flags = 0;return;}rate->idx = sample_idx % MCS_GROUP_RATES +(sample_group->streams - 1) * 8;rate->flags = IEEE80211_TX_RC_MCS | sample_group->flags; }


表示站點信息的結構體ieee80211_sta,定義如下:

/*** struct ieee80211_sta - station table entry** A station table entry represents a station we are possibly* communicating with. Since stations are RCU-managed in* mac80211, any ieee80211_sta pointer you get access to must* either be protected by rcu_read_lock() explicitly or implicitly,* or you must take good care to not use such a pointer after a* call to your sta_remove callback that removed it.*/ struct ieee80211_sta {u32 supp_rates[IEEE80211_NUM_BANDS];u8 addr[ETH_ALEN];u16 aid;struct ieee80211_sta_ht_cap ht_cap;struct ieee80211_sta_vht_cap vht_cap;bool wme;u8 uapsd_queues;u8 max_sp;u8 rx_nss;enum ieee80211_sta_rx_bandwidth bandwidth;enum ieee80211_smps_mode smps_mode;struct ieee80211_sta_rates __rcu *rates;bool tdls;/* must be last */u8 drv_priv[0] __aligned(sizeof(void *)); };


minstrel_ht_get_rate函數(shù)中rate_control_send_low函數(shù)是進行低速發(fā)送,內(nèi)容如下:

bool rate_control_send_low(struct ieee80211_sta *pubsta,void *priv_sta,struct ieee80211_tx_rate_control *txrc) {struct ieee80211_tx_info *info = IEEE80211_SKB_CB(txrc->skb);struct ieee80211_supported_band *sband = txrc->sband;struct sta_info *sta;int mcast_rate;bool use_basicrate = false;if (!pubsta || !priv_sta || rc_no_data_or_no_ack_use_min(txrc)) {__rate_control_send_low(txrc->hw, sband, pubsta, info,txrc->rate_idx_mask);if (!pubsta && txrc->bss) {mcast_rate = txrc->bss_conf->mcast_rate[sband->band];if (mcast_rate > 0) {info->control.rates[0].idx = mcast_rate - 1;return true;}use_basicrate = true;} else if (pubsta) {sta = container_of(pubsta, struct sta_info, sta);if (ieee80211_vif_is_mesh(&sta->sdata->vif))use_basicrate = true;}if (use_basicrate)rc_send_low_basicrate(&info->control.rates[0].idx,txrc->bss_conf->basic_rates,sband);return true;}return false; }


如果不是數(shù)據(jù)幀或沒有ACK,則調(diào)用__rate_control_send_low函數(shù),該函數(shù)內(nèi)容如下:

static void __rate_control_send_low(struct ieee80211_hw *hw,struct ieee80211_supported_band *sband,struct ieee80211_sta *sta,struct ieee80211_tx_info *info,u32 rate_mask) {int i;u32 rate_flags =ieee80211_chandef_rate_flags(&hw->conf.chandef);if ((sband->band == IEEE80211_BAND_2GHZ) &&(info->flags & IEEE80211_TX_CTL_NO_CCK_RATE))rate_flags |= IEEE80211_RATE_ERP_G;info->control.rates[0].idx = 0;for (i = 0; i < sband->n_bitrates; i++) {if (!(rate_mask & BIT(i)))continue;if ((rate_flags & sband->bitrates[i].flags) != rate_flags)continue;if (!rate_supported(sta, sband->band, i))continue;info->control.rates[0].idx = i;break;}WARN_ON_ONCE(i == sband->n_bitrates);info->control.rates[0].count =(info->flags & IEEE80211_TX_CTL_NO_ACK) ?1 : hw->max_rate_tries;info->control.skip_table = 1; }


其中用到發(fā)送tx速率控制結構體ieee80211_tx_rate_control ,定義如下:

/*** struct ieee80211_tx_rate_control - rate control information for/from RC algo*/ struct ieee80211_tx_rate_control {struct ieee80211_hw *hw;struct ieee80211_supported_band *sband;struct ieee80211_bss_conf *bss_conf;struct sk_buff *skb;struct ieee80211_tx_rate reported_rate;bool rts, short_preamble;u8 max_rate_idx;u32 rate_idx_mask;u8 *rate_idx_mcs_mask;bool bss; };


發(fā)送tx速率結構體ieee80211_tx_rate,定義如下:

?

/*** struct ieee80211_tx_rate - rate selection/status* * A value of -1 for @idx indicates an invalid rate and, if used* in an array of retry rates, that no more rates should be tried.** When used for transmit status reporting, the driver should* always report the rate along with the flags it used.** &struct ieee80211_tx_info contains an array of these structs* in the control information, and it will be filled by the rate* control algorithm according to what should be sent. For example,* if this array contains, in the format { <idx>, <count> } the* information* { 3, 2 }, { 2, 2 }, { 1, 4 }, { -1, 0 }, { -1, 0 }* then this means that the frame should be transmitted* up to twice at rate 3, up to twice at rate 2, and up to four* times at rate 1 if it doesn't get acknowledged. Say it gets* acknowledged by the peer after the fifth attempt, the status* information should then contain* { 3, 2 }, { 2, 2 }, { 1, 1 }, { -1, 0 } ...* since it was transmitted twice at rate 3, twice at rate 2* and once at rate 1 after which we received an acknowledgement.*/ struct ieee80211_tx_rate {s8 idx;u16 count:5,flags:11; } __packed;


發(fā)送速率tx的數(shù)據(jù)信息結構體ieee80211_tx_info ,定義如下:

/*** struct ieee80211_tx_info - skb transmit information** This structure is placed in skb->cb for three uses:* (1) mac80211 TX control - mac80211 tells the driver what to do* (2) driver internal use (if applicable)* (3) TX status information - driver tells mac80211 what happened** @flags: transmit info flags, defined above* @band: the band to transmit on (use for checking for races)* @hw_queue: HW queue to put the frame on, skb_get_queue_mapping() gives the AC* @ack_frame_id: internal frame ID for TX status, used internally* @control: union for control data* @status: union for status data* @driver_data: array of driver_data pointers* @ampdu_ack_len: number of acked aggregated frames.* relevant only if IEEE80211_TX_STAT_AMPDU was set.* @ampdu_len: number of aggregated frames.* relevant only if IEEE80211_TX_STAT_AMPDU was set.* @ack_signal: signal strength of the ACK frame*/ struct ieee80211_tx_info {/* common information */u32 flags;u8 band;u8 hw_queue;u16 ack_frame_id;union {struct {union {/* rate control */struct {struct ieee80211_tx_rate rates[IEEE80211_TX_MAX_RATES];s8 rts_cts_rate_idx;u8 use_rts:1;u8 use_cts_prot:1;u8 short_preamble:1;u8 skip_table:1;/* 2 bytes free */};/* 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;u32 flags;/* 4 bytes free */} control;struct {struct ieee80211_tx_rate rates[IEEE80211_TX_MAX_RATES];s32 ack_signal;u8 ampdu_ack_len;u8 ampdu_len;u8 antenna;void *status_driver_data[21 / sizeof(void *)];} status;struct {struct ieee80211_tx_rate driver_rates[IEEE80211_TX_MAX_RATES];u8 pad[4];void *rate_driver_data[IEEE80211_TX_INFO_RATE_DRIVER_DATA_SIZE / sizeof(void *)];};void *driver_data[IEEE80211_TX_INFO_DRIVER_DATA_SIZE / sizeof(void *)];}; };


使用簡單速率控制則調(diào)用minstrel_get_sample_rate函數(shù)來實現(xiàn),內(nèi)容如下:

static int minstrel_get_sample_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi) {struct minstrel_rate_stats *mr;struct minstrel_mcs_group_data *mg;unsigned int sample_dur, sample_group;int sample_idx = 0;if (mi->sample_wait > 0) {mi->sample_wait--;return -1;}if (!mi->sample_tries)return -1;sample_group = mi->sample_group;mg = &mi->groups[sample_group];sample_idx = sample_table[mg->column][mg->index];minstrel_next_sample_idx(mi);if (!(mg->supported & BIT(sample_idx)))return -1;mr = &mg->rates[sample_idx];sample_idx += sample_group * MCS_GROUP_RATES;/** Sampling might add some overhead (RTS, no aggregation)* to the frame. Hence, don't use sampling for the currently* used rates.*/if (sample_idx == mi->max_tp_rate ||sample_idx == mi->max_tp_rate2 ||sample_idx == mi->max_prob_rate)return -1;/** Do not sample if the probability is already higher than 95%* to avoid wasting airtime.*/if (mr->probability > MINSTREL_FRAC(95, 100))return -1;/** Make sure that lower rates get sampled only occasionally,* if the link is working perfectly.*/sample_dur = minstrel_get_duration(sample_idx);if (sample_dur >= minstrel_get_duration(mi->max_tp_rate2) &&(mi->max_prob_streams <minstrel_mcs_groups[sample_group].streams ||sample_dur >= minstrel_get_duration(mi->max_prob_rate))) {if (mr->sample_skipped < 20)return -1;if (mi->sample_slow++ > 2)return -1;}mi->sample_tries--;return sample_idx; }


經(jīng)過速率算法的計算后得到結果,其實最后修改速率的結果傳遞了minstrel_ht_get_rate函數(shù)最后的rate->idx和rate->flags:

rate->idx = sample_idx % MCS_GROUP_RATES +(sample_group->streams - 1) * 8; rate->flags = IEEE80211_TX_RC_MCS | sample_group->flags;


可以根據(jù)rate結構體ieee80211_tx_rate,自定義符合要求的idx和flags來實現(xiàn)速率的控制和修改。
————————————————
版權聲明:本文為CSDN博主「viewsky11」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權協(xié)議,轉(zhuǎn)載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/viewsky11/article/details/56843450

總結

以上是生活随笔為你收集整理的mac80211解析之发送速率控制的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 亚洲精品一二三四区 | 国产精品日韩无码 | 亚洲日本精品一区 | 国产在线黄色 | 99国产精品99久久久久久 | 国产女人18毛片水18精 | 天天操中文字幕 | 亚洲精品国产电影 | av鲁丝一区鲁丝二区鲁丝三区 | 毛片在线免费观看网站 | 风流少妇 | 亚洲一二区在线 | 中文字幕一区二区久久人妻 | 九九爱精品视频 | 可以看的毛片 | 91精品在线观看视频 | 亚洲免费观看在线 | 青春草视频在线免费观看 | jiizzyou欧美2 | 亚洲污网站 | 男女做爰猛烈高潮描写 | 久久精品视频3 | 成人免费看高清电影在线观看 | 激情五月色播五月 | 91禁在线看 | 日韩一级免费视频 | 欧美丰满艳妇bbwbbw | 99riav国产在线观看 | 欧美激情自拍偷拍 | 久久精品综合网 | 极品超粉嫩尤物69xx | 色婷婷aⅴ一区二区三区 | 98久久 | 无码精品a∨在线观看中文 福利片av | 又黄又湿的网站 | 91麻豆网 | 亚洲欧美偷拍一区 | 夜夜爽夜夜叫夜夜高潮漏水 | 天天色综网 | 久操伊人网 | 久草免费在线色站 | 日本一区二区不卡在线观看 | 蜜臀av性久久久久蜜臀aⅴ涩爱 | 国产精品自拍合集 | 91国产免费看 | 91sao| 91美女片黄 | 欧美xxxx黑人又粗又长密月 | 成人免费看类便视频 | 国产精品久久久久久白浆 | 成人av电影在线观看 | 尤物视频免费观看 | 国产成人精品一区二区三区免费 | 欧美大片黄色 | 婷婷av一区二区三区 | 日本午夜电影 | 日韩专区一区二区三区 | 色偷偷噜噜噜亚洲男人 | 欧美永久| 91大尺度| 色97色 | 午夜少妇影院 | 欧美人体做爰大胆视频 | aaa黄色一级片 | 成人免费观看网站 | 一本大道东京热无码 | 欧美人与性囗牲恔配 | av在线浏览| 麻豆一区二区在线观看 | 台湾性生生活1 | 亚洲码中文 | 伊人91视频 | 在线观看视频中文字幕 | 精品黑人一区二区三区观看时间 | 国产欧美日韩在线视频 | 操比网站 | 国产aⅴ一区二区三区 | 中国毛片视频 | 久久99久久99精品免视看婷婷 | 黄色长视频| 免费的黄色网址 | 九月婷婷| 97av视频在线 | 国产91传媒| 香蕉午夜视频 | 亚洲观看黄色网 | 精品人妻一区二区三区蜜桃 | 中文毛片无遮挡高潮免费 | 男朋友是消防员第一季 | 亚洲深夜福利 | 69av在线播放 | 99久久精品免费 | 97超级碰碰人妻中文字幕 | 亚洲精品h | 国产欧美精品在线 | 神秘马戏团在线观看免费高清中文 | 欧美性大战xxxxx久久久 | 国产一区二区三区免费在线观看 | 日本乱淫视频 |