17 char netifName[NETMAN_NETIF_NAME_MAX_LEN];
20}TransmitBuffer ALIGNED(64);
28}ReceiveBuffer ALIGNED(64);
30static int NetManIOSemaID = -1, NETMAN_Tx_threadID = -1;
31static unsigned char NETMAN_Tx_ThreadStack[0x1000] ALIGNED(16);
33static unsigned short int IOPFrameBufferWrPtr;
34static u8 *IOPFrameBuffer = NULL;
35static struct NetManBD *IOPFrameBufferStatus = NULL;
36static struct NetManBD *FrameBufferStatus = NULL;
38static unsigned char IsInitialized=0, IsProcessingTx;
40static void deinitCleanup(
void)
42 if(NetManIOSemaID >= 0)
44 DeleteSema(NetManIOSemaID);
47 if(NETMAN_Tx_threadID >= 0)
49 TerminateThread(NETMAN_Tx_threadID);
50 DeleteThread(NETMAN_Tx_threadID);
51 NETMAN_Tx_threadID = -1;
55static void NETMAN_TxThread(
void *arg);
57int NetManInitRPCClient(
void){
58 static const char NetManID[]=
"NetMan";
66 SemaData.init_count=1;
67 SemaData.option=(u32)NetManID;
69 if((NetManIOSemaID=CreateSema(&SemaData)) < 0)
72 return NetManIOSemaID;
75 thread.func=&NETMAN_TxThread;
76 thread.stack=NETMAN_Tx_ThreadStack;
77 thread.stack_size=
sizeof(NETMAN_Tx_ThreadStack);
79 thread.initial_priority=0x56;
82 if((NETMAN_Tx_threadID=CreateThread(&
thread)) >= 0)
85 StartThread(NETMAN_Tx_threadID, NULL);
88 return NETMAN_Tx_threadID;
91 while((SifBindRpc(&NETMAN_rpc_cd, NETMAN_RPC_NUMBER, 0)<0)||(NETMAN_rpc_cd.server==NULL))
94 if((result=SifCallRpc(&NETMAN_rpc_cd, NETMAN_IOP_RPC_FUNC_INIT, 0, NULL, 0, &ReceiveBuffer,
sizeof(s32), NULL, NULL))>=0)
96 if((result=ReceiveBuffer.result) == 0)
109int NetManRPCRegisterNetworkStack(
void)
113 WaitSema(NetManIOSemaID);
115 if(FrameBufferStatus == NULL) FrameBufferStatus = memalign(64, NETMAN_RPC_BLOCK_SIZE *
sizeof(
struct NetManBD));
117 if(FrameBufferStatus != NULL)
119 memset(UNCACHED_SEG(FrameBufferStatus), 0, NETMAN_RPC_BLOCK_SIZE *
sizeof(
struct NetManBD));
120 TransmitBuffer.NetStack.FrameBufferStatus = FrameBufferStatus;
121 IOPFrameBufferWrPtr = 0;
125 if((result=ReceiveBuffer.NetStackResult.result) == 0)
127 IOPFrameBuffer = ReceiveBuffer.NetStackResult.FrameBuffer;
128 IOPFrameBufferStatus = ReceiveBuffer.NetStackResult.FrameBufferStatus;
137 SignalSema(NetManIOSemaID);
142int NetManRPCUnregisterNetworkStack(
void)
146 WaitSema(NetManIOSemaID);
148 result=SifCallRpc(&NETMAN_rpc_cd, NETMAN_IOP_RPC_FUNC_UNREG_NETWORK_STACK, 0, NULL, 0, NULL, 0, NULL, NULL);
149 IOPFrameBuffer = NULL;
150 IOPFrameBufferWrPtr = 0;
152 free(FrameBufferStatus);
153 FrameBufferStatus = NULL;
155 SignalSema(NetManIOSemaID);
160void NetManDeinitRPCClient(
void)
164 WaitSema(NetManIOSemaID);
166 SifCallRpc(&NETMAN_rpc_cd, NETMAN_IOP_RPC_FUNC_DEINIT, 0, NULL, 0, NULL, 0, NULL, NULL);
173int NetManRpcIoctl(
unsigned int command,
void *args,
unsigned int args_len,
void *output,
unsigned int length)
176 struct NetManIoctl *IoctlArgs=&TransmitBuffer.IoctlArgs;
178 WaitSema(NetManIOSemaID);
180 IoctlArgs->command=command;
181 memcpy(IoctlArgs->args, args, args_len);
182 IoctlArgs->args_len=args_len;
183 IoctlArgs->output=output;
184 IoctlArgs->length=length;
186 if((result=SifCallRpc(&NETMAN_rpc_cd, NETMAN_IOP_RPC_FUNC_IOCTL, 0, &TransmitBuffer,
sizeof(
struct NetManIoctl), &ReceiveBuffer,
sizeof(
struct NetManIoctlResult), NULL, NULL))>=0)
188 result=ReceiveBuffer.IoctlResult.result;
189 memcpy(output, ReceiveBuffer.IoctlResult.output, length);
192 SignalSema(NetManIOSemaID);
197static void NETMAN_TxThread(
void *arg)
202 int dmat_id, unaligned, unalignedCache;
203 void *payload, *payloadAligned, *payloadCacheAligned;
204 volatile struct NetManBD *bd, *bdNext;
214 while((length = NetManTxPacketNext(&payload)) > 0)
219 unaligned = (int)((u32)payload & 15);
220 unalignedCache = (int)((u32)payload & 63);
221 payloadAligned = (
void*)((u32)payload & ~15);
222 payloadCacheAligned = (
void*)((u32)payload & ~63);
223 SifWriteBackDCache(payloadCacheAligned, (length + unalignedCache + 63) & ~63);
227 bd = UNCACHED_SEG(&FrameBufferStatus[IOPFrameBufferWrPtr]);
228 while(bd->length != 0){}
232 bdNext = UNCACHED_SEG(&FrameBufferStatus[(IOPFrameBufferWrPtr + 1) % NETMAN_RPC_BLOCK_SIZE]);
233 if((NumTx + 1) >= NETMAN_FRAME_GROUP_SIZE || bdNext->length == 0)
238 npcmd->length = length;
239 npcmd->offset = unaligned;
240 npcmd->id = IOPFrameBufferWrPtr;
242 while((dmat_id = SifSendCmd(NETMAN_SIFCMD_ID, &cmd,
sizeof(
SifCmdHeader_t),
243 (
void*)payloadAligned,
244 (
void*)&IOPFrameBuffer[IOPFrameBufferWrPtr * NETMAN_MAX_FRAME_SIZE],
245 (length + unaligned + 15) & ~15)) == 0){ };
249 bd->offset = unaligned;
252 dmat[0].src = (
void*)payloadAligned;
253 dmat[0].dest = (
void*)&IOPFrameBuffer[IOPFrameBufferWrPtr * NETMAN_MAX_FRAME_SIZE];
254 dmat[0].size = (length + unaligned + 15) & ~15;
256 dmat[1].src = (
void*)&FrameBufferStatus[IOPFrameBufferWrPtr];
257 dmat[1].dest = (
void*)&IOPFrameBufferStatus[IOPFrameBufferWrPtr];
258 dmat[1].size =
sizeof(
struct NetManBD);
261 while((dmat_id = SifSetDma(dmat, 2)) == 0){ };
265 IOPFrameBufferWrPtr = (IOPFrameBufferWrPtr + 1) % NETMAN_RPC_BLOCK_SIZE;
267 if((length = NetManTxPacketAfter(&payload)) > 0)
269 unaligned = (int)((u32)payload & 15);
270 unalignedCache = (int)((u32)payload & 63);
271 payloadAligned = (
void*)((u32)payload & ~15);
272 payloadCacheAligned = (
void*)((u32)payload & ~63);
273 SifWriteBackDCache(payloadCacheAligned, (length + unalignedCache + 63) & ~63);
278 while(SifDmaStat(dmat_id) >= 0){ };
287void NetManRpcNetIFXmit(
void)
290 WakeupThread(NETMAN_Tx_threadID);
293int NetManSetMainIF(
const char *name)
300 WaitSema(NetManIOSemaID);
302 strncpy(TransmitBuffer.netifName, name, NETMAN_NETIF_NAME_MAX_LEN);
303 TransmitBuffer.netifName[NETMAN_NETIF_NAME_MAX_LEN-1] =
'\0';
304 if((result=SifCallRpc(&NETMAN_rpc_cd, NETMAN_IOP_RPC_FUNC_SET_MAIN_NETIF, 0, &TransmitBuffer, NETMAN_NETIF_NAME_MAX_LEN, &ReceiveBuffer,
sizeof(s32), NULL, NULL))>=0)
305 result=ReceiveBuffer.result;
307 SignalSema(NetManIOSemaID);
312int NetManQueryMainIF(
char *name)
319 WaitSema(NetManIOSemaID);
321 if((result=SifCallRpc(&NETMAN_rpc_cd, NETMAN_IOP_RPC_FUNC_QUERY_MAIN_NETIF, 0, NULL, 0, &ReceiveBuffer,
sizeof(
struct NetManQueryMainNetIFResult), NULL, NULL))>=0)
323 if((result=ReceiveBuffer.QueryMainNetIFResult.result) == 0)
325 strncpy(name, ReceiveBuffer.QueryMainNetIFResult.name, NETMAN_NETIF_NAME_MAX_LEN);
326 name[NETMAN_NETIF_NAME_MAX_LEN-1] =
'\0';
330 SignalSema(NetManIOSemaID);
335int NetManSetLinkMode(
int mode)
342 WaitSema(NetManIOSemaID);
344 TransmitBuffer.mode = mode;
345 if((result=SifCallRpc(&NETMAN_rpc_cd, NETMAN_IOP_RPC_FUNC_SET_LINK_MODE, 0, &TransmitBuffer,
sizeof(s32), &ReceiveBuffer,
sizeof(s32), NULL, NULL))>=0)
346 result=ReceiveBuffer.result;
348 SignalSema(NetManIOSemaID);