1*db86f07eSLuis R. Rodriguez /* 2*db86f07eSLuis R. Rodriguez * Copyright (c) 2009 Atheros Communications Inc. 3*db86f07eSLuis R. Rodriguez * 4*db86f07eSLuis R. Rodriguez * Permission to use, copy, modify, and/or distribute this software for any 5*db86f07eSLuis R. Rodriguez * purpose with or without fee is hereby granted, provided that the above 6*db86f07eSLuis R. Rodriguez * copyright notice and this permission notice appear in all copies. 7*db86f07eSLuis R. Rodriguez * 8*db86f07eSLuis R. Rodriguez * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9*db86f07eSLuis R. Rodriguez * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10*db86f07eSLuis R. Rodriguez * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11*db86f07eSLuis R. Rodriguez * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12*db86f07eSLuis R. Rodriguez * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13*db86f07eSLuis R. Rodriguez * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14*db86f07eSLuis R. Rodriguez * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15*db86f07eSLuis R. Rodriguez */ 16*db86f07eSLuis R. Rodriguez 17*db86f07eSLuis R. Rodriguez #include <net/mac80211.h> 18*db86f07eSLuis R. Rodriguez 19*db86f07eSLuis R. Rodriguez #include "../ath.h" 20*db86f07eSLuis R. Rodriguez #include "../debug.h" 21*db86f07eSLuis R. Rodriguez 22*db86f07eSLuis R. Rodriguez #include "hw.h" 23*db86f07eSLuis R. Rodriguez 24*db86f07eSLuis R. Rodriguez /* Common header for Atheros 802.11n base driver cores */ 25*db86f07eSLuis R. Rodriguez 26*db86f07eSLuis R. Rodriguez #define WME_NUM_TID 16 27*db86f07eSLuis R. Rodriguez #define WME_BA_BMP_SIZE 64 28*db86f07eSLuis R. Rodriguez #define WME_MAX_BA WME_BA_BMP_SIZE 29*db86f07eSLuis R. Rodriguez #define ATH_TID_MAX_BUFS (2 * WME_MAX_BA) 30*db86f07eSLuis R. Rodriguez 31*db86f07eSLuis R. Rodriguez #define WME_AC_BE 0 32*db86f07eSLuis R. Rodriguez #define WME_AC_BK 1 33*db86f07eSLuis R. Rodriguez #define WME_AC_VI 2 34*db86f07eSLuis R. Rodriguez #define WME_AC_VO 3 35*db86f07eSLuis R. Rodriguez #define WME_NUM_AC 4 36*db86f07eSLuis R. Rodriguez 37*db86f07eSLuis R. Rodriguez #define ATH_RSSI_DUMMY_MARKER 0x127 38*db86f07eSLuis R. Rodriguez #define ATH_RSSI_LPF_LEN 10 39*db86f07eSLuis R. Rodriguez #define RSSI_LPF_THRESHOLD -20 40*db86f07eSLuis R. Rodriguez #define ATH_RSSI_EP_MULTIPLIER (1<<7) 41*db86f07eSLuis R. Rodriguez #define ATH_EP_MUL(x, mul) ((x) * (mul)) 42*db86f07eSLuis R. Rodriguez #define ATH_RSSI_IN(x) (ATH_EP_MUL((x), ATH_RSSI_EP_MULTIPLIER)) 43*db86f07eSLuis R. Rodriguez #define ATH_LPF_RSSI(x, y, len) \ 44*db86f07eSLuis R. Rodriguez ((x != ATH_RSSI_DUMMY_MARKER) ? (((x) * ((len) - 1) + (y)) / (len)) : (y)) 45*db86f07eSLuis R. Rodriguez #define ATH_RSSI_LPF(x, y) do { \ 46*db86f07eSLuis R. Rodriguez if ((y) >= RSSI_LPF_THRESHOLD) \ 47*db86f07eSLuis R. Rodriguez x = ATH_LPF_RSSI((x), ATH_RSSI_IN((y)), ATH_RSSI_LPF_LEN); \ 48*db86f07eSLuis R. Rodriguez } while (0) 49*db86f07eSLuis R. Rodriguez #define ATH_EP_RND(x, mul) \ 50*db86f07eSLuis R. Rodriguez ((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul)) 51*db86f07eSLuis R. Rodriguez 52*db86f07eSLuis R. Rodriguez struct ath_atx_ac { 53*db86f07eSLuis R. Rodriguez int sched; 54*db86f07eSLuis R. Rodriguez int qnum; 55*db86f07eSLuis R. Rodriguez struct list_head list; 56*db86f07eSLuis R. Rodriguez struct list_head tid_q; 57*db86f07eSLuis R. Rodriguez }; 58*db86f07eSLuis R. Rodriguez 59*db86f07eSLuis R. Rodriguez struct ath_buf_state { 60*db86f07eSLuis R. Rodriguez int bfs_nframes; 61*db86f07eSLuis R. Rodriguez u16 bfs_al; 62*db86f07eSLuis R. Rodriguez u16 bfs_frmlen; 63*db86f07eSLuis R. Rodriguez int bfs_seqno; 64*db86f07eSLuis R. Rodriguez int bfs_tidno; 65*db86f07eSLuis R. Rodriguez int bfs_retries; 66*db86f07eSLuis R. Rodriguez u8 bf_type; 67*db86f07eSLuis R. Rodriguez u32 bfs_keyix; 68*db86f07eSLuis R. Rodriguez enum ath9k_key_type bfs_keytype; 69*db86f07eSLuis R. Rodriguez }; 70*db86f07eSLuis R. Rodriguez 71*db86f07eSLuis R. Rodriguez struct ath_buf { 72*db86f07eSLuis R. Rodriguez struct list_head list; 73*db86f07eSLuis R. Rodriguez struct ath_buf *bf_lastbf; /* last buf of this unit (a frame or 74*db86f07eSLuis R. Rodriguez an aggregate) */ 75*db86f07eSLuis R. Rodriguez struct ath_buf *bf_next; /* next subframe in the aggregate */ 76*db86f07eSLuis R. Rodriguez struct sk_buff *bf_mpdu; /* enclosing frame structure */ 77*db86f07eSLuis R. Rodriguez struct ath_desc *bf_desc; /* virtual addr of desc */ 78*db86f07eSLuis R. Rodriguez dma_addr_t bf_daddr; /* physical addr of desc */ 79*db86f07eSLuis R. Rodriguez dma_addr_t bf_buf_addr; /* physical addr of data buffer */ 80*db86f07eSLuis R. Rodriguez bool bf_stale; 81*db86f07eSLuis R. Rodriguez u16 bf_flags; 82*db86f07eSLuis R. Rodriguez struct ath_buf_state bf_state; 83*db86f07eSLuis R. Rodriguez dma_addr_t bf_dmacontext; 84*db86f07eSLuis R. Rodriguez }; 85*db86f07eSLuis R. Rodriguez 86*db86f07eSLuis R. Rodriguez struct ath_atx_tid { 87*db86f07eSLuis R. Rodriguez struct list_head list; 88*db86f07eSLuis R. Rodriguez struct list_head buf_q; 89*db86f07eSLuis R. Rodriguez struct ath_node *an; 90*db86f07eSLuis R. Rodriguez struct ath_atx_ac *ac; 91*db86f07eSLuis R. Rodriguez struct ath_buf *tx_buf[ATH_TID_MAX_BUFS]; 92*db86f07eSLuis R. Rodriguez u16 seq_start; 93*db86f07eSLuis R. Rodriguez u16 seq_next; 94*db86f07eSLuis R. Rodriguez u16 baw_size; 95*db86f07eSLuis R. Rodriguez int tidno; 96*db86f07eSLuis R. Rodriguez int baw_head; /* first un-acked tx buffer */ 97*db86f07eSLuis R. Rodriguez int baw_tail; /* next unused tx buffer slot */ 98*db86f07eSLuis R. Rodriguez int sched; 99*db86f07eSLuis R. Rodriguez int paused; 100*db86f07eSLuis R. Rodriguez u8 state; 101*db86f07eSLuis R. Rodriguez }; 102*db86f07eSLuis R. Rodriguez 103*db86f07eSLuis R. Rodriguez struct ath_node { 104*db86f07eSLuis R. Rodriguez struct ath_common *common; 105*db86f07eSLuis R. Rodriguez struct ath_atx_tid tid[WME_NUM_TID]; 106*db86f07eSLuis R. Rodriguez struct ath_atx_ac ac[WME_NUM_AC]; 107*db86f07eSLuis R. Rodriguez u16 maxampdu; 108*db86f07eSLuis R. Rodriguez u8 mpdudensity; 109*db86f07eSLuis R. Rodriguez int last_rssi; 110*db86f07eSLuis R. Rodriguez }; 111*db86f07eSLuis R. Rodriguez 112*db86f07eSLuis R. Rodriguez int ath9k_cmn_rx_skb_preprocess(struct ath_common *common, 113*db86f07eSLuis R. Rodriguez struct ieee80211_hw *hw, 114*db86f07eSLuis R. Rodriguez struct sk_buff *skb, 115*db86f07eSLuis R. Rodriguez struct ath_rx_status *rx_stats, 116*db86f07eSLuis R. Rodriguez struct ieee80211_rx_status *rx_status, 117*db86f07eSLuis R. Rodriguez bool *decrypt_error); 118*db86f07eSLuis R. Rodriguez 119*db86f07eSLuis R. Rodriguez void ath9k_cmn_rx_skb_postprocess(struct ath_common *common, 120*db86f07eSLuis R. Rodriguez struct sk_buff *skb, 121*db86f07eSLuis R. Rodriguez struct ath_rx_status *rx_stats, 122*db86f07eSLuis R. Rodriguez struct ieee80211_rx_status *rxs, 123*db86f07eSLuis R. Rodriguez bool decrypt_error); 124