#ifndef __WLAN_QOS_H__
|
#define __WLAN_QOS_H__
|
#include "msg.h"
|
#include "cfg80211.h"
|
#include "wl_core.h"
|
#include <linux/skbuff.h>
|
#include "sprdwl.h"
|
|
typedef enum {
|
SPRDWL_AC_VO,
|
SPRDWL_AC_VI,
|
SPRDWL_AC_BE,
|
SPRDWL_AC_BK,
|
SPRDWL_AC_MAX,
|
} qos_head_type_t;
|
|
struct peer_list {
|
struct list_head head_list;
|
spinlock_t p_lock;/*peer list lock*/
|
atomic_t l_num;
|
/*u8 delay_flag;
|
u8 l_prio;*/
|
};
|
|
struct qos_list {
|
struct peer_list p_list[MAX_LUT_NUM];
|
};
|
|
struct tx_t {
|
int ac_index;
|
unsigned char lut_id;
|
atomic_t mode_list_num;
|
struct qos_list q_list[SPRDWL_AC_MAX];
|
/*int index;*/
|
/*int going[SPRDWL_AC_MAX];*/
|
/*high priority tx_index of two streams*/
|
/*tx ratio of two streams*/
|
/*int ratio;
|
unsigned char *dscp2up_table;*/
|
};
|
|
typedef enum {
|
prio_0 = 0,/* Mapped to AC_BE_Q */
|
prio_1 = 1,/* Mapped to AC_BK_Q */
|
prio_4 = 4,/* Mapped to AC_VI_Q */
|
prio_6 = 6,/* Mapped to AC_VO_Q */
|
} ip_pkt_prio_t;
|
|
struct qos_capab_info {
|
unsigned char id;
|
unsigned char len;
|
unsigned char qos_info[1];
|
};
|
|
struct dscp_range {
|
u8 low;
|
u8 high;
|
};
|
|
struct dscp_exception {
|
u8 dscp;
|
u8 up;
|
};
|
|
struct qos_map_range {
|
u8 low;
|
u8 high;
|
u8 up;
|
};
|
|
#define QOS_MAP_MAX_DSCP_EXCEPTION 21
|
|
struct qos_map_set {
|
struct dscp_exception qos_exceptions[QOS_MAP_MAX_DSCP_EXCEPTION];
|
struct qos_map_range qos_ranges[8];
|
};
|
|
#ifdef WMMAC_WFA_CERTIFICATION
|
#define NUM_AC 4
|
#define NUM_TID 16
|
#define WMMAC_EDCA_TIMEOUT_MS 1000
|
#define WMMAC_TIME_RATIO 12
|
|
#define WLAN_EID_VENDOR_SPECIFIC 221
|
#define OUI_MICROSOFT 0x0050f2 /* Microsoft (also used in Wi-Fi specs)
|
* 00:50:F2 */
|
#define WMM_OUI_TYPE 2
|
#define WMM_AC_ACM 0x10
|
|
|
typedef enum {
|
AC_BK = 0,
|
AC_BE = 1,
|
AC_VI = 2,
|
AC_VO = 3,
|
} edca_ac_t;
|
|
struct wmm_ac_ts_t {
|
bool exist;
|
u8 ac;
|
u8 up;
|
u8 direction;
|
u16 admitted_time;
|
};
|
#endif
|
|
#define INCR_RING_BUFF_INDX(indx, max_num) \
|
((((indx) + 1) < (max_num)) ? ((indx) + 1) : (0))
|
|
#define ETHER_ADDR_LEN 6
|
|
struct ether_header {
|
unsigned char ether_dhost[ETHER_ADDR_LEN];
|
unsigned char ether_shost[ETHER_ADDR_LEN];
|
unsigned short ether_type;
|
|
} __packed;
|
|
struct ethervlan_header {
|
unsigned char ether_dhost[ETHER_ADDR_LEN];
|
unsigned char ether_shost[ETHER_ADDR_LEN];
|
/* 0x8100 */
|
unsigned short vlan_type;
|
/* priority, cfi and vid */
|
unsigned short vlan_tag;
|
unsigned short ether_type;
|
};
|
/* 11u QoS map set */
|
#define DOT11_MNG_QOS_MAP_ID 110
|
/* DSCP ranges fixed with 8 entries */
|
#define QOS_MAP_FIXED_LENGTH (8 * 2)
|
/* header length */
|
#define TLV_HDR_LEN 2
|
|
/* user priority */
|
#define VLAN_PRI_SHIFT 13
|
/* 3 bits of priority */
|
#define VLAN_PRI_MASK 7
|
/* VLAN ethertype/Tag Protocol ID */
|
#define VLAN_TPID 0x8100
|
|
/* IPV4 and IPV6 common */
|
#define ETHER_TYPE_IP 0x0800
|
/* IPv6 */
|
#define ETHER_TYPE_IPV6 0x86dd
|
/* offset to version field */
|
#define IP_VER_OFFSET 0x0
|
/* version mask */
|
#define IP_VER_MASK 0xf0
|
/* version shift */
|
#define IP_VER_SHIFT 4
|
/* version number for IPV4 */
|
#define IP_VER_4 4
|
/* version number for IPV6 */
|
#define IP_VER_6 6
|
/* type of service offset */
|
#define IPV4_TOS_OFFSET 1
|
/* DiffServ codepoint shift */
|
#define IPV4_TOS_DSCP_SHIFT 2
|
#define IPV4_TOS(ipv4_body)\
|
(((unsigned char *)(ipv4_body))[IPV4_TOS_OFFSET])
|
/* Historical precedence shift */
|
#define IPV4_TOS_PREC_SHIFT 5
|
/* 802.1Q */
|
#define ETHER_TYPE_8021Q 0x8100
|
|
/* IPV6 field decodes */
|
#define IPV6_TRAFFIC_CLASS(ipv6_body) \
|
(((((unsigned char *)(ipv6_body))[0] & 0x0f) << 4) | \
|
((((unsigned char *)(ipv6_body))[1] & 0xf0) >> 4))
|
|
#define IP_VER(ip_body) \
|
((((unsigned char *)(ip_body))[IP_VER_OFFSET] & IP_VER_MASK) >> \
|
IP_VER_SHIFT)
|
|
/* IPV4 TOS or IPV6 Traffic Classifier or 0 */
|
#define IP_TOS46(ip_body) \
|
(IP_VER(ip_body) == IP_VER_4 ? IPV4_TOS(ip_body) : \
|
IP_VER(ip_body) == IP_VER_6 ? IPV6_TRAFFIC_CLASS(ip_body) : 0)
|
|
#define PKT_SET_PRIO(skb, x) (((struct sk_buff *)(skb))->priority = (x))
|
|
#define VI_TOTAL_QUOTA 1500
|
#define BE_TOTAL_QUOTA 200
|
#define BK_TOTAL_QUOTA 200
|
|
|
static inline u8 qos_index_2_tid(unsigned int qos_index)
|
{
|
unsigned char tid = 0;
|
|
switch (qos_index) {
|
case SPRDWL_AC_VO:
|
tid = 6;
|
break;
|
case SPRDWL_AC_VI:
|
tid = 4;
|
break;
|
case SPRDWL_AC_BK:
|
tid = 1;
|
break;
|
default:
|
tid = 0;
|
break;
|
}
|
return tid;
|
}
|
|
extern struct qos_map_set g_11u_qos_map;
|
void qos_init(struct tx_t *qos);
|
unsigned int qos_match_q(void *skb, int data_offset);
|
void qos_enable(int flag);
|
unsigned int pkt_get_prio(void *skb, int data_offset, unsigned char *tos);
|
#if 0
|
void qos_deinit(struct tx_t *qos);
|
void qos_sched_tx_most(struct tx_t *qos, struct qos_list **data_list);
|
void qos_set_dscp2up_table(unsigned char *dscp2up_table,
|
struct qos_capab_info *qos_map_ie);
|
struct qos_capab_info *qos_parse_capab_info(void *buf, int buflen, uint key);
|
void qos_sched(struct tx_t *qos, struct qos_list **q, int *num);
|
int qos_fq_ratio(struct tx_t *qos);
|
#endif
|
int get_list_num(struct list_head *list);
|
unsigned int tid_map_to_qosindex(unsigned char tid);
|
unsigned int get_tid_qosindex(void *skb, int data_offset, unsigned char *tid, unsigned char *tos);
|
#ifdef WMMAC_WFA_CERTIFICATION
|
void init_default_qos_map(void);
|
void wmm_ac_init(struct sprdwl_priv *priv);
|
void reset_wmmac_parameters(struct sprdwl_priv *priv);
|
void reset_wmmac_ts_info(void);
|
unsigned int map_edca_ac_to_priority(u8 ac);
|
unsigned int map_priority_to_edca_ac(int priority);
|
void update_wmmac_ts_info(u8 tsid, u8 up, u8 ac, bool status, u16 admitted_time);
|
void remove_wmmac_ts_info(u8 tsid);
|
void update_admitted_time(struct sprdwl_priv *priv, u8 tsid, u16 medium_time, bool increase);
|
u16 get_wmmac_admitted_time(u8 tsid);
|
void reset_wmmac_parameters(struct sprdwl_priv *priv);
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)
|
void update_wmmac_edcaftime_timeout(struct timer_list *t);
|
void update_wmmac_vo_timeout(struct timer_list *t);
|
void update_wmmac_vi_timeout(struct timer_list *t);
|
#else
|
void update_wmmac_edcaftime_timeout(unsigned long data);
|
void update_wmmac_vo_timeout(unsigned long data);
|
void update_wmmac_vi_timeout(unsigned long data);
|
#endif
|
unsigned int change_priority_if(struct sprdwl_priv *priv, unsigned char *tid, unsigned char *tos, u16 len);
|
const u8 *get_wmm_ie(u8 *res, u16 ie_len, u8 ie, uint oui, uint oui_type);
|
#endif
|
#endif
|