socsvn commit: r255023 - soc2013/ccqin/head/sys/net80211

ccqin at FreeBSD.org ccqin at FreeBSD.org
Mon Jul 22 02:11:34 UTC 2013


Author: ccqin
Date: Mon Jul 22 02:11:33 2013
New Revision: 255023
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=255023

Log:
  Add rate control options and some 11n features to net80211 rate control code.
   1) Add some rc options chip can provide to rc code when it init.
   2) Implement some 11n features. rc code can get the corresponding feature
      capability and decide whether to use it. If some 11n features are choosen to
      be used, rc code must fill corresponding flags. Other flags that rc code may
      not be interested by now are filled by ieee80211_ratectl_complete_rcflags.

Modified:
  soc2013/ccqin/head/sys/net80211/ieee80211_ratectl.c
  soc2013/ccqin/head/sys/net80211/ieee80211_ratectl.h

Modified: soc2013/ccqin/head/sys/net80211/ieee80211_ratectl.c
==============================================================================
--- soc2013/ccqin/head/sys/net80211/ieee80211_ratectl.c	Mon Jul 22 00:44:37 2013	(r255022)
+++ soc2013/ccqin/head/sys/net80211/ieee80211_ratectl.c	Mon Jul 22 02:11:33 2013	(r255023)
@@ -66,10 +66,11 @@
 }
 
 void
-ieee80211_ratectl_init(struct ieee80211vap *vap)
+ieee80211_ratectl_init(struct ieee80211vap *vap, uint32_t options)
 {
 	if (vap->iv_rate == ratectls[IEEE80211_RATECTL_NONE])
 		ieee80211_ratectl_set(vap, IEEE80211_RATECTL_AMRR);
+	vap->iv_rate.options = options;
 	vap->iv_rate->ir_init(vap);
 }
 

Modified: soc2013/ccqin/head/sys/net80211/ieee80211_ratectl.h
==============================================================================
--- soc2013/ccqin/head/sys/net80211/ieee80211_ratectl.h	Mon Jul 22 00:44:37 2013	(r255022)
+++ soc2013/ccqin/head/sys/net80211/ieee80211_ratectl.h	Mon Jul 22 02:11:33 2013	(r255023)
@@ -1,5 +1,6 @@
 /*-
  * Copyright (c) 2010 Rui Paulo <rpaulo at FreeBSD.org>
+ * Copyright (c) 2013 Chenchong Qin <ccqin at FreeBSD.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -37,6 +38,9 @@
 #define	IEEE80211_RATECTL_TX_SUCCESS	1
 #define	IEEE80211_RATECTL_TX_FAILURE	0
 
+#define	IEEE80211_RATECTL_TRUE		1
+#define	IEEE80211_RATECTL_FALSE		0
+
 #define	IEEE80211_RATECTL_NUM		4
 
 #define	IEEE80211_RATECTL_DS_FLAG		0x01	/* dual-stream rate */
@@ -47,17 +51,28 @@
 #define	IEEE80211_RATECTL_STBC_FLAG		0x20	/* enable STBC */
 #define	IEEE80211_RATECTL_TS_FLAG		0x40	/* triple-stream rate */
 
+/* Hardware options chip offered to rate control code */
+#define	IEEE80211_RATECTL_OPT_MRR			0x01	/* support MRR */
+#define	IEEE80211_RATECTL_OPT_MRRPROT		0x02	/* support MRR + protect */
+#define	IEEE80211_RATECTL_OPT_MULTXCHAIN	0x04	/* has more than 1 txchain */
+
+#define IS_VAP_HT(vap)	((vap)->iv_htcaps & IEEE80211_HTC_HT)
+
+#define IS_HT_RATE(_rate)   ((_rate) & 0x80)
+#define HT_RC_2_MCS(_rc)    ((_rc) & 0x7f)
+#define HT_RC_2_STREAMS(_rc)    ((((_rc) & 0x78) >> 3) + 1)
+
 struct ieee80211_rc_series {
 	uint8_t rix;		/* ratetable index, not rate code */
 	uint8_t ratecode;	/* hardware rate code */
 	uint8_t tries;
 	uint8_t tx_power_cap;
 	uint16_t flags;
-	uint16_t max4msframelen;
 };
 
 struct ieee80211_ratectl {
 	const char *ir_name;
+	uint32_t options;		/* IEEE80211_RATECTL_OPTs */
 	int	(*ir_attach)(const struct ieee80211vap *);
 	void	(*ir_detach)(const struct ieee80211vap *);
 	void	(*ir_init)(struct ieee80211vap *);
@@ -77,7 +92,7 @@
 
 void	ieee80211_ratectl_register(int, const struct ieee80211_ratectl *);
 void	ieee80211_ratectl_unregister(int);
-void	ieee80211_ratectl_init(struct ieee80211vap *);
+void	ieee80211_ratectl_init(struct ieee80211vap *, uint32_t);
 void	ieee80211_ratectl_set(struct ieee80211vap *, int);
 
 MALLOC_DECLARE(M_80211_RATECTL);
@@ -89,11 +104,11 @@
 }
 
 static void __inline
-ieee80211_ratectl_node_init(struct ieee80211_node *ni)
+ieee80211_ratectl_node_init(struct ieee80211_node *ni, uint32_t options)
 {
 	const struct ieee80211vap *vap = ni->ni_vap;
 
-	vap->iv_rate->ir_node_init(ni);
+	vap->iv_rate->ir_node_init(ni, options);
 }
 
 static void __inline
