Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 12 Sep 2013 01:29:23 +0800
From:      Chenchong Qin <qinchenchong@gmail.com>
To:        Adrian Chadd <adrian@freebsd.org>
Cc:        "freebsd-wireless@freebsd.org" <freebsd-wireless@freebsd.org>
Subject:   Re: Chenchong's work on net80211_ratectl
Message-ID:  <CAFnsE3e1r6Ah5SSrqnrxoqXMRm3yCaUxCjSD90epWQJEZU-pzw@mail.gmail.com>
In-Reply-To: <CAFnsE3fvpjCXEC1gN46VXfPdeXG5RSVzNiJkZJiQ6xSYQFb89g@mail.gmail.com>
References:  <CAFnsE3dYdPf5yGTFH683Q1Zh0mc-g%2B_YtCTraNNt28z2vBoSKw@mail.gmail.com> <CAJ-Vmom4sY7jcNwWmJkrDwfWjsok2fk8UEwTi5A=egj1JyerLw@mail.gmail.com> <CAFnsE3cyg=msBfQqqKUMmLABSL=j24VoMBwbBjxQ6b7Dyy7Mqg@mail.gmail.com> <CAJ-Vmo=k8NddAYyAJCkx4eOaA_8XsSxg6uKrdddx%2BgmeT%2BX9KA@mail.gmail.com> <CAFnsE3eaOyRcO3LXSi3L=jbzpyMv5Nt_jRGKt_mmA0WV-EV5vA@mail.gmail.com> <CAJ-VmokdxLhK5x6kO=jJzk-dv61EDK-ZgmndOimoyWWf76HiZA@mail.gmail.com> <CAJ-VmonMjR5iVTMVN9532d%2BPqOXWNUoZvxPtQir5h=yGxU-XdQ@mail.gmail.com> <CAFnsE3d9nG-X2b=z1srKfTtpxC3w5L%2B6Hg3TbOnAQrJN%2Bt19GA@mail.gmail.com> <CAJ-VmokF6hPtg9FoEdeJXLLaZRNhzd=nr_o6nHE%2BjYiQKTg3zQ@mail.gmail.com> <CAFnsE3eMwX-GiRzJt8jk4r9mxwSAQkcrDwk%2BnWVG7q6dabeA3A@mail.gmail.com> <CAJ-Vmo=mzvS0UBC7fGx2t501%2Bfioi4DJcw8qobOpbYOUiraqGg@mail.gmail.com> <CAFnsE3df=1WEuLZh5355v_K2eBgcuBbpoza74Y-5vvNupBz22A@mail.gmail.com> <CAJ-VmokyXwkKLdsJw74bux7G5EJSRvFhugTcLR9BgXfw4ysYRg@mail.gmail.com> <CAJ-VmokU=ZXysjZfAJ-REZL7kwg-_Z-LeAKca7AefONW_O1E5A@mail.gmail.com> <CAFnsE3cS_2Ad1geQQ0UB4doEgqVfhNBMi6j4fCRpFgQqcu2kJw@mail.gmail.com> <CAFnsE3eMrwpo=hcFb9XfpLL53Ppso%2B%2BXTBfpieP8FGejAKW1_w@mail.gmail.com> <CAJ-Vmo=s=0u7VO00vgzxmR7bE4aTtMrshZ3j5F312dya284V1g@mail.gmail.com> <CAFnsE3c%2BOg_2hVXO3zU7gmY4xFQjnxbv=ehJm=pbbpLJcgwJrQ@mail.gmail.com> <CAJ-Vmo=D3BNhhSn9D3x6hBry=fDecOd7BwttQ5Yw2iUKGDBN3w@mail.gmail.com> <CAFnsE3dw5bOyVRqMb9K3ME%2BHoDL61-e_XNJjjt_nRTaY=4dnhw@mail.gmail.com> <CAJ-Vmo=0tkTKQnOjrmYKqWqC%2B_nnFLqimdp06STETxLsFgxKxQ@mail.gmail.com> <CAFnsE3dm27483GVp4PRiwk=sxagT7NXQz4fmyOpth2zpCM2MwQ@mail.gmail.com> <CAFnsE3fvpjCXEC1gN46VXfPdeXG5RSVzNiJkZJiQ6xSYQFb89g@mail.gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help

