kern/126895: [PATCH] ral: Add antenna selection (marked as TBD)

David Naylor naylor.b.david at gmail.com
Wed Aug 27 18:00:03 UTC 2008


>Number:         126895
>Category:       kern
>Synopsis:       [PATCH] ral: Add antenna selection (marked as TBD)
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          update
>Submitter-Id:   current-users
>Arrival-Date:   Wed Aug 27 18:00:02 UTC 2008
>Closed-Date:
>Last-Modified:
>Originator:     David Naylor
>Release:        8-Current
>Organization:
Private
>Environment:
n/a
>Description:
The rt2661_select_antenna function has a whole section marked as "TBD".  I looked into the reference driver from RalinkTeck and the rt2x00 and duplicated their behaviour.  Thus it is now mostly done.

Two sysctl's were added.  One a read only that displays which TX antenna is in use (did not find any code to actually change it) and another to select which RX antenna to use.  [This mimics the rt2560 set of systl's]

The txpower is also tweaked to confirm to standard behaviour.  

I created this patch since my RT2501 is not operating correctly.  The signal strength is about 30 dBm to lower (it does associate) and does not transmit any data.  The patch has no consequince but brings the driver closer in line with the one from RalinkTeck and rt2x00.  

Tested with a RT2501.  No change in behaviour... [Well I tried the wifi branch from p4 and it appeared to work a bit better with this patch but that branch is not compatible with -current since vaps was introduced]

WARNING: Although the code mimics the reference drivers it is coded with little understanding of how it is supposed to work.
>How-To-Repeat:
n/a
>Fix:
n/a

Patch attached with submission follows:

Only in /home/DragonSA/ral: Makefile
diff -u src/sys/dev/ral/rt2661.c /home/DragonSA/ral/rt2661.c
--- src/sys/dev/ral/rt2661.c	2008-07-27 09:56:15.000000000 +0200
+++ /home/DragonSA/ral/rt2661.c	2008-08-26 17:42:12.000000000 +0200
@@ -71,11 +71,11 @@
 #ifdef RAL_DEBUG
 #define DPRINTF(sc, fmt, ...) do {				\
 	if (sc->sc_debug > 0)					\
-		printf(fmt, __VA_ARGS__);			\
+		device_printf(sc->sc_dev, fmt, __VA_ARGS__);			\
 } while (0)
 #define DPRINTFN(sc, n, fmt, ...) do {				\
 	if (sc->sc_debug >= (n))				\
-		printf(fmt, __VA_ARGS__);			\
+		device_printf(sc->sc_dev, fmt, __VA_ARGS__);			\
 } while (0)
 #else
 #define DPRINTF(sc, fmt, ...)
@@ -337,6 +337,15 @@
 	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
 	    "debug", CTLFLAG_RW, &sc->sc_debug, 0, "debug msgs");
 #endif
+
+	SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
+	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
+	    "txantenna", CTLFLAG_RD, &sc->tx_ant, 0, "tx antenna (0=auto)");
+
+	SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
+	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
+	    "rxantenna", CTLFLAG_RW, &sc->rx_ant, 0, "rx antenna (0=auto)");
+
 	if (bootverbose)
 		ieee80211_announce(ic);
 
