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