[-- Attachment #1 --]
Hi!

I've added some aggregation support here!

At first I intend to pass subframe informations(nframes, per-subframe
length etc.)
to the ratectl api. But it seems to be a paradox that rate lookup must be
performed
before the ampdu is formed (aggregation limit based on the rate control
decision
is need) and subframe informations can be obtain only after the ampdu is
formed.
So, I add a new ieee80211_rc_info flag to ieee80211_ratectl to let it
distinguish
aggregation and non-aggregation scenarios. If rate lookup is called in an
aggregation
scenario, this flag is set. Then, ratectl algo knows that it's now finding
rates for an
ampdu and the framelen which records len of the first frame can be ignored.
When
it comes to complete period, tx status that shows number of subframes been
sent
and number of subframes been successfully received is passed to the ratectl
api.

I also get a question here - whether one tx that doesn't perform rate
lookup will call
the complete procedure?

Thanks!

Chenchong


On Sun, Sep 8, 2013 at 11:18 PM, Chenchong Qin <qinchenchong@gmail.com>wrote:

> Hi!
>
> I've added the common ratectl state as an mbuf tag!
>
> After days of frustration (compile errors, boot failed, kernel panics,
> suddenly kernel freezing...), it seems that ath now can use 11n-aware
> net80211 ratectl api to do rate control. Attachment[0] is the diff of
> modifications to dev/ath. Changes to net80211 is minor this time. Just add
> some debug msgs to it. Please reference my gsoc svn repo<https://svnweb.freebsd.org/socsvn/soc2013/ccqin/head/>;
> .
>
> It's worth mentioning that sometimes the kernel will "freezing" (it looks
> like all things stop working, screen is freezing, keyboard and mouse are
> not responding) after wireless stuff start working for a while. At first, I
> consider it caused by my modification to ath. But this strange thing can
> also happen in a head kernel (r255382). Attachment[1] is some useful
> messages just before it happens. By the way, I use a AR9227 device.
>
> And, I found that, for aggregation scenario, ath gathers tx information
> and update the ratectl states. So, what we can do to net80211 to let it
> support aggregation?
>
> Thanks!
>
> Chenchong
>
>
> On Tue, Sep 3, 2013 at 9:29 AM, Chenchong Qin <qinchenchong@gmail.com>wrote:
>
>> OK!
>>
>> Thanks! :-)
>>
>> Chenchong
>>
>>
>> On Tue, Sep 3, 2013 at 1:56 AM, Adrian Chadd <adrian@freebsd.org> wrote:
>>
>>> Hi!
>>>
>>> You can declare an mbuf tag and use that. Look at M_TXCB in net80211 and
>>> how mbuf tags are added.
>>>
>>> I've long thought about adding a net80211 mbuf tag to represent -all- of
>>> the tx related state - TX callback, rate control, rate completion,
>>> aggregation state, retry count, etc. That way all the drivers can use it.
>>>
>>>
>>>
>>> -adrian
>>>
>>>
>>
>

