198186Sgordon/*
298186Sgordon * Copyright (c) 2010-2011 Atheros Communications Inc.
378344Sobrien *
498186Sgordon * Permission to use, copy, modify, and/or distribute this software for any
578344Sobrien * purpose with or without fee is hereby granted, provided that the above
678344Sobrien * copyright notice and this permission notice appear in all copies.
778344Sobrien *
878344Sobrien * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
978344Sobrien * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1078344Sobrien * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1178344Sobrien * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1278344Sobrien * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1378344Sobrien * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1478344Sobrien * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1578344Sobrien */
1678344Sobrien
1778344Sobrien#ifndef MCI_H
1878344Sobrien#define MCI_H
1978344Sobrien
2078344Sobrien#include "ar9003_mci.h"
2178344Sobrien
2278344Sobrien#define ATH_MCI_SCHED_BUF_SIZE		(16 * 16) /* 16 entries, 4 dword each */
2378344Sobrien#define ATH_MCI_GPM_MAX_ENTRY		16
2478344Sobrien#define ATH_MCI_GPM_BUF_SIZE		(ATH_MCI_GPM_MAX_ENTRY * 16)
2578344Sobrien#define ATH_MCI_DEF_BT_PERIOD		40
2678344Sobrien#define ATH_MCI_BDR_DUTY_CYCLE		20
2778344Sobrien#define ATH_MCI_MAX_DUTY_CYCLE		90
2878344Sobrien
2978344Sobrien#define ATH_MCI_DEF_AGGR_LIMIT		6 /* in 0.24 ms */
3078344Sobrien#define ATH_MCI_MAX_ACL_PROFILE		7
3178344Sobrien#define ATH_MCI_MAX_SCO_PROFILE		1
3278344Sobrien#define ATH_MCI_MAX_PROFILE		(ATH_MCI_MAX_ACL_PROFILE +\
3378344Sobrien					 ATH_MCI_MAX_SCO_PROFILE)
3478344Sobrien
3578344Sobrien#define ATH_MCI_INQUIRY_PRIO         62
3678344Sobrien#define ATH_MCI_HI_PRIO              60
3778344Sobrien#define ATH_MCI_NUM_BT_CHANNELS      79
3878344Sobrien#define ATH_MCI_CONCUR_TX_SWITCH      5
3978344Sobrien
4078344Sobrien#define MCI_GPM_SET_CHANNEL_BIT(_p_gpm, _bt_chan)			  \
4178344Sobrien	do {								  \
4278344Sobrien		if (_bt_chan < ATH_MCI_NUM_BT_CHANNELS) {		  \
4398186Sgordon			*(((u8 *)(_p_gpm)) + MCI_GPM_COEX_B_CHANNEL_MAP + \
4498186Sgordon				(_bt_chan / 8)) |= (1 << (_bt_chan & 7)); \
4598186Sgordon		}							  \
4698186Sgordon	} while (0)
4798186Sgordon
4898186Sgordon#define MCI_GPM_CLR_CHANNEL_BIT(_p_gpm, _bt_chan)			  \
49103018Sgordon	do {								  \
5098186Sgordon		if (_bt_chan < ATH_MCI_NUM_BT_CHANNELS) {		  \
51103018Sgordon			*(((u8 *)(_p_gpm)) + MCI_GPM_COEX_B_CHANNEL_MAP + \
5298186Sgordon				(_bt_chan / 8)) &= ~(1 << (_bt_chan & 7));\
5398186Sgordon		}							  \
5498186Sgordon	} while (0)
5598186Sgordon
5698186Sgordon#define INC_PROF(_mci, _info) do {		 \
5798186Sgordon		switch (_info->type) {		 \
5898186Sgordon		case MCI_GPM_COEX_PROFILE_RFCOMM:\
5998186Sgordon			_mci->num_other_acl++;	 \
6098186Sgordon			break;			 \
6178344Sobrien		case MCI_GPM_COEX_PROFILE_A2DP:	 \
6278344Sobrien			_mci->num_a2dp++;	 \
6378344Sobrien			if (!_info->edr)	 \
6478344Sobrien				_mci->num_bdr++; \
6598186Sgordon			break;			 \
6698186Sgordon		case MCI_GPM_COEX_PROFILE_HID:	 \
6798186Sgordon			_mci->num_hid++;	 \
6898186Sgordon			break;			 \
6998186Sgordon		case MCI_GPM_COEX_PROFILE_BNEP:	 \
7098186Sgordon			_mci->num_pan++;	 \
7198186Sgordon			break;			 \
7298186Sgordon		case MCI_GPM_COEX_PROFILE_VOICE: \
7398186Sgordon		case MCI_GPM_COEX_PROFILE_A2DPVO:\
7498186Sgordon			_mci->num_sco++;	 \
7598186Sgordon			break;			 \
7698186Sgordon		default:			 \
7798186Sgordon			break;			 \
7898186Sgordon		}				 \
7998186Sgordon	} while (0)
8098186Sgordon
8198186Sgordon#define DEC_PROF(_mci, _info) do {		 \
82103018Sgordon		switch (_info->type) {		 \
8398186Sgordon		case MCI_GPM_COEX_PROFILE_RFCOMM:\
8498186Sgordon			_mci->num_other_acl--;	 \
8598186Sgordon			break;			 \
8698186Sgordon		case MCI_GPM_COEX_PROFILE_A2DP:	 \
8798186Sgordon			_mci->num_a2dp--;	 \
8898186Sgordon			if (!_info->edr)	 \
8998186Sgordon				_mci->num_bdr--; \
9098186Sgordon			break;			 \
9198186Sgordon		case MCI_GPM_COEX_PROFILE_HID:	 \
9298186Sgordon			_mci->num_hid--;	 \
9398186Sgordon			break;			 \
9498186Sgordon		case MCI_GPM_COEX_PROFILE_BNEP:	 \
9598186Sgordon			_mci->num_pan--;	 \
9698186Sgordon			break;			 \
9798186Sgordon		case MCI_GPM_COEX_PROFILE_VOICE: \
9898186Sgordon		case MCI_GPM_COEX_PROFILE_A2DPVO:\
9998186Sgordon			_mci->num_sco--;	 \
10098186Sgordon			break;			 \
10198186Sgordon		default:			 \
10298186Sgordon			break;			 \
10398186Sgordon		}				 \
10498186Sgordon	} while (0)
10598186Sgordon
10698186Sgordon#define NUM_PROF(_mci)	(_mci->num_other_acl + _mci->num_a2dp + \
10798186Sgordon			 _mci->num_hid + _mci->num_pan + _mci->num_sco)
10898186Sgordon
10998186Sgordonstruct ath_mci_profile_info {
11098186Sgordon	u8 type;
11198186Sgordon	u8 conn_handle;
11298186Sgordon	bool start;
11398186Sgordon	bool master;
11498186Sgordon	bool edr;
11578344Sobrien	u8 voice_type;
11678344Sobrien	u16 T;		/* Voice: Tvoice, HID: Tsniff,        in slots */
11778344Sobrien	u8 W;		/* Voice: Wvoice, HID: Sniff timeout, in slots */
11878344Sobrien	u8 A;		/*		  HID: Sniff attempt, in slots */
11978344Sobrien	struct list_head list;
12078344Sobrien};
12178344Sobrien
12298186Sgordonstruct ath_mci_profile_status {
12378344Sobrien	bool is_critical;
12478344Sobrien	bool is_link;
12578344Sobrien	u8 conn_handle;
12678344Sobrien};
12778344Sobrien
12878344Sobrienstruct ath_mci_profile {
12978344Sobrien	struct list_head info;
13078344Sobrien	DECLARE_BITMAP(status, ATH_MCI_MAX_PROFILE);
13178344Sobrien	u16 aggr_limit;
13278344Sobrien	u8 num_mgmt;
13378344Sobrien	u8 num_sco;
13478344Sobrien	u8 num_a2dp;
135106643Sgordon	u8 num_hid;
13678344Sobrien	u8 num_pan;
13778344Sobrien	u8 num_other_acl;
13878344Sobrien	u8 num_bdr;
13978344Sobrien	u8 voice_priority;
14078344Sobrien};
14198186Sgordon
14298186Sgordonstruct ath_mci_buf {
14378344Sobrien	void *bf_addr;		/* virtual addr of desc */
14498186Sgordon	dma_addr_t bf_paddr;    /* physical addr of buffer */
14598186Sgordon	u32 bf_len;		/* len of data */
14698186Sgordon};
14798186Sgordon
14898186Sgordonstruct ath_mci_coex {
14998186Sgordon	struct ath_mci_buf sched_buf;
15098186Sgordon	struct ath_mci_buf gpm_buf;
15198186Sgordon};
15298186Sgordon
15378344Sobrienvoid ath_mci_flush_profile(struct ath_mci_profile *mci);
15498186Sgordonint ath_mci_setup(struct ath_softc *sc);
15598186Sgordonvoid ath_mci_cleanup(struct ath_softc *sc);
15698186Sgordonvoid ath_mci_intr(struct ath_softc *sc);
15798186Sgordonvoid ath9k_mci_update_rssi(struct ath_softc *sc);
15898186Sgordon
15978344Sobrien#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
16078344Sobrienvoid ath_mci_enable(struct ath_softc *sc);
16198186Sgordonvoid ath9k_mci_update_wlan_channels(struct ath_softc *sc, bool allow_all);
16278344Sobrienvoid ath9k_mci_set_txpower(struct ath_softc *sc, bool setchannel,
16378344Sobrien			   bool concur_tx);
16478344Sobrien#else
16578344Sobrienstatic inline void ath_mci_enable(struct ath_softc *sc)
16678344Sobrien{
16778344Sobrien}
16878344Sobrienstatic inline void ath9k_mci_update_wlan_channels(struct ath_softc *sc,
16978344Sobrien						  bool allow_all)
17098186Sgordon{
17178344Sobrien}
17278344Sobrienstatic inline void ath9k_mci_set_txpower(struct ath_softc *sc, bool setchannel,
17398186Sgordon					 bool concur_tx)
17478344Sobrien{
17578344Sobrien}
17678344Sobrien#endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */
17778344Sobrien
17898186Sgordon#endif /* MCI_H*/
17998186Sgordon