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