44#include <sys/sysctl.h>
45#include <sys/kernel.h>
47#include <sys/malloc.h>
51#include <machine/bus.h>
52#include <machine/resource.h>
56#include <sys/socket.h>
59#include <net/if_var.h>
60#include <net/if_media.h>
61#include <net/if_arp.h>
62#include <net/ethernet.h>
64#include <net80211/ieee80211_var.h>
69#include <netinet/in.h>
70#include <netinet/if_ether.h>
82#define ATH_MCI_GPM_MAX_ENTRY 16
83#define ATH_MCI_GPM_BUF_SIZE (ATH_MCI_GPM_MAX_ENTRY * 16)
84#define ATH_MCI_SCHED_BUF_SIZE (16 * 16)
95 "MCI bufs", buflen, 1);
97 device_printf(sc->
sc_dev,
"%s: failed to alloc MCI RAM\n",
176 const struct ieee80211_channel *chan)
225 "(MCI) Flush BT profile\n");
239 DPRINTF(sc, ATH_DEBUG_BTCOEX,
"(MCI) BT_NOOP\n");
259 device_printf(sc->
sc_dev,
"%s: TODO!\n", __func__);
267 uint32_t payload[4] = {0, 0, 0, 0};
271 DPRINTF(sc, ATH_DEBUG_BTCOEX,
"(MCI) receive BT_CAL_REQ\n");
279 "(MCI) State mismatches: %d\n",
285 DPRINTF(sc, ATH_DEBUG_BTCOEX,
"(MCI) receive BT_CAL_DONE\n");
289 "(MCI) ERROR ILLEGAL!\n");
292 "(MCI) BT not in CAL state.\n");
296 DPRINTF(sc, ATH_DEBUG_BTCOEX,
"(MCI) receive BT_CAL_GRANT\n");
298 DPRINTF(sc, ATH_DEBUG_BTCOEX,
"(MCI) Send WLAN_CAL_DONE\n");
304 "(MCI) Unknown GPM CAL message.\n");
327 struct ieee80211com *ic = &sc->
sc_ic;
328 struct ieee80211_channel *chan = ic->ic_curchan;
329 uint32_t channel_info[4] =
330 { 0x00000000, 0xffffffff, 0xffffffff, 0x7fffffff };
331 int32_t wl_chan, bt_chan, bt_start = 0, bt_end = 79;
334 if (IEEE80211_IS_CHAN_2GHZ(chan)) {
335 wl_chan = chan->ic_freq - 2402;
336 if (IEEE80211_IS_CHAN_HT40U(chan)) {
337 bt_start = wl_chan - 10;
338 bt_end = wl_chan + 30;
339 }
else if (IEEE80211_IS_CHAN_HT40D(chan)) {
340 bt_start = wl_chan - 30;
341 bt_end = wl_chan + 10;
344 bt_start = wl_chan - 10;
345 bt_end = wl_chan + 10;
357 DPRINTF(sc, ATH_DEBUG_BTCOEX,
"(MCI) WLAN use channel %d\n",
360 "(MCI) mask BT channel %d - %d\n", bt_start, bt_end);
361 for (bt_chan = bt_start; bt_chan < bt_end; bt_chan++) {
366 "(MCI) WLAN not use any 2G channel, unmask all for BT\n");
384 "(MCI) Recv GPM COEX Version Query.\n");
391 "(MCI) Recv GPM COEX Version Response.\n");
395 "(MCI) BT Coex version: %d.%d\n", major, minor);
396 version = (major << 8) + minor;
403 "(MCI) Recv GPM COEX Status Query = 0x%02x.\n",
415 "(MCI) TODO: Recv GPM COEX BT_Profile_Info.\n");
419 seq_num = *((uint32_t *)(rx_payload + 12));
421 "(MCI) Recv GPM COEX BT_Status_Update: SEQ=%d\n",
427 "(MCI) Unknown GPM COEX message = 0x%02x\n", opcode);
435 uint32_t mciInt, mciIntRxMsg;
436 uint32_t offset, subtype, opcode;
440 bool skip_gpm =
false;
442 DPRINTF(sc, ATH_DEBUG_BTCOEX,
"%s: called\n", __func__);
451 "(MCI) INTR but MCI_disabled\n");
453 "(MCI) MCI interrupt: mciInt = 0x%x, mciIntRxMsg = 0x%x\n",
454 mciInt, mciIntRxMsg);
459 uint32_t payload4[4] = { 0xffffffff, 0xffffffff, 0xffffffff,
468 "(MCI) 1. INTR Send REMOTE_RESET\n");
472 "(MCI) 1. INTR Send SYS_WAKING\n");
476 mciIntRxMsg &= ~HAL_MCI_INTERRUPT_RX_MSG_REQ_WAKE;
482 "(MCI) 1. Set BT state to AWAKE.\n");
489 mciIntRxMsg &= ~HAL_MCI_INTERRUPT_RX_MSG_SYS_WAKING;
495 "(MCI) 2. BT stays in SLEEP mode.\n");
498 "(MCI) 2. Set BT state to AWAKE.\n");
504 "(MCI) 2. BT stays in AWAKE mode.\n");
509 mciIntRxMsg &= ~HAL_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING;
515 "(MCI) 3. BT stays in AWAKE mode.\n");
518 "(MCI) 3. Set BT state to SLEEP.\n");
524 "(MCI) 3. BT stays in SLEEP mode.\n");
534 "(MCI) MCI RX broken, skip GPM messages\n");
541 mciIntRxMsg &= ~HAL_MCI_INTERRUPT_RX_MSG_SCHD_INFO;
550 mciIntRxMsg &= ~HAL_MCI_INTERRUPT_RX_MSG_GPM;
559 pGpm += (offset >> 2);
575 opcode, (uint8_t*) pGpm);
579 "(MCI) TODO: GPM_BT_DEBUG!\n");
583 "(MCI) Unknown GPM message.\n");
603 mciIntRxMsg &= ~HAL_MCI_INTERRUPT_RX_MSG_LNA_CONTROL;
604 DPRINTF(sc, ATH_DEBUG_BTCOEX,
"(MCI) LNA_CONTROL\n");
607 mciIntRxMsg &= ~HAL_MCI_INTERRUPT_RX_MSG_LNA_INFO;
608 DPRINTF(sc, ATH_DEBUG_BTCOEX,
"(MCI) LNA_INFO\n");
614 mciIntRxMsg &= ~HAL_MCI_INTERRUPT_RX_MSG_CONT_INFO;
618 "(MCI) CONT_INFO: (tx) pri = %d, pwr = %d dBm\n",
624 "(MCI) CONT_INFO: (rx) pri = %d, rssi = %d dBm\n",
631 mciIntRxMsg &= ~HAL_MCI_INTERRUPT_RX_MSG_CONT_NACK;
632 DPRINTF(sc, ATH_DEBUG_BTCOEX,
"(MCI) CONT_NACK\n");
635 mciIntRxMsg &= ~HAL_MCI_INTERRUPT_RX_MSG_CONT_RST;
636 DPRINTF(sc, ATH_DEBUG_BTCOEX,
"(MCI) CONT_RST\n");
651 if (mciIntRxMsg & 0xfffffffe) {
653 "(MCI) Not processed IntRxMsg = 0x%x\n", mciIntRxMsg);
#define MCI_GPM_SET_CAL_TYPE(_p_gpm, _cal_type)
#define MCI_GPM_TYPE(_p_gpm)
#define MCI_GPM_IS_CAL_TYPE(_type)
#define HAL_MCI_INTERRUPT_CONT_INFO_TIMEOUT
#define MCI_GPM_RECYCLE(_p_gpm)
#define HAL_MCI_INTERRUPT_RX_MSG_LNA_CONTROL
#define MCI_GPM_OPCODE(_p_gpm)
@ MCI_GPM_COEX_BT_PROFILE_INFO
@ MCI_GPM_COEX_VERSION_QUERY
@ MCI_GPM_COEX_VERSION_RESPONSE
@ MCI_GPM_COEX_STATUS_QUERY
@ MCI_GPM_COEX_BT_STATUS_UPDATE
#define HAL_MCI_INTERRUPT_RX_MSG_CONT_INFO
#define HAL_MCI_INTERRUPT_RX_MSG_REQ_WAKE
#define HAL_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING
#define HAL_MCI_INTERRUPT_RX_MSG_CONT_NACK
#define HAL_MCI_GPM_INVALID
#define HAL_MCI_INTERRUPT_RX_INVALID_HDR
#define HAL_MCI_INTERRUPT_RX_MSG_CONT_RST
#define HAL_MCI_INTERRUPT_RX_MSG_LNA_INFO
#define HAL_MCI_INTERRUPT_RX_MSG_SCHD_INFO
#define MCI_NUM_BT_CHANNELS
#define HAL_MCI_INTERRUPT_RX_MSG_SYS_WAKING
#define HAL_MCI_INTERRUPT_RX_MSG_GPM
@ MCI_GPM_COEX_B_MAJOR_VERSION
@ MCI_GPM_COEX_B_WLAN_BITMAP
@ MCI_GPM_COEX_B_MINOR_VERSION
#define MCI_GPM_CLR_CHANNEL_BIT(_p_gpm, _bt_chan)
@ HAL_MCI_STATE_CONT_PRIORITY
@ HAL_MCI_STATE_INIT_GPM_OFFSET
@ HAL_MCI_STATE_RECOVER_RX
@ HAL_MCI_STATE_RESET_REQ_WAKE
@ HAL_MCI_STATE_LAST_SCHD_MSG_OFFSET
@ HAL_MCI_STATE_NEXT_GPM_OFFSET
@ HAL_MCI_STATE_SEND_WLAN_CHANNELS
@ HAL_MCI_STATE_SET_BT_SLEEP
@ HAL_MCI_STATE_CONT_TXRX
@ HAL_MCI_STATE_SEND_STATUS_QUERY
@ HAL_MCI_STATE_SEND_WLAN_COEX_VERSION
@ HAL_MCI_STATE_NEED_FLUSH_BT_INFO
@ HAL_MCI_STATE_SET_BT_COEX_VERSION
@ HAL_MCI_STATE_CONT_RSSI_POWER
@ HAL_MCI_STATE_SET_BT_CAL_START
@ HAL_MCI_STATE_REMOTE_SLEEP
@ HAL_MCI_STATE_SET_BT_AWAKE
#define HAL_MCI_INTERRUPT_RX_MSG_MONITOR
static void ath_btcoex_mci_cal_msg(struct ath_softc *sc, uint8_t opcode, uint8_t *rx_payload)
#define ATH_MCI_GPM_BUF_SIZE
static int ath_btcoex_mci_bt_cal_do(struct ath_softc *sc, int tx_timeout, int rx_timeout)
void ath_btcoex_mci_intr(struct ath_softc *sc)
static void ath_btcoex_mci_update_wlan_channels(struct ath_softc *sc)
int ath_btcoex_mci_enable(struct ath_softc *sc, const struct ieee80211_channel *chan)
static void ath_btcoex_mci_send_gpm(struct ath_softc *sc, uint32_t *payload)
int ath_btcoex_mci_detach(struct ath_softc *sc)
#define ATH_MCI_SCHED_BUF_SIZE
int ath_btcoex_mci_attach(struct ath_softc *sc)
static void ath_btcoex_mci_event(struct ath_softc *sc, ATH_BT_COEX_EVENT nevent, void *param)
static void ath_btcoex_mci_coex_msg(struct ath_softc *sc, uint8_t opcode, uint8_t *rx_payload)
#define DPRINTF(sc, m, fmt,...)
int ath_descdma_alloc_desc(struct ath_softc *sc, struct ath_descdma *dd, ath_bufhead *head, const char *name, int ds_size, int ndesc)
void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd, ath_bufhead *head)
#define ath_hal_btcoex_mci_setup(_ah, _gp, _gb, _gl, _sp)
#define ath_hal_btcoex_set_weights(_ah, _weight)
#define ath_hal_btcoex_mci_get_interrupt(_ah, _mi, _mm)
#define ath_hal_btcoex_mci_send_message(_ah, _h, _f, _p, _l, _wd, _cbt)
#define ath_hal_btcoex_mci_state(_ah, _st, _pd)
#define ath_hal_btcoex_mci_detach(_ah)
struct ath_desc * dd_desc
uint32_t wlan_channels[4]
struct ath_softc::@36 sc_btcoex
struct ieee80211com sc_ic