[-- Attachment #2 --]
Index: if_ath_tx_ht.c
===================================================================
--- if_ath_tx_ht.c	(revision 254826)
+++ if_ath_tx_ht.c	(working copy)
@@ -64,6 +64,8 @@
 
 #include <net80211/ieee80211_var.h>
 #include <net80211/ieee80211_regdomain.h>
+
+#include <net80211/ieee80211_ratectl.h>
 #ifdef IEEE80211_SUPPORT_SUPERG
 #include <net80211/ieee80211_superg.h>
 #endif
@@ -221,13 +223,47 @@
 void
 ath_tx_rate_fill_rcflags(struct ath_softc *sc, struct ath_buf *bf)
 {
-	struct ieee80211_node *ni = bf->bf_node;
-	struct ieee80211com *ic = ni->ni_ic;
+	// struct ieee80211_node *ni = bf->bf_node;
+	// struct ieee80211com *ic = ni->ni_ic;
 	const HAL_RATE_TABLE *rt = sc->sc_currates;
-	struct ath_rc_series *rc = bf->bf_state.bfs_rc;
+	struct ath_rc_series *ath_rc = bf->bf_state.bfs_rc;
+	struct ieee80211_rc_info *rc_info = NULL;
+	struct ieee80211_rc_series *rc = NULL;
+	struct m_tag *mtag;
 	uint8_t rate;
 	int i;
 
+	mtag = m_tag_locate(bf->bf_m, MTAG_ABI_NET80211, 
+			NET80211_TAG_RATECTL, NULL);
+	if (NULL == mtag)
+		return;
+
+	rc_info = (struct ieee80211_rc_info*)(mtag + 1);
+	rc = rc_info->iri_rc;
+
+	for (i = 0; i < IEEE80211_RATECTL_NUM; i++) {
+		if (rc[i].tries == 0)
+			continue;
+
+		rate = rt->info[rc[i].rix].rateCode;
+		if (rc[i].flags & IEEE80211_RATECTL_FLAG_SP)
+			rate |= rt->info[rc[i].rix].shortPreamble;
+
+		rc[i].ratecode = rate;
+
+		ath_rc[i].rix = rc[i].rix;
+		ath_rc[i].tries = rc[i].tries;
+		ath_rc[i].flags = rc[i].flags;
+		ath_rc[i].ratecode = rc[i].ratecode;
+		ath_rc[i].tx_power_cap = rc[i].tx_power_cap;
+		ath_rc[i].max4msframelen = rc[i].max4msframelen;
+		
+		DPRINTF(sc, ATH_DEBUG_SW_TX_AGGR,
+		    "%s: i=%d, rate=0x%x, flags=0x%x, max4ms=%d\n",
+		    __func__, i, rate, rc[i].flags, rc[i].max4msframelen);
+	}
+
+#if 0
 	for (i = 0; i < ATH_RC_NUM; i++) {
 		rc[i].flags = 0;
 		if (rc[i].tries == 0)
@@ -325,6 +361,7 @@
 		    "%s: i=%d, rate=0x%x, flags=0x%x, max4ms=%d\n",
 		    __func__, i, rate, rc[i].flags, rc[i].max4msframelen);
 	}
+#endif
 }
 
 /*
Index: if_ath_tx.c
===================================================================
--- if_ath_tx.c	(revision 254826)
+++ if_ath_tx.c	(working copy)
@@ -72,6 +72,8 @@
 
 #include <net80211/ieee80211_var.h>
 #include <net80211/ieee80211_regdomain.h>
+
+#include <net80211/ieee80211_ratectl.h>
 #ifdef IEEE80211_SUPPORT_SUPERG
 #include <net80211/ieee80211_superg.h>
 #endif
@@ -1387,6 +1389,10 @@
 static void
 ath_tx_do_ratelookup(struct ath_softc *sc, struct ath_buf *bf)
 {
+	struct ieee80211_node *ni = bf->bf_node;
+	struct ieee80211_rc_info *rc_info = NULL;
+	struct ieee80211_rc_series *rc = NULL;
+	struct m_tag *mtag;
 	uint8_t rate, rix;
 	int try0;
 
@@ -1395,7 +1401,7 @@
 
 	/* Get rid of any previous state */
 	bzero(bf->bf_state.bfs_rc, sizeof(bf->bf_state.bfs_rc));
-
+#if 0
 	ATH_NODE_LOCK(ATH_NODE(bf->bf_node));
 	ath_rate_findrate(sc, ATH_NODE(bf->bf_node), bf->bf_state.bfs_shpream,
 	    bf->bf_state.bfs_pktlen, &rix, &try0, &rate);
@@ -1409,7 +1415,44 @@
 		ath_rate_getxtxrates(sc, ATH_NODE(bf->bf_node), rix,
 		    bf->bf_state.bfs_rc);
 	ATH_NODE_UNLOCK(ATH_NODE(bf->bf_node));
+#endif
 