@@ -117,19 +132,10 @@
 		int shortPreamble, size_t frameLen)
 {
 	const struct ieee80211vap *vap = ni->ni_vap;
-	struct ieee80211com *ic = vap->iv_ic; 
 
 	vap->iv_rate->ir_rates(ni, rc, shortPreamble, frameLen);
-
-	/* if enable rts/cts and is pre-802.11n, blank tries 1, 2, 3 */
-	if (!(ic->ic_htcaps & IEEE80211_HTC_HT))
-	{
-		if (rc[0].flags & IEEE80211_RATECTL_RTSCTS_FLAG)
-			rc[1].tries = rc[2].tries = rc[3].tries = 0;
-		rc[1].flags &= ~IEEE80211_RATECTL_RTSCTS_FLAG; 
-		rc[2].flags &= ~IEEE80211_RATECTL_RTSCTS_FLAG; 
-		rc[3].flags &= ~IEEE80211_RATECTL_RTSCTS_FLAG; 
-	}
+	
+	ieee80211_ratectl_complete_rcflags(ni, rc, shortPreamble);
 }
 
 static void __inline
@@ -155,3 +161,106 @@
 		return;
 	vap->iv_rate->ir_setinterval(vap, msecs);
 }
+
+static int __inline
+ieee80211_ratectl_hascap_cw40(const struct ieee80211vap *vap,
+		const struct ieee80211_node *ni)
+{
+	return IS_VAP_HT(vap) && (ni->ni_chw == 40);
+}
+
+static int __inline
+ieee80211_ratectl_hascap_shortgi(const struct ieee80211vap *vap,
+		const struct ieee80211_node *ni)
+{
+	if (! IS_VAP_HT(vap))
+		return IEEE80211_RATECTL_FALSE;
+
+	if (ni->ni_chw == 40 &&
+			vap->iv_htcaps & IEEE80211_HTCAP_SHORTGI40 &&
+			ni->ni_htcap & IEEE80211_HTCAP_SHORTGI40)
+		return IEEE80211_RATECTL_TRUE;
+
+	if (ni->ni_chw == 20 &&
+			vap->iv_htcaps & IEEE80211_HTCAP_SHORTGI20 &&
+			ni->ni_htcap & IEEE80211_HTCAP_SHORTGI20)
+		return IEEE80211_RATECTL_TRUE;
+}
+
+
+static int __inline
+ieee80211_ratectl_hascap_stbc(const struct ieee80211vap *vap,
+		const struct ieee80211_node *ni)
+{
+   return IS_VAP_HT(vap) && (vap->iv_htcaps & IEEE80211_HTCAP_TXSTBC) &&
+			    (ni->ni_htcap & IEEE80211_HTCAP_RXSTBC_1STREAM) &&
+			    (vap->iv_rate->options & IEEE80211_RATECTL_OPT_MULTXCHAIN);
+}
+
+static void
+ieee80211_ratectl_complete_rcflags(struct ieee80211_node *ni,
+		struct ieee80211_rc_series *rc, int shortPreamble)
+{
+	struct ieee80211com *ic = ni->ni_ic;
+	const struct ieee80211_rate_table * rt = ic->ic_rt;
+	uint8_t rate0, rate;
+	int i;
+
+	rate0 = rt->info[rc[0].rix].rateCode;
+	
+	/* Make sure that rate control code doesn't mess it up.
+	 * If enable rts/cts and is pre-802.11n, blank tries 1, 2, 3 
+	 */
+
+	if (! IS_HT_RATE(rate0))
+	{
+		if (rc[0].flags & IEEE80211_RATECTL_RTSCTS_FLAG)
+			rc[1].tries = rc[2].tries = rc[3].tries = 0;
+		rc[1].flags &= ~IEEE80211_RATECTL_RTSCTS_FLAG; 
+		rc[2].flags &= ~IEEE80211_RATECTL_RTSCTS_FLAG; 
+		rc[3].flags &= ~IEEE80211_RATECTL_RTSCTS_FLAG; 
+	}
+
+	for (i = 0; i < IEEE80211_RATECTL_NUM; i++) {
+		
+		if (rc[i].tries == 0)
+			continue;
+
+		rate = rt->info[rc[i].rix].rateCode;
+
+		/*
+		 * Only enable short preamble for legacy rates
+		 */
+		if ((! IS_HT_RATE(rate)) && shortPreamble)
+			rate |= rt->info[rc[i].rix].shortPreamble;
+
+		/*
+		 * Save this, used by the TX and completion code
+		 */
+		rc[i].ratecode = rate;
+
+		/* Only enable shortgi, 2040, dual-stream if HT is set */
+		if (IS_HT_RATE(rate)) {
+			rc[i].flags |= IEEE80211_RATECTL_HT_FLAG;
+
+			/*
+			 * XXX TODO: LDPC
+			 */
+
+			/*
+			 * Dual / Triple stream rate?
+			 */
+			if (HT_RC_2_STREAMS(rate) == 2)
+				rc[i].flags |= IEEE80211_RATECTL_DS_FLAG;
+			else if (HT_RC_2_STREAMS(rate) == 3)
+				rc[i].flags |= IEEE80211_RATECTL_TS_FLAG;
+		}
+
+		/*
+		 * Calculate the maximum TX power cap for the current
+		 * node. 
+		 * Rate control algo can't control TX power by now.
+		 */
+		rc[i].tx_power_cap = ieee80211_get_node_txpower(ni);
+	}
+}


More information about the svn-soc-all mailing list