Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
csr_wifi_router_transport.c
Go to the documentation of this file.
1 
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"
25 #include "csr_wifi_sme_prim.h"
26 #include "csr_wifi_sme_sef.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"
33 #endif
34 #endif
35 
36 static unifi_priv_t *drvpriv = NULL;
38 {
39  unifi_trace(priv, UDBG1, "CsrWifiRouterTransportInit: \n");
40 
41  drvpriv = priv;
46 #ifdef CSR_SUPPORT_WEXT
47 #ifdef CSR_SUPPORT_WEXT_AP
49 #endif
50 #endif
51 }
52 
53 void CsrWifiRouterTransportRecv(unifi_priv_t *priv, u8* buffer, size_t bufferLength)
54 {
55  CsrMsgConvMsgEntry* msgEntry;
56  u16 primType;
59  u16 msgType;
60  size_t offset = 0;
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  {
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  {
88  u16 dr1Offset = (bufferLength - req.dataRef2Length) - req.dataRef1Length;
89  req.dataRef1 = &buffer[dr1Offset];
90  }
91 
92  if (req.dataRef2Length)
93  {
94  u16 dr2Offset = bufferLength - req.dataRef2Length;
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 
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  {
127  break;
131  break;
132  case CSR_WIFI_SME_PRIM:
135  break;
136 #ifdef CSR_SUPPORT_WEXT
137 #ifdef CSR_SUPPORT_WEXT_AP
141  break;
142 #endif
143 #endif
144  default:
145  unifi_error(priv, "CsrWifiRouterTransportDeserialiseAndSend unhandled prim type 0x%.4X\n", primType);
146  break;
147  }
148  kfree(msg);
149 }
150 
151 static void CsrWifiRouterTransportSerialiseAndSend(u16 primType, void* msg)
152 {
154  CsrMsgConvMsgEntry* msgEntry;
155  size_t msgSize;
156  size_t encodeBufferLen = 0;
157  size_t offset = 0;
158  u8* encodeBuffer;
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 
173  encodeBuffer = kmalloc(msgSize, GFP_KERNEL);
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 */
186  kfree(msg);
187 }
188 
189 #if defined(CSR_LOG_ENABLE) && defined(CSR_LOG_INCLUDE_FILE_NAME_AND_LINE_NUMBER)
190 void CsrSchedMessagePutStringLog(CsrSchedQid q, u16 mi, void *mv, u32 line, char *file)
191 #else
192 void CsrSchedMessagePut(CsrSchedQid q, u16 mi, void *mv)
193 #endif
194 {
195  CsrWifiFsmEvent* evt = (CsrWifiFsmEvent*)mv;
196  evt->destination = q;
197  CsrWifiRouterTransportSerialiseAndSend(mi, mv);
198 }
199