Author: bschmidt
Date: Wed Apr 20 16:59:27 2011
New Revision: 220891
URL: http://svn.freebsd.org/changeset/base/220891

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

Modified:
  head/sys/dev/iwn/if_iwn.c
  head/sys/dev/iwn/if_iwnreg.h
  head/sys/dev/iwn/if_iwnvar.h

Modified: head/sys/dev/iwn/if_iwn.c
==============================================================================
--- head/sys/dev/iwn/if_iwn.c   Wed Apr 20 16:38:05 2011        (r220890)
+++ head/sys/dev/iwn/if_iwn.c   Wed Apr 20 16:59:27 2011        (r220891)
@@ -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: head/sys/dev/iwn/if_iwnreg.h
==============================================================================
--- head/sys/dev/iwn/if_iwnreg.h        Wed Apr 20 16:38:05 2011        
(r220890)
+++ head/sys/dev/iwn/if_iwnreg.h        Wed Apr 20 16:59:27 2011        
(r220891)
@@ -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: head/sys/dev/iwn/if_iwnvar.h
==============================================================================
--- head/sys/dev/iwn/if_iwnvar.h        Wed Apr 20 16:38:05 2011        
(r220890)
+++ head/sys/dev/iwn/if_iwnvar.h        Wed Apr 20 16:59:27 2011        
(r220891)
@@ -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;
 
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to