+	/* net80211 ratectl */
+	mtag = m_tag_locate(bf->bf_m, MTAG_ABI_NET80211, 
+			NET80211_TAG_RATECTL, NULL);
+again:	
+	if (NULL == mtag) {
+		mtag = m_tag_alloc(MTAG_ABI_NET80211, NET80211_TAG_RATECTL,
+				sizeof(struct ieee80211_rc_info), M_NOWAIT);
+		if (NULL == mtag) {
+			IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni,
+					"%s: can't alloc mbuf tag for ratectl.\n", __func__);
+			goto again;
+		}
+	} else
+		IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni,
+				"%s: nani? find mbuf tag for ratectl directly.\n", __func__);
+	
+	rc_info = (struct ieee80211_rc_info*)(mtag + 1);
+	rc = rc_info->iri_rc;
+	
+	bzero(rc_info, sizeof(rc_info));
+
+	if (bf->bf_state.bfs_shpream)
+		rc_info->iri_flags |= IEEE80211_RATECTL_INFO_SP;
+	if (bf->bf_state.bfs_aggr)
+		rc_info->iri_flags |= IEEE80211_RATECTL_INFO_AGGR;
+
+	rc_info->iri_framelen = bf->bf_state.bfs_pktlen;
+
+	ieee80211_ratectl_rates(ni, rc_info);
+
+	m_tag_prepend(bf->bf_m, mtag);
+
+	rix = rc[0].rix;
+	try0 = rc[0].tries;
+	rate = ni->ni_txrate;
+
 	sc->sc_txrix = rix;	/* for LED blinking */
 	sc->sc_lastdatarix = rix;	/* for fast frames */
 	bf->bf_state.bfs_try0 = try0;
@@ -1530,7 +1573,8 @@
 	 * frames that must go out - eg management/raw frames.
 	 */
 	bf->bf_state.bfs_txflags |= HAL_TXDESC_CLRDMASK;
-
+	
+	bf->bf_state.bfs_aggr = 0;
 	/* Setup the descriptor before handoff */
 	ath_tx_do_ratelookup(sc, bf);
 	ath_tx_calc_duration(sc, bf);
@@ -4058,6 +4102,8 @@
 	int tid = bf->bf_state.bfs_tid;
 	struct ath_tid *atid = &an->an_tid[tid];
 	struct ath_tx_status *ts = &bf->bf_status.ds_txstat;
+	struct ieee80211_rc_info *rc_info = NULL;
+	struct m_tag *mtag;
 
 	/* The TID state is protected behind the TXQ lock */
 	ATH_TX_LOCK(sc);
@@ -4108,9 +4154,35 @@
 	 * during a hw queue drain and the frame wanted an ACK.
 	 */
 	if (fail == 0 && ((bf->bf_state.bfs_txflags & HAL_TXDESC_NOACK) == 0))
+	{
+#if 0
 		ath_tx_update_ratectrl(sc, ni, bf->bf_state.bfs_rc,
 		    ts, bf->bf_state.bfs_pktlen,
 		    1, (ts->ts_status == 0) ? 0 : 1);
+#endif
+	
+		/* net80211 ratectl */
+	    mtag = m_tag_locate(bf->bf_m, MTAG_ABI_NET80211, 
+			            NET80211_TAG_RATECTL, NULL);
+		if (NULL == mtag) {
+			IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni,
+					"%s: no ratectl mbuf tag found.\n", __func__);
+			struct ieee80211_rc_info tmp_rc_info;
+			rc_info = &tmp_rc_info;
+			bzero(rc_info, sizeof(rc_info));
+		} else {
+			IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni,
+					"%s: found ratectl mbuf tag.\n", __func__);
+			rc_info = (struct ieee80211_rc_info*)(mtag + 1);
+		}
+		rc_info->iri_flags &= ~IEEE80211_RATECTL_INFO_AGGR;	
+		ieee80211_ratectl_rc_info_set(rc_info,
+				1, (ts->ts_status == 0 ? 0 : 1), 
+				bf->bf_state.bfs_pktlen,
+				ts->ts_shortretry, ts->ts_longretry,
+				ts->ts_finaltsi, ts->ts_rate);
+		ieee80211_ratectl_tx_complete(ni->ni_vap, ni, rc_info);
+	}
 
 	ath_tx_default_comp(sc, bf, fail);
 }
@@ -4475,6 +4547,9 @@
 	int drops = 0;
 	struct ieee80211_tx_ampdu *tap;
 	ath_bufhead bf_cq;
