Add basic support for advanced bluetooth coexistence required

for 6005 gen2b (1030/6030) adapters.
This commit is contained in:
bschmidt 2011-04-20 16:59:27 +00:00
parent 5e2adb5a7c
commit 0ba66a6c39
3 changed files with 105 additions and 2 deletions

View File

@ -253,6 +253,7 @@ static void iwn_tune_sensitivity(struct iwn_softc *,
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, uint16_t pid)
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",
@ -4720,6 +4723,63 @@ iwn_send_btcoex(struct iwn_softc *sc)
return iwn_cmd(sc, IWN_CMD_BT_COEX, &cmd, sizeof(cmd), 0);
}
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)
{
@ -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",

View File

@ -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;

View File

@ -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;