GFS2: Check for glock already held in gfs2_getxattr
[deliverable/linux.git] / drivers / staging / csr / sme_sys.c
CommitLineData
635d2b00
GKH
1/*
2 * ---------------------------------------------------------------------------
3 * FILE: sme_sys.c
4 *
5 * PURPOSE:
6 * Driver specific implementation of the SME SYS SAP.
7 * It is part of the porting exercise.
8 *
9 * Copyright (C) 2008-2011 by Cambridge Silicon Radio Ltd.
10 *
11 * Refer to LICENSE.txt included with this source code for details on
12 * the license terms.
13 *
14 * ---------------------------------------------------------------------------
15 */
16
17#include "csr_wifi_hip_unifiversion.h"
18#include "unifi_priv.h"
19#include "csr_wifi_hip_conversions.h"
20#ifdef CSR_SUPPORT_WEXT_AP
fa6173a0 21#include "csr_wifi_sme_sef.h"
635d2b00 22#endif
95edd09e 23
635d2b00
GKH
24/*
25 * This file implements the SME SYS API and contains the following functions:
26 * CsrWifiRouterCtrlMediaStatusReqHandler()
27 * CsrWifiRouterCtrlHipReqHandler()
28 * CsrWifiRouterCtrlPortConfigureReqHandler()
29 * CsrWifiRouterCtrlWifiOnReqHandler()
30 * CsrWifiRouterCtrlWifiOffReqHandler()
31 * CsrWifiRouterCtrlSuspendResHandler()
32 * CsrWifiRouterCtrlResumeResHandler()
33 * CsrWifiRouterCtrlQosControlReqHandler()
34 * CsrWifiRouterCtrlConfigurePowerModeReqHandler()
35 * CsrWifiRouterCtrlWifiOnResHandler()
36 * CsrWifiRouterCtrlWifiOffRspHandler()
37 * CsrWifiRouterCtrlMulticastAddressResHandler()
38 * CsrWifiRouterCtrlTrafficConfigReqHandler()
39 * CsrWifiRouterCtrlTrafficClassificationReqHandler()
40 * CsrWifiRouterCtrlTclasAddReqHandler()
41 * CsrWifiRouterCtrlTclasDelReqHandler()
42 * CsrWifiRouterCtrlSetModeReqHandler()
43 * CsrWifiRouterCtrlWapiMulticastFilterReqHandler()
635d2b00 44 * CsrWifiRouterCtrlWapiUnicastFilterReqHandler()
95edd09e
GKH
45 * CsrWifiRouterCtrlWapiUnicastTxPktReqHandler()
46 * CsrWifiRouterCtrlWapiRxPktReqHandler()
47 * CsrWifiRouterCtrlWapiFilterReqHandler()
635d2b00
GKH
48 */
49
50#ifdef CSR_SUPPORT_SME
51static void check_inactivity_timer_expire_func(unsigned long data);
52void uf_send_disconnected_ind_wq(struct work_struct *work);
53#endif
54
55void send_auto_ma_packet_confirm(unifi_priv_t *priv,
56 netInterface_priv_t *interfacePriv,
57 struct list_head *buffered_frames_list)
58{
59 tx_buffered_packets_t *buffered_frame_item = NULL;
60 struct list_head *listHead;
61 struct list_head *placeHolder;
62 int client_id;
63
64 CSR_SIGNAL unpacked_signal;
7e6f5794 65 u8 sigbuf[UNIFI_PACKED_SIGBUF_SIZE];
8c87f69a 66 u16 packed_siglen;
635d2b00
GKH
67
68
69 list_for_each_safe(listHead, placeHolder, buffered_frames_list)
70 {
71 buffered_frame_item = list_entry(listHead, tx_buffered_packets_t, q);
72
73 if(!buffered_frame_item) {
74 unifi_error(priv, "Entry should exist, otherwise it is a (BUG)\n");
75 continue;
76 }
77
78 if ((interfacePriv->interfaceMode != CSR_WIFI_ROUTER_CTRL_MODE_NONE) &&
79 (priv->wifi_on_state == wifi_on_done))
80 {
81
82 unifi_warning(priv, "Send MA_PACKET_CONFIRM to SenderProcessId = %x for (HostTag = %x TransmissionControl = %x)\n",
83 (buffered_frame_item->leSenderProcessId),
84 buffered_frame_item->hostTag,
85 buffered_frame_item->transmissionControl);
86
87 client_id = buffered_frame_item->leSenderProcessId & 0xFF00;
88
89 if (client_id == priv->sme_cli->sender_id)
90 {
91 /* construct a MA-PACKET.confirm message for SME */
92 memset(&unpacked_signal, 0, sizeof(unpacked_signal));
93 unpacked_signal.SignalPrimitiveHeader.SignalId = CSR_MA_PACKET_CONFIRM_ID;
94 unpacked_signal.SignalPrimitiveHeader.ReceiverProcessId = buffered_frame_item->leSenderProcessId;
95 unpacked_signal.SignalPrimitiveHeader.SenderProcessId = CSR_WIFI_ROUTER_IFACEQUEUE;
96
97 unpacked_signal.u.MaPacketConfirm.VirtualInterfaceIdentifier = uf_get_vif_identifier(interfacePriv->interfaceMode,
98 interfacePriv->InterfaceTag);
99 unpacked_signal.u.MaPacketConfirm.TransmissionStatus = CSR_RESULT_FAILURE;
100 unpacked_signal.u.MaPacketConfirm.RetryCount = 0;
101 unpacked_signal.u.MaPacketConfirm.Rate = buffered_frame_item->rate;
102 unpacked_signal.u.MaPacketConfirm.HostTag = buffered_frame_item->hostTag;
103
104 write_pack(&unpacked_signal, sigbuf, &packed_siglen);
105 unifi_warning(priv, "MA_PACKET_CONFIRM for SME (0x%x, 0x%x, 0x%x, 0x%x)\n",
106 unpacked_signal.SignalPrimitiveHeader.ReceiverProcessId,
107 unpacked_signal.SignalPrimitiveHeader.SenderProcessId,
108 unpacked_signal.u.MaPacketConfirm.VirtualInterfaceIdentifier,
109 unpacked_signal.u.MaPacketConfirm.HostTag);
110
111 CsrWifiRouterCtrlHipIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,
112 packed_siglen,
7e6f5794 113 (u8 *)sigbuf,
635d2b00
GKH
114 0, NULL,
115 0, NULL);
116 }
117 else if((buffered_frame_item->hostTag & 0x80000000))
118 {
119 /* construct a MA-PACKET.confirm message for NME */
120 unifi_warning(priv, "MA_PACKET_CONFIRM for NME (0x%x, 0x%x, 0x%x, 0x%x)\n",
121 buffered_frame_item->leSenderProcessId,
122 buffered_frame_item->interfaceTag,
123 buffered_frame_item->transmissionControl,
124 (buffered_frame_item->hostTag & 0x3FFFFFFF));
125
126 CsrWifiRouterMaPacketCfmSend((buffered_frame_item->leSenderProcessId & 0xFF),
127 buffered_frame_item->interfaceTag,
128 CSR_RESULT_FAILURE,
129 (buffered_frame_item->hostTag & 0x3FFFFFFF),
130 buffered_frame_item->rate);
131
132 }
133 else
134 {
135 unifi_warning(priv, "Buffered packet dropped without sending a confirm\n");
136 }
137
138 }
139
140 list_del(listHead);
141 kfree(buffered_frame_item);
142 buffered_frame_item = NULL;
143 }
144}
145
146void CsrWifiRouterCtrlMediaStatusReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
147{
148 unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
149 CsrWifiRouterCtrlMediaStatusReq* req = (CsrWifiRouterCtrlMediaStatusReq*)msg;
150 netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag];
151 unsigned long flags;
152
153 if (priv->smepriv == NULL) {
154 unifi_error(priv, "CsrWifiRouterCtrlMediaStatusReqHandler: invalid smepriv\n");
155 return;
156 }
157 if (req->interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
158 unifi_error(priv, "CsrWifiRouterCtrlMediaStatusReqHandler: invalid interfaceTag\n");
159 return;
160 }
6aac2e03 161 unifi_trace(priv, UDBG3, "CsrWifiRouterCtrlMediaStatusReqHandler: Mode = %d req->mediaStatus = %d\n", interfacePriv->interfaceMode, req->mediaStatus);
635d2b00
GKH
162 if (interfacePriv->interfaceMode != CSR_WIFI_ROUTER_CTRL_MODE_AMP) {
163 bulk_data_desc_t bulk_data;
164
165 bulk_data.data_length = 0;
166
167 spin_lock_irqsave(&priv->m4_lock, flags);
168 if (interfacePriv->m4_bulk_data.data_length > 0) {
169 bulk_data = interfacePriv->m4_bulk_data;
170 interfacePriv->m4_bulk_data.net_buf_length = 0;
171 interfacePriv->m4_bulk_data.data_length = 0;
172 interfacePriv->m4_bulk_data.os_data_ptr = interfacePriv->m4_bulk_data.os_net_buf_ptr = NULL;
173 }
174 spin_unlock_irqrestore(&priv->m4_lock, flags);
175
176 if (bulk_data.data_length != 0) {
177 unifi_trace(priv, UDBG5, "CsrWifiRouterCtrlMediaStatusReqHandler: free M4\n");
178 unifi_net_data_free(priv, &bulk_data);
179 }
180
181 if ((req->mediaStatus == CSR_WIFI_SME_MEDIA_STATUS_CONNECTED) &&
182 (interfacePriv->connected != UnifiConnected)) {
183
184 switch(interfacePriv->interfaceMode){
185 case CSR_WIFI_ROUTER_CTRL_MODE_AP:
186 case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO:
187 interfacePriv->connected = UnifiConnected;
188 netif_carrier_on(priv->netdev[req->interfaceTag]);
189#ifdef CSR_SUPPORT_WEXT
190 wext_send_started_event(priv);
191#endif
192 unifi_trace(priv, UDBG1,
193 "CsrWifiRouterCtrlMediaStatusReqHandler: AP/P2PGO setting netif_carrier_on\n");
4febd649 194 netif_tx_wake_all_queues(priv->netdev[req->interfaceTag]);
635d2b00
GKH
195 break;
196
197 default:
198#ifdef CSR_SUPPORT_WEXT
199 /* In the WEXT builds (sme and native), the userspace is not ready
200 * to process any EAPOL or WAPI packets, until it has been informed
201 * of the NETDEV_CHANGE.
202 */
203 if (interfacePriv->netdev_callback_registered && (interfacePriv->interfaceMode != CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI)) {
204 interfacePriv->wait_netdev_change = TRUE;
205 unifi_trace(priv, UDBG1,
206 "CsrWifiRouterCtrlMediaStatusReqHandler: waiting for NETDEV_CHANGE\n");
207 /*
208 * Carrier can go to on, only after wait_netdev_change is set to TRUE.
209 * Otherwise there can be a race in uf_netdev_event().
210 */
211 netif_carrier_on(priv->netdev[req->interfaceTag]);
212 unifi_trace(priv, UDBG1,
213 "CsrWifiRouterCtrlMediaStatusReqHandler: STA/P2PCLI setting netif_carrier_on\n");
214 }
215 else
216#endif
217 {
218 /* In the NME build, the userspace does not wait for the NETDEV_CHANGE
219 * so it is ready to process all the EAPOL or WAPI packets.
220 * At this point, we enable all the Tx queues, and we indicate any packets
221 * that are queued (and the respective port is opened).
222 */
223 static const CsrWifiMacAddress broadcast_address = {{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}};
224 interfacePriv->connected = UnifiConnected;
225 unifi_trace(priv, UDBG1,
226 "CsrWifiRouterMediaStatusReqHandler: UnifiConnected && netif_carrier_on\n");
227 netif_carrier_on(priv->netdev[req->interfaceTag]);
4febd649 228 netif_tx_wake_all_queues(priv->netdev[req->interfaceTag]);
635d2b00
GKH
229 uf_process_rx_pending_queue(priv, UF_UNCONTROLLED_PORT_Q, broadcast_address, 1, interfacePriv->InterfaceTag);
230 uf_process_rx_pending_queue(priv, UF_CONTROLLED_PORT_Q, broadcast_address, 1, interfacePriv->InterfaceTag);
231 }
232 break;
233 }
234 }
235
236 if (req->mediaStatus == CSR_WIFI_SME_MEDIA_STATUS_DISCONNECTED) {
237#ifdef CSR_SUPPORT_WEXT
238 unifi_trace(priv, UDBG1,
239 "CsrWifiRouterMediaStatusReqHandler: cancel waiting for NETDEV_CHANGE\n");
240 interfacePriv->wait_netdev_change = FALSE;
241#endif
242 unifi_trace(priv, UDBG1,
243 "CsrWifiRouterMediaStatusReqHandler: setting netif_carrier_off\n");
244 netif_carrier_off(priv->netdev[req->interfaceTag]);
245#ifdef CSR_SUPPORT_WEXT
246 switch(interfacePriv->interfaceMode){
247 case CSR_WIFI_ROUTER_CTRL_MODE_AP:
248 case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO:
249 wext_send_started_event(priv);
250 break;
251 default:
252 break;
253 }
254#endif
255 interfacePriv->connected = UnifiNotConnected;
256 }
257 } else {
258 /* For AMP, just update the L2 connected flag */
259 if (req->mediaStatus == CSR_WIFI_SME_MEDIA_STATUS_CONNECTED) {
260 unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlMediaStatusReqHandler: AMP connected\n");
261 interfacePriv->connected = UnifiConnected;
262 } else {
263 unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlMediaStatusReqHandler: AMP disconnected\n");
264 interfacePriv->connected = UnifiNotConnected;
265 }
266 }
267}
268
269
270void CsrWifiRouterCtrlHipReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
271{
272 unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
273 CsrWifiRouterCtrlHipReq* hipreq = (CsrWifiRouterCtrlHipReq*)msg;
274 bulk_data_param_t bulkdata;
275 u8 *signal_ptr;
276 int signal_length;
277 int r=0;
278 void *dest;
279 CsrResult csrResult;
280 CSR_SIGNAL *signal;
8c87f69a 281 u16 interfaceTag = 0;
635d2b00 282 CSR_MA_PACKET_REQUEST *req;
94b84e45 283 netInterface_priv_t *interfacePriv;
635d2b00
GKH
284
285 if (priv == NULL) {
286 return;
287 }
288 if (priv->smepriv == NULL) {
289 unifi_error(priv, "CsrWifiRouterCtrlHipReqHandler: invalid smepriv\n");
290 return;
291 }
292 if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
293 unifi_error(priv, "CsrWifiRouterCtrlHipReqHandler: invalid interfaceTag\n");
294 return;
295 }
296
94b84e45
PH
297 interfacePriv = priv->interfacePriv[interfaceTag];
298
635d2b00
GKH
299 /* Initialize bulkdata to avoid os_net_buf is garbage */
300 memset(&bulkdata, 0, sizeof(bulk_data_param_t));
301
302 signal = (CSR_SIGNAL *)hipreq->mlmeCommand;
303
304 unifi_trace(priv, UDBG4, "CsrWifiRouterCtrlHipReqHandler: 0x04%X ---->\n",
8c87f69a 305 *((u16*)hipreq->mlmeCommand));
635d2b00
GKH
306
307 /* Construct the signal. */
308 signal_ptr = (u8*)hipreq->mlmeCommand;
309 signal_length = hipreq->mlmeCommandLength;
310
311 /*
312 * The MSB of the sender ID needs to be set to the client ID.
313 * The LSB is controlled by the SME.
314 */
315 signal_ptr[5] = (priv->sme_cli->sender_id >> 8) & 0xff;
316
317 /* Allocate buffers for the bulk data. */
318 if (hipreq->dataRef1Length) {
319 csrResult = unifi_net_data_malloc(priv, &bulkdata.d[0], hipreq->dataRef1Length);
320 if (csrResult == CSR_RESULT_SUCCESS) {
321 dest = (void*)bulkdata.d[0].os_data_ptr;
322 memcpy(dest, hipreq->dataRef1, hipreq->dataRef1Length);
323 bulkdata.d[0].data_length = hipreq->dataRef1Length;
324 } else {
325 unifi_warning(priv, "signal not sent down, allocation failed in CsrWifiRouterCtrlHipReqHandler\n");
326 return;
327 }
328 } else {
329 bulkdata.d[0].os_data_ptr = NULL;
330 bulkdata.d[0].data_length = 0;
331 }
332 if (hipreq->dataRef2Length) {
333 csrResult = unifi_net_data_malloc(priv, &bulkdata.d[1], hipreq->dataRef2Length);
334 if (csrResult == CSR_RESULT_SUCCESS) {
335 dest = (void*)bulkdata.d[1].os_data_ptr;
336 memcpy(dest, hipreq->dataRef2, hipreq->dataRef2Length);
337 bulkdata.d[1].data_length = hipreq->dataRef2Length;
338 } else {
339 if (bulkdata.d[0].data_length)
340 {
341 unifi_net_data_free(priv, &bulkdata.d[0]);
342 }
343 unifi_warning(priv, "signal not sent down, allocation failed in CsrWifiRouterCtrlHipReqHandler\n");
344 return;
345 }
346 } else {
347 bulkdata.d[1].os_data_ptr = NULL;
348 bulkdata.d[1].data_length = 0;
349 }
350
351 unifi_trace(priv, UDBG3, "SME SEND: Signal 0x%.4X \n",
8c87f69a 352 *((u16*)signal_ptr));
635d2b00
GKH
353 if (signal->SignalPrimitiveHeader.SignalId == CSR_MA_PACKET_REQUEST_ID)
354 {
355 CSR_SIGNAL unpacked_signal;
356 read_unpack_signal((u8 *) signal, &unpacked_signal);
357 req = &unpacked_signal.u.MaPacketRequest;
358 interfaceTag = req->VirtualInterfaceIdentifier & 0xff;
359 switch(interfacePriv->interfaceMode)
360 {
361 case CSR_WIFI_ROUTER_CTRL_MODE_NONE:
362 unifi_error(priv, "CsrWifiRouterCtrlHipReqHandler: invalid mode: NONE \n");
363 break;
364 default:
365 unifi_trace(priv, UDBG5, "mode is %x\n", interfacePriv->interfaceMode);
366 }
367 /* While sending ensure that first 2 bits b31 and b30 are 00. These are used for local routing*/
368 r = uf_process_ma_packet_req(priv, req->Ra.x, (req->HostTag & 0x3FFFFFFF), interfaceTag,
369 req->TransmissionControl, req->TransmitRate,
370 req->Priority, signal->SignalPrimitiveHeader.SenderProcessId,
371 &bulkdata);
372 if (r)
373 {
374 if (bulkdata.d[0].data_length)
375 {
376 unifi_net_data_free(priv, &bulkdata.d[0]);
377 }
378 if (bulkdata.d[1].data_length)
379 {
380 unifi_net_data_free(priv, &bulkdata.d[1]);
381 }
382 }
383 } else {
384 /* ul_send_signal_raw frees the bulk data if it fails */
385 r = ul_send_signal_raw(priv, signal_ptr, signal_length, &bulkdata);
386 }
387
388 if (r) {
389 unifi_error(priv,
390 "CsrWifiRouterCtrlHipReqHandler: Failed to send signal (0x%.4X - %u)\n",
8c87f69a 391 *((u16*)signal_ptr), r);
6aac2e03 392 CsrWifiRouterCtrlWifiOffIndSend(priv->CSR_WIFI_SME_IFACEQUEUE, 0, CSR_WIFI_SME_CONTROL_INDICATION_ERROR);
635d2b00
GKH
393 }
394
395 unifi_trace(priv, UDBG4, "CsrWifiRouterCtrlHipReqHandler: <----\n");
396}
397
398#ifdef CSR_WIFI_SEND_GRATUITOUS_ARP
399static void
8c87f69a 400uf_send_gratuitous_arp(unifi_priv_t *priv, u16 interfaceTag)
635d2b00
GKH
401{
402 netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
403 CSR_PRIORITY priority;
404 CSR_SIGNAL signal;
405 bulk_data_param_t bulkdata;
406 CsrResult csrResult;
407 struct sk_buff *skb, *newSkb = NULL;
163eb0d8 408 s8 protection;
635d2b00 409 int r;
7e6f5794 410 static const u8 arp_req[36] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00,
635d2b00
GKH
411 0x08, 0x06, 0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x01,
412 0x00, 0x02, 0x5f, 0x20, 0x2f, 0x02,
413 0xc0, 0xa8, 0x00, 0x02,
414 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
415 0xc0, 0xa8, 0x00, 0x02};
416
635d2b00
GKH
417 csrResult = unifi_net_data_malloc(priv, &bulkdata.d[0], sizeof(arp_req));
418 if (csrResult != CSR_RESULT_SUCCESS)
419 {
420 unifi_error(priv, "Failed to allocate bulk data in CsrWifiSmeRoamCompleteIndHandler()\n");
421 return;
422 }
423 skb = (struct sk_buff *)(bulkdata.d[0].os_net_buf_ptr);
424 skb->len = bulkdata.d[0].data_length;
425
426 memcpy(skb->data, arp_req, sizeof(arp_req));
427 /* add MAC and IP address */
428 memcpy(skb->data + 16, priv->netdev[interfaceTag]->dev_addr, ETH_ALEN);
429 skb->data[22] = (priv->sta_ip_address ) & 0xFF;
430 skb->data[23] = (priv->sta_ip_address >> 8) & 0xFF;
431 skb->data[24] = (priv->sta_ip_address >> 16) & 0xFF;
432 skb->data[25] = (priv->sta_ip_address >> 24) & 0xFF;
433 skb->data[32] = (priv->sta_ip_address ) & 0xFF;
434 skb->data[33] = (priv->sta_ip_address >> 8) & 0xFF;
435 skb->data[34] = (priv->sta_ip_address >> 16) & 0xFF;
436 skb->data[35] = (priv->sta_ip_address >> 24) & 0xFF;
437
438 bulkdata.d[1].os_data_ptr = NULL;
439 bulkdata.d[1].os_net_buf_ptr = NULL;
440 bulkdata.d[1].net_buf_length = bulkdata.d[1].data_length = 0;
441
442 if ((protection = uf_get_protection_bit_from_interfacemode(priv, interfaceTag, &arp_req[26])) < 0)
443 {
444 unifi_error(priv, "CsrWifiSmeRoamCompleteIndHandler: Failed to determine protection mode\n");
445 unifi_net_data_free(priv, &bulkdata.d[0]);
446 return;
447 }
448
449 if ((priv->sta_wmm_capabilities & QOS_CAPABILITY_WMM_ENABLED) == 1)
450 {
451 priority = CSR_QOS_UP0;
452 }
453 else
454 {
455 priority = CSR_CONTENTION;
456 }
457
458 if (prepare_and_add_macheader(priv, skb, newSkb, priority, &bulkdata,
459 interfaceTag, &arp_req[26],
460 priv->netdev[interfaceTag]->dev_addr, protection))
461 {
462 unifi_error(priv, "CsrWifiSmeRoamCompleteIndHandler: failed to create MAC header\n");
463 unifi_net_data_free(priv, &bulkdata.d[0]);
464 return;
465 }
466 bulkdata.d[0].os_data_ptr = skb->data;
467 bulkdata.d[0].os_net_buf_ptr = skb;
468 bulkdata.d[0].data_length = skb->len;
469
470 unifi_frame_ma_packet_req(priv, priority, 0, 0xffffffff, interfaceTag,
471 CSR_NO_CONFIRM_REQUIRED, priv->netdev_client->sender_id,
472 interfacePriv->bssid.a, &signal);
473
474 r = ul_send_signal_unpacked(priv, &signal, &bulkdata);
475 if (r)
476 {
6aac2e03 477 unifi_error(priv, "CsrWifiSmeRoamCompleteIndHandler: failed to send QOS data null packet result: %d\n", r);
635d2b00
GKH
478 unifi_net_data_free(priv, &bulkdata.d[0]);
479 return;
480 }
481
635d2b00
GKH
482}
483#endif /* CSR_WIFI_SEND_GRATUITOUS_ARP */
484
485/*
486 * ---------------------------------------------------------------------------
487 * configure_data_port
488 *
489 * Store the new controlled port configuration.
490 *
491 * Arguments:
492 * priv Pointer to device private context struct
493 * port_cfg Pointer to the port configuration
494 *
495 * Returns:
496 * An unifi_ControlledPortAction value.
497 * ---------------------------------------------------------------------------
498 */
499static int
500configure_data_port(unifi_priv_t *priv,
501 CsrWifiRouterCtrlPortAction port_action,
502 const CsrWifiMacAddress *macAddress,
503 const int queue,
8c87f69a 504 u16 interfaceTag)
635d2b00 505{
7e6f5794 506 const u8 broadcast_mac_address[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
635d2b00
GKH
507 unifi_port_config_t *port;
508 netInterface_priv_t *interfacePriv;
509 int i;
510 const char* controlled_string; /* cosmetic "controlled"/"uncontrolled" for trace */
511
512 if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
513 unifi_error(priv, "configure_data_port: bad interfaceTag\n");
514 return -EFAULT;
515 }
516
517 interfacePriv = priv->interfacePriv[interfaceTag];
518
519 if (queue == UF_CONTROLLED_PORT_Q) {
520 port = &interfacePriv->controlled_data_port;
521 controlled_string = "controlled";
522 } else {
523 port = &interfacePriv->uncontrolled_data_port;
524 controlled_string = "uncontrolled";
525 }
526
a6737c73
AS
527 unifi_trace(priv, UDBG2,
528 "port config request %pM %s with port_action %d.\n",
529 macAddress->a, controlled_string, port_action);
635d2b00
GKH
530
531 /* If the new configuration has the broadcast MAC address or if we are in infrastructure mode then clear the list first and set port overide mode */
532 if ((CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode ||
533 interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI) ||
534 !memcmp(macAddress->a, broadcast_mac_address, ETH_ALEN)) {
535
536 port->port_cfg[0].port_action = port_action;
537 port->port_cfg[0].mac_address = *macAddress;
538 port->port_cfg[0].in_use = TRUE;
539 port->entries_in_use = 1;
540 port->overide_action = UF_DATA_PORT_OVERIDE;
541
542 unifi_trace(priv, UDBG2, "%s port override on\n",
543 (queue == UF_CONTROLLED_PORT_Q) ? "Controlled" : "Uncontrolled");
544
545 /* Discard the remaining entries in the port config table */
546 for (i = 1; i < UNIFI_MAX_CONNECTIONS; i++) {
547 port->port_cfg[i].in_use = FALSE;
548 }
549
550 if (port_action == CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN) {
551 unifi_trace(priv, UDBG1, "%s port broadcast set to open.\n",
552 (queue == UF_CONTROLLED_PORT_Q) ? "Controlled" : "Uncontrolled");
553
554 /*
555 * Ask stack to schedule for transmission any packets queued
556 * while controlled port was not open.
557 * Use netif_schedule() instead of netif_wake_queue() because
558 * transmission should be already enabled at this point. If it
559 * is not, probably the interface is down and should remain as is.
560 */
561 uf_resume_data_plane(priv, queue, *macAddress, interfaceTag);
562
563#ifdef CSR_WIFI_SEND_GRATUITOUS_ARP
564 if ((CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode) &&
565 (queue == UF_CONTROLLED_PORT_Q) && (priv->sta_ip_address != 0xFFFFFFFF))
566 {
567 uf_send_gratuitous_arp(priv, interfaceTag);
568 }
569#endif
570 } else {
571 unifi_trace(priv, UDBG1, "%s port broadcast set to %s.\n",
572 (queue == UF_CONTROLLED_PORT_Q) ? "Controlled" : "Uncontrolled",
573 (port_action == CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD) ? "discard": "closed");
574
575 /* If port is closed, discard all the pending Rx packets */
576 if (port_action == CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD) {
6aac2e03 577 uf_free_pending_rx_packets(priv, queue, *macAddress, interfaceTag);
635d2b00
GKH
578 }
579 }
580 } else {
581 /* store the new configuration, either in the entry with matching mac address (if already present),
582 * otherwise in a new entry
583 */
584
585 int found_entry_flag;
586 int first_free_slot = -1;
587
588 /* If leaving override mode, free the port entry used for override */
589 if (port->overide_action == UF_DATA_PORT_OVERIDE) {
590 port->port_cfg[0].in_use = FALSE;
591 port->entries_in_use = 0;
592 port->overide_action = UF_DATA_PORT_NOT_OVERIDE;
593
594 unifi_trace(priv, UDBG2, "%s port override off\n",
595 (queue == UF_CONTROLLED_PORT_Q) ? "Controlled" : "Uncontrolled");
596 }
597
598 found_entry_flag = 0;
599 for (i = 0; i < UNIFI_MAX_CONNECTIONS; i++) {
600 if (port->port_cfg[i].in_use) {
601 if (!memcmp(&port->port_cfg[i].mac_address.a, macAddress->a, ETH_ALEN)) {
602 /* We've seen this address before, reconfigure it */
603 port->port_cfg[i].port_action = port_action;
604 found_entry_flag = 1;
605 break;
606 }
607 } else if (first_free_slot == -1) {
608 /* Remember the first free slot on the way past so it can be claimed
609 * if this turns out to be a new MAC address (to save walking the list again).
610 */
611 first_free_slot = i;
612 }
613 }
614
615 /* At this point we found an existing entry and have updated it, or need to
616 * add a new entry. If all slots are allocated, give up and return an error.
617 */
618 if (!found_entry_flag) {
619 if (first_free_slot == -1) {
620 unifi_error(priv, "no free slot found in port config array (%d used)\n", port->entries_in_use);
621 return -EFAULT;
622 } else {
623 port->entries_in_use++;
624 }
625
626 unifi_trace(priv, UDBG3, "port config index assigned in config_data_port = %d\n", first_free_slot);
627 port->port_cfg[first_free_slot].in_use = TRUE;
628 port->port_cfg[first_free_slot].port_action = port_action;
629 port->port_cfg[first_free_slot].mac_address = *macAddress;
630 }
631
632 if (port_action == CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN) {
633 /*
634 * Ask stack to schedule for transmission any packets queued
635 * while controlled port was not open.
636 * Use netif_schedule() instead of netif_wake_queue() because
637 * transmission should be already enabled at this point. If it
638 * is not, probably the interface is down and should remain as is.
639 */
640 uf_resume_data_plane(priv, queue, *macAddress, interfaceTag);
641 }
642
643 /*
644 * If port is closed, discard all the pending Rx packets
645 * coming from the peer station.
646 */
647 if (port_action == CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD) {
6aac2e03 648 uf_free_pending_rx_packets(priv, queue, *macAddress, interfaceTag);
635d2b00
GKH
649 }
650
a6737c73
AS
651 unifi_trace(priv, UDBG2,
652 "port config %pM with port_action %d.\n",
653 macAddress->a, port_action);
635d2b00
GKH
654 }
655 return 0;
656} /* configure_data_port() */
657
658
659void CsrWifiRouterCtrlPortConfigureReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
660{
661 unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
662 CsrWifiRouterCtrlPortConfigureReq* req = (CsrWifiRouterCtrlPortConfigureReq*)msg;
663 netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag];
664
665 unifi_trace(priv, UDBG3, "entering CsrWifiRouterCtrlPortConfigureReqHandler\n");
666 if (priv->smepriv == NULL) {
667 unifi_error(priv, "CsrWifiRouterCtrlPortConfigureReqHandler: invalid smepriv\n");
668 return;
669 }
670
671 /* To update the protection status of the peer/station */
672 switch(interfacePriv->interfaceMode)
673 {
674 case CSR_WIFI_ROUTER_CTRL_MODE_STA:
675 case CSR_WIFI_ROUTER_CTRL_MODE_AMP:
676 case CSR_WIFI_ROUTER_CTRL_MODE_IBSS:
677 case CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI:
678 /* Since for Unifi as a station, the station record not maintained & interfaceID is
679 * only needed to update the peer protection status
680 */
681 interfacePriv->protect = req->setProtection;
682 break;
683 case CSR_WIFI_ROUTER_CTRL_MODE_AP:
684 case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO:
685 {
7e6f5794 686 u8 i;
635d2b00
GKH
687 CsrWifiRouterCtrlStaInfo_t *staRecord;
688 /* Ifscontrolled port is open means, The peer has been added to station record
689 * so that the protection corresponding to the peer is valid in this req
690 */
691 if (req->controlledPortAction == CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN) {
692 for(i =0; i < UNIFI_MAX_CONNECTIONS; i++) {
693 staRecord = (CsrWifiRouterCtrlStaInfo_t *) (interfacePriv->staInfo[i]);
694 if (staRecord) {
695 /* Find the matching station record & set the protection type */
696 if (!memcmp(req->macAddress.a, staRecord->peerMacAddress.a, ETH_ALEN)) {
697 staRecord->protection = req->setProtection;
698 break;
699 }
700 }
701 }
702 }
703 }
704 break;
705 default:
706 unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlPortConfigureReqHandler(0x%.4X) Uncaught mode %d\n",
707 msg->source, interfacePriv->interfaceMode);
708 }
709
710 configure_data_port(priv, req->uncontrolledPortAction, (const CsrWifiMacAddress *)&req->macAddress,
711 UF_UNCONTROLLED_PORT_Q, req->interfaceTag);
712 configure_data_port(priv, req->controlledPortAction, (const CsrWifiMacAddress *)&req->macAddress,
713 UF_CONTROLLED_PORT_Q, req->interfaceTag);
714
6aac2e03 715 CsrWifiRouterCtrlPortConfigureCfmSend(msg->source, req->clientData, req->interfaceTag,
635d2b00
GKH
716 CSR_RESULT_SUCCESS, req->macAddress);
717 unifi_trace(priv, UDBG3, "leaving CsrWifiRouterCtrlPortConfigureReqHandler\n");
718}
719
720
721void CsrWifiRouterCtrlWifiOnReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
722{
723 unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
724 CsrWifiRouterCtrlVersions versions;
725 CsrWifiRouterCtrlWifiOnReq* req = (CsrWifiRouterCtrlWifiOnReq*)msg;
6aac2e03 726 int r, i;
635d2b00
GKH
727 CsrResult csrResult;
728
729 if (priv == NULL) {
730 return;
731 }
95edd09e
GKH
732 if( priv->wol_suspend ) {
733 unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWifiOnReqHandler: Don't reset mode\n");
734 } else {
735#ifdef ANDROID_BUILD
736 /* Take the wakelock while Wi-Fi On is in progress */
737 unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWifiOnReqHandler: take wake lock\n");
738 wake_lock(&unifi_sdio_wake_lock);
739#endif
740 for (i=0; i<CSR_WIFI_NUM_INTERFACES; i++) {
741 unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWifiOnReqHandler: Setting interface %d to NONE\n", i );
742
743 priv->interfacePriv[i]->interfaceMode = 0;
744 }
745 }
746 unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWifiOnReqHandler(0x%.4X) req->dataLength=%d req->data=0x%x\n", msg->source, req->dataLength, req->data);
747
748 if(req->dataLength==3 && req->data && req->data[0]==0 && req->data[1]==1 && req->data[2]==1)
749 {
750 priv->cmanrTestMode = TRUE;
751 unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWifiOnReqHandler: cmanrTestMode=%d\n", priv->cmanrTestMode);
752 }
753 else
754 {
755 priv->cmanrTestMode = FALSE;
635d2b00 756 }
635d2b00
GKH
757
758 /*
759 * The request to initialise UniFi might come while UniFi is running.
760 * We need to block all I/O activity until the reset completes, otherwise
761 * an SDIO error might occur resulting an indication to the SME which
762 * makes it think that the initialisation has failed.
763 */
764 priv->bh_thread.block_thread = 1;
765
766 /* Update the wifi_on state */
767 priv->wifi_on_state = wifi_on_in_progress;
768
95edd09e
GKH
769 /* If UniFi was unpowered, acquire the firmware for download to chip */
770 if (!priv->wol_suspend) {
771 r = uf_request_firmware_files(priv, UNIFI_FW_STA);
772 if (r) {
773 unifi_error(priv, "CsrWifiRouterCtrlWifiOnReqHandler: Failed to get f/w\n");
774 CsrWifiRouterCtrlWifiOnCfmSend(msg->source, req->clientData, CSR_RESULT_FAILURE);
775 return;
776 }
777 } else {
778 unifi_trace(priv, UDBG1, "Don't need firmware\n");
635d2b00
GKH
779 }
780
781 /* Power on UniFi (which may not necessarily have been off) */
782 CsrSdioClaim(priv->sdio);
783 csrResult = CsrSdioPowerOn(priv->sdio);
784 CsrSdioRelease(priv->sdio);
785 if (csrResult != CSR_RESULT_SUCCESS && csrResult != CSR_SDIO_RESULT_NOT_RESET) {
786 unifi_error(priv, "CsrWifiRouterCtrlWifiOnReqHandler: Failed to power on UniFi\n");
787 CsrWifiRouterCtrlWifiOnCfmSend(msg->source, req->clientData, CSR_RESULT_FAILURE);
788 return;
789 }
790
791 /* If CsrSdioPowerOn() returns CSR_RESULT_SUCCESS, it means that we need to initialise UniFi */
792 if (csrResult == CSR_RESULT_SUCCESS && !priv->wol_suspend) {
793 /* Initialise UniFi hardware */
794 r = uf_init_hw(priv);
795 if (r) {
796 unifi_error(priv, "CsrWifiRouterCtrlWifiOnReqHandler: Failed to initialise h/w, error %d\n", r);
797 CsrWifiRouterCtrlWifiOnCfmSend(msg->source, req->clientData, CSR_RESULT_FAILURE);
798 return;
799 }
800 } else {
801 unifi_trace(priv, UDBG1, "UniFi already initialised\n");
802 }
803
804 /* Completed handling of wake up from suspend with UniFi powered */
805 priv->wol_suspend = FALSE;
806
807 /* Re-enable the I/O thread */
808 priv->bh_thread.block_thread = 0;
809
810 /*
811 * Start the I/O thread. The thread might be already running.
812 * This fine, just carry on with the request.
813 */
814 r = uf_init_bh(priv);
815 if (r) {
816 CsrSdioClaim(priv->sdio);
817 CsrSdioPowerOff(priv->sdio);
818 CsrSdioRelease(priv->sdio);
819 CsrWifiRouterCtrlWifiOnCfmSend(msg->source, req->clientData, CSR_RESULT_FAILURE);
820 return;
821 }
822
823 /* Get the version information from the core */
824 unifi_card_info(priv->card, &priv->card_info);
825
826 /* Set the sme queue id */
827 priv->CSR_WIFI_SME_IFACEQUEUE = msg->source;
828 CSR_WIFI_SME_IFACEQUEUE = msg->source;
829
830
831 /* Copy to the unifiio_card_info structure. */
832 versions.chipId = priv->card_info.chip_id;
833 versions.chipVersion = priv->card_info.chip_version;
834 versions.firmwareBuild = priv->card_info.fw_build;
835 versions.firmwareHip = priv->card_info.fw_hip_version;
c781b96b 836 versions.routerBuild = (char*)CSR_WIFI_VERSION;
635d2b00
GKH
837 versions.routerHip = (UNIFI_HIP_MAJOR_VERSION << 8) | UNIFI_HIP_MINOR_VERSION;
838
839 CsrWifiRouterCtrlWifiOnIndSend(msg->source, 0, CSR_RESULT_SUCCESS, versions);
840
841 /* Update the wifi_on state */
842 priv->wifi_on_state = wifi_on_done;
843}
844
845
846/*
847 * wifi_off:
848 * Common code for CsrWifiRouterCtrlWifiOffReqHandler() and
849 * CsrWifiRouterCtrlWifiOffRspHandler().
850 */
851static void
852wifi_off(unifi_priv_t *priv)
853{
854 int power_off;
855 int priv_instance;
856 int i;
857 CsrResult csrResult;
858
95edd09e
GKH
859
860 /* Already off? */
861 if (priv->wifi_on_state == wifi_on_unspecified) {
862 unifi_trace(priv, UDBG1, "wifi_off already\n");
863 return;
864 }
865
635d2b00
GKH
866 unifi_trace(priv, UDBG1, "wifi_off\n");
867
868 /* Destroy the Traffic Analysis Module */
635d2b00
GKH
869 cancel_work_sync(&priv->ta_ind_work.task);
870 cancel_work_sync(&priv->ta_sample_ind_work.task);
871#ifdef CSR_SUPPORT_WEXT
872 cancel_work_sync(&priv->sme_config_task);
95edd09e 873 wext_send_disassoc_event(priv);
635d2b00
GKH
874#endif
875
876 /* Cancel pending M4 stuff */
877 for (i = 0; i < CSR_WIFI_NUM_INTERFACES; i++) {
878 if (priv->netdev[i]) {
879 netInterface_priv_t *netpriv = (netInterface_priv_t *) netdev_priv(priv->netdev[i]);
880 cancel_work_sync(&netpriv->send_m4_ready_task);
881 }
882 }
635d2b00
GKH
883 flush_workqueue(priv->unifi_workqueue);
884
885 /* fw_init parameter can prevent power off UniFi, for debugging */
886 priv_instance = uf_find_priv(priv);
887 if (priv_instance == -1) {
888 unifi_warning(priv,
889 "CsrWifiRouterCtrlStopReqHandler: Unknown priv instance, will power off card.\n");
890 power_off = 1;
891 } else {
892 power_off = (fw_init[priv_instance] > 0) ? 0 : 1;
893 }
894
895 /* Production test mode requires power to the chip, too */
896 if (priv->ptest_mode) {
897 power_off = 0;
898 }
899
900 /* Stop the bh_thread */
901 uf_stop_thread(priv, &priv->bh_thread);
902
903 /* Read the f/w panic codes, if any. Protect against second wifi_off() call,
904 * which may happen if SME requests a wifi_off and closes the char device */
905 if (priv->init_progress != UNIFI_INIT_NONE) {
906 CsrSdioClaim(priv->sdio);
907 unifi_capture_panic(priv->card);
908 CsrSdioRelease(priv->sdio);
909 }
910
911 /* Unregister the interrupt handler */
912 if (csr_sdio_linux_remove_irq(priv->sdio)) {
913 unifi_notice(priv,
914 "csr_sdio_linux_remove_irq failed to talk to card.\n");
915 }
916
917 if (power_off) {
918 unifi_trace(priv, UDBG2,
919 "Force low power and try to power off\n");
920 /* Put UniFi to deep sleep, in case we can not power it off */
921 CsrSdioClaim(priv->sdio);
922 csrResult = unifi_force_low_power_mode(priv->card);
923 CsrSdioRelease(priv->sdio);
924
925 CsrSdioPowerOff(priv->sdio);
926 }
927
928 /* Consider UniFi to be uninitialised */
929 priv->init_progress = UNIFI_INIT_NONE;
930 priv->wifi_on_state = wifi_on_unspecified;
931
932
933} /* wifi_off() */
934
935
936void CsrWifiRouterCtrlWifiOffReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
937{
938 unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
939 CsrWifiRouterCtrlWifiOffReq* req = (CsrWifiRouterCtrlWifiOffReq*)msg;
940 int i = 0;
635d2b00
GKH
941
942 if (priv == NULL) {
943 return;
944 }
945
946 unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWifiOffReqHandler(0x%.4X)\n", msg->source);
947
948 /* Stop the network traffic on all interfaces before freeing the core. */
949 for (i=0; i<CSR_WIFI_NUM_INTERFACES; i++) {
950 netInterface_priv_t *interfacePriv = priv->interfacePriv[i];
951 if (interfacePriv->netdev_registered == 1) {
952 netif_carrier_off(priv->netdev[i]);
4febd649 953 netif_tx_stop_all_queues(priv->netdev[i]);
95edd09e 954 interfacePriv->connected = UnifiConnectedUnknown;
635d2b00
GKH
955 }
956 interfacePriv->interfaceMode = 0;
957
958 /* Enable all queues by default */
959 interfacePriv->queueEnabled[0] = 1;
960 interfacePriv->queueEnabled[1] = 1;
961 interfacePriv->queueEnabled[2] = 1;
962 interfacePriv->queueEnabled[3] = 1;
963 }
964 wifi_off(priv);
965
6aac2e03 966 CsrWifiRouterCtrlWifiOffCfmSend(msg->source, req->clientData);
95edd09e
GKH
967
968 /* If this is called in response to closing the character device, the
969 * caller must use uf_sme_cancel_request() to terminate any pending SME
970 * blocking request or there will be a delay while the operation times out.
635d2b00 971 */
635d2b00
GKH
972}
973
974
975void CsrWifiRouterCtrlQosControlReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
976{
977 unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
978 CsrWifiRouterCtrlQosControlReq* req = (CsrWifiRouterCtrlQosControlReq*)msg;
979 netInterface_priv_t *interfacePriv;
980
981 if (priv->smepriv == NULL) {
982 unifi_error(priv, "CsrWifiRouterCtrlQosControlReqHandler: invalid smepriv\n");
983 return;
984 }
985
986 unifi_trace(priv, UDBG4, "CsrWifiRouterCtrlQosControlReqHandler:scontrol = %d", req->control);
987
988 if (req->interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
989 unifi_error(priv, "CsrWifiRouterCtrlQosControlReqHandler: interfaceID >= CSR_WIFI_NUM_INTERFACES.\n");
990 return;
991 }
992 interfacePriv = priv->interfacePriv[req->interfaceTag];
993
994 if (req->control == CSR_WIFI_ROUTER_CTRL_QOS_CONTROL_WMM_ON) {
995 priv->sta_wmm_capabilities |= QOS_CAPABILITY_WMM_ENABLED;
996 unifi_trace(priv, UDBG1, "WMM enabled\n");
997
998 unifi_trace(priv, UDBG1, "Queue Config %x\n", req->queueConfig);
999
1000 interfacePriv->queueEnabled[UNIFI_TRAFFIC_Q_BK] = (req->queueConfig & CSR_WIFI_ROUTER_CTRL_QUEUE_BK_ENABLE)?1:0;
1001 interfacePriv->queueEnabled[UNIFI_TRAFFIC_Q_BE] = (req->queueConfig & CSR_WIFI_ROUTER_CTRL_QUEUE_BE_ENABLE)?1:0;
1002 interfacePriv->queueEnabled[UNIFI_TRAFFIC_Q_VI] = (req->queueConfig & CSR_WIFI_ROUTER_CTRL_QUEUE_VI_ENABLE)?1:0;
1003 interfacePriv->queueEnabled[UNIFI_TRAFFIC_Q_VO] = (req->queueConfig & CSR_WIFI_ROUTER_CTRL_QUEUE_VO_ENABLE)?1:0;
1004
1005 } else {
1006 priv->sta_wmm_capabilities = 0;
1007 unifi_trace(priv, UDBG1, "WMM disabled\n");
1008 }
1009}
1010
1011
1012void CsrWifiRouterCtrlTclasAddReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
1013{
1014 unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
1015 CsrWifiRouterCtrlTclasAddReq* req = (CsrWifiRouterCtrlTclasAddReq*)msg;
1016
1017 if (priv == NULL) {
1018 unifi_error(priv, "CsrWifiRouterCtrlTclasAddReqHandler: invalid smepriv\n");
1019 return;
1020 }
1021
1022 CsrWifiRouterCtrlTclasAddCfmSend(msg->source, req->clientData, req->interfaceTag , CSR_RESULT_SUCCESS);
1023}
1024
1025void CsrWifiRouterCtrlTclasDelReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
1026{
1027 unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
1028 CsrWifiRouterCtrlTclasDelReq* req = (CsrWifiRouterCtrlTclasDelReq*)msg;
1029
1030 if (priv == NULL) {
1031 unifi_error(priv, "CsrWifiRouterCtrlTclasDelReqHandler: invalid smepriv\n");
1032 return;
1033 }
1034
1035 CsrWifiRouterCtrlTclasDelCfmSend(msg->source, req->clientData, req->interfaceTag, CSR_RESULT_SUCCESS);
1036}
1037
1038
1039void CsrWifiRouterCtrlConfigurePowerModeReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
1040{
1041 unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
1042 CsrWifiRouterCtrlConfigurePowerModeReq* req = (CsrWifiRouterCtrlConfigurePowerModeReq*)msg;
1043 enum unifi_low_power_mode pm;
1044 CsrResult csrResult;
1045
1046 if (priv->smepriv == NULL) {
1047 unifi_error(priv, "CsrWifiRouterCtrlConfigurePowerModeReqHandler: invalid smepriv\n");
1048 return;
1049 }
1050
1051 if (req->mode == CSR_WIFI_ROUTER_CTRL_LOW_POWER_MODE_DISABLED) {
1052 pm = UNIFI_LOW_POWER_DISABLED;
1053 } else {
1054 pm = UNIFI_LOW_POWER_ENABLED;
1055 }
1056
1057 unifi_trace(priv, UDBG2,
1058 "CsrWifiRouterCtrlConfigurePowerModeReqHandler (mode=%d, wake=%d)\n",
1059 req->mode, req->wakeHost);
1060 csrResult = unifi_configure_low_power_mode(priv->card, pm,
1061 (req->wakeHost ? UNIFI_PERIODIC_WAKE_HOST_ENABLED : UNIFI_PERIODIC_WAKE_HOST_DISABLED));
1062}
1063
1064
1065void CsrWifiRouterCtrlWifiOnResHandler(void* drvpriv, CsrWifiFsmEvent* msg)
1066{
1067 unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
1068 CsrWifiRouterCtrlWifiOnRes* res = (CsrWifiRouterCtrlWifiOnRes*)msg;
1069
1070 if (priv == NULL) {
1071 unifi_error(NULL, "CsrWifiRouterCtrlWifiOnResHandler: Invalid ospriv.\n");
1072 return;
1073 }
1074
1075 unifi_trace(priv, UDBG1,
1076 "CsrWifiRouterCtrlWifiOnResHandler: status %d (patch %u)\n", res->status, res->smeVersions.firmwarePatch);
1077
1078 if (res->smeVersions.firmwarePatch != 0) {
1079 unifi_info(priv, "Firmware patch %d\n", res->smeVersions.firmwarePatch);
1080 }
1081
1082 if (res->numInterfaceAddress > CSR_WIFI_NUM_INTERFACES) {
1083 unifi_error(priv, "WifiOnResHandler bad numInterfaceAddress %d\n", res->numInterfaceAddress);
1084 return;
1085 }
1086
1087 /* UniFi is now initialised, complete the init. */
1088 if (res->status == CSR_RESULT_SUCCESS)
1089 {
1090 int i; /* used as a loop counter */
26a6b2e1 1091 u32 intmode = CSR_WIFI_INTMODE_DEFAULT;
95edd09e 1092#ifdef CSR_WIFI_SPLIT_PATCH
5379b13d 1093 u8 switching_ap_fw = FALSE;
95edd09e 1094#endif
635d2b00
GKH
1095 /* Register the UniFi device with the OS network manager */
1096 unifi_trace(priv, UDBG3, "Card Init Completed Successfully\n");
1097
1098 /* Store the MAC address in the netdev */
1099 for(i=0;i<res->numInterfaceAddress;i++)
1100 {
1101 memcpy(priv->netdev[i]->dev_addr, res->stationMacAddress[i].a, ETH_ALEN);
1102 }
1103
1104 /* Copy version structure into the private versions field */
1105 priv->sme_versions = res->smeVersions;
1106
1107 unifi_trace(priv, UDBG2, "network interfaces count = %d\n",
1108 res->numInterfaceAddress);
1109
1110 /* Register the netdevs for each interface. */
1111 for(i=0;i<res->numInterfaceAddress;i++)
1112 {
1113 netInterface_priv_t *interfacePriv = priv->interfacePriv[i];
1114 if(!interfacePriv->netdev_registered)
1115 {
1116 int r;
1117 unifi_trace(priv, UDBG3, "registering net device %d\n", i);
1118 r = uf_register_netdev(priv, i);
1119 if (r)
1120 {
1121 /* unregister the net_device that are registered in the previous iterations */
1122 uf_unregister_netdev(priv);
1123 unifi_error(priv, "Failed to register the network device.\n");
1124 CsrWifiRouterCtrlWifiOnCfmSend(msg->source, res->clientData, CSR_RESULT_FAILURE);
1125 return;
1126 }
1127 }
95edd09e
GKH
1128#ifdef CSR_WIFI_SPLIT_PATCH
1129 else
1130 {
1131 /* If a netdev is already registered, we have received this WifiOnRes
1132 * in response to switching AP/STA firmware in a ModeSetReq.
1133 * Rememeber this in order to send a ModeSetCfm once
1134 */
1135 switching_ap_fw = TRUE;
1136 }
1137#endif
635d2b00
GKH
1138 }
1139 priv->totalInterfaceCount = res->numInterfaceAddress;
1140
1141 /* If the MIB has selected f/w scheduled interrupt mode, apply it now
1142 * but let module param override.
1143 */
1144 if (run_bh_once != -1) {
26a6b2e1 1145 intmode = (u32)run_bh_once;
635d2b00
GKH
1146 } else if (res->scheduledInterrupt) {
1147 intmode = CSR_WIFI_INTMODE_RUN_BH_ONCE;
1148 }
1149 unifi_set_interrupt_mode(priv->card, intmode);
1150
1151 priv->init_progress = UNIFI_INIT_COMPLETED;
1152
1153 /* Acknowledge the CsrWifiRouterCtrlWifiOnReq now */
1154 CsrWifiRouterCtrlWifiOnCfmSend(msg->source, res->clientData, CSR_RESULT_SUCCESS);
1155
95edd09e
GKH
1156#ifdef CSR_WIFI_SPLIT_PATCH
1157 if (switching_ap_fw && (priv->pending_mode_set.common.destination != 0xaaaa)) {
1158 unifi_info(priv, "Completed firmware reload with %s patch\n",
1159 CSR_WIFI_HIP_IS_AP_FW(priv->interfacePriv[0]->interfaceMode) ? "AP" : "STA");
1160
1161 /* Confirm the ModeSetReq that requested the AP/STA patch switch */
1162 CsrWifiRouterCtrlModeSetCfmSend(priv->pending_mode_set.common.source,
1163 priv->pending_mode_set.clientData,
1164 priv->pending_mode_set.interfaceTag,
1165 priv->pending_mode_set.mode,
1166 CSR_RESULT_SUCCESS);
1167 priv->pending_mode_set.common.destination = 0xaaaa;
1168 }
1169#endif
635d2b00
GKH
1170 unifi_info(priv, "UniFi ready\n");
1171
95edd09e
GKH
1172#ifdef ANDROID_BUILD
1173 /* Release the wakelock */
1174 unifi_trace(priv, UDBG1, "ready: release wake lock\n");
1175 wake_unlock(&unifi_sdio_wake_lock);
1176#endif
635d2b00
GKH
1177 /* Firmware initialisation is complete, so let the SDIO bus
1178 * clock be raised when convienent to the core.
1179 */
1180 unifi_request_max_sdio_clock(priv->card);
1181
1182#ifdef CSR_SUPPORT_WEXT
1183 /* Notify the Android wpa_supplicant that we are ready */
1184 wext_send_started_event(priv);
1185
1186 queue_work(priv->unifi_workqueue, &priv->sme_config_task);
1187#endif
1188
1189 } else {
1190 /* Acknowledge the CsrWifiRouterCtrlWifiOnReq now */
1191 CsrWifiRouterCtrlWifiOnCfmSend(msg->source, res->clientData, CSR_RESULT_FAILURE);
1192 }
1193}
1194
1195
1196void CsrWifiRouterCtrlWifiOffResHandler(void* drvpriv, CsrWifiFsmEvent* msg)
1197{
1198}
1199
1200
1201void CsrWifiRouterCtrlMulticastAddressResHandler(void* drvpriv, CsrWifiFsmEvent* msg)
1202{
1203}
1204
1205
1206void CsrWifiRouterMaPacketSubscribeReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
1207{
1208 unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
1209 CsrWifiRouterMaPacketSubscribeReq* req = (CsrWifiRouterMaPacketSubscribeReq*)msg;
7e6f5794 1210 u8 i;
635d2b00
GKH
1211 CsrResult result;
1212
1213 if (priv == NULL) {
1214 unifi_error(priv, "CsrWifiRouterMaPacketSubscribeReqHandler: invalid priv\n");
1215 return;
1216 }
1217
1218 /* Look for an unused filter */
1219
1220 result = CSR_WIFI_RESULT_NO_ROOM;
1221 for (i = 0; i < MAX_MA_UNIDATA_IND_FILTERS; i++) {
1222
1223 if (!priv->sme_unidata_ind_filters[i].in_use) {
1224
1225 priv->sme_unidata_ind_filters[i].in_use = 1;
1226 priv->sme_unidata_ind_filters[i].appHandle = msg->source;
1227 priv->sme_unidata_ind_filters[i].encapsulation = req->encapsulation;
1228 priv->sme_unidata_ind_filters[i].protocol = req->protocol;
1229
7e6f5794
GKH
1230 priv->sme_unidata_ind_filters[i].oui[2] = (u8) (req->oui & 0xFF);
1231 priv->sme_unidata_ind_filters[i].oui[1] = (u8) ((req->oui >> 8) & 0xFF);
1232 priv->sme_unidata_ind_filters[i].oui[0] = (u8) ((req->oui >> 16) & 0xFF);
635d2b00
GKH
1233
1234 result = CSR_RESULT_SUCCESS;
1235 break;
1236 }
1237 }
1238
1239 unifi_trace(priv, UDBG1,
1240 "subscribe_req: encap=%d, handle=%d, result=%d\n",
1241 req->encapsulation, i, result);
6aac2e03 1242 CsrWifiRouterMaPacketSubscribeCfmSend(msg->source, req->interfaceTag, i, result, 0);
635d2b00
GKH
1243}
1244
1245
1246void CsrWifiRouterMaPacketUnsubscribeReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
1247{
1248 unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
1249 CsrWifiRouterMaPacketUnsubscribeReq* req = (CsrWifiRouterMaPacketUnsubscribeReq*)msg;
1250 CsrResult result;
1251
1252 if (priv == NULL) {
1253 unifi_error(priv, "CsrWifiRouterMaPacketUnsubscribeReqHandler: invalid priv\n");
1254 return;
1255 }
1256
1257 result = CSR_WIFI_RESULT_NOT_FOUND;
1258
1259 if (req->subscriptionHandle < MAX_MA_UNIDATA_IND_FILTERS) {
1260 if (priv->sme_unidata_ind_filters[req->subscriptionHandle].in_use) {
1261 priv->sme_unidata_ind_filters[req->subscriptionHandle].in_use = 0;
1262 result = CSR_RESULT_SUCCESS;
1263 } else {
1264 result = CSR_WIFI_RESULT_NOT_FOUND;
1265 }
1266 }
1267
1268 unifi_trace(priv, UDBG1,
1269 "unsubscribe_req: handle=%d, result=%d\n",
1270 req->subscriptionHandle, result);
6aac2e03 1271 CsrWifiRouterMaPacketUnsubscribeCfmSend(msg->source, req->interfaceTag, result);
635d2b00
GKH
1272}
1273
1274
1275void CsrWifiRouterCtrlCapabilitiesReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
1276{
1277 unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
1278 CsrWifiRouterCtrlCapabilitiesReq* req = (CsrWifiRouterCtrlCapabilitiesReq*)msg;
1279
1280 if (priv == NULL) {
1281 unifi_error(priv, "CsrWifiRouterCtrlCapabilitiesReqHandler: invalid priv\n");
1282 return;
1283 }
1284
6aac2e03 1285 CsrWifiRouterCtrlCapabilitiesCfmSend(msg->source, req->clientData,
635d2b00
GKH
1286 UNIFI_SOFT_COMMAND_Q_LENGTH - 1,
1287 UNIFI_SOFT_TRAFFIC_Q_LENGTH - 1);
1288}
1289
1290
1291void CsrWifiRouterCtrlSuspendResHandler(void* drvpriv, CsrWifiFsmEvent* msg)
1292{
1293 unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
1294 CsrWifiRouterCtrlSuspendRes* res = (CsrWifiRouterCtrlSuspendRes*)msg;
1295
1296 if (priv == NULL) {
1297 unifi_error(priv, "CsrWifiRouterCtrlSuspendResHandler: invalid priv\n");
1298 return;
1299 }
1300
1301 sme_complete_request(priv, res->status);
1302}
1303
1304
1305void CsrWifiRouterCtrlResumeResHandler(void* drvpriv, CsrWifiFsmEvent* msg)
1306{
1307 unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
1308 CsrWifiRouterCtrlResumeRes* res = (CsrWifiRouterCtrlResumeRes*)msg;
1309
1310 if (priv == NULL) {
1311 unifi_error(priv, "CsrWifiRouterCtrlResumeResHandler: invalid priv\n");
1312 return;
1313 }
1314
95edd09e 1315 sme_complete_request(priv, res->status);
635d2b00
GKH
1316}
1317
1318
1319void CsrWifiRouterCtrlTrafficConfigReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
1320{
1321 unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
1322 CsrWifiRouterCtrlTrafficConfigReq* req = (CsrWifiRouterCtrlTrafficConfigReq*)msg;
1323 CsrResult csrResult;
1324
1325 if (priv == NULL) {
1326 unifi_error(priv, "CsrWifiRouterCtrlTrafficConfigReqHandler: invalid smepriv\n");
1327 return;
1328 }
1329 if (req->trafficConfigType == CSR_WIFI_ROUTER_CTRL_TRAFFIC_CONFIG_TYPE_FILTER)
1330 {
1331 req->config.packetFilter |= CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_CUSTOM;
1332 }
1333 csrResult = unifi_ta_configure(priv->card, req->trafficConfigType, (const CsrWifiRouterCtrlTrafficConfig *)&req->config);
1334}
1335
1336void CsrWifiRouterCtrlTrafficClassificationReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
1337{
1338 unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
1339 CsrWifiRouterCtrlTrafficClassificationReq* req = (CsrWifiRouterCtrlTrafficClassificationReq*)msg;
1340
1341 if (priv == NULL) {
1342 unifi_error(priv, "CsrWifiRouterCtrlTrafficClassificationReqHandler: invalid smepriv\n");
1343 return;
1344 }
1345
1346 unifi_ta_classification(priv->card, req->trafficType, req->period);
1347}
1348
1349static int
1350_sys_packet_req(unifi_priv_t *priv, const CSR_SIGNAL *signal,
7e6f5794 1351 u8 subscriptionHandle,
8c87f69a 1352 u16 frameLength, u8 *frame,
635d2b00
GKH
1353 int proto)
1354{
1355 int r;
1356 const sme_ma_unidata_ind_filter_t *subs;
1357 bulk_data_param_t bulkdata;
1358 CSR_MA_PACKET_REQUEST req = signal->u.MaPacketRequest;
1359 struct sk_buff *skb, *newSkb = NULL;
1360 CsrWifiMacAddress peerMacAddress;
1361 CsrResult csrResult;
8c87f69a 1362 u16 interfaceTag = req.VirtualInterfaceIdentifier & 0xff;
5379b13d 1363 u8 eapolStore = FALSE;
163eb0d8 1364 s8 protection = 0;
635d2b00
GKH
1365 netInterface_priv_t *interfacePriv;
1366 unsigned long flags;
1367
1368 if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
1369 unifi_error(priv, "_sys_packet_req: interfaceID >= CSR_WIFI_NUM_INTERFACES.\n");
1370 return -EINVAL;
1371 }
1372 interfacePriv = priv->interfacePriv[interfaceTag];
1373 if (!priv->sme_unidata_ind_filters[subscriptionHandle].in_use) {
1374 unifi_error(priv, "_sys_packet_req: unknown subscription.\n");
1375 return -EINVAL;
1376 }
1377
1378 subs = &priv->sme_unidata_ind_filters[subscriptionHandle];
1379 unifi_trace(priv, UDBG1,
1380 "_sys_packet_req: handle=%d, subs=%p, encap=%d\n",
1381 subscriptionHandle, subs, subs->encapsulation);
1382
1383 csrResult = unifi_net_data_malloc(priv, &bulkdata.d[0], frameLength);
1384 if (csrResult != CSR_RESULT_SUCCESS) {
1385 unifi_error(priv, "_sys_packet_req: failed to allocate bulkdata.\n");
1386 return (int)CsrHipResultToStatus(csrResult);
1387 }
1388
1389 /* get the peer Mac address */
1390 memcpy(&peerMacAddress, frame, ETH_ALEN);
1391
1392 /* Determine if we need to add encapsulation header */
1393 if (subs->encapsulation == CSR_WIFI_ROUTER_ENCAPSULATION_ETHERNET) {
1394 memcpy((void*)bulkdata.d[0].os_data_ptr, frame, frameLength);
1395
1396 /* The translation is performed on the skb */
1397 skb = (struct sk_buff*)bulkdata.d[0].os_net_buf_ptr;
1398
1399 unifi_trace(priv, UDBG1,
1400 "_sys_packet_req: skb_add_llc_snap -->\n");
1401 r = skb_add_llc_snap(priv->netdev[interfaceTag], skb, proto);
1402 unifi_trace(priv, UDBG1,
1403 "_sys_packet_req: skb_add_llc_snap <--\n");
1404 if (r) {
1405 unifi_error(priv,
1406 "_sys_packet_req: failed to translate eth frame.\n");
6aac2e03 1407 unifi_net_data_free(priv, &bulkdata.d[0]);
635d2b00
GKH
1408 return r;
1409 }
1410
1411 bulkdata.d[0].data_length = skb->len;
1412 } else {
1413 /* Crop the MAC addresses from the packet */
1414 memcpy((void*)bulkdata.d[0].os_data_ptr, frame + 2*ETH_ALEN, frameLength - 2*ETH_ALEN);
1415 bulkdata.d[0].data_length = frameLength - 2*ETH_ALEN;
1416 skb = (struct sk_buff*)bulkdata.d[0].os_net_buf_ptr;
1417 skb->len = bulkdata.d[0].data_length;
1418
1419 }
1420
1421 bulkdata.d[1].os_data_ptr = NULL;
1422 bulkdata.d[1].os_net_buf_ptr = NULL;
1423 bulkdata.d[1].data_length = 0;
1424
1425 /* check for m4 detection */
1426 if (0 == uf_verify_m4(priv, bulkdata.d[0].os_data_ptr, bulkdata.d[0].data_length)) {
1427 eapolStore = TRUE;
1428 }
1429
1430#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
1431 if (proto == ETH_P_WAI)
1432 {
1433 protection = 0; /*WAI packets always sent unencrypted*/
1434 }
1435 else
1436 {
1437#endif
1438
1439#ifdef CSR_SUPPORT_SME
1440 if ((protection = uf_get_protection_bit_from_interfacemode(priv, interfaceTag, peerMacAddress.a)) < 0) {
1441 unifi_error(priv, "unicast address, but destination not in station record database\n");
6aac2e03 1442 unifi_net_data_free(priv, &bulkdata.d[0]);
635d2b00
GKH
1443 return -1;
1444 }
1445#else
1446 protection = 0;
1447#endif
1448
1449#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
1450 }
1451#endif
1452
1453 /* add Mac header */
1454 if (prepare_and_add_macheader(priv, skb, newSkb, req.Priority, &bulkdata, interfaceTag, frame, frame + ETH_ALEN, protection)) {
1455 unifi_error(priv, "failed to create MAC header\n");
6aac2e03 1456 unifi_net_data_free(priv, &bulkdata.d[0]);
635d2b00
GKH
1457 return -1;
1458 }
1459
1460 if (eapolStore) {
1461 spin_lock_irqsave(&priv->m4_lock, flags);
1462 /* Store the EAPOL M4 packet for later */
1463 interfacePriv->m4_signal = *signal;
1464 interfacePriv->m4_bulk_data.net_buf_length = bulkdata.d[0].net_buf_length;
1465 interfacePriv->m4_bulk_data.data_length = bulkdata.d[0].data_length;
1466 interfacePriv->m4_bulk_data.os_data_ptr = bulkdata.d[0].os_data_ptr;
1467 interfacePriv->m4_bulk_data.os_net_buf_ptr = bulkdata.d[0].os_net_buf_ptr;
1468 spin_unlock_irqrestore(&priv->m4_lock, flags);
1469 /* Send a signal to SME */
1470 unifi_trace(priv, UDBG1, "_sys_packet_req: Sending CsrWifiRouterCtrlM4ReadyToSendInd\n");
1471 CsrWifiRouterCtrlM4ReadyToSendIndSend(priv->CSR_WIFI_SME_IFACEQUEUE, 0, interfaceTag, peerMacAddress);
1472 return 0;
1473 }
1474
1475 /* Send the signal to UniFi */
1476 /* Set the B31 to 1 for local routing*/
1477 r= uf_process_ma_packet_req(priv, peerMacAddress.a, (req.HostTag | 0x80000000), interfaceTag, 0,
1478 (CSR_RATE)0, req.Priority, signal->SignalPrimitiveHeader.SenderProcessId, &bulkdata);
1479 if (r) {
1480 unifi_error(priv,
1481 "_sys_packet_req: failed to send signal.\n");
6aac2e03 1482 unifi_net_data_free(priv, &bulkdata.d[0]);
635d2b00
GKH
1483 return r;
1484 }
1485 /* The final CsrWifiRouterMaPacketCfmSend() will called when the actual MA-PACKET.cfm is received from the chip */
1486
1487 return 0;
1488}
1489
1490void CsrWifiRouterMaPacketReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
1491{
1492 int r;
1493 unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
1494 CsrWifiRouterMaPacketReq* mareq = (CsrWifiRouterMaPacketReq*)msg;
1495 llc_snap_hdr_t *snap;
8c87f69a 1496 u16 snap_protocol;
635d2b00
GKH
1497 CSR_SIGNAL signal;
1498 CSR_MA_PACKET_REQUEST *req = &signal.u.MaPacketRequest;
1499 CsrWifiRouterCtrlPortAction controlPortaction;
7e6f5794 1500 u8 *daddr, *saddr;
8c87f69a 1501 u16 interfaceTag = mareq->interfaceTag & 0x00ff;
635d2b00 1502 int queue;
94b84e45 1503 netInterface_priv_t *interfacePriv;
635d2b00
GKH
1504
1505 if (!mareq->frame || !priv || !priv->smepriv)
1506 {
1507 unifi_error(priv, "CsrWifiRouterMaPacketReqHandler: invalid frame/priv/priv->smepriv\n");
1508 return;
1509 }
1510
1511 if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
1512 unifi_error(priv, "CsrWifiRouterMaPacketReqHandler: interfaceID >= CSR_WIFI_NUM_INTERFACES.\n");
1513 return;
1514 }
94b84e45
PH
1515
1516 interfacePriv = priv->interfacePriv[interfaceTag];
635d2b00
GKH
1517 /* get a pointer to dest & source Mac address */
1518 daddr = mareq->frame;
1519 saddr = (mareq->frame + ETH_ALEN);
1520 /* point to the proper position of frame, since frame has MAC header */
1521 snap = (llc_snap_hdr_t *) (mareq->frame + 2 * ETH_ALEN);
1522 snap_protocol = ntohs(snap->protocol);
1523 if((snap_protocol == ETH_P_PAE)
1524#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
1525 || (snap_protocol == ETH_P_WAI)
1526#endif
1527 )
1528 {
1529 queue = UF_UNCONTROLLED_PORT_Q;
1530 }
1531 else
1532 {
1533 queue = UF_CONTROLLED_PORT_Q;
1534 }
1535
1536 /* Controlled port restrictions apply to the packets */
1537 controlPortaction = uf_sme_port_state(priv, daddr, queue, interfaceTag);
1538 if (controlPortaction != CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN)
1539 {
1540 unifi_warning(priv, "CsrWifiRouterMaPacketReqHandler: (%s)controlled port is closed.\n", (queue == UF_CONTROLLED_PORT_Q)?"":"un");
1541 if(mareq->cfmRequested)
1542 {
1543 CsrWifiRouterMaPacketCfmSend(msg->source,
1544 interfaceTag,
1545 CSR_RESULT_FAILURE,
1546 mareq->hostTag, 0);
1547 }
1548 return;
1549 }
1550
1551 signal.SignalPrimitiveHeader.SignalId = CSR_MA_PACKET_REQUEST_ID;
1552 /* Store the appHandle in the LSB of the SenderId. */
1553 CSR_COPY_UINT16_TO_LITTLE_ENDIAN(((priv->sme_cli->sender_id & 0xff00) | (unsigned int)msg->source),
1554 (u8*)&signal.SignalPrimitiveHeader.SenderProcessId);
1555 signal.SignalPrimitiveHeader.ReceiverProcessId = 0;
1556
1557 /* Fill in the MA-PACKET.req signal */
1558 memcpy(req->Ra.x, daddr, ETH_ALEN);
1559 req->Priority = mareq->priority;
1560 req->TransmitRate = 0; /* Let firmware select the rate*/
6aac2e03 1561 req->VirtualInterfaceIdentifier = uf_get_vif_identifier(interfacePriv->interfaceMode, interfaceTag);
635d2b00
GKH
1562 req->HostTag = mareq->hostTag;
1563
1564 if(mareq->cfmRequested)
1565 req->TransmissionControl = 0;
1566 else
1567 req->TransmissionControl = CSR_NO_CONFIRM_REQUIRED;
1568
1569 r = _sys_packet_req(priv, &signal, mareq->subscriptionHandle,
1570 mareq->frameLength, mareq->frame, snap_protocol);
1571
635d2b00
GKH
1572 if (r && mareq->cfmRequested)
1573 {
6aac2e03 1574 CsrWifiRouterMaPacketCfmSend(msg->source, interfaceTag,
635d2b00
GKH
1575 CSR_RESULT_FAILURE,
1576 mareq->hostTag, 0);
1577 }
1578 return;
1579}
1580
1581void CsrWifiRouterMaPacketCancelReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
1582{
1583}
1584
1585void CsrWifiRouterCtrlM4TransmitReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
1586{
1587 unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
1588 CsrWifiRouterCtrlM4TransmitReq* req = (CsrWifiRouterCtrlM4TransmitReq*)msg;
1589 int r;
1590 bulk_data_param_t bulkdata;
1591 netInterface_priv_t *interfacePriv;
1592 CSR_SIGNAL m4_signal;
1593 unsigned long flags;
1594
1595 if (priv == NULL) {
1596 unifi_error(priv, "CsrWifiRouterCtrlM4TransmitReqHandler: invalid smepriv\n");
1597 return;
1598 }
1599 if (req->interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
1600 unifi_error(priv, "M4TransmitReqHandler: interfaceTag >= CSR_WIFI_NUM_INTERFACES\n");
1601 return;
1602 }
1603
1604 interfacePriv = priv->interfacePriv[req->interfaceTag];
1605 spin_lock_irqsave(&priv->m4_lock, flags);
1606 if (interfacePriv->m4_bulk_data.data_length == 0) {
1607 spin_unlock_irqrestore(&priv->m4_lock, flags);
1608 unifi_error(priv, "CsrWifiRouterCtrlM4TransmitReqHandler: invalid buffer\n");
1609 return;
1610 }
1611
1612 memcpy(&bulkdata.d[0], &interfacePriv->m4_bulk_data, sizeof(bulk_data_desc_t));
1613
1614 interfacePriv->m4_bulk_data.net_buf_length = 0;
1615 interfacePriv->m4_bulk_data.data_length = 0;
1616 interfacePriv->m4_bulk_data.os_data_ptr = interfacePriv->m4_bulk_data.os_net_buf_ptr = NULL;
1617 m4_signal = interfacePriv->m4_signal;
1618 spin_unlock_irqrestore(&priv->m4_lock, flags);
1619
1620 bulkdata.d[1].os_data_ptr = NULL;
1621 bulkdata.d[1].data_length = 0;
1622
1623 interfacePriv->m4_sent = TRUE;
1624 m4_signal.u.MaPacketRequest.HostTag |= 0x80000000;
1625 /* Store the hostTag for later varification */
1626 interfacePriv->m4_hostTag = m4_signal.u.MaPacketRequest.HostTag;
1627 r = ul_send_signal_unpacked(priv, &m4_signal, &bulkdata);
1628 unifi_trace(priv, UDBG1,
1629 "CsrWifiRouterCtrlM4TransmitReqHandler: sent\n");
1630 if (r) {
1631 unifi_error(priv,
1632 "CsrWifiRouterCtrlM4TransmitReqHandler: failed to send signal.\n");
1633 unifi_net_data_free(priv, &bulkdata.d[0]);
1634 }
1635}
1636
1637/* reset the station records when the mode is set as CSR_WIFI_ROUTER_CTRL_MODE_NONE */
8c87f69a 1638static void CsrWifiRouterCtrlResetStationRecordList(unifi_priv_t *priv, u16 interfaceTag)
635d2b00 1639{
6aac2e03 1640 u8 i, j;
635d2b00
GKH
1641 CsrWifiRouterCtrlStaInfo_t *staInfo=NULL;
1642 netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
1643 unsigned long lock_flags;
1644
1645 /* create a list for sending confirms of un-delivered packets */
1646 struct list_head send_cfm_list;
1647
1648 if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
1649 unifi_error(priv, "CsrWifiRouterCtrlResetStationRecordList: bad interfaceTag\n");
1650 return;
1651 }
1652
1653 INIT_LIST_HEAD(&send_cfm_list);
1654
1655 /* Reset the station record to NULL if mode is NONE */
1656 for(i = 0; i < UNIFI_MAX_CONNECTIONS; i++) {
1657 if ((staInfo=interfacePriv->staInfo[i]) != NULL) {
1658 uf_prepare_send_cfm_list_for_queued_pkts(priv,
1659 &send_cfm_list,
1660 &(staInfo->mgtFrames));
6aac2e03 1661 uf_flush_list(priv, &(staInfo->mgtFrames));
635d2b00
GKH
1662 for(j=0;j<MAX_ACCESS_CATOGORY;j++){
1663 uf_prepare_send_cfm_list_for_queued_pkts(priv,
1664 &send_cfm_list,
1665 &(staInfo->dataPdu[j]));
6aac2e03 1666 uf_flush_list(priv, &(staInfo->dataPdu[j]));
635d2b00
GKH
1667 }
1668
6aac2e03 1669 spin_lock_irqsave(&priv->staRecord_lock, lock_flags);
635d2b00
GKH
1670 /* Removing station record information from port config array */
1671 memset(staInfo->peerControlledPort, 0, sizeof(unifi_port_cfg_t));
1672 staInfo->peerControlledPort->port_action = CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD;
1673 staInfo->peerControlledPort->in_use = FALSE;
1674 interfacePriv->controlled_data_port.entries_in_use--;
1675
1676 memset(staInfo->peerUnControlledPort, 0, sizeof(unifi_port_cfg_t));
1677 staInfo->peerUnControlledPort->port_action = CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD;
1678 staInfo->peerUnControlledPort->in_use = FALSE;
1679 interfacePriv->uncontrolled_data_port.entries_in_use--;
1680
1681 kfree(interfacePriv->staInfo[i]);
1682 interfacePriv->staInfo[i] = NULL;
6aac2e03 1683 spin_unlock_irqrestore(&priv->staRecord_lock, lock_flags);
635d2b00
GKH
1684 }
1685 }
1686 /* after the critical region process the list of frames that requested cfm
1687 * and send cfm to requestor one by one
1688 */
1689 send_auto_ma_packet_confirm(priv, interfacePriv, &send_cfm_list);
1690
1691#ifdef CSR_SUPPORT_SME
1692 /* Interface Independent, no of packet queued, incase of mode is None or AP set to 0 */
1693 switch(interfacePriv->interfaceMode)
1694 {
1695 case CSR_WIFI_ROUTER_CTRL_MODE_AP:
1696 case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO:
1697 case CSR_WIFI_ROUTER_CTRL_MODE_NONE:
1698 if (priv->noOfPktQueuedInDriver) {
1699 unifi_warning(priv, "After reset the noOfPktQueuedInDriver = %x\n", priv->noOfPktQueuedInDriver);
6aac2e03 1700 spin_lock_irqsave(&priv->tx_q_lock, lock_flags);
635d2b00 1701 priv->noOfPktQueuedInDriver = 0;
6aac2e03 1702 spin_unlock_irqrestore(&priv->tx_q_lock, lock_flags);
635d2b00
GKH
1703 }
1704 break;
1705 case CSR_WIFI_ROUTER_CTRL_MODE_IBSS:
1706 break;
1707 default:
1708 unifi_error(priv, "interfacemode is not correct in CsrWifiRouterCtrlResetStationRecordList: debug\n");
1709 }
1710#endif
1711
1712 if (((interfacePriv->controlled_data_port.entries_in_use != 0) || (interfacePriv->uncontrolled_data_port.entries_in_use != 0))
1713 && (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_NONE)) {
1714 /* Print in case if the value of entries goes to -ve/+ve (apart from 0)
1715 * we expect the entries should be zero here if mode is set as NONE
1716 */
1717 unifi_trace(priv, UDBG3, "In %s controlled port entries = %d, uncontrolled port entries = %d\n",
1718 __FUNCTION__, interfacePriv->controlled_data_port.entries_in_use,
1719 interfacePriv->uncontrolled_data_port.entries_in_use);
1720 }
1721}
1722
8c87f69a 1723void CsrWifiRouterCtrlInterfaceReset(unifi_priv_t *priv, u16 interfaceTag)
635d2b00
GKH
1724{
1725 netInterface_priv_t *interfacePriv;
1726
1727 /* create a list for sending confirms of un-delivered packets */
1728 struct list_head send_cfm_list;
1729
1730 if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
1731 unifi_error(priv, "CsrWifiRouterCtrlInterfaceReset: bad interfaceTag\n");
1732 return;
1733 }
1734
1735 interfacePriv = priv->interfacePriv[interfaceTag];
1736
1737 INIT_LIST_HEAD(&send_cfm_list);
1738
1739 /* Enable all queues by default */
1740 interfacePriv->queueEnabled[0] = 1;
1741 interfacePriv->queueEnabled[1] = 1;
1742 interfacePriv->queueEnabled[2] = 1;
1743 interfacePriv->queueEnabled[3] = 1;
1744
1745 uf_prepare_send_cfm_list_for_queued_pkts(priv,
1746 &send_cfm_list,
1747 &(interfacePriv->genericMgtFrames));
6aac2e03 1748 uf_flush_list(priv, &(interfacePriv->genericMgtFrames));
635d2b00
GKH
1749
1750 uf_prepare_send_cfm_list_for_queued_pkts(priv,
1751 &send_cfm_list,
1752 &(interfacePriv->genericMulticastOrBroadCastMgtFrames));
6aac2e03 1753 uf_flush_list(priv, &(interfacePriv->genericMulticastOrBroadCastMgtFrames));
635d2b00
GKH
1754
1755 uf_prepare_send_cfm_list_for_queued_pkts(priv,
1756 &send_cfm_list,
1757 &(interfacePriv->genericMulticastOrBroadCastFrames));
1758
6aac2e03 1759 uf_flush_list(priv, &(interfacePriv->genericMulticastOrBroadCastFrames));
635d2b00
GKH
1760
1761 /* process the list of frames that requested cfm
1762 and send cfm to requestor one by one */
1763 send_auto_ma_packet_confirm(priv, interfacePriv, &send_cfm_list);
1764
1765 /* Reset the station record to NULL if mode is tried to set as NONE */
1766 switch(interfacePriv->interfaceMode)
1767 {
1768 case CSR_WIFI_ROUTER_CTRL_MODE_STA:
1769 case CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI:
1770 case CSR_WIFI_ROUTER_CTRL_MODE_MONITOR:
1771 case CSR_WIFI_ROUTER_CTRL_MODE_AMP:
1772 /* station records not available in these modes */
1773 break;
1774 default:
6aac2e03 1775 CsrWifiRouterCtrlResetStationRecordList(priv, interfaceTag);
635d2b00
GKH
1776 }
1777
1778 interfacePriv->num_stations_joined = 0;
1779 interfacePriv->sta_activity_check_enabled = FALSE;
1780}
1781
1782
1783void CsrWifiRouterCtrlModeSetReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
1784{
1785 unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
1786 CsrWifiRouterCtrlModeSetReq* req = (CsrWifiRouterCtrlModeSetReq*)msg;
1787
1788 if (priv == NULL)
1789 {
1790 unifi_error(priv, "CsrWifiRouterCtrlModeSetReqHandler: invalid smepriv\n");
1791 return;
1792 }
1793
1794 if (req->interfaceTag < CSR_WIFI_NUM_INTERFACES)
1795 {
1796 netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag];
95edd09e 1797#ifdef CSR_WIFI_SPLIT_PATCH
7e6f5794 1798 u8 old_mode = interfacePriv->interfaceMode;
95edd09e 1799#endif
635d2b00
GKH
1800 unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlModeSetReqHandler: interfacePriv->interfaceMode = %d\n",
1801 interfacePriv->interfaceMode);
1802
95edd09e
GKH
1803 interfacePriv->interfaceMode = req->mode;
1804
1805#ifdef CSR_WIFI_SPLIT_PATCH
1806 /* Detect a change in mode that requires a switch to/from the AP firmware patch.
1807 * This should only happen when transitioning in/out of AP modes.
635d2b00 1808 */
95edd09e
GKH
1809 if (CSR_WIFI_HIP_IS_AP_FW(req->mode) != CSR_WIFI_HIP_IS_AP_FW(old_mode))
1810 {
1811 CsrWifiRouterCtrlVersions versions;
1812 int r;
1813
1814#ifdef ANDROID_BUILD
1815 /* Take the wakelock while switching patch */
1816 unifi_trace(priv, UDBG1, "patch switch: take wake lock\n");
1817 wake_lock(&unifi_sdio_wake_lock);
1818#endif
1819 unifi_info(priv, "Resetting UniFi with %s patch\n", CSR_WIFI_HIP_IS_AP_FW(req->mode) ? "AP" : "STA");
1820
1821 r = uf_request_firmware_files(priv, UNIFI_FW_STA);
1822 if (r) {
1823 unifi_error(priv, "CsrWifiRouterCtrlModeSetReqHandler: Failed to get f/w\n");
1824 CsrWifiRouterCtrlModeSetCfmSend(msg->source, req->clientData, req->interfaceTag,
1825 req->mode, CSR_RESULT_FAILURE);
1826 return;
1827 }
1828
1829 /* Block the I/O thread */
1830 priv->bh_thread.block_thread = 1;
1831
1832 /* Reset and download the new patch */
1833 r = uf_init_hw(priv);
1834 if (r) {
1835 unifi_error(priv, "CsrWifiRouterCtrlWifiOnReqHandler: Failed to initialise h/w, error %d\n", r);
1836 CsrWifiRouterCtrlModeSetCfmSend(msg->source, req->clientData, req->interfaceTag,
1837 req->mode, CSR_RESULT_FAILURE);
1838 return;
1839 }
1840
1841 /* Re-enable the I/O thread */
1842 priv->bh_thread.block_thread = 0;
1843
1844 /* Get the version information from the core */
1845 unifi_card_info(priv->card, &priv->card_info);
1846
1847 /* Copy to the unifiio_card_info structure. */
1848 versions.chipId = priv->card_info.chip_id;
1849 versions.chipVersion = priv->card_info.chip_version;
1850 versions.firmwareBuild = priv->card_info.fw_build;
1851 versions.firmwareHip = priv->card_info.fw_hip_version;
c781b96b 1852 versions.routerBuild = (char*)CSR_WIFI_VERSION;
95edd09e
GKH
1853 versions.routerHip = (UNIFI_HIP_MAJOR_VERSION << 8) | UNIFI_HIP_MINOR_VERSION;
1854
1855 /* Now that new firmware is running, send a WifiOnInd to the NME. This will
1856 * cause it to retransfer the MIB.
1857 */
1858 CsrWifiRouterCtrlWifiOnIndSend(msg->source, 0, CSR_RESULT_SUCCESS, versions);
1859
1860 /* Store the request so we know where to send the ModeSetCfm */
1861 priv->pending_mode_set = *req;
1862 }
1863 else
1864#endif
1865 {
1866 /* No patch switch, confirm straightaway */
1867 CsrWifiRouterCtrlModeSetCfmSend(msg->source, req->clientData, req->interfaceTag,
1868 req->mode, CSR_RESULT_SUCCESS);
1869 }
635d2b00 1870
635d2b00
GKH
1871 interfacePriv->bssid = req->bssid;
1872 /* For modes other than AP/P2PGO, set below member FALSE */
1873 interfacePriv->intraBssEnabled = FALSE;
95edd09e
GKH
1874 /* Initialise the variable bcTimSet with a value
1875 * other then CSR_WIFI_TIM_SET or CSR_WIFI_TIM_RESET value
1876 */
1877 interfacePriv->bcTimSet = 0xFF;
1878 interfacePriv->bcTimSetReqPendingFlag = FALSE;
1879 /* Initialise the variable bcTimSetReqQueued with a value
1880 * other then CSR_WIFI_TIM_SET or CSR_WIFI_TIM_RESET value
1881 */
1882 interfacePriv->bcTimSetReqQueued =0xFF;
6aac2e03 1883 CsrWifiRouterCtrlInterfaceReset(priv, req->interfaceTag);
635d2b00
GKH
1884
1885 if(req->mode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
1886 req->mode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
1887 interfacePriv->protect = req->protection;
1888 interfacePriv->dtimActive=FALSE;
1889 interfacePriv->multicastPduHostTag = 0xffffffff;
1890 /* For AP/P2PGO mode SME sending intraBssDistEnabled
1891 * i.e. for AP: intraBssDistEnabled = TRUE, for P2PGO
1892 * intraBssDistEnabled = TRUE/FALSE on requirement
1893 */
1894 interfacePriv->intraBssEnabled = req->intraBssDistEnabled;
1895 unifi_trace(priv, UDBG3, "CsrWifiRouterCtrlModeSetReqHandler: IntraBssDisEnabled = %d\n",
1896 req->intraBssDistEnabled);
1897 } else if (req->mode == CSR_WIFI_ROUTER_CTRL_MODE_NONE) {
1898 netif_carrier_off(priv->netdev[req->interfaceTag]);
1899 interfacePriv->connected = UnifiConnectedUnknown;
1900 }
1901 }
1902 else {
6aac2e03 1903 unifi_error(priv, "CsrWifiRouterCtrlModeSetReqHandler: invalid interfaceTag :%d\n", req->interfaceTag);
635d2b00
GKH
1904 }
1905}
1906
1907void CsrWifiRouterMaPacketResHandler(void* drvpriv, CsrWifiFsmEvent* msg)
1908{
1909}
1910
1911/* delete the station record from the station record data base */
1912static int peer_delete_record(unifi_priv_t *priv, CsrWifiRouterCtrlPeerDelReq *req)
1913{
7e6f5794 1914 u8 j;
635d2b00
GKH
1915 CsrWifiRouterCtrlStaInfo_t *staInfo = NULL;
1916 unifi_port_config_t *controlledPort;
1917 unifi_port_config_t *unControlledPort;
1918 netInterface_priv_t *interfacePriv;
635d2b00 1919
7e6f5794 1920 u8 ba_session_idx = 0;
635d2b00
GKH
1921 ba_session_rx_struct *ba_session_rx = NULL;
1922 ba_session_tx_struct *ba_session_tx = NULL;
1923
1924 /* create a list for sending confirms of un-delivered packets */
1925 struct list_head send_cfm_list;
1926
1927 unsigned long lock_flags;
1928
1929 if ((req->peerRecordHandle >= UNIFI_MAX_CONNECTIONS) || (req->interfaceTag >= CSR_WIFI_NUM_INTERFACES)) {
1930 unifi_error(priv, "handle/interfaceTag is not proper, handle = %d, interfaceTag = %d\n", req->peerRecordHandle, req->interfaceTag);
1931 return CSR_RESULT_FAILURE;
1932 }
1933
1934 INIT_LIST_HEAD(&send_cfm_list);
1935
1936 interfacePriv = priv->interfacePriv[req->interfaceTag];
1937 /* remove the station record & make it NULL */
1938 if ((staInfo=interfacePriv->staInfo[req->peerRecordHandle])!=NULL) {
1939
1940 uf_prepare_send_cfm_list_for_queued_pkts(priv,
1941 &send_cfm_list,
1942 &(staInfo->mgtFrames));
1943
6aac2e03 1944 uf_flush_list(priv, &(staInfo->mgtFrames));
635d2b00
GKH
1945 for(j=0;j<MAX_ACCESS_CATOGORY;j++){
1946 uf_prepare_send_cfm_list_for_queued_pkts(priv,
1947 &send_cfm_list,
1948 &(staInfo->dataPdu[j]));
6aac2e03 1949 uf_flush_list(priv, &(staInfo->dataPdu[j]));
635d2b00
GKH
1950 }
1951
6aac2e03 1952 spin_lock_irqsave(&priv->staRecord_lock, lock_flags);
635d2b00
GKH
1953 /* clear the port configure array info, for the corresponding peer entry */
1954 controlledPort = &interfacePriv->controlled_data_port;
1955 unControlledPort = &interfacePriv->uncontrolled_data_port;
1956
1957 unifi_trace(priv, UDBG1, "peer_delete_record: Peer found handle = %d, port in use: cont(%d), unCont(%d)\n",
1958 req->peerRecordHandle, controlledPort->entries_in_use, unControlledPort->entries_in_use);
1959
1960 memset(staInfo->peerControlledPort, 0, sizeof(unifi_port_cfg_t));
1961 staInfo->peerControlledPort->port_action = CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD;
1962 staInfo->peerControlledPort->in_use = FALSE;
1963 if (controlledPort->entries_in_use) {
1964 controlledPort->entries_in_use--;
1965 } else {
1966 unifi_warning(priv, "number of controlled port entries is zero, trying to decrement: debug\n");
1967 }
1968
1969 memset(staInfo->peerUnControlledPort, 0, sizeof(unifi_port_cfg_t));
1970 staInfo->peerUnControlledPort->port_action = CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD;
1971 staInfo->peerUnControlledPort->in_use = FALSE;
1972 if (unControlledPort->entries_in_use) {
1973 unControlledPort->entries_in_use--;
1974 } else {
1975 unifi_warning(priv, "number of uncontrolled port entries is zero, trying to decrement: debug\n");
1976 }
1977
6aac2e03 1978 spin_unlock_irqrestore(&priv->staRecord_lock, lock_flags);
635d2b00
GKH
1979 /* update the TIM with zero */
1980 if (interfacePriv->interfaceMode != CSR_WIFI_ROUTER_CTRL_MODE_IBSS &&
1981 staInfo->timSet == CSR_WIFI_TIM_SET) {
1982 unifi_trace(priv, UDBG3, "peer is deleted so TIM updated to 0, in firmware\n");
6aac2e03 1983 update_tim(priv, staInfo->aid, 0, req->interfaceTag, req->peerRecordHandle);
635d2b00
GKH
1984 }
1985
1986
1987 /* Stop BA session if it is active, for this peer address all BA sessions
1988 (per tID per role) are closed */
1989
95edd09e 1990 down(&priv->ba_mutex);
635d2b00
GKH
1991 for(ba_session_idx=0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_RX; ba_session_idx++){
1992 ba_session_rx = priv->interfacePriv[req->interfaceTag]->ba_session_rx[ba_session_idx];
1993 if(ba_session_rx) {
1994 if(!memcmp(ba_session_rx->macAddress.a, staInfo->peerMacAddress.a, ETH_ALEN)){
1995 blockack_session_stop(priv,
1996 req->interfaceTag,
1997 CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_RECIPIENT,
1998 ba_session_rx->tID,
1999 ba_session_rx->macAddress);
2000 }
2001 }
2002 }
2003
2004 for(ba_session_idx=0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_TX; ba_session_idx++){
2005 ba_session_tx = priv->interfacePriv[req->interfaceTag]->ba_session_tx[ba_session_idx];
2006 if(ba_session_tx) {
2007 if(!memcmp(ba_session_tx->macAddress.a, staInfo->peerMacAddress.a, ETH_ALEN)){
2008 blockack_session_stop(priv,
2009 req->interfaceTag,
2010 CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ORIGINATOR,
2011 ba_session_tx->tID,
2012 ba_session_tx->macAddress);
2013 }
2014 }
2015 }
2016
95edd09e 2017 up(&priv->ba_mutex);
635d2b00
GKH
2018
2019#ifdef CSR_SUPPORT_SME
2020 unifi_trace(priv, UDBG1, "Canceling work queue for STA with AID: %d\n", staInfo->aid);
2021 cancel_work_sync(&staInfo->send_disconnected_ind_task);
2022#endif
2023
6aac2e03 2024 spin_lock_irqsave(&priv->staRecord_lock, lock_flags);
635d2b00
GKH
2025#ifdef CSR_SUPPORT_SME
2026 interfacePriv->num_stations_joined--;
2027
2028 staInfo->nullDataHostTag = INVALID_HOST_TAG;
2029
2030 if ((interfacePriv->sta_activity_check_enabled) &&
2031 (interfacePriv->num_stations_joined < STA_INACTIVE_DETECTION_TRIGGER_THRESHOLD))
2032 {
2033 unifi_trace(priv, UDBG1, "STOPPING the Inactivity Timer (num of stations = %d)\n", interfacePriv->num_stations_joined);
2034 interfacePriv->sta_activity_check_enabled = FALSE;
2035 del_timer_sync(&interfacePriv->sta_activity_check_timer);
2036 }
2037#endif
2038
2039 /* Free the station record for corresponding peer */
2040 kfree(interfacePriv->staInfo[req->peerRecordHandle]);
2041 interfacePriv->staInfo[req->peerRecordHandle] = NULL;
6aac2e03 2042 spin_unlock_irqrestore(&priv->staRecord_lock, lock_flags);
635d2b00
GKH
2043
2044 /* after the critical region process the list of frames that requested cfm
2045 and send cfm to requestor one by one */
2046 send_auto_ma_packet_confirm(priv, interfacePriv, &send_cfm_list);
2047
2048
2049 }
2050 else
2051 {
2052 unifi_trace(priv, UDBG3, " peer not found: Delete request Peer handle[%d]\n", req->peerRecordHandle);
2053 }
2054
2055 return CSR_RESULT_SUCCESS;
2056}
2057
2058void CsrWifiRouterCtrlPeerDelReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
2059{
2060 CsrWifiRouterCtrlPeerDelReq* req = (CsrWifiRouterCtrlPeerDelReq*)msg;
2061 CsrResult status = CSR_RESULT_SUCCESS;
2062 unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
94b84e45 2063 netInterface_priv_t *interfacePriv;
635d2b00 2064
94b84e45 2065 unifi_trace(priv, UDBG2, "entering CsrWifiRouterCtrlPeerDelReqHandler\n");
635d2b00
GKH
2066 if (priv == NULL)
2067 {
2068 unifi_error(priv, "CsrWifiRouterCtrlPeerDelReqHandler: invalid smepriv\n");
2069 return;
2070 }
2071
2072 if (req->interfaceTag >= CSR_WIFI_NUM_INTERFACES)
2073 {
2074 unifi_error(priv, "CsrWifiRouterCtrlPeerDelReqHandler: bad interfaceTag\n");
2075 return;
2076 }
2077
94b84e45
PH
2078 interfacePriv = priv->interfacePriv[req->interfaceTag];
2079
635d2b00
GKH
2080 switch(interfacePriv->interfaceMode)
2081 {
2082 case CSR_WIFI_ROUTER_CTRL_MODE_AP:
2083 case CSR_WIFI_ROUTER_CTRL_MODE_IBSS:
2084 case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO:
2085 /* remove the station from station record data base */
2086 status = peer_delete_record(priv, req);
2087 break;
2088 case CSR_WIFI_ROUTER_CTRL_MODE_STA:
2089 case CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI:
2090 default:
2091 /* No station record to maintain in these modes */
2092 break;
2093 }
2094
6aac2e03 2095 CsrWifiRouterCtrlPeerDelCfmSend(msg->source, req->clientData, req->interfaceTag, status);
635d2b00
GKH
2096 unifi_trace(priv, UDBG2, "leaving CsrWifiRouterCtrlPeerDelReqHandler \n");
2097}
2098
2099/* Add the new station to the station record data base */
6aac2e03 2100static int peer_add_new_record(unifi_priv_t *priv, CsrWifiRouterCtrlPeerAddReq *req, u32 *handle)
635d2b00 2101{
7e6f5794 2102 u8 i, powerModeTemp = 0;
5379b13d 2103 u8 freeSlotFound = FALSE;
635d2b00
GKH
2104 CsrWifiRouterCtrlStaInfo_t *newRecord = NULL;
2105 netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag];
aad3d31f 2106 u32 currentTime, currentTimeHi;
635d2b00
GKH
2107 unsigned long lock_flags;
2108
2109 if (req->interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
2110 unifi_error(priv, "peer_add_new_record: bad interfaceTag\n");
2111 return CSR_RESULT_FAILURE;
2112 }
2113
2114 currentTime = CsrTimeGet(&currentTimeHi);
2115
2116 for(i = 0; i < UNIFI_MAX_CONNECTIONS; i++) {
2117 if(interfacePriv->staInfo[i] == NULL) {
2118 /* Slot is empty, so can be used for station record */
2119 freeSlotFound = TRUE;
2120 *handle = i;
2121
2122 /* Allocate for the new station record , to avoid race condition would happen between ADD_PEER &
2123 * DEL_PEER the allocation made atomic memory rather than kernel memory
2124 */
6f6ed3db 2125 newRecord = kmalloc(sizeof(CsrWifiRouterCtrlStaInfo_t), GFP_ATOMIC);
635d2b00
GKH
2126 if (!newRecord) {
2127 unifi_error(priv, "failed to allocate the %d bytes of mem for station record\n",
2128 sizeof(CsrWifiRouterCtrlStaInfo_t));
2129 return CSR_RESULT_FAILURE;
2130 }
2131
2132 unifi_trace(priv, UDBG1, "peer_add_new_record: handle = %d AID = %d addr = %x:%x:%x:%x:%x:%x LI=%u\n",
2133 *handle, req->associationId, req->peerMacAddress.a[0], req->peerMacAddress.a[1], req->peerMacAddress.a[2],
2134 req->peerMacAddress.a[3], req->peerMacAddress.a[4], req->peerMacAddress.a[5],
2135 req->staInfo.listenIntervalInTus);
2136
2137 /* disable the preemption until station record updated */
6aac2e03 2138 spin_lock_irqsave(&priv->staRecord_lock, lock_flags);
635d2b00
GKH
2139
2140 interfacePriv->staInfo[i] = newRecord;
2141 /* Initialize the record*/
6aac2e03 2142 memset(newRecord, 0, sizeof(CsrWifiRouterCtrlStaInfo_t));
635d2b00
GKH
2143 /* update the station record */
2144 memcpy(newRecord->peerMacAddress.a, req->peerMacAddress.a, ETH_ALEN);
2145 newRecord->wmmOrQosEnabled = req->staInfo.wmmOrQosEnabled;
2146
2147 /* maxSpLength is bit map in qosInfo field, so converting accordingly */
2148 newRecord->maxSpLength = req->staInfo.maxSpLength * 2;
2149
2150 /*Max SP 0 mean any number of packets. since we buffer only 512
2151 packets we are hard coding this to zero for the moment */
2152
2153 if(newRecord->maxSpLength == 0)
2154 newRecord->maxSpLength=512;
2155
2156 newRecord->assignedHandle = i;
2157
2158 /* copy power save mode of all access catagory (Trigger/Delivery/both enabled/disabled) */
7e6f5794 2159 powerModeTemp = (u8) ((req->staInfo.powersaveMode >> 4) & 0xff);
635d2b00
GKH
2160
2161 if(!(req->staInfo.powersaveMode & 0x0001))
2162 newRecord->powersaveMode[UNIFI_TRAFFIC_Q_BK]= CSR_WIFI_AC_LEGACY_POWER_SAVE;
2163 else
2164 newRecord->powersaveMode[UNIFI_TRAFFIC_Q_BK]= powerModeTemp & 0x03;
2165
2166 if(!(req->staInfo.powersaveMode & 0x0002))
2167 newRecord->powersaveMode[UNIFI_TRAFFIC_Q_BE]= CSR_WIFI_AC_LEGACY_POWER_SAVE;
2168 else
2169 newRecord->powersaveMode[UNIFI_TRAFFIC_Q_BE]= ((powerModeTemp & 0x0C)>> 2);
2170
2171 if(!(req->staInfo.powersaveMode & 0x0004))
2172 newRecord->powersaveMode[UNIFI_TRAFFIC_Q_VI]= CSR_WIFI_AC_LEGACY_POWER_SAVE;
2173 else
2174 newRecord->powersaveMode[UNIFI_TRAFFIC_Q_VI]= ((powerModeTemp & 0x30)>> 4);
2175
2176 if(!(req->staInfo.powersaveMode & 0x0008))
2177 newRecord->powersaveMode[UNIFI_TRAFFIC_Q_VO]= CSR_WIFI_AC_LEGACY_POWER_SAVE;
2178 else
2179 newRecord->powersaveMode[UNIFI_TRAFFIC_Q_VO]= ((powerModeTemp & 0xC0)>> 6);
2180
2181 {
7e6f5794 2182 u8 k;
635d2b00
GKH
2183 for(k=0; k< MAX_ACCESS_CATOGORY ;k++)
2184 unifi_trace(priv, UDBG2, "peer_add_new_record: WMM : %d ,AC %d, powersaveMode %x \n",
6aac2e03 2185 req->staInfo.wmmOrQosEnabled, k, newRecord->powersaveMode[k]);
635d2b00
GKH
2186 }
2187
2188 unifi_trace(priv, UDBG3, "newRecord->wmmOrQosEnabled : %d , MAX SP : %d\n",
6aac2e03 2189 newRecord->wmmOrQosEnabled, newRecord->maxSpLength);
635d2b00
GKH
2190
2191 /* Initialize the mgtFrames & data Pdu list */
2192 {
7e6f5794 2193 u8 j;
635d2b00
GKH
2194 INIT_LIST_HEAD(&newRecord->mgtFrames);
2195 for(j = 0; j < MAX_ACCESS_CATOGORY; j++) {
2196 INIT_LIST_HEAD(&newRecord->dataPdu[j]);
2197 }
2198 }
2199
2200 newRecord->lastActivity = currentTime;
2201 newRecord->activity_flag = TRUE;
2202
2203 /* enable the preemption as station record updated */
6aac2e03 2204 spin_unlock_irqrestore(&priv->staRecord_lock, lock_flags);
635d2b00
GKH
2205
2206 /* First time port actions are set for the peer with below information */
2207 configure_data_port(priv, CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN, &newRecord->peerMacAddress,
2208 UF_UNCONTROLLED_PORT_Q, req->interfaceTag);
2209
2210 if (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_IBSS) {
2211 configure_data_port(priv, CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN, &newRecord->peerMacAddress,
2212 UF_CONTROLLED_PORT_Q, req->interfaceTag);
2213 } else {
2214 configure_data_port(priv, CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD, &newRecord->peerMacAddress,
2215 UF_CONTROLLED_PORT_Q, req->interfaceTag);
2216 }
2217
2218
6aac2e03 2219 spin_lock_irqsave(&priv->staRecord_lock, lock_flags);
635d2b00
GKH
2220 /* Port status must be already set before calling the Add Peer request */
2221 newRecord->peerControlledPort = uf_sme_port_config_handle(priv, newRecord->peerMacAddress.a,
2222 UF_CONTROLLED_PORT_Q, req->interfaceTag);
2223 newRecord->peerUnControlledPort = uf_sme_port_config_handle(priv, newRecord->peerMacAddress.a,
2224 UF_UNCONTROLLED_PORT_Q, req->interfaceTag);
2225
2226 if (!newRecord->peerControlledPort || !newRecord->peerUnControlledPort) {
2227 /* enable the preemption as station record failed to update */
2228 unifi_warning(priv, "Un/ControlledPort record not found in port configuration array index = %d\n", i);
2229 kfree(interfacePriv->staInfo[i]);
2230 interfacePriv->staInfo[i] = NULL;
6aac2e03 2231 spin_unlock_irqrestore(&priv->staRecord_lock, lock_flags);
635d2b00
GKH
2232 return CSR_RESULT_FAILURE;
2233 }
2234
2235 newRecord->currentPeerState = CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_ACTIVE;
2236
2237 /* changes done during block ack handling */
2238 newRecord->txSuspend = FALSE;
2239
2240 /*U-APSD related data structure*/
95edd09e
GKH
2241 newRecord->timRequestPendingFlag = FALSE;
2242
2243 /* Initialise the variable updateTimReqQueued with a value
2244 * other then CSR_WIFI_TIM_SET or CSR_WIFI_TIM_RESET value
2245 */
2246 newRecord->updateTimReqQueued = 0xFF;
2247 newRecord->timSet = CSR_WIFI_TIM_RESET;
635d2b00
GKH
2248 newRecord->uapsdActive = FALSE;
2249 newRecord->noOfSpFramesSent =0;
95edd09e 2250 newRecord->triggerFramePriority = CSR_QOS_UP0;
635d2b00
GKH
2251
2252 /* The protection bit is updated once the port opens for corresponding peer in
2253 * routerPortConfigure request */
2254
2255 /* update the association ID */
2256 newRecord->aid = req->associationId;
2257
2258#ifdef CSR_SUPPORT_SME
2259 interfacePriv->num_stations_joined++;
2260 newRecord->interfacePriv = interfacePriv;
2261 newRecord->listenIntervalInTus = req->staInfo.listenIntervalInTus;
2262 newRecord->nullDataHostTag = INVALID_HOST_TAG;
2263
2264 INIT_WORK(&newRecord->send_disconnected_ind_task, uf_send_disconnected_ind_wq);
2265
2266 if(!(interfacePriv->sta_activity_check_enabled) &&
2267 (interfacePriv->num_stations_joined >= STA_INACTIVE_DETECTION_TRIGGER_THRESHOLD)){
2268 unifi_trace(priv, UDBG1,
2269 "peer_add_new_record: STARTING the Inactivity Timer (num of stations = %d)",
2270 interfacePriv->num_stations_joined);
2271
2272 interfacePriv->sta_activity_check_enabled = TRUE;
2273 interfacePriv->sta_activity_check_timer.function = check_inactivity_timer_expire_func;
2274 interfacePriv->sta_activity_check_timer.data = (unsigned long)interfacePriv;
2275
2276 init_timer(&interfacePriv->sta_activity_check_timer);
2277 mod_timer(&interfacePriv->sta_activity_check_timer,
2278 (jiffies + usecs_to_jiffies(STA_INACTIVE_DETECTION_TIMER_INTERVAL * 1000 * 1000)));
2279
2280 }
2281#endif
6aac2e03 2282 spin_unlock_irqrestore(&priv->staRecord_lock, lock_flags);
635d2b00
GKH
2283 break;
2284 }
2285 }
2286
2287 if(!freeSlotFound) {
2288 unifi_error(priv, "Limited connectivity, Free slot not found for station record addition\n");
2289 return CSR_RESULT_FAILURE;
2290 }
2291 return CSR_RESULT_SUCCESS;
2292}
2293
2294#ifdef CSR_SUPPORT_SME
2295static void check_inactivity_timer_expire_func(unsigned long data)
2296{
2297 struct unifi_priv *priv;
2298 CsrWifiRouterCtrlStaInfo_t *sta_record = NULL;
7e6f5794 2299 u8 i = 0;
aad3d31f
DN
2300 u32 now;
2301 u32 inactive_time;
635d2b00
GKH
2302 netInterface_priv_t *interfacePriv = (netInterface_priv_t *) data;
2303
2304 if (!interfacePriv)
2305 {
2306 return;
2307 }
2308
2309 priv = interfacePriv->privPtr;
2310
2311 if (interfacePriv->InterfaceTag >= CSR_WIFI_NUM_INTERFACES)
2312 {
2313 unifi_error(priv, "check_inactivity_timer_expire_func: Invalid interfaceTag\n");
2314 return;
2315 }
2316
2317 /* RUN Algorithm to check inactivity for each connected station */
2318 now = CsrTimeGet(NULL);
2319
2320 for(i = 0; i < UNIFI_MAX_CONNECTIONS; i++) {
2321 if(interfacePriv->staInfo[i] != NULL) {
2322 sta_record = interfacePriv->staInfo[i];
2323
2324 if (sta_record->activity_flag == TRUE){
2325 sta_record->activity_flag = FALSE;
2326 sta_record->lastActivity = now;
2327 continue;
2328 }
2329
2330 if (sta_record->lastActivity > now)
2331 {
2332 /* simple timer wrap (for 1 wrap) */
aad3d31f 2333 inactive_time = CsrTimeAdd((u32)CsrTimeSub(CSR_SCHED_TIME_MAX, sta_record->lastActivity), now);
635d2b00
GKH
2334 }
2335 else
2336 {
aad3d31f 2337 inactive_time = (u32)CsrTimeSub(now, sta_record->lastActivity);
635d2b00
GKH
2338 }
2339
2340 if (inactive_time >= STA_INACTIVE_TIMEOUT_VAL)
2341 {
2342 unifi_trace(priv, UDBG1, "STA is Inactive - AID = %d inactive_time = %d\n",
2343 sta_record->aid,
2344 inactive_time);
2345
2346 /* station is in-active, if it is in active mode send a null frame
2347 * and the station should acknowledge the null frame, if acknowledgement
2348 * is not received throw out the station.
2349 * If the station is in Power Save, update TIM for the station so
2350 * that it wakes up and register some activity through PS-Poll or
2351 * trigger frame.
2352 */
2353 if (sta_record->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_ACTIVE)
2354 {
2355 unifi_trace(priv, UDBG1, "STA power save state - Active, send a NULL frame to check if it is ALIVE\n");
2356 uf_send_nulldata ( priv,
2357 sta_record->interfacePriv->InterfaceTag,
2358 sta_record->peerMacAddress.a,
2359 CSR_CONTENTION,
2360 sta_record);
2361 }
2362 else if (sta_record->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE)
2363 {
2364 if((sta_record->timSet == CSR_WIFI_TIM_SET) ||
2365 (sta_record->timSet == CSR_WIFI_TIM_SETTING))
2366 {
2367 unifi_trace(priv, UDBG1, "STA power save state - PS, TIM is already SET\n");
2368
2369 /* If TIM is set and we do not have any activity for
2370 * more than 3 listen intervals then send a disconnected
2371 * indication to SME, to delete the station from station
2372 * record list.
2373 * The inactivity is already more than STA_INACTIVE_TIMEOUT_VAL
2374 * and this check ensures if the listen interval is a larger
2375 * value than STA_INACTIVE_TIMEOUT_VAL.
2376 */
2377 if (inactive_time > (3 * (sta_record->listenIntervalInTus * 1024)))
2378 {
2379 unifi_trace(priv, UDBG1, "STA is inactive for more than 3 listen intervals\n");
2380 queue_work( priv->unifi_workqueue,
2381 &sta_record->send_disconnected_ind_task);
2382 }
2383
2384 }
2385 else
2386 {
2387 unifi_trace(priv, UDBG1, "STA power save state - PS, update TIM to see if it is ALIVE\n");
2388 update_tim(priv,
2389 sta_record->aid,
2390 CSR_WIFI_TIM_SET,
2391 interfacePriv->InterfaceTag,
2392 sta_record->assignedHandle);
2393 }
2394 }
2395 }
2396 }
2397 }
2398
2399 /* re-run the timer interrupt */
2400 mod_timer(&interfacePriv->sta_activity_check_timer,
2401 (jiffies + usecs_to_jiffies(STA_INACTIVE_DETECTION_TIMER_INTERVAL * 1000 * 1000)));
2402
2403}
2404
2405
2406void uf_send_disconnected_ind_wq(struct work_struct *work)
2407{
2408
2409 CsrWifiRouterCtrlStaInfo_t *staInfo = container_of(work, CsrWifiRouterCtrlStaInfo_t, send_disconnected_ind_task);
2410 unifi_priv_t *priv;
8c87f69a 2411 u16 interfaceTag;
635d2b00 2412 struct list_head send_cfm_list;
7e6f5794 2413 u8 j;
635d2b00 2414
635d2b00
GKH
2415 if(!staInfo) {
2416 return;
2417 }
2418
2419 if(!staInfo->interfacePriv) {
2420 return;
2421 }
2422
2423 priv = staInfo->interfacePriv->privPtr;
2424 interfaceTag = staInfo->interfacePriv->InterfaceTag;
2425
2426 if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
2427 unifi_error(priv, "uf_send_disconnected_ind_wq: invalid interfaceTag\n");
2428 return;
2429 }
2430
2431 /* The SME/NME may be waiting for confirmation for requested frames to this station.
2432 * So loop through buffered frames for this station and if confirmation is
2433 * requested, send auto confirmation with failure status. Also flush the frames so
2434 * that these are not processed again in PEER_DEL_REQ handler.
2435 */
2436 INIT_LIST_HEAD(&send_cfm_list);
2437
2438 uf_prepare_send_cfm_list_for_queued_pkts(priv,
2439 &send_cfm_list,
2440 &(staInfo->mgtFrames));
2441
2442 uf_flush_list(priv, &(staInfo->mgtFrames));
2443
2444 for(j = 0; j < MAX_ACCESS_CATOGORY; j++){
2445 uf_prepare_send_cfm_list_for_queued_pkts(priv,
2446 &send_cfm_list,
2447 &(staInfo->dataPdu[j]));
2448
6aac2e03 2449 uf_flush_list(priv, &(staInfo->dataPdu[j]));
635d2b00
GKH
2450 }
2451
2452 send_auto_ma_packet_confirm(priv, staInfo->interfacePriv, &send_cfm_list);
2453
2454 unifi_warning(priv, "uf_send_disconnected_ind_wq: Router Disconnected IND Peer (%x-%x-%x-%x-%x-%x)\n",
2455 staInfo->peerMacAddress.a[0],
2456 staInfo->peerMacAddress.a[1],
2457 staInfo->peerMacAddress.a[2],
2458 staInfo->peerMacAddress.a[3],
2459 staInfo->peerMacAddress.a[4],
2460 staInfo->peerMacAddress.a[5]);
2461
2462 CsrWifiRouterCtrlConnectedIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,
2463 0,
2464 staInfo->interfacePriv->InterfaceTag,
2465 staInfo->peerMacAddress,
2466 CSR_WIFI_ROUTER_CTRL_PEER_DISCONNECTED);
2467
2468
2469 return;
2470}
2471
2472
2473#endif
6aac2e03 2474void CsrWifiRouterCtrlPeerAddReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
635d2b00
GKH
2475{
2476 CsrWifiRouterCtrlPeerAddReq* req = (CsrWifiRouterCtrlPeerAddReq*)msg;
2477 CsrResult status = CSR_RESULT_SUCCESS;
2478 unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
26a6b2e1 2479 u32 handle = 0;
94b84e45 2480 netInterface_priv_t *interfacePriv;
635d2b00
GKH
2481
2482 unifi_trace(priv, UDBG2, "entering CsrWifiRouterCtrlPeerAddReqHandler \n");
2483 if (priv == NULL)
2484 {
2485 unifi_error(priv, "CsrWifiRouterCtrlPeerAddReqHandler: invalid smepriv\n");
2486 return;
2487 }
2488
2489 if (req->interfaceTag >= CSR_WIFI_NUM_INTERFACES)
2490 {
2491 unifi_error(priv, "CsrWifiRouterCtrlPeerAddReqHandler: bad interfaceTag\n");
2492 return;
2493 }
2494
94b84e45
PH
2495 interfacePriv = priv->interfacePriv[req->interfaceTag];
2496
635d2b00
GKH
2497 switch(interfacePriv->interfaceMode)
2498 {
2499 case CSR_WIFI_ROUTER_CTRL_MODE_AP:
2500 case CSR_WIFI_ROUTER_CTRL_MODE_IBSS:
2501 case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO:
2502 /* Add station record */
6aac2e03 2503 status = peer_add_new_record(priv, req, &handle);
635d2b00
GKH
2504 break;
2505 case CSR_WIFI_ROUTER_CTRL_MODE_STA:
2506 case CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI:
2507 default:
2508 /* No station record to maintain in these modes */
2509 break;
2510 }
2511
6aac2e03 2512 CsrWifiRouterCtrlPeerAddCfmSend(msg->source, req->clientData, req->interfaceTag, req->peerMacAddress, handle, status);
635d2b00
GKH
2513 unifi_trace(priv, UDBG2, "leaving CsrWifiRouterCtrlPeerAddReqHandler \n");
2514}
2515
6aac2e03 2516void CsrWifiRouterCtrlPeerUpdateReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
635d2b00
GKH
2517{
2518 CsrWifiRouterCtrlPeerUpdateReq* req = (CsrWifiRouterCtrlPeerUpdateReq*)msg;
2519 CsrResult status = CSR_RESULT_SUCCESS;
2520 unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
2521
2522 unifi_trace(priv, UDBG2, "entering CsrWifiRouterCtrlPeerUpdateReqHandler \n");
2523 if (priv == NULL)
2524 {
2525 unifi_error(priv, "CsrWifiRouterCtrlPeerUpdateReqHandler: invalid smepriv\n");
2526 return;
2527 }
2528
6aac2e03 2529 CsrWifiRouterCtrlPeerUpdateCfmSend(msg->source, req->clientData, req->interfaceTag, status);
635d2b00
GKH
2530 unifi_trace(priv, UDBG2, "leaving CsrWifiRouterCtrlPeerUpdateReqHandler \n");
2531}
2532
2533
2534 void CsrWifiRouterCtrlRawSdioDeinitialiseReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
2535{
2536 /* This will never be called as it is intercepted in the Userspace */
2537}
2538
2539void CsrWifiRouterCtrlRawSdioInitialiseReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
2540{
2541 /* This will never be called as it is intercepted in the Userspace */
2542}
2543
2544void
2545uf_send_ba_err_wq(struct work_struct *work)
2546{
2547 ba_session_rx_struct *ba_session = container_of(work, ba_session_rx_struct, send_ba_err_task);
2548 unifi_priv_t *priv;
2549
2550 if(!ba_session) {
2551 return;
2552 }
2553
2554 if(!ba_session->interfacePriv) {
2555 return;
2556 }
2557
2558 priv = ba_session->interfacePriv->privPtr;
2559
2560 if (ba_session->interfacePriv->InterfaceTag >= CSR_WIFI_NUM_INTERFACES) {
2561 unifi_error(priv, "%s: invalid interfaceTag\n", __FUNCTION__);
2562 return;
2563 }
2564
2565 unifi_warning(priv, "%s: Calling CsrWifiRouterCtrlBlockAckErrorIndSend(%d, %d, %d, %d, %x:%x:%x:%x:%x:%x, %d)\n",
2566 __FUNCTION__,
2567 priv->CSR_WIFI_SME_IFACEQUEUE,
2568 0,
2569 ba_session->interfacePriv->InterfaceTag,
2570 ba_session->tID,
2571 ba_session->macAddress.a[0],
2572 ba_session->macAddress.a[1],
2573 ba_session->macAddress.a[2],
2574 ba_session->macAddress.a[3],
2575 ba_session->macAddress.a[4],
2576 ba_session->macAddress.a[5],
2577 CSR_RESULT_SUCCESS
2578 );
2579 CsrWifiRouterCtrlBlockAckErrorIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,
2580 0,
2581 ba_session->interfacePriv->InterfaceTag,
2582 ba_session->tID,
2583 ba_session->macAddress,
2584 CSR_RESULT_SUCCESS);
2585}
2586
2587
2588static void ba_session_terminate_timer_func(unsigned long data)
2589{
2590 ba_session_rx_struct *ba_session = (ba_session_rx_struct*)data;
2591 struct unifi_priv *priv;
2592
2593 if(!ba_session) {
2594 return;
2595 }
2596
2597 if(!ba_session->interfacePriv) {
2598 return;
2599 }
2600
2601 priv = ba_session->interfacePriv->privPtr;
2602
2603 if (ba_session->interfacePriv->InterfaceTag >= CSR_WIFI_NUM_INTERFACES) {
2604 unifi_error(priv, "%s: invalid interfaceTag\n", __FUNCTION__);
2605 return;
2606 }
2607
2608 queue_work(priv->unifi_workqueue, &ba_session->send_ba_err_task);
2609}
2610
2611
5379b13d 2612u8 blockack_session_stop(unifi_priv_t *priv,
8c87f69a 2613 u16 interfaceTag,
635d2b00 2614 CsrWifiRouterCtrlBlockAckRole role,
8c87f69a 2615 u16 tID,
635d2b00
GKH
2616 CsrWifiMacAddress macAddress)
2617{
2618 netInterface_priv_t *interfacePriv;
2619 ba_session_rx_struct *ba_session_rx = NULL;
2620 ba_session_tx_struct *ba_session_tx = NULL;
7e6f5794 2621 u8 ba_session_idx = 0;
635d2b00
GKH
2622 int i;
2623
2624 if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
2625 unifi_error(priv, "%s: bad interfaceTag = %d\n", __FUNCTION__, interfaceTag);
2626 return FALSE;
2627 }
2628
2629 interfacePriv = priv->interfacePriv[interfaceTag];
2630
2631 if(!interfacePriv) {
2632 unifi_error(priv, "%s: bad interfacePriv\n", __FUNCTION__);
2633 return FALSE;
2634 }
2635
2636 if(tID > 15) {
2637 unifi_error(priv, "%s: bad tID = %d\n", __FUNCTION__, tID);
2638 return FALSE;
2639 }
2640
2641 if((role != CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ORIGINATOR) &&
2642 (role != CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_RECIPIENT)) {
2643 unifi_error(priv, "%s: bad role = %d\n", __FUNCTION__, role);
2644 return FALSE;
2645 }
2646
a6737c73
AS
2647 unifi_warning(priv,
2648 "%s: stopping ba_session for peer = %pM role = %d tID = %d\n",
2649 __func__, macAddress.a, role, tID);
635d2b00
GKH
2650
2651 /* find out the appropriate ba session (/station /tid /role) for which stop is requested */
2652 if (role == CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_RECIPIENT){
2653 for (ba_session_idx =0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_RX; ba_session_idx++){
2654
2655 ba_session_rx = interfacePriv->ba_session_rx[ba_session_idx];
2656
2657 if(ba_session_rx){
2658 if ((!memcmp(ba_session_rx->macAddress.a, macAddress.a, ETH_ALEN)) && (ba_session_rx->tID == tID)){
2659 break;
2660 }
2661 }
2662 }
2663
2664 if (!ba_session_rx || (ba_session_idx == MAX_SUPPORTED_BA_SESSIONS_RX)) {
2665 unifi_error(priv, "%s: bad ba_session for Rx [tID=%d]\n", __FUNCTION__, tID);
2666 return FALSE;
2667 }
2668
2669
2670 if(ba_session_rx->timeout) {
2671 del_timer_sync(&ba_session_rx->timer);
2672 }
2673 cancel_work_sync(&ba_session_rx->send_ba_err_task);
2674 for (i = 0; i < ba_session_rx->wind_size; i++) {
2675 if(ba_session_rx->buffer[i].active) {
2676 frame_desc_struct *frame_desc = &ba_session_rx->buffer[i];
2677 unifi_net_data_free(priv, &frame_desc->bulkdata.d[0]);
2678 }
2679 }
2680 kfree(ba_session_rx->buffer);
2681
2682 interfacePriv->ba_session_rx[ba_session_idx] = NULL;
2683 kfree(ba_session_rx);
2684 }else if (role == CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ORIGINATOR){
2685 for (ba_session_idx =0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_TX; ba_session_idx++){
2686 ba_session_tx = interfacePriv->ba_session_tx[ba_session_idx];
2687 if(ba_session_tx){
2688 if ((!memcmp(ba_session_tx->macAddress.a, macAddress.a, ETH_ALEN)) && (ba_session_tx->tID == tID)){
2689 break;
2690 }
2691 }
2692 }
2693
2694 if (!ba_session_tx || (ba_session_idx == MAX_SUPPORTED_BA_SESSIONS_TX)) {
2695 unifi_error(priv, "%s: bad ba_session for Tx [tID=%d]\n", __FUNCTION__, tID);
2696 return FALSE;
2697 }
2698 interfacePriv->ba_session_tx[ba_session_idx] = NULL;
2699 kfree(ba_session_tx);
2700
2701 }
2702
2703 return TRUE;
2704}
2705
2706
2707void CsrWifiRouterCtrlBlockAckDisableReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
2708{
2709 CsrWifiRouterCtrlBlockAckDisableReq* req = (CsrWifiRouterCtrlBlockAckDisableReq*)msg;
5379b13d 2710 u8 r;
635d2b00
GKH
2711 unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
2712
2713 unifi_trace(priv, UDBG6, "%s: in ok\n", __FUNCTION__);
2714
95edd09e 2715 down(&priv->ba_mutex);
635d2b00
GKH
2716 r = blockack_session_stop(priv,
2717 req->interfaceTag,
2718 req->role,
2719 req->trafficStreamID,
2720 req->macAddress);
95edd09e 2721 up(&priv->ba_mutex);
635d2b00
GKH
2722
2723 CsrWifiRouterCtrlBlockAckDisableCfmSend(msg->source,
2724 req->clientData,
2725 req->interfaceTag,
2726 r?CSR_RESULT_SUCCESS:CSR_RESULT_FAILURE);
2727
2728 unifi_trace(priv, UDBG6, "%s: out ok\n", __FUNCTION__);
2729}
2730
2731
5379b13d 2732u8 blockack_session_start(unifi_priv_t *priv,
8c87f69a
GKH
2733 u16 interfaceTag,
2734 u16 tID,
2735 u16 timeout,
635d2b00 2736 CsrWifiRouterCtrlBlockAckRole role,
8c87f69a
GKH
2737 u16 wind_size,
2738 u16 start_sn,
635d2b00
GKH
2739 CsrWifiMacAddress macAddress
2740 )
2741{
2742 netInterface_priv_t *interfacePriv;
2743 ba_session_rx_struct *ba_session_rx = NULL;
2744 ba_session_tx_struct *ba_session_tx = NULL;
7e6f5794 2745 u8 ba_session_idx = 0;
635d2b00
GKH
2746
2747
2748 if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
2749 unifi_error(priv, "%s: bad interfaceTag = %d\n", __FUNCTION__, interfaceTag);
2750 return FALSE;
2751 }
2752
2753 interfacePriv = priv->interfacePriv[interfaceTag];
2754
2755 if(!interfacePriv) {
2756 unifi_error(priv, "%s: bad interfacePriv\n", __FUNCTION__);
2757 return FALSE;
2758 }
2759
2760 if(tID > 15)
2761 {
2762 unifi_error(priv, "%s: bad tID=%d\n", __FUNCTION__, tID);
2763 return FALSE;
2764 }
2765
2766 if(wind_size > MAX_BA_WIND_SIZE) {
2767 unifi_error(priv, "%s: bad wind_size = %d\n", __FUNCTION__, wind_size);
2768 return FALSE;
2769 }
2770
2771 if(role != CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ORIGINATOR &&
2772 role != CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_RECIPIENT) {
2773 unifi_error(priv, "%s: bad role = %d\n", __FUNCTION__, role);
2774 return FALSE;
2775 }
2776
a6737c73
AS
2777 unifi_warning(priv,
2778 "%s: ba session with peer= (%pM)\n", __func__,
2779 macAddress.a);
635d2b00
GKH
2780
2781 unifi_warning(priv, "%s: ba session for tID=%d timeout=%d role=%d wind_size=%d start_sn=%d\n", __FUNCTION__,
2782 tID,
2783 timeout,
2784 role,
2785 wind_size,
2786 start_sn);
2787
2788 /* Check if BA session exists for per station, per TID, per role or not.
2789 if BA session exists update parameters and if it does not exist
2790 create a new BA session */
2791 if (role == CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ORIGINATOR){
2792 for (ba_session_idx =0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_TX; ba_session_idx++){
2793 ba_session_tx = interfacePriv->ba_session_tx[ba_session_idx];
2794 if (ba_session_tx) {
2795 if ((!memcmp(ba_session_tx->macAddress.a, macAddress.a, ETH_ALEN)) && (ba_session_tx->tID == tID)){
2796 unifi_warning(priv, "%s: ba_session for Tx already exists\n", __FUNCTION__);
2797 return TRUE;
2798 }
2799 }
2800 }
2801
2802 /* we have to create new ba_session_tx struct */
2803 ba_session_tx = NULL;
2804
2805 /* loop through until an empty BA session slot is there and save the session there */
2806 for (ba_session_idx=0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_TX ; ba_session_idx++){
2807 if (!(interfacePriv->ba_session_tx[ba_session_idx])){
2808 break;
2809 }
2810 }
2811 if (ba_session_idx == MAX_SUPPORTED_BA_SESSIONS_TX){
2812 unifi_error(priv, "%s: All ba_session used for Tx, NO free session available\n", __FUNCTION__);
2813 return FALSE;
2814 }
2815
2816 /* create and populate the new BA session structure */
7cd4e8c5 2817 ba_session_tx = kzalloc(sizeof(ba_session_tx_struct), GFP_KERNEL);
635d2b00
GKH
2818 if (!ba_session_tx) {
2819 unifi_error(priv, "%s: kmalloc failed for ba_session_tx\n", __FUNCTION__);
2820 return FALSE;
2821 }
635d2b00
GKH
2822
2823 ba_session_tx->interfacePriv = interfacePriv;
2824 ba_session_tx->tID = tID;
2825 ba_session_tx->macAddress = macAddress;
2826
2827 interfacePriv->ba_session_tx[ba_session_idx] = ba_session_tx;
2828
2829 } else if (role == CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_RECIPIENT){
2830
2831 for (ba_session_idx =0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_RX; ba_session_idx++){
2832 ba_session_rx = interfacePriv->ba_session_rx[ba_session_idx];
2833 if (ba_session_rx) {
2834 if ((!memcmp(ba_session_rx->macAddress.a, macAddress.a, ETH_ALEN)) && (ba_session_rx->tID == tID)){
2835 unifi_warning(priv, "%s: ba_session for Rx[tID = %d] already exists\n", __FUNCTION__, tID);
2836
2837 if(ba_session_rx->wind_size == wind_size &&
2838 ba_session_rx->timeout == timeout &&
2839 ba_session_rx->expected_sn == start_sn) {
2840 return TRUE;
2841 }
2842
2843 if(ba_session_rx->timeout) {
2844 del_timer_sync(&ba_session_rx->timer);
2845 ba_session_rx->timeout = 0;
2846 }
2847
2848 if(ba_session_rx->wind_size != wind_size) {
2849 blockack_session_stop(priv, interfaceTag, role, tID, macAddress);
2850 } else {
2851 if (timeout) {
2852 ba_session_rx->timeout = timeout;
2853 ba_session_rx->timer.function = ba_session_terminate_timer_func;
2854 ba_session_rx->timer.data = (unsigned long)ba_session_rx;
2855 init_timer(&ba_session_rx->timer);
2856 mod_timer(&ba_session_rx->timer, (jiffies + usecs_to_jiffies((ba_session_rx->timeout) * 1024)));
2857 }
95edd09e
GKH
2858 /*
2859 * The starting sequence number shall remain same if the BA
2860 * enable request is issued to update BA parameters only. If
2861 * it is not same, then we scroll our window to the new starting
2862 * sequence number. This could happen if the DELBA frame from
2863 * originator is lost and then we receive ADDBA frame with new SSN.
2864 */
2865 if(ba_session_rx->start_sn != start_sn) {
2866 scroll_ba_window(priv, interfacePriv, ba_session_rx, start_sn);
2867 }
635d2b00
GKH
2868 return TRUE;
2869 }
2870 }
2871 }
2872 }
2873
2874 /* we could have a valid BA session pointer here or un-initialized
2875 ba session pointer. but in any case we have to create a new session.
2876 so re-initialize the ba_session pointer */
2877 ba_session_rx = NULL;
2878
2879 /* loop through until an empty BA session slot is there and save the session there */
2880 for (ba_session_idx=0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_RX ; ba_session_idx++){
2881 if (!(interfacePriv->ba_session_rx[ba_session_idx])){
2882 break;
2883 }
2884 }
2885 if (ba_session_idx == MAX_SUPPORTED_BA_SESSIONS_RX){
2886 unifi_error(priv, "%s: All ba_session used for Rx, NO free session available\n", __FUNCTION__);
2887 return FALSE;
2888 }
2889
95edd09e
GKH
2890 /* It is observed that with some devices there is a race between
2891 * EAPOL exchanges and BA session establishment. This results in
2892 * some EAPOL authentication packets getting stuck in BA reorder
2893 * buffer and hence the conection cannot be established. To avoid
2894 * this we check here if the EAPOL authentication is complete and
2895 * if so then only allow the BA session to establish.
2896 *
2897 * It is verified that the peers normally re-establish
2898 * the BA session after the initial rejection.
2899 */
2900 if (CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN != uf_sme_port_state(priv, macAddress.a, UF_CONTROLLED_PORT_Q, interfacePriv->InterfaceTag))
2901 {
2902 unifi_warning(priv, "blockack_session_start: Controlled port not opened, Reject BA request\n");
2903 return FALSE;
2904 }
635d2b00 2905
7cd4e8c5 2906 ba_session_rx = kzalloc(sizeof(ba_session_rx_struct), GFP_KERNEL);
635d2b00
GKH
2907 if (!ba_session_rx) {
2908 unifi_error(priv, "%s: kmalloc failed for ba_session_rx\n", __FUNCTION__);
2909 return FALSE;
2910 }
635d2b00
GKH
2911
2912 ba_session_rx->wind_size = wind_size;
2913 ba_session_rx->start_sn = ba_session_rx->expected_sn = start_sn;
2914 ba_session_rx->trigger_ba_after_ssn = FALSE;
2915
7cd4e8c5 2916 ba_session_rx->buffer = kzalloc(ba_session_rx->wind_size*sizeof(frame_desc_struct), GFP_KERNEL);
635d2b00
GKH
2917 if (!ba_session_rx->buffer) {
2918 kfree(ba_session_rx);
2919 unifi_error(priv, "%s: kmalloc failed for buffer\n", __FUNCTION__);
2920 return FALSE;
2921 }
2922
635d2b00
GKH
2923 INIT_WORK(&ba_session_rx->send_ba_err_task, uf_send_ba_err_wq);
2924 if (timeout) {
2925 ba_session_rx->timeout = timeout;
2926 ba_session_rx->timer.function = ba_session_terminate_timer_func;
2927 ba_session_rx->timer.data = (unsigned long)ba_session_rx;
2928 init_timer(&ba_session_rx->timer);
2929 mod_timer(&ba_session_rx->timer, (jiffies + usecs_to_jiffies((ba_session_rx->timeout) * 1024)));
2930 }
2931
2932 ba_session_rx->interfacePriv = interfacePriv;
2933 ba_session_rx->tID = tID;
2934 ba_session_rx->macAddress = macAddress;
2935
2936 interfacePriv->ba_session_rx[ba_session_idx] = ba_session_rx;
2937 }
2938 return TRUE;
2939}
2940
2941void CsrWifiRouterCtrlBlockAckEnableReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
2942{
2943 CsrWifiRouterCtrlBlockAckEnableReq* req = (CsrWifiRouterCtrlBlockAckEnableReq*)msg;
5379b13d 2944 u8 r;
635d2b00
GKH
2945 unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
2946
2947 unifi_trace(priv, UDBG6, ">>%s\n", __FUNCTION__);
95edd09e 2948 down(&priv->ba_mutex);
635d2b00
GKH
2949 r = blockack_session_start(priv,
2950 req->interfaceTag,
2951 req->trafficStreamID,
2952 req->timeout,
2953 req->role,
2954 req->bufferSize,
2955 req->ssn,
2956 req->macAddress
2957 );
95edd09e 2958 up(&priv->ba_mutex);
635d2b00
GKH
2959
2960 CsrWifiRouterCtrlBlockAckEnableCfmSend(msg->source,
2961 req->clientData,
2962 req->interfaceTag,
2963 r?CSR_RESULT_SUCCESS:CSR_RESULT_FAILURE);
2964 unifi_trace(priv, UDBG6, "<<%s: r=%d\n", __FUNCTION__, r);
2965
2966}
2967
2968void CsrWifiRouterCtrlWapiMulticastFilterReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
2969{
95edd09e
GKH
2970#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
2971
635d2b00
GKH
2972 unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
2973 CsrWifiRouterCtrlWapiMulticastFilterReq* req = (CsrWifiRouterCtrlWapiMulticastFilterReq*)msg;
95edd09e 2974 netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag];
635d2b00 2975
95edd09e
GKH
2976 if (CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode) {
2977
2978 unifi_trace(priv, UDBG6, ">>%s\n", __FUNCTION__);
2979
2980 unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWapiMulticastFilterReq: req->status = %d\n", req->status);
2981
2982 /* status 1 - Filter on
2983 * status 0 - Filter off */
2984 priv->wapi_multicast_filter = req->status;
2985
2986 unifi_trace(priv, UDBG6, "<<%s\n", __FUNCTION__);
2987 } else {
635d2b00 2988
6aac2e03 2989 unifi_warning(priv, "%s is NOT applicable for interface mode - %d\n", __FUNCTION__, interfacePriv->interfaceMode);
635d2b00 2990
95edd09e
GKH
2991 }
2992#elif defined(UNIFI_DEBUG)
2993 /*WAPI Disabled*/
2994 unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
6aac2e03 2995 unifi_error(priv, "CsrWifiRouterCtrlWapiMulticastFilterReqHandler: called when WAPI isn't enabled\n");
95edd09e 2996#endif
635d2b00
GKH
2997}
2998
2999void CsrWifiRouterCtrlWapiUnicastFilterReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
3000{
95edd09e
GKH
3001#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
3002
635d2b00
GKH
3003 unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
3004 CsrWifiRouterCtrlWapiUnicastFilterReq* req = (CsrWifiRouterCtrlWapiUnicastFilterReq*)msg;
95edd09e 3005 netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag];
635d2b00 3006
95edd09e 3007 if (CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode) {
635d2b00 3008
95edd09e 3009 unifi_trace(priv, UDBG6, ">>%s\n", __FUNCTION__);
635d2b00 3010
95edd09e 3011 unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWapiUnicastFilterReq: req->status= %d\n", req->status);
635d2b00 3012
95edd09e
GKH
3013 if ((priv->wapi_unicast_filter == 1) && (req->status == 0)) {
3014 /* When we have successfully re-associated and obtained a new unicast key with keyid = 0 */
3015 priv->wapi_unicast_queued_pkt_filter = 1;
3016 }
635d2b00 3017
95edd09e
GKH
3018 /* status 1 - Filter ON
3019 * status 0 - Filter OFF */
3020 priv->wapi_unicast_filter = req->status;
635d2b00 3021
95edd09e
GKH
3022 unifi_trace(priv, UDBG6, "<<%s\n", __FUNCTION__);
3023 } else {
3024
6aac2e03 3025 unifi_warning(priv, "%s is NOT applicable for interface mode - %d\n", __FUNCTION__, interfacePriv->interfaceMode);
95edd09e
GKH
3026
3027 }
3028#elif defined(UNIFI_DEBUG)
3029 /*WAPI Disabled*/
635d2b00 3030 unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
6aac2e03 3031 unifi_error(priv, "CsrWifiRouterCtrlWapiUnicastFilterReqHandler: called when WAPI isn't enabled\n");
95edd09e
GKH
3032#endif
3033}
3034
3035void CsrWifiRouterCtrlWapiRxPktReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
3036{
3037#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
635d2b00 3038
95edd09e
GKH
3039 unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
3040 CsrWifiRouterCtrlWapiRxPktReq* req = (CsrWifiRouterCtrlWapiRxPktReq*)msg;
635d2b00
GKH
3041 int client_id, receiver_id;
3042 bulk_data_param_t bulkdata;
3043 CsrResult res;
3044 ul_client_t *client;
635d2b00
GKH
3045 CSR_SIGNAL signal;
3046 CSR_MA_PACKET_INDICATION *pkt_ind;
94b84e45
PH
3047 netInterface_priv_t *interfacePriv;
3048
3049 if (priv == NULL) {
3050 unifi_error(priv, "CsrWifiRouterCtrlWapiRxPktReq : invalid priv\n", __func__);
3051 return;
3052 }
3053
3054 if (priv->smepriv == NULL) {
3055 unifi_error(priv, "CsrWifiRouterCtrlWapiRxPktReq : invalid sme priv\n", __func__);
3056 return;
3057 }
3058
3059 interfacePriv = priv->interfacePriv[req->interfaceTag];
635d2b00 3060
95edd09e 3061 if (CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode) {
635d2b00 3062
95edd09e 3063 unifi_trace(priv, UDBG6, ">>%s\n", __FUNCTION__);
635d2b00 3064
635d2b00 3065
95edd09e 3066 if (req->dataLength == 0 || req->data == NULL) {
6aac2e03 3067 unifi_error(priv, "CsrWifiRouterCtrlWapiRxPktReq: invalid request\n", __FUNCTION__);
95edd09e
GKH
3068 return;
3069 }
635d2b00 3070
95edd09e
GKH
3071 res = unifi_net_data_malloc(priv, &bulkdata.d[0], req->dataLength);
3072 if (res != CSR_RESULT_SUCCESS) {
6aac2e03 3073 unifi_error(priv, "CsrWifiRouterCtrlWapiRxPktReq: Could not allocate net data\n", __FUNCTION__);
95edd09e
GKH
3074 return;
3075 }
3076
3077 /* This function is expected to be called only when the MIC has been verified by SME to be correct
3078 * So reset the reception status to rx_success */
3079 res = read_unpack_signal(req->signal, &signal);
3080 if (res) {
6aac2e03 3081 unifi_error(priv, "CsrWifiRouterCtrlWapiRxPktReqHandler: Received unknown or corrupted signal.\n");
95edd09e
GKH
3082 return;
3083 }
3084 pkt_ind = (CSR_MA_PACKET_INDICATION*) (&((&signal)->u).MaPacketIndication);
3085 if (pkt_ind->ReceptionStatus != CSR_MICHAEL_MIC_ERROR) {
6aac2e03 3086 unifi_error(priv, "CsrWifiRouterCtrlWapiRxPktReqHandler: Unknown signal with reception status = %d\n", pkt_ind->ReceptionStatus);
95edd09e
GKH
3087 return;
3088 } else {
6aac2e03 3089 unifi_trace(priv, UDBG4, "CsrWifiRouterCtrlWapiRxPktReqHandler: MIC verified , RX_SUCCESS \n", __FUNCTION__);
95edd09e
GKH
3090 pkt_ind->ReceptionStatus = CSR_RX_SUCCESS;
3091 write_pack(&signal, req->signal, &(req->signalLength));
3092 }
3093
3094 memcpy((void*)bulkdata.d[0].os_data_ptr, req->data, req->dataLength);
3095
ab2b8c73 3096 receiver_id = CSR_GET_UINT16_FROM_LITTLE_ENDIAN((req->signal) + sizeof(s16)) & 0xFFF0;
95edd09e
GKH
3097 client_id = (receiver_id & 0x0F00) >> UDI_SENDER_ID_SHIFT;
3098
3099 client = &priv->ul_clients[client_id];
3100
3101 if (client && client->event_hook) {
3102 unifi_trace(priv, UDBG3,
3103 "CsrWifiRouterCtrlWapiRxPktReq: "
3104 "Sending signal to client %d, (s:0x%X, r:0x%X) - Signal 0x%X \n",
3105 client->client_id, client->sender_id, receiver_id,
3106 CSR_GET_UINT16_FROM_LITTLE_ENDIAN(req->signal));
3107
3108 client->event_hook(client, req->signal, req->signalLength, &bulkdata, UDI_TO_HOST);
3109 } else {
3110 unifi_trace(priv, UDBG4, "No client to give the packet to\n");
3111 unifi_net_data_free(priv, &bulkdata.d[0]);
3112 }
3113
3114 unifi_trace(priv, UDBG6, "<<%s\n", __FUNCTION__);
3115 } else {
6aac2e03 3116 unifi_warning(priv, "%s is NOT applicable for interface mode - %d\n", __FUNCTION__, interfacePriv->interfaceMode);
635d2b00 3117 }
95edd09e
GKH
3118#elif defined(UNIFI_DEBUG)
3119 /*WAPI Disabled*/
3120 unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
6aac2e03 3121 unifi_error(priv, "CsrWifiRouterCtrlWapiRxPktReqHandler: called when WAPI isn't enabled\n");
95edd09e
GKH
3122#endif
3123}
635d2b00 3124
95edd09e
GKH
3125void CsrWifiRouterCtrlWapiUnicastTxPktReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
3126{
3127#if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION))
635d2b00 3128
95edd09e
GKH
3129 unifi_priv_t *priv = (unifi_priv_t*) drvpriv;
3130 CsrWifiRouterCtrlWapiUnicastTxPktReq *req = (CsrWifiRouterCtrlWapiUnicastTxPktReq*) msg;
3131 netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag];
3132 bulk_data_param_t bulkdata;
7e6f5794 3133 u8 macHeaderLengthInBytes = MAC_HEADER_SIZE;
95edd09e 3134 /*KeyID, Reserved, PN, MIC*/
7e6f5794 3135 u8 appendedCryptoFields = 1 + 1 + 16 + 16;
95edd09e
GKH
3136 CsrResult result;
3137 /* Retrieve the MA PACKET REQ fields from the Signal retained from send_ma_pkt_request() */
3138 CSR_MA_PACKET_REQUEST *storedSignalMAPktReq = &interfacePriv->wapi_unicast_ma_pkt_sig.u.MaPacketRequest;
635d2b00 3139
95edd09e
GKH
3140 if (CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode) {
3141
3142 unifi_trace(priv, UDBG6, ">>%s\n", __FUNCTION__);
3143
3144 if (priv == NULL) {
6aac2e03 3145 unifi_error(priv, "CsrWifiRouterCtrlWapiUnicastTxPktReqHandler : invalid priv\n", __FUNCTION__);
95edd09e
GKH
3146 return;
3147 }
3148 if (priv->smepriv == NULL) {
6aac2e03 3149 unifi_error(priv, "CsrWifiRouterCtrlWapiUnicastTxPktReqHandler : invalid sme priv\n", __FUNCTION__);
95edd09e
GKH
3150 return;
3151 }
3152 if (req->data == NULL) {
6aac2e03 3153 unifi_error(priv, "CsrWifiRouterCtrlWapiUnicastTxPktReqHandler: invalid request\n", __FUNCTION__);
95edd09e
GKH
3154 return;
3155 } else {
3156 /* If it is QoS data (type = data subtype = QoS), frame header contains QoS control field */
3157 if ((req->data[0] & 0x88) == 0x88) {
3158 macHeaderLengthInBytes = macHeaderLengthInBytes + QOS_CONTROL_HEADER_SIZE;
3159 }
3160 }
3161 if ( !(req->dataLength>(macHeaderLengthInBytes+appendedCryptoFields)) ) {
6aac2e03 3162 unifi_error(priv, "CsrWifiRouterCtrlWapiUnicastTxPktReqHandler: invalid dataLength\n", __FUNCTION__);
95edd09e
GKH
3163 return;
3164 }
3165
3166 /* Encrypted DATA Packet contained in (req->data)
3167 * -------------------------------------------------------------------
3168 * |MAC Header| KeyId | Reserved | PN | xxDataxx | xxMICxxx |
3169 * -------------------------------------------------------------------
3170 * (<-----Encrypted----->)
3171 * -------------------------------------------------------------------
3172 * |24/26(QoS)| 1 | 1 | 16 | x | 16 |
3173 * -------------------------------------------------------------------
3174 */
3175 result = unifi_net_data_malloc(priv, &bulkdata.d[0], req->dataLength);
3176 if (result != CSR_RESULT_SUCCESS) {
6aac2e03 3177 unifi_error(priv, "CsrWifiRouterCtrlWapiUnicastTxPktReqHandler: Could not allocate net data\n", __FUNCTION__);
95edd09e
GKH
3178 return;
3179 }
3180 memcpy((void*)bulkdata.d[0].os_data_ptr, req->data, req->dataLength);
3181 bulkdata.d[0].data_length = req->dataLength;
3182 bulkdata.d[1].os_data_ptr = NULL;
3183 bulkdata.d[1].data_length = 0;
3184
3185 /* Send UniFi msg */
3186 /* Here hostTag is been sent as 0xffffffff, its been appended properly while framing MA-Packet request in pdu_processing.c file */
3187 result = uf_process_ma_packet_req(priv,
3188 storedSignalMAPktReq->Ra.x,
3189 storedSignalMAPktReq->HostTag,/* Ask for a new HostTag */
3190 req->interfaceTag,
3191 storedSignalMAPktReq->TransmissionControl,
3192 storedSignalMAPktReq->TransmitRate,
3193 storedSignalMAPktReq->Priority, /* Retained value */
3194 interfacePriv->wapi_unicast_ma_pkt_sig.SignalPrimitiveHeader.SenderProcessId, /*FIXME AP: VALIDATE ???*/
3195 &bulkdata);
3196
3197 if (result == NETDEV_TX_OK) {
3198 (priv->netdev[req->interfaceTag])->trans_start = jiffies;
3199 /* Should really count tx stats in the UNITDATA.status signal but
3200 * that doesn't have the length.
3201 */
3202 interfacePriv->stats.tx_packets++;
3203
3204 /* count only the packet payload */
3205 interfacePriv->stats.tx_bytes += req->dataLength - macHeaderLengthInBytes - appendedCryptoFields;
3206 unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWapiUnicastTxPktReqHandler: (Packet Sent), sent count = %x\n", interfacePriv->stats.tx_packets);
3207 } else {
3208 /* Failed to send: fh queue was full, and the skb was discarded*/
3209 unifi_trace(priv, UDBG1, "(HIP validation failure) Result = %d\n", result);
3210 unifi_net_data_free(priv, &bulkdata.d[0]);
3211
3212 interfacePriv->stats.tx_dropped++;
3213 unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWapiUnicastTxPktReqHandler: (Packet Drop), dropped count = %x\n", interfacePriv->stats.tx_dropped);
3214 }
635d2b00 3215
95edd09e
GKH
3216 unifi_trace(priv, UDBG6, "<<%s\n", __FUNCTION__);
3217
3218 } else {
3219
6aac2e03 3220 unifi_warning(priv, "%s is NOT applicable for interface mode - %d\n", __FUNCTION__, interfacePriv->interfaceMode);
635d2b00 3221
635d2b00 3222 }
95edd09e
GKH
3223#elif defined(UNIFI_DEBUG)
3224 /*WAPI Disabled*/
3225 unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
6aac2e03 3226 unifi_error(priv, "CsrWifiRouterCtrlWapiUnicastTxPktReqHandler: called when WAPI SW ENCRYPTION isn't enabled\n");
95edd09e
GKH
3227#endif
3228}
3229
3230void CsrWifiRouterCtrlWapiFilterReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
3231{
3232#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
3233
3234#ifdef CSR_WIFI_SECURITY_WAPI_QOSCTRL_MIC_WORKAROUND
3235 unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
3236 CsrWifiRouterCtrlWapiFilterReq* req = (CsrWifiRouterCtrlWapiFilterReq*)msg;
3237 netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag];
3238
3239 if (CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode) {
3240
3241 unifi_trace(priv, UDBG6, ">>%s\n", __FUNCTION__);
3242
6aac2e03 3243 unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWapiFilterReq: req->isWapiConnected [0/1] = %d \n", req->isWapiConnected);
95edd09e
GKH
3244
3245 priv->isWapiConnection = req->isWapiConnected;
3246
3247 unifi_trace(priv, UDBG6, "<<%s\n", __FUNCTION__);
3248 } else {
3249
6aac2e03 3250 unifi_warning(priv, "%s is NOT applicable for interface mode - %d\n", __FUNCTION__, interfacePriv->interfaceMode);
95edd09e 3251
635d2b00 3252 }
95edd09e 3253#endif
635d2b00 3254
95edd09e
GKH
3255#elif defined(UNIFI_DEBUG)
3256 /*WAPI Disabled*/
3257 unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
6aac2e03 3258 unifi_error(priv, "CsrWifiRouterCtrlWapiFilterReq: called when WAPI isn't enabled\n");
95edd09e 3259#endif
635d2b00 3260}
This page took 0.338985 seconds and 5 git commands to generate.