Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 18 Jun 2011 12:11:49 +0000 (UTC)
From:      Bernhard Schmidt <bschmidt@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org
Subject:   svn commit: r223252 - stable/8/sys/dev/iwn
Message-ID:  <201106181211.p5ICBn5k040447@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: bschmidt
Date: Sat Jun 18 12:11:48 2011
New Revision: 223252
URL: http://svn.freebsd.org/changeset/base/223252

Log:
  MFC r220891:
  Add basic support for advanced bluetooth coexistence required
  for 6005 gen2b (1030/6030) adapters.

Modified:
  stable/8/sys/dev/iwn/if_iwn.c
  stable/8/sys/dev/iwn/if_iwnreg.h
  stable/8/sys/dev/iwn/if_iwnvar.h
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)

Modified: stable/8/sys/dev/iwn/if_iwn.c
==============================================================================
--- stable/8/sys/dev/iwn/if_iwn.c	Sat Jun 18 12:10:06 2011	(r223251)
+++ stable/8/sys/dev/iwn/if_iwn.c	Sat Jun 18 12:11:48 2011	(r223252)
@@ -253,6 +253,7 @@ static void	iwn_tune_sensitivity(struct 
 static int	iwn_send_sensitivity(struct iwn_softc *);
 static int	iwn_set_pslevel(struct iwn_softc *, int, int, int);
 static int	iwn_send_btcoex(struct iwn_softc *);
+static int	iwn_send_advanced_btcoex(struct iwn_softc *);
 static int	iwn_config(struct iwn_softc *);
 static uint8_t	*ieee80211_add_ssid(uint8_t *, const uint8_t *, u_int);
 static int	iwn_scan(struct iwn_softc *);
@@ -816,6 +817,8 @@ iwn5000_attach(struct iwn_softc *sc, uin
 	case IWN_HW_REV_TYPE_6005:
 		sc->limits = &iwn6000_sensitivity_limits;
 		sc->fwname = "iwn6005fw";
+		if (pid != 0x0082 && pid != 0x0085)
+			sc->sc_flags |= IWN_FLAG_ADV_BTCOEX;
 		break;
 	default:
 		device_printf(sc->sc_dev, "adapter type %d not supported\n",
@@ -4721,6 +4724,63 @@ iwn_send_btcoex(struct iwn_softc *sc)
 }
 
 static int
+iwn_send_advanced_btcoex(struct iwn_softc *sc)
+{
+	static const uint32_t btcoex_3wire[12] = {
+		0xaaaaaaaa, 0xaaaaaaaa, 0xaeaaaaaa, 0xaaaaaaaa,
+		0xcc00ff28, 0x0000aaaa, 0xcc00aaaa, 0x0000aaaa,
+		0xc0004000, 0x00004000, 0xf0005000, 0xf0005000,
+	};
+	struct iwn6000_btcoex_config btconfig;
+	struct iwn_btcoex_priotable btprio;
+	struct iwn_btcoex_prot btprot;
+	int error, i;
+
+	memset(&btconfig, 0, sizeof btconfig);
+	btconfig.flags = 145;
+	btconfig.max_kill = 5;
+	btconfig.bt3_t7_timer = 1;
+	btconfig.kill_ack = htole32(0xffff0000);
+	btconfig.kill_cts = htole32(0xffff0000);
+	btconfig.sample_time = 2;
+	btconfig.bt3_t2_timer = 0xc;
+	for (i = 0; i < 12; i++)
+		btconfig.lookup_table[i] = htole32(btcoex_3wire[i]);
+	btconfig.valid = htole16(0xff);
+	btconfig.prio_boost = 0xf0;
+	DPRINTF(sc, IWN_DEBUG_RESET,
+	    "%s: configuring advanced bluetooth coexistence\n", __func__);
+	error = iwn_cmd(sc, IWN_CMD_BT_COEX, &btconfig, sizeof(btconfig), 1);
+	if (error != 0)
+		return error;
+
+	memset(&btprio, 0, sizeof btprio);
+	btprio.calib_init1 = 0x6;
+	btprio.calib_init2 = 0x7;
+	btprio.calib_periodic_low1 = 0x2;
+	btprio.calib_periodic_low2 = 0x3;
+	btprio.calib_periodic_high1 = 0x4;
+	btprio.calib_periodic_high2 = 0x5;
+	btprio.dtim = 0x6;
+	btprio.scan52 = 0x8;
+	btprio.scan24 = 0xa;
+	error = iwn_cmd(sc, IWN_CMD_BT_COEX_PRIOTABLE, &btprio, sizeof(btprio),
+	    1);
+	if (error != 0)
+		return error;
+
+	/* Force BT state machine change. */
+	memset(&btprot, 0, sizeof btprio);
+	btprot.open = 1;
+	btprot.type = 1;
+	error = iwn_cmd(sc, IWN_CMD_BT_COEX_PROT, &btprot, sizeof(btprot), 1);
+	if (error != 0)
+		return error;
+	btprot.open = 0;
+	return iwn_cmd(sc, IWN_CMD_BT_COEX_PROT, &btprot, sizeof(btprot), 1);
+}
+
+static int
 iwn_config(struct iwn_softc *sc)
 {
 	struct iwn_ops *ops = &sc->ops;
@@ -4756,7 +4816,10 @@ iwn_config(struct iwn_softc *sc)
 	}
 
 	/* Configure bluetooth coexistence. */
-	error = iwn_send_btcoex(sc);
+	if (sc->sc_flags & IWN_FLAG_ADV_BTCOEX)
+		error = iwn_send_advanced_btcoex(sc);
+	else
+		error = iwn_send_btcoex(sc);
 	if (error != 0) {
 		device_printf(sc->sc_dev,
 		    "%s: could not configure bluetooth coexistence, error %d\n",

Modified: stable/8/sys/dev/iwn/if_iwnreg.h
==============================================================================
--- stable/8/sys/dev/iwn/if_iwnreg.h	Sat Jun 18 12:10:06 2011	(r223251)
+++ stable/8/sys/dev/iwn/if_iwnreg.h	Sat Jun 18 12:11:48 2011	(r223252)
@@ -434,6 +434,8 @@ struct iwn_tx_cmd {
 #define IWN_CMD_SET_CRITICAL_TEMP	164
 #define IWN_CMD_SET_SENSITIVITY		168
 #define IWN_CMD_PHY_CALIB		176
+#define IWN_CMD_BT_COEX_PRIOTABLE	204
+#define IWN_CMD_BT_COEX_PROT		205
 
 	uint8_t	flags;
 	uint8_t	idx;
@@ -829,7 +831,7 @@ struct iwn5000_cmd_txpower {
 	uint8_t	reserved;
 } __packed;
 
-/* Structure for command IWN_CMD_BLUETOOTH. */
+/* Structures for command IWN_CMD_BLUETOOTH. */
 struct iwn_bluetooth {
 	uint8_t		flags;
 #define IWN_BT_COEX_CHAN_ANN	(1 << 0)
@@ -847,6 +849,43 @@ struct iwn_bluetooth {
 	uint32_t	kill_cts;
 } __packed;
 
+struct iwn6000_btcoex_config {
+	uint8_t		flags;
+	uint8_t		lead_time;
+	uint8_t		max_kill;
+	uint8_t		bt3_t7_timer;
+	uint32_t	kill_ack;
+	uint32_t	kill_cts;
+	uint8_t		sample_time;
+	uint8_t		bt3_t2_timer;
+	uint16_t	bt4_reaction;
+	uint32_t	lookup_table[12];
+	uint16_t	bt4_decision;
+	uint16_t	valid;
+	uint8_t		prio_boost;
+	uint8_t		tx_prio_boost;
+	uint16_t	rx_prio_boost;
+} __packed;
+
+struct iwn_btcoex_priotable {
+	uint8_t		calib_init1;
+	uint8_t		calib_init2;
+	uint8_t		calib_periodic_low1;
+	uint8_t		calib_periodic_low2;
+	uint8_t		calib_periodic_high1;
+	uint8_t		calib_periodic_high2;
+	uint8_t		dtim;
+	uint8_t		scan52;
+	uint8_t		scan24;
+	uint8_t		reserved[7];
+} __packed;
+
+struct iwn_btcoex_prot {
+	uint8_t		open;
+	uint8_t		type;
+	uint8_t		reserved[2];
+} __packed;
+
 /* Structure for command IWN_CMD_SET_CRITICAL_TEMP. */
 struct iwn_critical_temp {
 	uint32_t	reserved;

Modified: stable/8/sys/dev/iwn/if_iwnvar.h
==============================================================================
--- stable/8/sys/dev/iwn/if_iwnvar.h	Sat Jun 18 12:10:06 2011	(r223251)
+++ stable/8/sys/dev/iwn/if_iwnvar.h	Sat Jun 18 12:11:48 2011	(r223252)
@@ -206,6 +206,7 @@ struct iwn_softc {
 #define IWN_FLAG_INTERNAL_PA	(1 << 4)
 #define IWN_FLAG_HAS_11N	(1 << 6)
 #define IWN_FLAG_ENH_SENS	(1 << 7)
+#define IWN_FLAG_ADV_BTCOEX	(1 << 8)
 
 	uint8_t 		hw_type;
 



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