Commit | Line | Data |
---|---|---|
635d2b00 GKH |
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 | ||
635d2b00 GKH |
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 | ||
d4fda8db | 53 | void CsrWifiRouterTransportRecv(unifi_priv_t *priv, u8* buffer, size_t bufferLength) |
635d2b00 GKH |
54 | { |
55 | CsrMsgConvMsgEntry* msgEntry; | |
8c87f69a | 56 | u16 primType; |
635d2b00 GKH |
57 | CsrSchedQid src; |
58 | CsrSchedQid dest; | |
8c87f69a | 59 | u16 msgType; |
d4fda8db | 60 | size_t offset = 0; |
635d2b00 GKH |
61 | CsrWifiFsmEvent* msg; |
62 | ||
63 | /* Decode the prim and message type */ | |
64 | CsrUint16Des(&primType, buffer, &offset); | |
65 | CsrUint16Des(&src, buffer, &offset); | |
66 | CsrUint16Des(&dest, buffer, &offset); | |
67 | CsrUint16Des(&msgType, buffer, &offset); | |
68 | offset -= 2; /* Adjust as the Deserialise Function will read this as well */ | |
69 | ||
70 | unifi_trace(priv, UDBG4, "CsrWifiRouterTransportRecv: primType=0x%.4X, msgType=0x%.4X, bufferLength=%d\n", | |
71 | primType, msgType, bufferLength); | |
72 | ||
73 | /* Special handling for HOSTIO messages.... */ | |
74 | if (primType == CSR_WIFI_HOSTIO_PRIM) | |
75 | { | |
76 | CsrWifiRouterCtrlHipReq req = {{CSR_WIFI_ROUTER_CTRL_HIP_REQ, CSR_WIFI_ROUTER_CTRL_PRIM, dest, src, NULL}, 0, NULL, 0, NULL, 0, NULL}; | |
77 | ||
78 | req.mlmeCommandLength = bufferLength; | |
79 | req.mlmeCommand = buffer; | |
80 | ||
81 | offset += 8;/* Skip the id, src, dest and slot number */ | |
82 | CsrUint16Des(&req.dataRef1Length, buffer, &offset); | |
83 | offset += 2; /* Skip the slot number */ | |
84 | CsrUint16Des(&req.dataRef2Length, buffer, &offset); | |
85 | ||
86 | if (req.dataRef1Length) | |
87 | { | |
8c87f69a | 88 | u16 dr1Offset = (bufferLength - req.dataRef2Length) - req.dataRef1Length; |
635d2b00 GKH |
89 | req.dataRef1 = &buffer[dr1Offset]; |
90 | } | |
91 | ||
92 | if (req.dataRef2Length) | |
93 | { | |
8c87f69a | 94 | u16 dr2Offset = bufferLength - req.dataRef2Length; |
635d2b00 GKH |
95 | req.dataRef2 = &buffer[dr2Offset]; |
96 | } | |
97 | ||
98 | /* Copy the hip data but strip off the prim type */ | |
99 | req.mlmeCommandLength -= (req.dataRef1Length + req.dataRef2Length + 6); | |
100 | req.mlmeCommand = &buffer[6]; | |
101 | ||
102 | CsrWifiRouterCtrlHipReqHandler(priv, &req.common); | |
103 | return; | |
104 | } | |
105 | ||
106 | msgEntry = CsrMsgConvFindEntry(primType, msgType); | |
107 | if (!msgEntry) | |
108 | { | |
109 | unifi_error(priv, "CsrWifiRouterTransportDeserialiseAndSend can not process the message. primType=0x%.4X, msgType=0x%.4X\n", | |
110 | primType, msgType); | |
111 | dump(buffer, bufferLength); | |
112 | return; | |
113 | } | |
114 | ||
115 | msg = (CsrWifiFsmEvent*)(msgEntry->deserFunc)(&buffer[offset], bufferLength - offset); | |
116 | ||
117 | msg->primtype = primType; | |
118 | msg->type = msgType; | |
119 | msg->source = src; | |
120 | msg->destination = dest; | |
121 | ||
122 | switch(primType) | |
123 | { | |
124 | case CSR_WIFI_ROUTER_CTRL_PRIM: | |
125 | CsrWifiRouterCtrlDownstreamStateHandlers[msg->type - CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST](priv, msg); | |
126 | CsrWifiRouterCtrlFreeDownstreamMessageContents(CSR_WIFI_ROUTER_CTRL_PRIM, msg); | |
127 | break; | |
128 | case CSR_WIFI_ROUTER_PRIM: | |
129 | CsrWifiRouterDownstreamStateHandlers[msg->type - CSR_WIFI_ROUTER_PRIM_DOWNSTREAM_LOWEST](priv, msg); | |
130 | CsrWifiRouterFreeDownstreamMessageContents(CSR_WIFI_ROUTER_PRIM, msg); | |
131 | break; | |
132 | case CSR_WIFI_SME_PRIM: | |
133 | CsrWifiSmeUpstreamStateHandlers[msg->type - CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST](priv, msg); | |
134 | CsrWifiSmeFreeUpstreamMessageContents(CSR_WIFI_SME_PRIM, msg); | |
135 | break; | |
136 | #ifdef CSR_SUPPORT_WEXT | |
137 | #ifdef CSR_SUPPORT_WEXT_AP | |
138 | case CSR_WIFI_NME_AP_PRIM: | |
139 | CsrWifiNmeApUpstreamStateHandlers(priv, msg); | |
140 | CsrWifiNmeApFreeUpstreamMessageContents(CSR_WIFI_NME_AP_PRIM, msg); | |
141 | break; | |
142 | #endif | |
143 | #endif | |
144 | default: | |
145 | unifi_error(priv, "CsrWifiRouterTransportDeserialiseAndSend unhandled prim type 0x%.4X\n", primType); | |
146 | break; | |
147 | } | |
55a27055 | 148 | kfree(msg); |
635d2b00 GKH |
149 | } |
150 | ||
8c87f69a | 151 | static void CsrWifiRouterTransportSerialiseAndSend(u16 primType, void* msg) |
635d2b00 GKH |
152 | { |
153 | CsrWifiFsmEvent* evt = (CsrWifiFsmEvent*)msg; | |
154 | CsrMsgConvMsgEntry* msgEntry; | |
d4fda8db GKH |
155 | size_t msgSize; |
156 | size_t encodeBufferLen = 0; | |
157 | size_t offset = 0; | |
7e6f5794 | 158 | u8* encodeBuffer; |
635d2b00 GKH |
159 | |
160 | unifi_trace(drvpriv, UDBG4, "CsrWifiRouterTransportSerialiseAndSend: primType=0x%.4X, msgType=0x%.4X\n", | |
161 | primType, evt->type); | |
162 | ||
163 | msgEntry = CsrMsgConvFindEntry(primType, evt->type); | |
164 | if (!msgEntry) | |
165 | { | |
166 | unifi_error(drvpriv, "CsrWifiRouterTransportSerialiseAndSend can not process the message. primType=0x%.4X, msgType=0x%.4X\n", | |
167 | primType, evt->type); | |
168 | return; | |
169 | } | |
170 | ||
171 | msgSize = 6 + (msgEntry->sizeofFunc)((void*)msg); | |
172 | ||
786eeeb3 | 173 | encodeBuffer = kmalloc(msgSize, GFP_KERNEL); |
635d2b00 GKH |
174 | |
175 | /* Encode PrimType */ | |
176 | CsrUint16Ser(encodeBuffer, &encodeBufferLen, primType); | |
177 | CsrUint16Ser(encodeBuffer, &encodeBufferLen, evt->source); | |
178 | CsrUint16Ser(encodeBuffer, &encodeBufferLen, evt->destination); | |
179 | ||
180 | (void)(msgEntry->serFunc)(&encodeBuffer[encodeBufferLen], &offset, msg); | |
181 | encodeBufferLen += offset; | |
182 | ||
183 | uf_sme_queue_message(drvpriv, encodeBuffer, encodeBufferLen); | |
184 | ||
185 | /* Do not use msgEntry->freeFunc because the memory is owned by the driver */ | |
55a27055 | 186 | kfree(msg); |
635d2b00 GKH |
187 | } |
188 | ||
189 | #if defined(CSR_LOG_ENABLE) && defined(CSR_LOG_INCLUDE_FILE_NAME_AND_LINE_NUMBER) | |
c781b96b | 190 | void CsrSchedMessagePutStringLog(CsrSchedQid q, u16 mi, void *mv, u32 line, char *file) |
635d2b00 | 191 | #else |
8c87f69a | 192 | void CsrSchedMessagePut(CsrSchedQid q, u16 mi, void *mv) |
635d2b00 GKH |
193 | #endif |
194 | { | |
195 | CsrWifiFsmEvent* evt = (CsrWifiFsmEvent*)mv; | |
196 | evt->destination = q; | |
197 | CsrWifiRouterTransportSerialiseAndSend(mi, mv); | |
198 | } | |
199 |