+	struct ath_tx_status ts = bf_first->bf_status.ds_txstat;
+	struct ieee80211_rc_info *rc_info = NULL;
+	struct m_tag *mtag;
 
 	TAILQ_INIT(&bf_q);
 	TAILQ_INIT(&bf_cq);
@@ -4485,11 +4560,36 @@
 	 * XXX use the length in the first frame in the series;
 	 * XXX just so things are consistent for now.
 	 */
+#if 0
 	ath_tx_update_ratectrl(sc, ni, bf_first->bf_state.bfs_rc,
 	    &bf_first->bf_status.ds_txstat,
 	    bf_first->bf_state.bfs_pktlen,
 	    bf_first->bf_state.bfs_nframes, bf_first->bf_state.bfs_nframes);
+#endif
+	/* net80211 ratectl */
+	mtag = m_tag_locate(bf_first->bf_m, MTAG_ABI_NET80211, 
+			NET80211_TAG_RATECTL, NULL);
+	if (NULL == mtag) {
+		IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni,
+				"%s: no ratectl mbuf tag found.\n", __func__);
+		struct ieee80211_rc_info tmp_rc_info;
+		rc_info = &tmp_rc_info;
+		bzero(rc_info, sizeof(rc_info));
+	} else {
+		IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni,
+				"%s: found ratectl mbuf tag.\n", __func__);
+		rc_info = (struct ieee80211_rc_info*)(mtag + 1);
+	}
 
+	ieee80211_ratectl_rc_info_set(rc_info,
+			bf_first->bf_state.bfs_nframes, 
+			bf_first->bf_state.bfs_nframes,
+			bf_first->bf_state.bfs_pktlen,
+			ts.ts_shortretry, ts.ts_longretry,
+			ts.ts_finaltsi, ts.ts_rate);
+	rc_info->iri_flags |= IEEE80211_RATECTL_INFO_AGGR;
+	ieee80211_ratectl_tx_complete(ni->ni_vap, ni, rc_info);
+
 	ATH_TX_LOCK(sc);
 	tap = ath_tx_get_tx_tid(an, tid->tid);
 	sc->sc_stats.ast_tx_aggr_failall++;
@@ -4626,8 +4726,12 @@
 	int nframes = 0, nbad = 0, nf;
 	int pktlen;
 	/* XXX there's too much on the stack? */
+#if 0
 	struct ath_rc_series rc[ATH_RC_NUM];
+#endif
 	int txseq;
+	struct ieee80211_rc_info *rc_info = NULL;
+	struct m_tag *mtag;
 
 	DPRINTF(sc, ATH_DEBUG_SW_TX_AGGR, "%s: called; hwq_depth=%d\n",
 	    __func__, atid->hwq_depth);
@@ -4748,7 +4852,7 @@
 	isaggr = bf_first->bf_state.bfs_aggr;
 	ba[0] = ts.ts_ba_low;
 	ba[1] = ts.ts_ba_high;
-
+#if 0
 	/*
 	 * Copy the TX completion status and the rate control
 	 * series from the first descriptor, as it may be freed
@@ -4756,6 +4860,13 @@
 	 * into things.
 	 */
 	memcpy(rc, bf_first->bf_state.bfs_rc, sizeof(rc));
+#endif
+	/* 
+	 * Get the net80211 ratectl mtag here, as bf_first will 
+	 * be set to NULL later. 
+	 */
+	mtag = m_tag_locate(bf_first->bf_m, MTAG_ABI_NET80211, 
+			NET80211_TAG_RATECTL, NULL);
 
 	DPRINTF(sc, ATH_DEBUG_SW_TX_AGGR,
 	    "%s: txa_start=%d, tx_ok=%d, status=%.8x, flags=%.8x, "
@@ -4873,9 +4984,32 @@
 	 * control code.
 	 */
 	if (fail == 0)
+	{
+#if 0	
 		ath_tx_update_ratectrl(sc, ni, rc, &ts, pktlen, nframes,
 		    nbad);
+#endif
+		/* net80211 ratectl */
+		if (NULL == mtag) {
+			IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni,
+					"%s: no ratectl mbuf tag found.\n", __func__);
+			struct ieee80211_rc_info tmp_rc_info;
+			rc_info = &tmp_rc_info;
+			bzero(rc_info, sizeof(rc_info));
+		} else {
+			IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni,
+					"%s: found ratectl mbuf tag.\n", __func__);
+			rc_info = (struct ieee80211_rc_info*)(mtag + 1);
+		}
 
