blob: 89677e0f4779935a371257fc57808c3450d8c23e [file] [log] [blame]
/*SH1
*******************************************************************************
** **
** Copyright (c) 2008 - 2009 Quantenna Communications Inc **
** All Rights Reserved **
** **
** Date : 01/28/09 **
** File : txbf_api.h **
** Description : **
** **
*******************************************************************************
** **
** Redistribution and use in source and binary forms, with or without **
** modification, are permitted provided that the following conditions **
** are met: **
** 1. Redistributions of source code must retain the above copyright **
** notice, this list of conditions and the following disclaimer. **
** 2. Redistributions in binary form must reproduce the above copyright **
** notice, this list of conditions and the following disclaimer in the **
** documentation and/or other materials provided with the distribution. **
** 3. The name of the author may not be used to endorse or promote products **
** derived from this software without specific prior written permission. **
** **
** Alternatively, this software may be distributed under the terms of the **
** GNU General Public License ("GPL") version 2, or (at your option) any **
** later version as published by the Free Software Foundation. **
** **
** In the case this software is distributed under the GPL license, **
** you should have received a copy of the GNU General Public License **
** along with this software; if not, write to the Free Software **
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA **
** **
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR **
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES**
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. **
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, **
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT **
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,**
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY **
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT **
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF **
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. **
** **
*******************************************************************************
EH1*/
#ifndef _TXBF_API_H_
#define _TXBF_API_H_
/*
* Enable installation of a fixed Q matrix in place of the derived ones.
* The matrix should be put in the file drivers/qdrv/fixedqmat.h
* The format of the data should be word values comma delimited.
*/
#define TXBF_CANNED_QMAT
#undef TXBF_CANNED_QMAT
/* Until we get 2 tx antennas working on a 2x4 station */
#define HAL_2x4STA_USE_4_TX_ANTENNAS
/*
* Comment this line to disable locking.
* Or set to 1 to enable manual locking.
* Or set to 0 to enable hw-centric automatic locking.
*/
#define QTN_TXBF_FFT_LOCK_MANUAL (1)
/* VHTTXBFTBD - 11ac BF enabled by default */
#define TXBF_ENABLE_VHT_BF
/* Use sw generated VHT BF path */
/* #define TXBF_VHT_SW_FEEDBACK */
/* #define TXBF_VHT_SW_UNCOMPRESSED */ /* for debugging */
/* Expansion Matrix Modes */
#define TXBF_MODE_NO_MATRIX 0
#define TXBF_MODE_DEFAULT_MATRIX 1
#define TXBF_MODE_BBF 2
#define TXBF_MODE_STD_BF 3
/* Enable (1) both hw and sw generated VHT BF feedback, used for debugging */
#define TXBF_VHT_HW_AND_SW_FEEDBACK 0
enum txbf_buff_state
{
/* Tx BF buffer for the frame is free */
TXBF_BUFF_FREE = 0,
/* The frame is stored in Tx BF buffer for processing and can not be released*/
TXBF_BUFF_IN_USE = 1,
/* Not used */
TXBF_DMA_FROM_BB = 2,
/* NDP only. The frame is being processed by DSP */
TXBF_DSP_PROC = 3,
/* DSP completes frame processing */
TXBF_DSP_DONE = 4,
/* For action frame only. Action frame is stored in action frame cache */
TXBF_DSP_STORED = 5
};
#define TXBF_BF_VER1 1 /* Envy */
#define TXBF_BF_VER2 2 /* 2 stream Ruby */
#define TXBF_BF_VER3 3 /* 4 stream non-tone grouping Ruby */
#define TXBF_BF_VER4 4 /* 4 stream tone grouping Ruby and later */
/*
* Version 4 means the action frames generated are now standards compliant
* and the BF parameters are derived from the various fields and association
* exchange, rather than from using a new version for each combination
*/
/*
* These structures are shared between Linux, MuC and DSP.
*/
struct txbf_ndp_info
{
char bw_mode;
char rxgain;
char MN;
char hwnoise;
char max_gain;
char macaddr[6];
signed char reg_scale_fac;
unsigned char Nsts;
unsigned char Ness;
};
#define TXBF_MUC_DSP_SHMEM_START (0x80060000)
#define QTN_MU_QMAT_MAX_SLOTS 3
/* Beamforming message types */
#define QTN_TXBF_NDP_RX_MSG 1
#define QTN_TXBF_ACT_FRM_TX_MSG 2
#define QTN_TXBF_ACT_FRM_RX_MSG 3
#define QTN_TXBF_ACT_FRM_FREE_MSG 4
#define QTN_TXBF_DEL_MU_NODE_MSG 5
#define QTN_TXBF_MU_GRP_UPD_DONE_MSG 6
#define QTN_TXBF_TRIG_MU_GRP_SEL_MSG 7
#define QTN_TXBF_RATE_TRAIN_MSG 8
#define QTN_TXBF_RATE_TRAIN_HASH_MSG 9
#define QTN_TXBF_NDP_DISCARD_MSG 10
#define QTN_TXBF_ACT_FRM_XTRA_HDR_LEN 10
#define QTN_TXBF_MODE_HT 0
#define QTN_TXBF_MODE_VHT 1
#define QTN_TXBF_NO_EXPMAT 0xFFFF
#define MU_NDPA_TOKEN_MASK 0x1F
/* Number of 10ms timeslots used on the DSP to process feedback */
#define QTN_TXBF_SU_DSP_TIMESLOTS 1
#define QTN_TXBF_MU_DSP_TIMESLOTS 2
/* We leave backward compatibility here. As SU token value was randomly chosen as 0x33
we now say when bit 5 is set it indicates SU sounding. */
#define MU_NDPA_SU_MASK 0x20
#define MU_NDPA_GRP_SND_MASK 0x10
#define IS_MU_GRP_SND(token) ((token) & MU_NDPA_GRP_SND_MASK)
/* TODO: Needs reworking. Some fields (at least mu_grp_id) are used only by
distinct message type */
struct txbf_pkts
{
unsigned msg_type;
unsigned state;
unsigned bf_ver;
unsigned bf_mode;
unsigned act_frame_phys;
unsigned buffer_start;
unsigned act_frame_len;
unsigned skb;
unsigned qmat_offset;
unsigned inst_1ss_def_mat;
unsigned success;
unsigned ndp_phys;
unsigned nstream;
unsigned bf_mimo_nc;
unsigned bf_mimo_nr;
unsigned bf_tone_grp;
unsigned bf_coeff_size;
unsigned bf_nss_snr[4];
unsigned bf_compressed;
unsigned bf_codebook;
unsigned pkt_indx;
unsigned short aid;
unsigned node_bw;
unsigned bw_pri_40m_lower;
unsigned bw_pri_20m_lower;
unsigned txbf_skip_dftmat_flag;
unsigned txbf_2x4sta_flag;
unsigned txbf_qmat_install_wait;
struct txbf_ndp_info ndp_info;
char act_frame_sa[6];
char act_frame_bssid[6];
char slot;
uint8_t mu_grp_id[QTN_MU_QMAT_MAX_SLOTS];
uint8_t vapid;
unsigned counter;
};
#define IEEE80211_ADDR_LEN 6
struct qtn_rate_train_info
{
unsigned msg_type;
unsigned state;
char src[IEEE80211_ADDR_LEN];
char dst[IEEE80211_ADDR_LEN];
unsigned ver;
unsigned nonce;
unsigned hash;
unsigned stamp;
unsigned ni;
void *next; /* Chaining for retry on mbox busy */
int index;
char devid;
char padding[15]; /* Cache aligned */
};
struct txbf_ctrl {
unsigned bf_tone_grp;
unsigned svd_mode;
unsigned bfoff_thresh;
};
typedef struct
{
signed int pad1:4;
signed int im:12;
signed int pad2:4;
signed int re:12;
} ndp_format;
typedef union
{
ndp_format ndp;
int wrd;
} bbmem_ndp;
typedef struct
{
/* Compq format BB0 20 bits */
signed int bb0_re_s0:8;
signed int bb0_im_s0:8;
signed int bb0_re_s1_lo:4;
/* Interleaved BB1 12 bits */
signed int bb1_re_s1_hi:4;
signed int bb1_im_s1:8;
/* Compq format BB0 12 bits */
signed int bb0_re_s1_hi:4;
signed int bb0_im_s1:8;
/* Interleaved BB1 20 bits */
signed int bb1_re_s0:8;
signed int bb1_im_s0:8;
signed int bb1_re_s1_lo:4;
}st_format;
typedef union
{
st_format st;
unsigned wrd[2];
} bbmem_st;
/*
* Maximum streams supported for different matrix types
*/
#define QTN_MAX_STREAMS 4
#define QTN_MAX_40M_VHT_STREAMS 2
#define QTN_MAX_20M_VHT_STREAMS 2
#define QTN_MAX_IOT_QMAT_STREAMS 3
/*
* Default decimation used for matrices in Q memory. Some matrices
* may use more decimation if space is a problem
*/
#define QTN_TXBF_DEFAULT_QMAT_NG 1
#define QTN_TXBF_MAX_QMAT_NG 2
#define NDP_TO_STVEC_SIZE_RATIO 4
#define NDP_START_DELAY 2 /* in seconds */
#define STVEC_SIZE_BYTES_1STRM_20M 0x100 /* Assumes NG 1 matrices */
#define STVEC_MAX_NODES 10
/*
* Matrix sizes for NG 1 matrices
*/
#define STVEC_SIZE_BYTES_1STRM_40M (STVEC_SIZE_BYTES_1STRM_20M << 1)
#define STVEC_SIZE_BYTES_1STRM_80M (STVEC_SIZE_BYTES_1STRM_40M << 1)
#define STVEC_SIZE_BYTES_2STRM_20M (STVEC_SIZE_BYTES_1STRM_20M << 1)
#define STVEC_SIZE_BYTES_2STRM_40M (STVEC_SIZE_BYTES_2STRM_20M << 1)
#define STVEC_SIZE_BYTES_2STRM_80M (STVEC_SIZE_BYTES_2STRM_40M << 1)
#define STVEC_SIZE_BYTES_3STRM_20M (STVEC_SIZE_BYTES_2STRM_20M + STVEC_SIZE_BYTES_1STRM_20M)
#define STVEC_SIZE_BYTES_3STRM_40M (STVEC_SIZE_BYTES_3STRM_20M << 1)
#define STVEC_SIZE_BYTES_3STRM_80M (STVEC_SIZE_BYTES_3STRM_40M << 1)
#define STVEC_SIZE_BYTES_4STRM_20M (STVEC_SIZE_BYTES_2STRM_20M << 1)
#define STVEC_SIZE_BYTES_4STRM_40M (STVEC_SIZE_BYTES_2STRM_40M << 1)
#define STVEC_SIZE_BYTES_4STRM_80M (STVEC_SIZE_BYTES_4STRM_40M << 1)
#define STVEC_SIZE_BYTES_1STRM_MAX STVEC_SIZE_BYTES_1STRM_80M
#define STVEC_SIZE_BYTES_2STRM_MAX STVEC_SIZE_BYTES_2STRM_80M
#define STVEC_SIZE_BYTES_3STRM_MAX STVEC_SIZE_BYTES_3STRM_80M
#define STVEC_SIZE_BYTES_4STRM_MAX STVEC_SIZE_BYTES_4STRM_80M
#ifndef QTN_BW_20M
# define QTN_BW_20M 0
# define QTN_BW_40M 1
# define QTN_BW_80M 2
#endif
#define QTN_BW_SW_MAX QTN_BW_80M
#define NDP_SIZE_BYTES_BASE 1024
#define NDP_SIZE_BYTES_20M (NDP_SIZE_BYTES_BASE << QTN_BW_20M)
#define NDP_SIZE_BYTES_40M (NDP_SIZE_BYTES_BASE << QTN_BW_40M)
#define NDP_SIZE_BYTES_80M (NDP_SIZE_BYTES_BASE << QTN_BW_80M)
#define NDP_SIZE_BYTES_MAX (NDP_SIZE_BYTES_BASE << QTN_BW_SW_MAX)
/*
* Q matrix defines for 80 MHz nodes using NG 1
*/
#define QTN_TXBF_QMAT80_1STRM_OFFSET(offset) (offset)
#define QTN_TXBF_QMAT80_1STRM_MAT_TOTAL (STVEC_SIZE_BYTES_1STRM_80M + \
STVEC_SIZE_BYTES_1STRM_40M + \
STVEC_SIZE_BYTES_1STRM_20M)
#define QTN_TXBF_QMAT80_2STRM_MAT_TOTAL (STVEC_SIZE_BYTES_2STRM_80M + \
STVEC_SIZE_BYTES_2STRM_40M + \
STVEC_SIZE_BYTES_2STRM_20M)
#define QTN_TXBF_QMAT80_3STRM_MAT_TOTAL (STVEC_SIZE_BYTES_3STRM_80M)
#define QTN_TXBF_QMAT80_4STRM_MAT_TOTAL (STVEC_SIZE_BYTES_4STRM_80M)
#define QTN_TXBF_QMAT80_1STRM_40M_OFFSET(offset) (offset + \
STVEC_SIZE_BYTES_1STRM_80M)
#define QTN_TXBF_QMAT80_1STRM_20M_OFFSET(offset) (offset + \
STVEC_SIZE_BYTES_1STRM_80M + \
STVEC_SIZE_BYTES_1STRM_40M)
#define QTN_TXBF_QMAT80_2STRM_OFFSET(offset) (offset + \
QTN_TXBF_QMAT80_1STRM_MAT_TOTAL)
#define QTN_TXBF_QMAT80_2STRM_40M_OFFSET(offset) (offset + \
QTN_TXBF_QMAT80_1STRM_MAT_TOTAL + \
STVEC_SIZE_BYTES_2STRM_80M)
#define QTN_TXBF_QMAT80_2STRM_20M_OFFSET(offset) (offset + \
QTN_TXBF_QMAT80_1STRM_MAT_TOTAL + \
STVEC_SIZE_BYTES_2STRM_80M + \
STVEC_SIZE_BYTES_2STRM_40M)
#define QTN_TXBF_QMAT80_3STRM_OFFSET(offset) (offset + \
QTN_TXBF_QMAT80_1STRM_MAT_TOTAL + \
QTN_TXBF_QMAT80_2STRM_MAT_TOTAL)
#define QTN_TXBF_QMAT80_4STRM_OFFSET(offset) (offset + \
QTN_TXBF_QMAT80_1STRM_MAT_TOTAL + \
QTN_TXBF_QMAT80_2STRM_MAT_TOTAL + \
QTN_TXBF_QMAT80_3STRM_MAT_TOTAL)
#define QTN_TXBF_QMAT80_TOTAL_SIZE (QTN_TXBF_QMAT80_1STRM_MAT_TOTAL + \
QTN_TXBF_QMAT80_2STRM_MAT_TOTAL + \
QTN_TXBF_QMAT80_3STRM_MAT_TOTAL + \
QTN_TXBF_QMAT80_4STRM_MAT_TOTAL)
/*
* Q matrix defines for 80 MHz nodes using NG 2
*/
#define QTN_TXBF_QMAT80_NG2_1STRM_OFFSET(offset) (offset)
#define QTN_TXBF_QMAT80_NG2_1STRM_MAT_TOTAL ((STVEC_SIZE_BYTES_1STRM_80M / 2) + \
( STVEC_SIZE_BYTES_1STRM_40M / 2) + \
(STVEC_SIZE_BYTES_1STRM_20M / 2))
#define QTN_TXBF_QMAT80_NG2_2STRM_MAT_TOTAL ((STVEC_SIZE_BYTES_2STRM_80M / 2) + \
(STVEC_SIZE_BYTES_2STRM_40M / 2) + \
(STVEC_SIZE_BYTES_2STRM_20M / 2))
#define QTN_TXBF_QMAT80_NG2_3STRM_MAT_TOTAL (STVEC_SIZE_BYTES_3STRM_80M / 2)
#define QTN_TXBF_QMAT80_NG2_4STRM_MAT_TOTAL (STVEC_SIZE_BYTES_4STRM_80M / 2)
#define QTN_TXBF_QMAT80_NG2_1STRM_40M_OFFSET(offset) (offset + \
(STVEC_SIZE_BYTES_1STRM_80M / 2))
#define QTN_TXBF_QMAT80_NG2_1STRM_20M_OFFSET(offset) (offset + \
(STVEC_SIZE_BYTES_1STRM_80M / 2) + \
(STVEC_SIZE_BYTES_1STRM_40M / 2))
#define QTN_TXBF_QMAT80_NG2_2STRM_OFFSET(offset) (offset + \
QTN_TXBF_QMAT80_NG2_1STRM_MAT_TOTAL)
#define QTN_TXBF_QMAT80_NG2_2STRM_40M_OFFSET(offset) (offset + \
QTN_TXBF_QMAT80_NG2_1STRM_MAT_TOTAL + \
(STVEC_SIZE_BYTES_2STRM_80M / 2))
#define QTN_TXBF_QMAT80_NG2_2STRM_20M_OFFSET(offset) (offset + \
QTN_TXBF_QMAT80_NG2_1STRM_MAT_TOTAL + \
(STVEC_SIZE_BYTES_2STRM_80M / 2) + \
(STVEC_SIZE_BYTES_2STRM_40M / 2))
#define QTN_TXBF_QMAT80_NG2_3STRM_OFFSET(offset) (offset + \
QTN_TXBF_QMAT80_NG2_1STRM_MAT_TOTAL + \
QTN_TXBF_QMAT80_NG2_2STRM_MAT_TOTAL)
#define QTN_TXBF_QMAT80_NG2_4STRM_OFFSET(offset) (offset + \
QTN_TXBF_QMAT80_NG2_1STRM_MAT_TOTAL + \
QTN_TXBF_QMAT80_NG2_2STRM_MAT_TOTAL + \
QTN_TXBF_QMAT80_NG2_3STRM_MAT_TOTAL)
#define QTN_TXBF_QMAT80_NG2_TOTAL_SIZE (QTN_TXBF_QMAT80_1STRM_MAT_TOTAL + \
QTN_TXBF_QMAT80_NG2_2STRM_MAT_TOTAL + \
QTN_TXBF_QMAT80_NG2_3STRM_MAT_TOTAL + \
QTN_TXBF_QMAT80_NG2_4STRM_MAT_TOTAL)
/*
* Q matrix defines for 40 MHz nodes using NG 1
*/
#define QTN_TXBF_QMAT40_1STRM_MAT_TOTAL (STVEC_SIZE_BYTES_1STRM_40M + \
STVEC_SIZE_BYTES_1STRM_20M)
#define QTN_TXBF_QMAT40_2STRM_MAT_TOTAL (STVEC_SIZE_BYTES_2STRM_40M + \
STVEC_SIZE_BYTES_2STRM_20M)
#define QTN_TXBF_QMAT40_3STRM_MAT_TOTAL (STVEC_SIZE_BYTES_3STRM_40M)
#define QTN_TXBF_QMAT40_4STRM_MAT_TOTAL (STVEC_SIZE_BYTES_4STRM_40M)
#define QTN_TXBF_QMAT40_1STRM_OFFSET(offset) (offset)
#define QTN_TXBF_QMAT40_1STRM_40M_OFFSET(offset) (offset)
#define QTN_TXBF_QMAT40_1STRM_20M_OFFSET(offset) (offset + \
STVEC_SIZE_BYTES_1STRM_40M)
#define QTN_TXBF_QMAT40_2STRM_OFFSET(offset) (offset + \
QTN_TXBF_QMAT40_1STRM_MAT_TOTAL)
#define QTN_TXBF_QMAT40_2STRM_40M_OFFSET(offset) (offset + \
QTN_TXBF_QMAT40_1STRM_MAT_TOTAL)
#define QTN_TXBF_QMAT40_2STRM_20M_OFFSET(offset) (offset + \
QTN_TXBF_QMAT40_1STRM_MAT_TOTAL + \
STVEC_SIZE_BYTES_2STRM_40M)
#define QTN_TXBF_QMAT40_3STRM_OFFSET(offset) (offset + \
QTN_TXBF_QMAT40_1STRM_MAT_TOTAL + \
QTN_TXBF_QMAT40_2STRM_MAT_TOTAL)
#define QTN_TXBF_QMAT40_4STRM_OFFSET(offset) (offset + \
QTN_TXBF_QMAT40_1STRM_MAT_TOTAL + \
QTN_TXBF_QMAT40_2STRM_MAT_TOTAL + \
QTN_TXBF_QMAT40_3STRM_MAT_TOTAL)
#define QTN_TXBF_QMAT40_TOTAL_SIZE (QTN_TXBF_QMAT40_1STRM_MAT_TOTAL + \
QTN_TXBF_QMAT40_2STRM_MAT_TOTAL + \
QTN_TXBF_QMAT40_3STRM_MAT_TOTAL + \
QTN_TXBF_QMAT40_4STRM_MAT_TOTAL)
/*
* Defines for dividing Q memory into slots for nodes using standard BF
*/
#define QTN_TXBF_QMAT_SLOT_SIZE MAX(QTN_TXBF_QMAT40_TOTAL_SIZE, \
QTN_TXBF_QMAT80_TOTAL_SIZE / 2)
#define QTN_TXBF_QMAT_SLOTS_USED(qn) (MAX(1, ((qn)->qn_node.ni_bw_cap >> \
MAX(((qn)->qn_expmat.ng - QTN_TXBF_DEFAULT_QMAT_NG), 0))))
#define QTN_TXBF_QMAT_SLOT(idx) ((idx) * QTN_TXBF_QMAT_SLOT_SIZE)
#define QTN_TXBF_QMAT_OFFSET_SHIFT 6
/*
* Defines for fixed matrix (BBF and default) sizes
*/
#define QTN_TXBF_QMAT_MIN_OFFSET (1 << QTN_TXBF_QMAT_OFFSET_SHIFT)
#define QTN_TXBF_1SS_WORDS_PER_TONE 2
#define QTN_TXBF_2SS_WORDS_PER_TONE 4
#define QTN_TXBF_3SS_WORDS_PER_TONE 6
#define QTN_TXBF_4SS_WORDS_PER_TONE 8
#define QTN_TXBF_IOT_QMAT_1SS_WORDS (QTN_TXBF_IOT_QMAT_TONES * \
QTN_TXBF_1SS_WORDS_PER_TONE)
#define QTN_TXBF_IOT_QMAT_2SS_WORDS (QTN_TXBF_IOT_QMAT_TONES * \
QTN_TXBF_2SS_WORDS_PER_TONE)
#define QTN_TXBF_IOT_QMAT_3SS_WORDS (QTN_TXBF_IOT_QMAT_TONES * \
QTN_TXBF_3SS_WORDS_PER_TONE)
#define QTN_TXBF_IOT_QMAT_4SS_WORDS (QTN_TXBF_IOT_QMAT_TONES * \
QTN_TXBF_4SS_WORDS_PER_TONE)
#define QTN_TXBF_IOT_QMAT_1SS_MEM MAX((QTN_TXBF_IOT_QMAT_1SS_WORDS * 4), \
QTN_TXBF_QMAT_MIN_OFFSET)
#define QTN_TXBF_IOT_QMAT_2SS_MEM MAX((QTN_TXBF_IOT_QMAT_2SS_WORDS * 4), \
QTN_TXBF_QMAT_MIN_OFFSET)
#define QTN_TXBF_IOT_QMAT_3SS_MEM MAX((QTN_TXBF_IOT_QMAT_3SS_WORDS * 4), \
QTN_TXBF_QMAT_MIN_OFFSET)
#define QTN_TXBF_IOT_QMAT_4SS_MEM MAX((QTN_TXBF_IOT_QMAT_4SS_WORDS * 4), \
QTN_TXBF_QMAT_MIN_OFFSET)
#define QTN_TXBF_QMAT_FIXED_MAT_START (QTN_TXBF_QMAT_SLOT_SIZE * STVEC_MAX_NODES)
/*
* Fixed 2x4 node matrix definitions
*/
/*
* 80MHz 2x4 matrices need to start in normal BF area to fit,
* this is OK, as they are used on the station only at present
*/
#define QTN_TXBF_QMAT_2x4STA_1_STRM_OFFSET (QTN_TXBF_QMAT_SLOT_SIZE * (STVEC_MAX_NODES - 1))
#define QTN_TXBF_QMAT_2x4STA_2_STRM_OFFSET (QTN_TXBF_QMAT_2x4STA_1_STRM_OFFSET + \
STVEC_SIZE_BYTES_1STRM_80M)
#define QTN_TXBF_2x4STA_1SS_TONE_DATA {0x00400040, 0x00000000}
#define QTN_TXBF_2x4STA_2SS_TONE_DATA {0x00000040, 0x00400000, 0x00000000, 0x00000000}
/*
* Fixed default matrix offset definitions
*/
#define QTN_TXBF_QMAT_STD_START QTN_TXBF_QMAT_FIXED_MAT_START
#define QTN_TXBF_QMAT_STD_1_STRM_OFFSET QTN_TXBF_QMAT_STD_START
#define QTN_TXBF_QMAT_STD_2_STRM_OFFSET (QTN_TXBF_QMAT_STD_1_STRM_OFFSET + \
QTN_TXBF_IOT_QMAT_1SS_MEM)
#define QTN_TXBF_QMAT_STD_3_STRM_OFFSET (QTN_TXBF_QMAT_STD_2_STRM_OFFSET + \
QTN_TXBF_IOT_QMAT_2SS_MEM)
#define QTN_TXBF_QMAT_STD_4_STRM_OFFSET (QTN_TXBF_QMAT_STD_3_STRM_OFFSET + \
QTN_TXBF_IOT_QMAT_3SS_MEM)
#define QTN_TXBF_IOT_QMAT_START (QTN_TXBF_QMAT_STD_4_STRM_OFFSET + \
QTN_TXBF_IOT_QMAT_4SS_MEM)
#define QTN_TXBF_IOT_QMAT_TONES 2 /* number of tones for fixed matrices */
/*
* BBF slot and matrix offset definitions
*
* For each slot there is space for the probed matrix, plus the 1, 2 and 3 streams
* matrices for the index being used by that node
*/
#define QTN_TXBF_IOT_QMAT_MAX_SLOTS 9
#define QTN_TXBF_IOT_QMAT_NG 7
#define QTN_TXBF_IOT_QMAT_PER_SS 18
#define QTN_TXBF_IOT_QMAT_PROBE_MEM QTN_TXBF_IOT_QMAT_3SS_MEM
#define QTN_TXBF_IOT_QMAT_SLOT_SIZE (QTN_TXBF_IOT_QMAT_1SS_MEM + \
QTN_TXBF_IOT_QMAT_2SS_MEM + \
QTN_TXBF_IOT_QMAT_3SS_MEM + \
QTN_TXBF_IOT_QMAT_PROBE_MEM)
#define QTN_TXBF_IOT_QMAT_BASE_OFFSET(slot) (QTN_TXBF_IOT_QMAT_START + \
(QTN_TXBF_IOT_QMAT_SLOT_SIZE * (slot)))
#define QTN_TXBF_IOT_QMAT_1SS_OFFSET(slot) (QTN_TXBF_IOT_QMAT_BASE_OFFSET(slot))
#define QTN_TXBF_IOT_QMAT_2SS_OFFSET(slot) (QTN_TXBF_IOT_QMAT_BASE_OFFSET(slot) + \
QTN_TXBF_IOT_QMAT_1SS_MEM)
#define QTN_TXBF_IOT_QMAT_3SS_OFFSET(slot) (QTN_TXBF_IOT_QMAT_BASE_OFFSET(slot) + \
QTN_TXBF_IOT_QMAT_1SS_MEM + \
QTN_TXBF_IOT_QMAT_2SS_MEM)
#define QTN_TXBF_IOT_QMAT_PROBE_OFFSET(slot) (QTN_TXBF_IOT_QMAT_BASE_OFFSET(slot) + \
QTN_TXBF_IOT_QMAT_1SS_MEM + \
QTN_TXBF_IOT_QMAT_2SS_MEM + \
QTN_TXBF_IOT_QMAT_3SS_MEM)
#define FFT_TONE_20M_LO 1
#define FFT_TONE_20M_HI 28
#define FFT_TONE_40M_LO 2
#define FFT_TONE_40M_HI 58
#define QTN_TXBF_TONES_PER_CHAN 64
#define QTN_TXBF_MAX_TONES 128
#define QTN_TXBF_MIN_TONES 1
#define QTN_TXBF_MODE 4 /* 80MHz Mode */
enum {
SVD_MODE_STREAM_MIXING =0,
SVD_MODE_TWO_STREAM,
SVD_MODE_PER_ANT_SCALE,
SVD_MODE_CHANNEL_INV,
SVD_MODE_BYPASS,
};
#define SVD_MODE_GET(X,S) (( X >> S) & 1)
#define SVD_MODE_SET(S) (1 << S)
#if !defined(QTN_TXBF_FFT_LOCK_MANUAL) || (QTN_TXBF_FFT_LOCK_MANUAL == 1)
/* Locking is disabled or manual locking */
#define QT3_BB_MIMO_BF_RX_INIT_VAL (0x0A)
#define QT4_BB_MIMO_BF_RX_INIT_VAL (QT3_BB_MIMO_BF_RX_INIT_VAL)
#else
/* Automatic, hw-centric locking. */
#define QT3_BB_MIMO_BF_RX_INIT_VAL (0x0B)
#define QT4_BB_MIMO_BF_RX_INIT_VAL (QT3_BB_MIMO_BF_RX_INIT_VAL)
#endif
/* should be 64 bytes aligned (expmat ptr in TxVector drops lower 5 bits)*/
struct phys_qmat_layout {
uint64_t length;
int8_t body[0];
} __packed;
// TODO: describe bodies as 2 dimensional arrays
struct phys_qmat_1x1 {
uint64_t length;
int8_t body[STVEC_SIZE_BYTES_2STRM_80M];
} __packed;
struct phys_qmat_2x1 {
uint64_t length;
int8_t body[STVEC_SIZE_BYTES_3STRM_80M];
} __packed;
struct phys_qmat_3x1 {
uint64_t length;
int8_t body[STVEC_SIZE_BYTES_4STRM_80M];
} __packed;
struct phys_qmat_1x2 {
uint64_t length;
int8_t body[STVEC_SIZE_BYTES_3STRM_80M];
} __packed;
struct phys_qmat_1x3 {
uint64_t length;
int8_t body[STVEC_SIZE_BYTES_4STRM_80M];
} __packed;
struct phys_qmat_2x2 {
uint64_t length;
int8_t body[STVEC_SIZE_BYTES_4STRM_80M];
} __packed;
struct phys_qmat_dummy {
uint64_t length;
int8_t body[0x10];
} __packed;
/* structure to hold MU group qmatrix info */
struct qtn_sram_qmat {
uint8_t valid; /* set to 1 when it is occupied, 0 indicates it is free */
uint8_t grp_id; /* MU group id */
uint16_t tk; /* Token */
uint16_t u0_aid; /* user position 0 AID */
uint16_t u1_aid; /* user position 1 AID */
int32_t rank;
/* Number of following Q matrix elements */
#define MU_QMAT_ELEM_NUM 6
/* matrix starting addresses in sram */
uint32_t u0_1ss_u1_1ss;
uint32_t u0_2ss_u1_1ss;
uint32_t u0_3ss_u1_1ss;
uint32_t u0_1ss_u1_2ss;
uint32_t u0_1ss_u1_3ss;
uint32_t u0_2ss_u1_2ss;
uint32_t dsp_cnt;
} __packed;
struct qtn_grp_rank {
uint16_t u0_aid;
uint16_t u1_aid;
int32_t rank;
} __packed;
#define TXBF_MAX_NC 4
#define TXBF_MAX_NR 4
#define TXBF_MAX_NG 3
#define TXBF_MAX_BW 4 /* Multiple of 20 MHz channels */
#define TXBF_EXPMAT_TYPE_0_BYPASS 0
#define TXBF_EXPMAT_TYPE_2_QMEM_MODE 2
#define TXBF_EXPMAT_TYPE_5_QREG_MODE 5
#define QTN_TXBF_QMAT_STD_1SS_TONE_DATA {0x00400040, 0x00400040, 0x00400040, 0x00400040}
#define QTN_TXBF_QMAT_STD_2SS_TONE_DATA {0x002D002D, 0x2D00002D, 0x00D3002D, 0xD300002D, \
0x002D002D, 0x2D00002D, 0x00D3002D, 0xD300002D}
#define QTN_TXBF_QMAT_STD_3SS_TONE_DATA {0x00250025, 0x00250025, 0x00DB2500, 0x00DB0025, \
0x00250025, 0x00DBDB00, 0x00250025, 0x00250025, \
0x00DB2500, 0x00DB0025, 0x00250025, 0x00DBDB00}
#define QTN_TXBF_QMAT_STD_4SS_TONE_DATA {0x00000040, 0x00000000, 0x00400000, 0x00000000, \
0x00000000, 0x00000040, 0x00000000, 0x00400000, \
0x00000040, 0x00000000, 0x00400000, 0x00000000, \
0x00000000, 0x00000040, 0x00000000, 0x00400000}
static __inline__ uint8_t qtn_txbf_get_bf_qmat_offsets(uint32_t *expmat_ss, uint8_t max,
uint32_t qmat_base_offset, uint8_t node_bw, uint8_t bw, uint8_t ng)
{
if ((bw == QTN_BW_40M) && (node_bw == QTN_BW_80M)) {
if (ng == QTN_TXBF_DEFAULT_QMAT_NG) {
expmat_ss[0] = QTN_TXBF_QMAT80_1STRM_40M_OFFSET(qmat_base_offset);
expmat_ss[1] = QTN_TXBF_QMAT80_2STRM_40M_OFFSET(qmat_base_offset);
} else {
expmat_ss[0] = QTN_TXBF_QMAT80_NG2_1STRM_40M_OFFSET(qmat_base_offset);
expmat_ss[1] = QTN_TXBF_QMAT80_NG2_2STRM_40M_OFFSET(qmat_base_offset);
}
return (QTN_MAX_40M_VHT_STREAMS - 1);
} else if ((bw == QTN_BW_20M) && (node_bw > QTN_BW_20M)) {
if ((node_bw == QTN_BW_80M) && (ng == QTN_TXBF_DEFAULT_QMAT_NG)) {
expmat_ss[0] = QTN_TXBF_QMAT80_1STRM_20M_OFFSET(qmat_base_offset);
expmat_ss[1] = QTN_TXBF_QMAT80_2STRM_20M_OFFSET(qmat_base_offset);
} else if (node_bw == QTN_BW_80M) {
expmat_ss[0] = QTN_TXBF_QMAT80_NG2_1STRM_20M_OFFSET(qmat_base_offset);
expmat_ss[1] = QTN_TXBF_QMAT80_NG2_2STRM_20M_OFFSET(qmat_base_offset);
} else {
expmat_ss[0] = QTN_TXBF_QMAT40_1STRM_20M_OFFSET(qmat_base_offset);
expmat_ss[1] = QTN_TXBF_QMAT40_2STRM_20M_OFFSET(qmat_base_offset);
}
return (QTN_MAX_20M_VHT_STREAMS - 1);
}
if (node_bw == QTN_BW_80M) {
if (ng == QTN_TXBF_DEFAULT_QMAT_NG) {
expmat_ss[0] = QTN_TXBF_QMAT80_1STRM_OFFSET(qmat_base_offset);
expmat_ss[1] = QTN_TXBF_QMAT80_2STRM_OFFSET(qmat_base_offset);
} else {
expmat_ss[0] = QTN_TXBF_QMAT80_NG2_1STRM_OFFSET(qmat_base_offset);
expmat_ss[1] = QTN_TXBF_QMAT80_NG2_2STRM_OFFSET(qmat_base_offset);
}
if ((max == QTN_MAX_STREAMS) && (ng == QTN_TXBF_DEFAULT_QMAT_NG)) {
expmat_ss[2] = QTN_TXBF_QMAT80_3STRM_OFFSET(qmat_base_offset);
expmat_ss[3] = QTN_TXBF_QMAT80_4STRM_OFFSET(qmat_base_offset);
} else if (max == QTN_MAX_STREAMS) {
expmat_ss[2] = QTN_TXBF_QMAT80_NG2_3STRM_OFFSET(qmat_base_offset);
expmat_ss[3] = QTN_TXBF_QMAT80_NG2_4STRM_OFFSET(qmat_base_offset);
}
} else {
expmat_ss[0] = QTN_TXBF_QMAT40_1STRM_OFFSET(qmat_base_offset);
expmat_ss[1] = QTN_TXBF_QMAT40_2STRM_OFFSET(qmat_base_offset);
if (max == QTN_MAX_STREAMS) {
expmat_ss[2] = QTN_TXBF_QMAT40_3STRM_OFFSET(qmat_base_offset);
expmat_ss[3] = QTN_TXBF_QMAT40_4STRM_OFFSET(qmat_base_offset);
}
}
return (QTN_MAX_STREAMS - 1);
}
unsigned dsp_rt_hash(volatile struct qtn_rate_train_info *p_rate_info);
#endif /*TXBF_COMMON_H_*/