Commit | Line | Data |
---|---|---|
635d2b00 GKH |
1 | /***************************************************************************** |
2 | ||
95edd09e | 3 | (c) Cambridge Silicon Radio Limited 2012 |
635d2b00 GKH |
4 | All rights reserved and confidential information of CSR |
5 | ||
6 | Refer to LICENSE.txt included with this source for details | |
7 | on the license terms. | |
8 | ||
9 | *****************************************************************************/ | |
10 | ||
11 | /* | |
12 | * --------------------------------------------------------------------------- | |
13 | * FILE: csr_wifi_hip_ta_sampling.c | |
14 | * | |
15 | * PURPOSE: | |
16 | * The traffic analysis sampling module. | |
17 | * This gathers data which is sent to the SME and used to analyse | |
18 | * the traffic behaviour. | |
19 | * | |
20 | * Provides: | |
21 | * unifi_ta_sampling_init - Initialise the internal state | |
22 | * unifi_ta_sample - Sampling function, call this for every data packet | |
23 | * | |
24 | * Calls these external functions which must be provided: | |
25 | * unifi_ta_indicate_sampling - Pass sample data to the SME. | |
26 | * unifi_ta_indicate_protocol - Report certain data packet types to the SME. | |
27 | * --------------------------------------------------------------------------- | |
28 | */ | |
29 | ||
30 | #include "csr_wifi_hip_card_sdio.h" | |
31 | ||
32 | /* Maximum number of Tx frames we store each CYCLE_1, for detecting period */ | |
33 | #define TA_MAX_INTERVALS_IN_C1 100 | |
34 | ||
35 | /* Number of intervals in CYCLE_1 (one second), for detecting periodic */ | |
36 | /* Must match size of unifi_TrafficStats.intervals - 1 */ | |
37 | #define TA_INTERVALS_NUM 10 | |
38 | ||
39 | /* Step (in msecs) between intervals, for detecting periodic */ | |
40 | /* We are only interested in periods up to 100ms, i.e. between beacons */ | |
41 | /* This is correct for TA_INTERVALS_NUM=10 */ | |
42 | #define TA_INTERVALS_STEP 10 | |
43 | ||
44 | ||
45 | enum 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 | ||
95edd09e GKH |
72 | #define snap_802_2 0xAAAA0300 |
73 | #define oui_rfc1042 0x00000000 | |
74 | #define oui_8021h 0x0000f800 | |
7e6f5794 | 75 | static const u8 aironet_snap[5] = { 0x00, 0x40, 0x96, 0x00, 0x00 }; |
635d2b00 GKH |
76 | |
77 | ||
78 | /* | |
79 | * --------------------------------------------------------------------------- | |
80 | * ta_detect_protocol | |
81 | * | |
82 | * Internal only. | |
83 | * Detects a specific protocol in a frame and indicates a TA event. | |
84 | * | |
85 | * Arguments: | |
86 | * ta The pointer to the TA module. | |
87 | * direction The direction of the frame (tx or rx). | |
88 | * data Pointer to the structure that contains the data. | |
89 | * | |
90 | * Returns: | |
91 | * None | |
92 | * --------------------------------------------------------------------------- | |
93 | */ | |
94 | static enum ta_frame_identity ta_detect_protocol(card_t *card, CsrWifiRouterCtrlProtocolDirection direction, | |
95 | const bulk_data_desc_t *data, | |
7e6f5794 GKH |
96 | const u8 *saddr, |
97 | const u8 *sta_macaddr) | |
635d2b00 GKH |
98 | { |
99 | ta_data_t *tad = &card->ta_sampling; | |
8c87f69a GKH |
100 | u16 proto; |
101 | u16 source_port, dest_port; | |
635d2b00 | 102 | CsrWifiMacAddress srcAddress; |
26a6b2e1 | 103 | u32 snap_hdr, oui_hdr; |
635d2b00 GKH |
104 | |
105 | if (data->data_length < TA_LLC_HEADER_SIZE) | |
106 | { | |
107 | return TA_FRAME_UNKNOWN; | |
108 | } | |
109 | ||
26a6b2e1 GKH |
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); | |
95edd09e | 113 | if (snap_hdr != snap_802_2) |
635d2b00 GKH |
114 | { |
115 | return TA_FRAME_UNKNOWN; | |
116 | } | |
117 | ||
118 | if (tad->packet_filter & CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_CUSTOM) | |
119 | { | |
120 | /* | |
121 | * Here we would use the custom filter to detect interesting frames. | |
122 | */ | |
123 | } | |
124 | ||
26a6b2e1 GKH |
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); | |
95edd09e | 128 | if ((oui_hdr == oui_rfc1042) || (oui_hdr == oui_8021h)) |
635d2b00 GKH |
129 | { |
130 | proto = (data->os_data_ptr[TA_ETHERNET_TYPE_OFFSET] * 256) + | |
131 | data->os_data_ptr[TA_ETHERNET_TYPE_OFFSET + 1]; | |
132 | ||
133 | /* The only interesting IP frames are the DHCP */ | |
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; | |
7e6f5794 | 141 | u8 l4proto = data->os_data_ptr[TA_IP_TYPE_OFFSET]; |
635d2b00 GKH |
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 | /* detect DHCP frames */ | |
168 | if (tad->packet_filter & CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_DHCP) | |
169 | { | |
170 | /* DHCP frames are UDP frames with BOOTP ports */ | |
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 | /* The DHCP should have at least a message type (request, ack, nack, etc) */ | |
184 | if (data->data_length > TA_DHCP_MESSAGE_TYPE_OFFSET + 6) | |
185 | { | |
95edd09e | 186 | UNIFI_MAC_ADDRESS_COPY(srcAddress.a, saddr); |
635d2b00 GKH |
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 | /* DHCPACK is a special indication */ | |
95edd09e | 198 | if (UNIFI_MAC_ADDRESS_CMP(data->os_data_ptr + TA_BOOTP_CLIENT_MAC_ADDR_OFFSET, sta_macaddr) == TRUE) |
635d2b00 GKH |
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 | /* detect protocol type EAPOL or WAI (treated as equivalent here) */ | |
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 | { | |
95edd09e | 233 | UNIFI_MAC_ADDRESS_COPY(srcAddress.a, saddr); |
635d2b00 GKH |
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 | /* detect protocol type 0x0806 (ARP) */ | |
243 | if (tad->packet_filter & CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_ARP) | |
244 | { | |
245 | if (proto == TA_PROTO_TYPE_ARP) | |
246 | { | |
95edd09e | 247 | UNIFI_MAC_ADDRESS_COPY(srcAddress.a, saddr); |
635d2b00 GKH |
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 | /* detect Aironet frames */ | |
85a334e3 | 260 | if (!memcmp(data->os_data_ptr + 3, aironet_snap, 5)) |
635d2b00 | 261 | { |
95edd09e | 262 | UNIFI_MAC_ADDRESS_COPY(srcAddress.a, saddr); |
635d2b00 GKH |
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 | } /* ta_detect_protocol() */ | |
270 | ||
271 | ||
272 | static void tas_reset_data(ta_data_t *tad) | |
273 | { | |
ab2b8c73 | 274 | s16 i; |
635d2b00 GKH |
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 | } /* tas_reset_data() */ | |
294 | ||
295 | ||
296 | /* | |
297 | * --------------------------------------------------------------------------- | |
298 | * API. | |
299 | * unifi_ta_sampling_init | |
300 | * | |
301 | * (Re)Initialise the Traffic Analysis sampling module. | |
302 | * Resets the counters and timestamps. | |
303 | * | |
304 | * Arguments: | |
305 | * tad Pointer to a ta_data_t structure containing the | |
306 | * context for this device instance. | |
307 | * drv_priv An opaque pointer that the TA sampling module will | |
308 | * pass in call-outs. | |
309 | * | |
310 | * Returns: | |
311 | * None. | |
312 | * --------------------------------------------------------------------------- | |
313 | */ | |
314 | void 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 | } /* unifi_ta_sampling_init() */ | |
321 | ||
322 | ||
323 | /* | |
324 | * --------------------------------------------------------------------------- | |
325 | * API. | |
326 | * unifi_ta_sample | |
327 | * | |
328 | * Sample a data frame for the TA module. | |
329 | * This function stores all the useful information it can extract from | |
330 | * the frame and detects any specific protocols. | |
331 | * | |
332 | * Arguments: | |
333 | * tad The pointer to the TA sampling context struct. | |
334 | * direction The direction of the frame (rx, tx) | |
335 | * data Pointer to the frame data | |
336 | * saddr Source MAC address of frame. | |
337 | * timestamp Time (in msecs) that the frame was received. | |
338 | * rate Reported data rate for the rx frame (0 for tx frames) | |
339 | * | |
340 | * Returns: | |
341 | * None | |
342 | * --------------------------------------------------------------------------- | |
343 | */ | |
344 | void unifi_ta_sample(card_t *card, | |
345 | CsrWifiRouterCtrlProtocolDirection direction, | |
346 | const bulk_data_desc_t *data, | |
7e6f5794 GKH |
347 | const u8 *saddr, |
348 | const u8 *sta_macaddr, | |
26a6b2e1 | 349 | u32 timestamp, |
8c87f69a | 350 | u16 rate) |
635d2b00 GKH |
351 | { |
352 | ta_data_t *tad = &card->ta_sampling; | |
353 | enum ta_frame_identity identity; | |
26a6b2e1 | 354 | u32 time_delta; |
635d2b00 GKH |
355 | |
356 | ||
357 | ||
358 | /* Step1: Check for specific frames */ | |
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 | /* Step2: Update the information in the current record */ | |
370 | if (direction == CSR_WIFI_ROUTER_CTRL_PROTOCOL_DIRECTION_RX) | |
371 | { | |
372 | /* Update the Rx packet count and the throughput count */ | |
373 | tad->stats.rxFramesNum++; | |
374 | tad->stats.rxBytesCount += data->data_length; | |
375 | ||
376 | /* Accumulate packet Rx rates for later averaging */ | |
377 | tad->rx_sum_rate += rate; | |
378 | } | |
379 | else | |
380 | { | |
381 | if (identity == TA_FRAME_ETHERNET_INTERESTING) | |
382 | { | |
383 | /* | |
384 | * Store the period between the last and the current frame. | |
385 | * There is not point storing more than TA_MAX_INTERVALS_IN_C1 periods, | |
386 | * the traffic will be bursty or continuous. | |
387 | */ | |
388 | if (tad->stats.txFramesNum < TA_MAX_INTERVALS_IN_C1) | |
389 | { | |
26a6b2e1 GKH |
390 | u32 interval; |
391 | u32 index_in_intervals; | |
635d2b00 GKH |
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 | /* If the interval is interesting, update the t1_intervals count */ | |
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 | /* Update the Tx packet count... */ | |
409 | tad->stats.txFramesNum++; | |
410 | /* ... and the number of bytes for throughput. */ | |
411 | tad->stats.txBytesCount += data->data_length; | |
412 | } | |
413 | ||
414 | /* | |
415 | * If more than one second has elapsed since the last report, send | |
416 | * another one. | |
417 | */ | |
418 | /* Unsigned subtraction handles wrap-around from 0xFFFFFFFF to 0 */ | |
419 | time_delta = timestamp - tad->last_indication_time; | |
420 | if (time_delta >= 1000) | |
421 | { | |
422 | /* | |
423 | * rxFramesNum can be flashed in tas_reset_data() by another thread. | |
424 | * Use a temp to avoid division by zero. | |
425 | */ | |
26a6b2e1 | 426 | u32 temp_rxFramesNum; |
635d2b00 GKH |
427 | temp_rxFramesNum = tad->stats.rxFramesNum; |
428 | ||
429 | /* Calculate this interval's mean frame Rx rate from the sum */ | |
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 | * Send the information collected in the stats struct | |
441 | * to the SME and reset the counters. | |
442 | */ | |
443 | if (tad->packet_filter & CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_CUSTOM) | |
444 | { | |
26a6b2e1 GKH |
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; | |
635d2b00 GKH |
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 | } /* unifi_ta_sample() */ | |
462 | ||
463 | ||
464 | /* | |
465 | * --------------------------------------------------------------------------- | |
466 | * External API. | |
467 | * unifi_ta_configure | |
468 | * | |
469 | * Configures the TA module parameters. | |
470 | * | |
471 | * Arguments: | |
472 | * ta The pointer to the TA module. | |
473 | * config_type The type of the configuration request | |
474 | * config Pointer to the configuration parameters. | |
475 | * | |
476 | * Returns: | |
477 | * CSR_RESULT_SUCCESS on success, CSR error code otherwise | |
478 | * --------------------------------------------------------------------------- | |
479 | */ | |
480 | CsrResult 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 | /* Reinitialise our data when we are reset */ | |
487 | if (config_type == CSR_WIFI_ROUTER_CTRL_TRAFFIC_CONFIG_TYPE_RESET) | |
488 | { | |
489 | /* Reset the stats to zero */ | |
490 | tas_reset_data(tad); | |
491 | ||
492 | /* Reset the timer variables */ | |
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 | } /* unifi_ta_configure() */ | |
513 | ||
514 | ||
515 | /* | |
516 | * --------------------------------------------------------------------------- | |
517 | * External API. | |
518 | * unifi_ta_classification | |
519 | * | |
520 | * Configures the current TA classification. | |
521 | * | |
522 | * Arguments: | |
523 | * ta The pointer to the TA module. | |
524 | * traffic_type The classification type | |
525 | * period The traffic period if the type is periodic | |
526 | * | |
527 | * Returns: | |
528 | * None | |
529 | * --------------------------------------------------------------------------- | |
530 | */ | |
531 | void unifi_ta_classification(card_t *card, | |
532 | CsrWifiRouterCtrlTrafficType traffic_type, | |
8c87f69a | 533 | u16 period) |
635d2b00 GKH |
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 |