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