hc
2024-08-16 62c46c9150c4afde7e5b25436263fddf79d66f0b
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
#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