@@ -1898,20 +1907,55 @@
 static void
 rt2661_select_antenna(struct rt2661_softc *sc)
 {
-	uint8_t bbp4, bbp77;
+	uint8_t bbp3, bbp4, bbp77;
 	uint32_t tmp;
 
+	bbp3  = rt2661_bbp_read(sc,  3);
 	bbp4  = rt2661_bbp_read(sc,  4);
 	bbp77 = rt2661_bbp_read(sc, 77);
 
-	/* TBD */
+	if ((sc->rf_rev == RT2661_RF_2529 && sc->nb_ant == 2) || sc->rf_rev < 4) {
+		if (sc->rf_rev == RT2661_RF_5325 || sc->rf_rev == RT2661_RF_2529)
+			bbp3 |= 0x01;  /* Set bits 00000001 */
+		else
+			bbp3 &= 0xfe;   /* Clear bits 00000001 */
+
+		/* Change bbp4 */
+		bbp4 &= ~0x23;  /* Clear bits 00100011 */
+		if (sc->rf_rev > 2) { /* RF_2527 or RF_2529 */
+			bbp4 |= (sc->rx_ant == 1 || sc->rx_ant == 2) ? 0x21 : 0x22;
+			bbp4 &= ~(sc->frame << 5);
+		} else  /* RF_5225 or RF_5235 */
+			bbp4 |= (sc->rx_ant == 1 || sc->rx_ant == 2) ? 0x01 :
+			        (IEEE80211_IS_CHAN_2GHZ(sc->sc_curchan)) ? 0x22 : 0x02;
+
+		/* Change bbp77 (only if not hardware diversify) */
+		if (sc->rx_ant == 1 || sc->rx_ant == 2) {
+			if ((sc->rx_ant == 1) ^ IEEE80211_IS_CHAN_5GHZ(sc->sc_curchan))
+				bbp77 |= 0x03;  /* Set bit 00000010 */
+			else
+				bbp77 &= 0xfc;  /* Clear bit 00000010 */
+		}
+
+		DPRINTFN(sc, 5, "antenna %d selected (bbp4=%x, bbp77=%x)\n", sc->rx_ant,
+		    bbp4, bbp77);
+	} else if (sc->rf_rev == RT2661_RF_2529) {
+		/* => RF_2529 without 2 antenna: TODO */
+		device_printf(sc->sc_dev,"could not select rx antenna, not implemented\n");
+	} else {
+		/* TODO: Unknown chipset revision */
+		device_printf(sc->sc_dev, "could not select rx antenna, unknown chipset\n");
+	}
+
+	/* TODO: Software diversify (and make default) */
 
 	/* make sure Rx is disabled before switching antenna */
 	tmp = RAL_READ(sc, RT2661_TXRX_CSR0);
 	RAL_WRITE(sc, RT2661_TXRX_CSR0, tmp | RT2661_DISABLE_RX);
 
+	rt2661_bbp_write(sc, 77, bbp77);  /* Should be set before bbp3/4 */
+	rt2661_bbp_write(sc,  3, bbp3);
 	rt2661_bbp_write(sc,  4, bbp4);
-	rt2661_bbp_write(sc, 77, bbp77);
 
 	/* restore Rx filter */
 	RAL_WRITE(sc, RT2661_TXRX_CSR0, tmp);
@@ -2055,10 +2099,12 @@
 
 	power = sc->txpow[i];
 	if (power < 0) {
-		bbp94 += power;
+		if (power > -7)
+			bbp94 += power;
 		power = 0;
 	} else if (power > 31) {
-		bbp94 += power - 31;
+		if (power < 37)
+			bbp94 += power - 31;
 		power = 31;
 	}
 
@@ -2246,6 +2292,7 @@
 	/* XXX: test if different from 0xffff? */
 	sc->rf_rev   = (val >> 11) & 0x1f;
 	sc->hw_radio = (val >> 10) & 0x1;
+	sc->frame    = (val >> 6)  & 0x1;
 	sc->rx_ant   = (val >> 4)  & 0x3;
 	sc->tx_ant   = (val >> 2)  & 0x3;
 	sc->nb_ant   = val & 0x3;
diff -u src/sys/dev/ral/rt2661var.h /home/DragonSA/ral/rt2661var.h
--- src/sys/dev/ral/rt2661var.h	2008-04-25 14:42:13.000000000 +0200
+++ /home/DragonSA/ral/rt2661var.h	2008-08-17 18:22:20.000000000 +0200
@@ -145,6 +145,7 @@
 	}				bbp_prom[16];
 
 	int				hw_radio;
+	int				frame;
 	int				rx_ant;
 	int				tx_ant;
 	int				nb_ant;


>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list