]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/staging/csr/csr_wifi_router_transport.c
staging: csr: remove CsrPmemFree()
[karo-tx-linux.git] / drivers / staging / csr / csr_wifi_router_transport.c
1 /** @file router_transport.c
2  *
3  *
4  * Copyright (C) Cambridge Silicon Radio Ltd 2006-2010. All rights reserved.
5  *
6  * Refer to LICENSE.txt included with this source code for details on
7  * the license terms.
8  *
9  ****************************************************************************/
10
11 #include "unifi_priv.h"
12
13 #include "csr_sched.h"
14 #include "csr_msgconv.h"
15
16 #include "sme_userspace.h"
17
18 #include "csr_wifi_hostio_prim.h"
19 #include "csr_wifi_router_lib.h"
20 #include "csr_wifi_router_sef.h"
21 #include "csr_wifi_router_converter_init.h"
22 #include "csr_wifi_router_ctrl_lib.h"
23 #include "csr_wifi_router_ctrl_sef.h"
24 #include "csr_wifi_router_ctrl_converter_init.h"
25 #include "csr_wifi_sme_prim.h"
26 #include "csr_wifi_sme_sef.h"
27 #include "csr_wifi_sme_converter_init.h"
28 #ifdef CSR_SUPPORT_WEXT
29 #ifdef CSR_SUPPORT_WEXT_AP
30 #include "csr_wifi_nme_ap_prim.h"
31 #include "csr_wifi_nme_ap_sef.h"
32 #include "csr_wifi_nme_ap_converter_init.h"
33 #endif
34 #endif
35
36 static unifi_priv_t *drvpriv = NULL;
37 void CsrWifiRouterTransportInit(unifi_priv_t *priv)
38 {
39     unifi_trace(priv, UDBG1, "CsrWifiRouterTransportInit: \n");
40
41     drvpriv = priv;
42     (void)CsrMsgConvInit();
43     CsrWifiRouterConverterInit();
44     CsrWifiRouterCtrlConverterInit();
45     CsrWifiSmeConverterInit();
46 #ifdef CSR_SUPPORT_WEXT
47 #ifdef CSR_SUPPORT_WEXT_AP
48     CsrWifiNmeApConverterInit();
49 #endif
50 #endif
51 }
52
53 void CsrWifiRouterTransportDeinit(unifi_priv_t *priv)
54 {
55     unifi_trace(priv, UDBG1, "CsrWifiRouterTransportDeinit: \n");
56     if (priv == drvpriv)
57     {
58         CsrMsgConvDeinit();
59         drvpriv = NULL;
60     }
61 }
62
63 void CsrWifiRouterTransportRecv(unifi_priv_t *priv, u8* buffer, size_t bufferLength)
64 {
65     CsrMsgConvMsgEntry* msgEntry;
66     u16 primType;
67     CsrSchedQid src;
68     CsrSchedQid dest;
69     u16 msgType;
70     size_t offset = 0;
71     CsrWifiFsmEvent* msg;
72
73     /* Decode the prim and message type */
74     CsrUint16Des(&primType, buffer, &offset);
75     CsrUint16Des(&src, buffer, &offset);
76     CsrUint16Des(&dest, buffer, &offset);
77     CsrUint16Des(&msgType, buffer, &offset);
78     offset -= 2; /* Adjust as the Deserialise Function will read this as well */
79
80     unifi_trace(priv, UDBG4, "CsrWifiRouterTransportRecv: primType=0x%.4X, msgType=0x%.4X, bufferLength=%d\n",
81                 primType, msgType, bufferLength);
82
83     /* Special handling for HOSTIO messages.... */
84     if (primType == CSR_WIFI_HOSTIO_PRIM)
85     {
86         CsrWifiRouterCtrlHipReq req = {{CSR_WIFI_ROUTER_CTRL_HIP_REQ, CSR_WIFI_ROUTER_CTRL_PRIM, dest, src, NULL}, 0, NULL, 0, NULL, 0, NULL};
87
88         req.mlmeCommandLength = bufferLength;
89         req.mlmeCommand = buffer;
90
91         offset += 8;/* Skip the id, src, dest and slot number */
92         CsrUint16Des(&req.dataRef1Length, buffer, &offset);
93         offset += 2; /* Skip the slot number */
94         CsrUint16Des(&req.dataRef2Length, buffer, &offset);
95
96         if (req.dataRef1Length)
97         {
98             u16 dr1Offset = (bufferLength - req.dataRef2Length) - req.dataRef1Length;
99             req.dataRef1 = &buffer[dr1Offset];
100         }
101
102         if (req.dataRef2Length)
103         {
104             u16 dr2Offset = bufferLength - req.dataRef2Length;
105             req.dataRef2 = &buffer[dr2Offset];
106         }
107
108         /* Copy the hip data but strip off the prim type */
109         req.mlmeCommandLength -= (req.dataRef1Length + req.dataRef2Length + 6);
110         req.mlmeCommand = &buffer[6];
111
112         CsrWifiRouterCtrlHipReqHandler(priv, &req.common);
113         return;
114     }
115
116     msgEntry = CsrMsgConvFindEntry(primType, msgType);
117     if (!msgEntry)
118     {
119         unifi_error(priv, "CsrWifiRouterTransportDeserialiseAndSend can not process the message. primType=0x%.4X, msgType=0x%.4X\n",
120                     primType, msgType);
121         dump(buffer, bufferLength);
122         return;
123     }
124
125     msg = (CsrWifiFsmEvent*)(msgEntry->deserFunc)(&buffer[offset], bufferLength - offset);
126
127     msg->primtype = primType;
128     msg->type = msgType;
129     msg->source = src;
130     msg->destination = dest;
131
132     switch(primType)
133     {
134     case CSR_WIFI_ROUTER_CTRL_PRIM:
135         CsrWifiRouterCtrlDownstreamStateHandlers[msg->type - CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST](priv, msg);
136         CsrWifiRouterCtrlFreeDownstreamMessageContents(CSR_WIFI_ROUTER_CTRL_PRIM, msg);
137         break;
138     case CSR_WIFI_ROUTER_PRIM:
139         CsrWifiRouterDownstreamStateHandlers[msg->type - CSR_WIFI_ROUTER_PRIM_DOWNSTREAM_LOWEST](priv, msg);
140         CsrWifiRouterFreeDownstreamMessageContents(CSR_WIFI_ROUTER_PRIM, msg);
141         break;
142         case CSR_WIFI_SME_PRIM:
143             CsrWifiSmeUpstreamStateHandlers[msg->type - CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST](priv, msg);
144             CsrWifiSmeFreeUpstreamMessageContents(CSR_WIFI_SME_PRIM, msg);
145             break;
146 #ifdef CSR_SUPPORT_WEXT
147 #ifdef CSR_SUPPORT_WEXT_AP
148         case CSR_WIFI_NME_AP_PRIM:
149             CsrWifiNmeApUpstreamStateHandlers(priv, msg);
150             CsrWifiNmeApFreeUpstreamMessageContents(CSR_WIFI_NME_AP_PRIM, msg);
151             break;
152 #endif
153 #endif
154         default:
155             unifi_error(priv, "CsrWifiRouterTransportDeserialiseAndSend unhandled prim type 0x%.4X\n", primType);
156             break;
157     }
158     kfree(msg);
159 }
160
161 static void CsrWifiRouterTransportSerialiseAndSend(u16 primType, void* msg)
162 {
163     CsrWifiFsmEvent* evt = (CsrWifiFsmEvent*)msg;
164     CsrMsgConvMsgEntry* msgEntry;
165     size_t msgSize;
166     size_t encodeBufferLen = 0;
167     size_t offset = 0;
168     u8* encodeBuffer;
169
170     unifi_trace(drvpriv, UDBG4, "CsrWifiRouterTransportSerialiseAndSend: primType=0x%.4X, msgType=0x%.4X\n",
171                 primType, evt->type);
172
173     msgEntry = CsrMsgConvFindEntry(primType, evt->type);
174     if (!msgEntry)
175     {
176         unifi_error(drvpriv, "CsrWifiRouterTransportSerialiseAndSend can not process the message. primType=0x%.4X, msgType=0x%.4X\n",
177                     primType, evt->type);
178         return;
179     }
180
181     msgSize = 6 + (msgEntry->sizeofFunc)((void*)msg);
182
183     encodeBuffer = CsrPmemAlloc(msgSize);
184
185     /* Encode PrimType */
186     CsrUint16Ser(encodeBuffer, &encodeBufferLen, primType);
187     CsrUint16Ser(encodeBuffer, &encodeBufferLen, evt->source);
188     CsrUint16Ser(encodeBuffer, &encodeBufferLen, evt->destination);
189
190     (void)(msgEntry->serFunc)(&encodeBuffer[encodeBufferLen], &offset, msg);
191     encodeBufferLen += offset;
192
193     uf_sme_queue_message(drvpriv, encodeBuffer, encodeBufferLen);
194
195     /* Do not use msgEntry->freeFunc because the memory is owned by the driver */
196     kfree(msg);
197 }
198
199 #if defined(CSR_LOG_ENABLE) && defined(CSR_LOG_INCLUDE_FILE_NAME_AND_LINE_NUMBER)
200 void CsrSchedMessagePutStringLog(CsrSchedQid q, u16 mi, void *mv, u32 line, char *file)
201 #else
202 void CsrSchedMessagePut(CsrSchedQid q, u16 mi, void *mv)
203 #endif
204 {
205     CsrWifiFsmEvent* evt = (CsrWifiFsmEvent*)mv;
206     evt->destination = q;
207     CsrWifiRouterTransportSerialiseAndSend(mi, mv);
208 }
209