+		rc_info->iri_flags |= IEEE80211_RATECTL_INFO_AGGR;
+		ieee80211_ratectl_rc_info_set(rc_info,
+					nframes, nbad, pktlen,
+					ts.ts_shortretry, ts.ts_longretry,
+					ts.ts_finaltsi, ts.ts_rate);
+		ieee80211_ratectl_tx_complete(ni->ni_vap, ni, rc_info);
+	}
+
 	/*
 	 * send bar if we dropped any frames
 	 */
@@ -4948,6 +5082,8 @@
 	struct ath_tid *atid = &an->an_tid[tid];
 	struct ath_tx_status ts;
 	int drops = 0;
+	struct ieee80211_rc_info *rc_info = NULL;
+	struct m_tag *mtag;
 
 	/*
 	 * Take a copy of this; filtering/cloning the frame may free the
@@ -4962,11 +5098,36 @@
 	 * Do it outside of the TXQ lock.
 	 */
 	if (fail == 0 && ((bf->bf_state.bfs_txflags & HAL_TXDESC_NOACK) == 0))
+	{
+#if 0	
 		ath_tx_update_ratectrl(sc, ni, bf->bf_state.bfs_rc,
 		    &bf->bf_status.ds_txstat,
 		    bf->bf_state.bfs_pktlen,
 		    1, (ts.ts_status == 0) ? 0 : 1);
+#endif
+		mtag = m_tag_locate(bf->bf_m, MTAG_ABI_NET80211, 
+				NET80211_TAG_RATECTL, NULL);
+		
+		if (NULL == mtag) {
+			IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni,
+					"%s: no ratectl mbuf tag found.\n", __func__);
+			struct ieee80211_rc_info tmp_rc_info;
+			rc_info = &tmp_rc_info;
+			bzero(rc_info, sizeof(rc_info));
+		} else {
+			IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni,
+					"%s: found ratectl mbuf tag.\n", __func__);
+			rc_info = (struct ieee80211_rc_info*)(mtag + 1);
+		}
 
+		rc_info->iri_flags &= ~IEEE80211_RATECTL_INFO_AGGR;
+		ieee80211_ratectl_rc_info_set(rc_info,
+				1, (ts.ts_status == 0 ? 0 : 1), 
+				bf->bf_state.bfs_pktlen,
+				ts.ts_shortretry, ts.ts_longretry,
+				ts.ts_finaltsi, ts.ts_rate);
+		ieee80211_ratectl_tx_complete(ni->ni_vap, ni, rc_info);
+	}
 	/*
 	 * This is called early so atid->hwq_depth can be tracked.
 	 * This unfortunately means that it's released and regrabbed
@@ -5183,6 +5344,15 @@
 		}
 
 		/*
+		 * If non-aggregate scenario appears, this will be 
+		 * turned off.
+		 *
+		 * This flag is used by ath_tx_do_ratelookup() to 
+		 * distinguish aggr/non-aggr scenario.  
+		 */
+		bf->bf_state.bfs_aggr = 1;
+
+		/*
 		 * If the packet doesn't fall within the BAW (eg a NULL
 		 * data frame), schedule it directly; continue.
 		 */
@@ -5425,6 +5595,7 @@
 		/* Update CLRDMASK just before this frame is queued */
 		ath_tx_update_clrdmask(sc, tid, bf);
 
+		bf->bf_state.bfs_aggr = 0; 
 		/* Program descriptors + rate control */
 		ath_tx_do_ratelookup(sc, bf);
 		ath_tx_calc_duration(sc, bf);
Index: if_ath.c
===================================================================
--- if_ath.c	(revision 254826)
+++ if_ath.c	(working copy)
@@ -82,6 +82,8 @@
 
 #include <net80211/ieee80211_var.h>
 #include <net80211/ieee80211_regdomain.h>
+
+#include <net80211/ieee80211_ratectl.h>
 #ifdef IEEE80211_SUPPORT_SUPERG
 #include <net80211/ieee80211_superg.h>
 #endif
