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#include "csr_wifi_hip_card_sdio.h"
31
32
33#define TA_MAX_INTERVALS_IN_C1 100
34
35
36
37#define TA_INTERVALS_NUM 10
38
39
40
41
42#define TA_INTERVALS_STEP 10
43
44
45enum ta_frame_identity
46{
47 TA_FRAME_UNKNOWN,
48 TA_FRAME_ETHERNET_UNINTERESTING,
49 TA_FRAME_ETHERNET_INTERESTING
50};
51
52
53#define TA_ETHERNET_TYPE_OFFSET 6
54#define TA_LLC_HEADER_SIZE 8
55#define TA_IP_TYPE_OFFSET 17
56#define TA_UDP_SOURCE_PORT_OFFSET 28
57#define TA_UDP_DEST_PORT_OFFSET (TA_UDP_SOURCE_PORT_OFFSET + 2)
58#define TA_BOOTP_CLIENT_MAC_ADDR_OFFSET 64
59#define TA_DHCP_MESSAGE_TYPE_OFFSET 278
60#define TA_DHCP_MESSAGE_TYPE_ACK 0x05
61#define TA_PROTO_TYPE_IP 0x0800
62#define TA_PROTO_TYPE_EAP 0x888E
63#define TA_PROTO_TYPE_WAI 0x8864
64#define TA_PROTO_TYPE_ARP 0x0806
65#define TA_IP_TYPE_TCP 0x06
66#define TA_IP_TYPE_UDP 0x11
67#define TA_UDP_PORT_BOOTPC 0x0044
68#define TA_UDP_PORT_BOOTPS 0x0043
69#define TA_EAPOL_TYPE_OFFSET 9
70#define TA_EAPOL_TYPE_START 0x01
71
72#define snap_802_2 0xAAAA0300
73#define oui_rfc1042 0x00000000
74#define oui_8021h 0x0000f800
75static const u8 aironet_snap[5] = { 0x00, 0x40, 0x96, 0x00, 0x00 };
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94static enum ta_frame_identity ta_detect_protocol(card_t *card, CsrWifiRouterCtrlProtocolDirection direction,
95 const bulk_data_desc_t *data,
96 const u8 *saddr,
97 const u8 *sta_macaddr)
98{
99 ta_data_t *tad = &card->ta_sampling;
100 u16 proto;
101 u16 source_port, dest_port;
102 CsrWifiMacAddress srcAddress;
103 u32 snap_hdr, oui_hdr;
104
105 if (data->data_length < TA_LLC_HEADER_SIZE)
106 {
107 return TA_FRAME_UNKNOWN;
108 }
109
110 snap_hdr = (((u32)data->os_data_ptr[0]) << 24) |
111 (((u32)data->os_data_ptr[1]) << 16) |
112 (((u32)data->os_data_ptr[2]) << 8);
113 if (snap_hdr != snap_802_2)
114 {
115 return TA_FRAME_UNKNOWN;
116 }
117
118 if (tad->packet_filter & CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_CUSTOM)
119 {
120
121
122
123 }
124
125 oui_hdr = (((u32)data->os_data_ptr[3]) << 24) |
126 (((u32)data->os_data_ptr[4]) << 16) |
127 (((u32)data->os_data_ptr[5]) << 8);
128 if ((oui_hdr == oui_rfc1042) || (oui_hdr == oui_8021h))
129 {
130 proto = (data->os_data_ptr[TA_ETHERNET_TYPE_OFFSET] * 256) +
131 data->os_data_ptr[TA_ETHERNET_TYPE_OFFSET + 1];
132
133
134 if (proto == TA_PROTO_TYPE_IP)
135 {
136 if (data->data_length > TA_IP_TYPE_OFFSET)
137 {
138 if (tad->packet_filter & CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_CUSTOM)
139 {
140 ta_l4stats_t *ta_l4stats = &tad->ta_l4stats;
141 u8 l4proto = data->os_data_ptr[TA_IP_TYPE_OFFSET];
142
143 if (l4proto == TA_IP_TYPE_TCP)
144 {
145 if (direction == CSR_WIFI_ROUTER_CTRL_PROTOCOL_DIRECTION_TX)
146 {
147 ta_l4stats->txTcpBytesCount += data->data_length;
148 }
149 else
150 {
151 ta_l4stats->rxTcpBytesCount += data->data_length;
152 }
153 }
154 else if (l4proto == TA_IP_TYPE_UDP)
155 {
156 if (direction == CSR_WIFI_ROUTER_CTRL_PROTOCOL_DIRECTION_TX)
157 {
158 ta_l4stats->txUdpBytesCount += data->data_length;
159 }
160 else
161 {
162 ta_l4stats->rxUdpBytesCount += data->data_length;
163 }
164 }
165 }
166
167
168 if (tad->packet_filter & CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_DHCP)
169 {
170
171 if (data->os_data_ptr[TA_IP_TYPE_OFFSET] == TA_IP_TYPE_UDP)
172 {
173 if (data->data_length > TA_UDP_DEST_PORT_OFFSET)
174 {
175 source_port = (data->os_data_ptr[TA_UDP_SOURCE_PORT_OFFSET] * 256) +
176 data->os_data_ptr[TA_UDP_SOURCE_PORT_OFFSET + 1];
177 dest_port = (data->os_data_ptr[TA_UDP_DEST_PORT_OFFSET] * 256) +
178 data->os_data_ptr[TA_UDP_DEST_PORT_OFFSET + 1];
179
180 if (((source_port == TA_UDP_PORT_BOOTPC) && (dest_port == TA_UDP_PORT_BOOTPS)) ||
181 ((source_port == TA_UDP_PORT_BOOTPS) && (dest_port == TA_UDP_PORT_BOOTPC)))
182 {
183
184 if (data->data_length > TA_DHCP_MESSAGE_TYPE_OFFSET + 6)
185 {
186 UNIFI_MAC_ADDRESS_COPY(srcAddress.a, saddr);
187
188 if (direction == CSR_WIFI_ROUTER_CTRL_PROTOCOL_DIRECTION_TX)
189 {
190 unifi_ta_indicate_protocol(card->ospriv,
191 CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_DHCP,
192 direction,
193 &srcAddress);
194 return TA_FRAME_ETHERNET_UNINTERESTING;
195 }
196
197
198 if (UNIFI_MAC_ADDRESS_CMP(data->os_data_ptr + TA_BOOTP_CLIENT_MAC_ADDR_OFFSET, sta_macaddr) == TRUE)
199 {
200 if (data->os_data_ptr[TA_DHCP_MESSAGE_TYPE_OFFSET] == TA_DHCP_MESSAGE_TYPE_ACK)
201 {
202 unifi_ta_indicate_protocol(card->ospriv,
203 CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_DHCP_ACK,
204 direction,
205 &srcAddress);
206 }
207 else
208 {
209 unifi_ta_indicate_protocol(card->ospriv,
210 CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_DHCP,
211 direction,
212 &srcAddress);
213 }
214 }
215 }
216 }
217 }
218 }
219 }
220 }
221
222 return TA_FRAME_ETHERNET_INTERESTING;
223 }
224
225
226 if (tad->packet_filter & CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_EAPOL)
227 {
228 if (TA_PROTO_TYPE_EAP == proto || TA_PROTO_TYPE_WAI == proto)
229 {
230 if ((TA_PROTO_TYPE_WAI == proto) || (direction != CSR_WIFI_ROUTER_CTRL_PROTOCOL_DIRECTION_TX) ||
231 (data->os_data_ptr[TA_EAPOL_TYPE_OFFSET] == TA_EAPOL_TYPE_START))
232 {
233 UNIFI_MAC_ADDRESS_COPY(srcAddress.a, saddr);
234 unifi_ta_indicate_protocol(card->ospriv,
235 CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_EAPOL,
236 direction, &srcAddress);
237 }
238 return TA_FRAME_ETHERNET_UNINTERESTING;
239 }
240 }
241
242
243 if (tad->packet_filter & CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_ARP)
244 {
245 if (proto == TA_PROTO_TYPE_ARP)
246 {
247 UNIFI_MAC_ADDRESS_COPY(srcAddress.a, saddr);
248 unifi_ta_indicate_protocol(card->ospriv,
249 CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_ARP,
250 direction, &srcAddress);
251 return TA_FRAME_ETHERNET_UNINTERESTING;
252 }
253 }
254
255 return TA_FRAME_ETHERNET_INTERESTING;
256 }
257 else if (tad->packet_filter & CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_AIRONET)
258 {
259
260 if (!memcmp(data->os_data_ptr + 3, aironet_snap, 5))
261 {
262 UNIFI_MAC_ADDRESS_COPY(srcAddress.a, saddr);
263 unifi_ta_indicate_protocol(card->ospriv, CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_AIRONET,
264 direction, &srcAddress);
265 }
266 }
267
268 return TA_FRAME_ETHERNET_UNINTERESTING;
269}
270
271
272static void tas_reset_data(ta_data_t *tad)
273{
274 s16 i;
275
276 for (i = 0; i < (TA_INTERVALS_NUM + 1); i++)
277 {
278 tad->stats.intervals[i] = 0;
279 }
280
281 tad->stats.rxFramesNum = 0;
282 tad->stats.txFramesNum = 0;
283 tad->stats.rxBytesCount = 0;
284 tad->stats.txBytesCount = 0;
285 tad->stats.rxMeanRate = 0;
286
287 tad->rx_sum_rate = 0;
288
289 tad->ta_l4stats.rxTcpBytesCount = 0;
290 tad->ta_l4stats.txTcpBytesCount = 0;
291 tad->ta_l4stats.rxUdpBytesCount = 0;
292 tad->ta_l4stats.txUdpBytesCount = 0;
293}
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314void unifi_ta_sampling_init(card_t *card)
315{
316 (void)unifi_ta_configure(card, CSR_WIFI_ROUTER_CTRL_TRAFFIC_CONFIG_TYPE_RESET, NULL);
317
318 card->ta_sampling.packet_filter = CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_NONE;
319 card->ta_sampling.traffic_type = CSR_WIFI_ROUTER_CTRL_TRAFFIC_TYPE_OCCASIONAL;
320}
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344void unifi_ta_sample(card_t *card,
345 CsrWifiRouterCtrlProtocolDirection direction,
346 const bulk_data_desc_t *data,
347 const u8 *saddr,
348 const u8 *sta_macaddr,
349 u32 timestamp,
350 u16 rate)
351{
352 ta_data_t *tad = &card->ta_sampling;
353 enum ta_frame_identity identity;
354 u32 time_delta;
355
356
357
358
359 if (tad->packet_filter != CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_NONE)
360 {
361 identity = ta_detect_protocol(card, direction, data, saddr, sta_macaddr);
362 }
363 else
364 {
365 identity = TA_FRAME_ETHERNET_INTERESTING;
366 }
367
368
369
370 if (direction == CSR_WIFI_ROUTER_CTRL_PROTOCOL_DIRECTION_RX)
371 {
372
373 tad->stats.rxFramesNum++;
374 tad->stats.rxBytesCount += data->data_length;
375
376
377 tad->rx_sum_rate += rate;
378 }
379 else
380 {
381 if (identity == TA_FRAME_ETHERNET_INTERESTING)
382 {
383
384
385
386
387
388 if (tad->stats.txFramesNum < TA_MAX_INTERVALS_IN_C1)
389 {
390 u32 interval;
391 u32 index_in_intervals;
392
393 interval = timestamp - tad->tx_last_ts;
394 tad->tx_last_ts = timestamp;
395 index_in_intervals = (interval + TA_INTERVALS_STEP / 2 - 1) / TA_INTERVALS_STEP;
396
397
398 if (index_in_intervals <= TA_INTERVALS_NUM)
399 {
400 unifi_trace(card->ospriv, UDBG5,
401 "unifi_ta_sample: TX interval=%d index=%d\n",
402 interval, index_in_intervals);
403 tad->stats.intervals[index_in_intervals]++;
404 }
405 }
406 }
407
408
409 tad->stats.txFramesNum++;
410
411 tad->stats.txBytesCount += data->data_length;
412 }
413
414
415
416
417
418
419 time_delta = timestamp - tad->last_indication_time;
420 if (time_delta >= 1000)
421 {
422
423
424
425
426 u32 temp_rxFramesNum;
427 temp_rxFramesNum = tad->stats.rxFramesNum;
428
429
430 if (temp_rxFramesNum)
431 {
432 tad->stats.rxMeanRate = tad->rx_sum_rate / temp_rxFramesNum;
433 }
434 unifi_trace(card->ospriv, UDBG5,
435 "unifi_ta_sample: RX fr=%lu, r=%u, sum=%lu, av=%lu\n",
436 tad->stats.rxFramesNum, rate,
437 tad->rx_sum_rate, tad->stats.rxMeanRate);
438
439
440
441
442
443 if (tad->packet_filter & CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_CUSTOM)
444 {
445 u32 rxTcpThroughput = tad->ta_l4stats.rxTcpBytesCount / time_delta;
446 u32 txTcpThroughput = tad->ta_l4stats.txTcpBytesCount / time_delta;
447 u32 rxUdpThroughput = tad->ta_l4stats.rxUdpBytesCount / time_delta;
448 u32 txUdpThroughput = tad->ta_l4stats.txUdpBytesCount / time_delta;
449
450 unifi_ta_indicate_l4stats(card->ospriv,
451 rxTcpThroughput,
452 txTcpThroughput,
453 rxUdpThroughput,
454 txUdpThroughput
455 );
456 }
457 unifi_ta_indicate_sampling(card->ospriv, &tad->stats);
458 tas_reset_data(tad);
459 tad->last_indication_time = timestamp;
460 }
461}
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480CsrResult unifi_ta_configure(card_t *card,
481 CsrWifiRouterCtrlTrafficConfigType config_type,
482 const CsrWifiRouterCtrlTrafficConfig *config)
483{
484 ta_data_t *tad = &card->ta_sampling;
485
486
487 if (config_type == CSR_WIFI_ROUTER_CTRL_TRAFFIC_CONFIG_TYPE_RESET)
488 {
489
490 tas_reset_data(tad);
491
492
493 tad->tx_last_ts = 0;
494 tad->last_indication_time = 0;
495
496 return CSR_RESULT_SUCCESS;
497 }
498
499 if (config_type == CSR_WIFI_ROUTER_CTRL_TRAFFIC_CONFIG_TYPE_FILTER)
500 {
501 tad->packet_filter = config->packetFilter;
502
503 if (tad->packet_filter & CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_CUSTOM)
504 {
505 tad->custom_filter = config->customFilter;
506 }
507
508 return CSR_RESULT_SUCCESS;
509 }
510
511 return CSR_RESULT_SUCCESS;
512}
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531void unifi_ta_classification(card_t *card,
532 CsrWifiRouterCtrlTrafficType traffic_type,
533 u16 period)
534{
535 unifi_trace(card->ospriv, UDBG3,
536 "Changed current ta classification to: %d\n", traffic_type);
537
538 card->ta_sampling.traffic_type = traffic_type;
539}
540
541
542