@@ -322,6 +324,7 @@
 	sc->sc_ah = ah;
 	sc->sc_invalid = 0;	/* ready to go, enable interrupt handling */
 #ifdef	ATH_DEBUG
+	ath_debug |= ATH_DEBUG_NODE; 
 	sc->sc_debug = ath_debug;
 #endif
 
@@ -1380,6 +1383,16 @@
 	}
 	ATH_UNLOCK(sc);
 
+	uint32_t caps = 0;
+	if (sc->sc_mrretry)
+		caps |= IEEE80211_RATECTL_CAP_MRR;
+	if (sc->sc_mrrprot)
+		caps |= IEEE80211_RATECTL_CAP_MRRPROT;
+	if (sc->sc_txchainmask > 1)
+		caps |= IEEE80211_RATECTL_CAP_MULTXCHAIN;
+
+	ieee80211_ratectl_init(vap, caps);
+	
 	/* complete setup */
 	ieee80211_vap_attach(vap, ath_media_change, ieee80211_media_status);
 	return vap;
@@ -1414,6 +1427,7 @@
 		ath_stoprecv(sc, 1);		/* stop recv side */
 	}
 
+	ieee80211_ratectl_deinit(vap);
 	ieee80211_vap_detach(vap);
 
 	/*
@@ -4042,6 +4056,8 @@
 {
 	struct ieee80211_node *ni = bf->bf_node;
 	struct ath_node *an = NULL;
+	struct ieee80211_rc_info *rc_info = NULL;
+	struct m_tag *mtag;
 
 	ATH_TX_UNLOCK_ASSERT(sc);
 	ATH_TXQ_UNLOCK_ASSERT(txq);
@@ -4068,10 +4084,34 @@
 			 * XXX assume this isn't an aggregate
 			 * frame.
 			 */
+#if 0
 			ath_tx_update_ratectrl(sc, ni,
 			     bf->bf_state.bfs_rc, ts,
 			    bf->bf_state.bfs_pktlen, 1,
 			    (ts->ts_status == 0 ? 0 : 1));
+#endif
+			/* net80211 ratectl */
+		    mtag = m_tag_locate(bf->bf_m, MTAG_ABI_NET80211, 
+				            NET80211_TAG_RATECTL, NULL);
+			if (NULL == mtag) {
+				IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni,
+						"%s: no ratectl mbuf tag found.\n", __func__);
+				struct ieee80211_rc_info tmp_rc_info;
+				rc_info = &tmp_rc_info;
+				bzero(rc_info, sizeof(rc_info));
+			} else {
+				IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni,
+						"%s: found ratectl mbuf tag.\n", __func__);
+				rc_info = (struct ieee80211_rc_info*)(mtag + 1);
+			}
+	
+			ieee80211_ratectl_rc_info_set(rc_info,
+					1, (ts->ts_status == 0 ? 0 : 1), 
+					bf->bf_state.bfs_pktlen,
+					ts->ts_shortretry, ts->ts_longretry,
+					ts->ts_finaltsi, ts->ts_rate);
+			rc_info->iri_flags &= ~IEEE80211_RATECTL_INFO_AGGR;	
+			ieee80211_ratectl_tx_complete(ni->ni_vap, ni, rc_info);
 		}
 		ath_tx_default_comp(sc, bf, 0);
 	} else
@@ -5574,9 +5614,15 @@
 
 	an->an_mcastrix = ath_tx_findrix(sc, tp->mcastrate);
 	an->an_mgmtrix = ath_tx_findrix(sc, tp->mgmtrate);
-
+#if 0
 	ath_rate_newassoc(sc, an, isnew);
+#endif
 
+	DPRINTF(sc, ATH_DEBUG_NODE, "%s: newassoc is new: %d\n",
+			__func__, isnew);
+	if (isnew)
+		ieee80211_ratectl_node_init(ni);
+
 	if (isnew &&
 	    (vap->iv_flags & IEEE80211_F_PRIVACY) == 0 && sc->sc_hasclrkey &&
 	    ni->ni_ucastkey.wk_keyix == IEEE80211_KEYIX_NONE)

Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAFnsE3e1r6Ah5SSrqnrxoqXMRm3yCaUxCjSD90epWQJEZU-pzw>