adding i18n strings
[open-ps2-loader.git] / modules / network / SMSMAP / main.c
blob897c9ccfa075b0987a73b2de2a252ecfb63017e3
1 /*
2 * Copyright (c) Tord Lindstrom (pukko@home.se)
3 * Copyright (c) adresd ( adresd_ps2dev@yahoo.com )
5 */
7 #include <stdio.h>
8 #include <loadcore.h>
9 #include <thbase.h>
10 #include <thevent.h>
11 #include <thsemap.h>
12 #include <vblank.h>
13 #include <intrman.h>
15 #include "ps2ip.h"
16 #include "smap.h"
17 #include "dev9.h"
19 #include "smsutils.h"
21 #define UNKN_1464 *(u16 volatile*)0xbf801464
23 #define IFNAME0 's'
24 #define IFNAME1 'm'
26 #define TIMER_INTERVAL (100*1000)
27 #define TIMEOUT (300*1000)
28 #define MAX_REQ_CNT 8
30 typedef struct ip_addr IPAddr;
31 typedef struct netif NetIF;
32 typedef struct SMapIF SMapIF;
33 typedef struct pbuf PBuf;
36 static int iSendMutex;
37 static int iSendReqMutex;
38 static int iSendReq = 0x80000000;
39 static int iReqNR=0;
40 static int iReqCNT=0;
41 static PBuf* apReqQueue[MAX_REQ_CNT];
42 static int iTimeoutCNT=0;
44 struct SMapIF {
46 NetIF* pNetIF;
50 static SMapIF SIF;
52 NetIF NIF;
54 #define ERR_OK 0
55 #define ERR_CONN -6
56 #define ERR_IF -11
58 static SMapStatus AddToQueue ( PBuf* pBuf ) {
60 int iIntFlags;
61 SMapStatus Ret;
63 CpuSuspendIntr ( &iIntFlags );
65 if ( !iReqCNT ) {
67 Ret = SMap_Send ( pBuf );
69 if ( Ret == SMap_TX ) {
71 iTimeoutCNT = 0;
72 goto storeLast;
74 } /* end if */
76 } else if ( iReqCNT < MAX_REQ_CNT ) {
77 storeLast:
78 apReqQueue[ ( iReqNR + iReqCNT ) % MAX_REQ_CNT ] = pBuf;
79 ++iReqCNT;
80 ++pBuf -> ref;
82 Ret = SMap_OK;
84 } else Ret = SMap_TX;
86 CpuResumeIntr ( iIntFlags );
88 return Ret;
90 } /* end AddToQueue */
92 static void SendRequests ( void ) {
94 while ( iReqCNT > 0 ) {
96 PBuf* lpReq = apReqQueue[ iReqNR ];
97 SMapStatus lSts = SMap_Send ( lpReq );
99 iTimeoutCNT = 0;
101 if ( lSts == SMap_TX ) return;
103 pbuf_free ( lpReq );
105 iReqNR = ( iReqNR + 1 ) % MAX_REQ_CNT;
106 --iReqCNT;
108 } /* end while */
110 } /* end SendRequests */
112 static void QueueHandler ( void ) {
114 SendRequests ();
116 if ( iSendReq >= 0 ) {
118 iSignalSema ( iSendReq );
119 iSendReq = 0x80000000;
121 } /* end if */
123 } /* end QueueHandler */
125 static int SMapInterrupt ( int iFlag ) {
127 int iFlags = SMap_GetIRQ ();
129 if ( iFlags & ( INTR_TXDNV | INTR_TXEND ) ) {
131 SMap_HandleTXInterrupt ( iFlags & ( INTR_TXDNV | INTR_TXEND ) );
133 QueueHandler ();
135 iFlags = SMap_GetIRQ ();
137 } /* end if */
139 if ( iFlags & ( INTR_EMAC3 | INTR_RXDNV | INTR_RXEND ) )
141 SMap_HandleRXEMACInterrupt ( iFlags & ( INTR_EMAC3 | INTR_RXDNV | INTR_RXEND ) );
143 return 1;
145 } /* end SMapInterrupt */
147 static unsigned int Timer ( void* pvArg ) {
149 if ( iReqCNT ) {
151 iTimeoutCNT += TIMER_INTERVAL;
153 if ( iTimeoutCNT >= TIMEOUT && iTimeoutCNT < ( TIMEOUT + TIMER_INTERVAL ) ) QueueHandler ();
155 } /* end if */
157 return ( unsigned int )pvArg;
159 } /* end Timer */
161 static err_t SMapLowLevelOutput ( NetIF* pNetIF, PBuf* pOutput ) {
163 while ( 1 ) {
165 int iFlags;
166 SMapStatus Res;
168 if ( ( Res = AddToQueue ( pOutput ) ) == SMap_OK ) return ERR_OK;
169 if ( Res == SMap_Err ) return ERR_IF;
170 if ( Res == SMap_Con ) return ERR_CONN;
172 WaitSema ( iSendMutex );
174 CpuSuspendIntr ( &iFlags );
176 if ( iReqCNT == MAX_REQ_CNT ) {
178 iSendReq = iSendReqMutex;
179 CpuResumeIntr ( iFlags );
181 WaitSema ( iSendReqMutex );
183 } else CpuResumeIntr ( iFlags );
185 SignalSema ( iSendMutex );
187 } /* end while */
189 } /* end SMapLowLevelOutput */
191 static err_t SMapOutput ( NetIF* pNetIF, PBuf* pOutput, IPAddr* pIPAddr ) {
193 PBuf* pBuf = etharp_output ( pNetIF, pIPAddr, pOutput );
195 return pBuf ? SMapLowLevelOutput ( pNetIF, pBuf ) : ERR_OK;
197 } /* end SMapOutput */
199 static err_t SMapIFInit ( NetIF* pNetIF ) {
201 SIF.pNetIF = pNetIF;
202 pNetIF -> state = &NIF;
203 pNetIF -> name[ 0 ] = IFNAME0;
204 pNetIF -> name[ 1 ] = IFNAME1;
205 pNetIF -> output = SMapOutput;
206 pNetIF -> linkoutput = SMapLowLevelOutput;
207 pNetIF -> hwaddr_len = 6;
208 pNetIF -> mtu = 1500;
210 mips_memcpy ( pNetIF -> hwaddr, SMap_GetMACAddress (), 6 );
212 SMap_Start ();
214 return ERR_OK;
216 } /* end SMapIFInit */
218 static int SMapInit ( IPAddr IP, IPAddr NM, IPAddr GW ) {
220 int i;
221 iop_sys_clock_t ClockTicks;
223 dev9IntrDisable ( INTR_BITMSK );
224 EnableIntr ( IOP_IRQ_DEV9 );
225 CpuEnableIntr ();
227 UNKN_1464 = 3;
229 if ( ( iSendMutex = CreateMutex ( IOP_MUTEX_UNLOCKED ) ) < 0 ) return 0;
230 if ( ( iSendReqMutex = CreateMutex ( IOP_MUTEX_UNLOCKED ) ) < 0 ) return 0;
231 if ( !SMap_Init () ) return 0;
233 for ( i = 2; i < 7; ++i ) dev9RegisterIntrCb ( i, SMapInterrupt );
235 USec2SysClock ( TIMER_INTERVAL, &ClockTicks );
236 SetAlarm ( &ClockTicks, Timer, ( void* )ClockTicks.lo );
238 netif_add ( &NIF, &IP, &NM, &GW, NULL, SMapIFInit, tcpip_input );
239 netif_set_default ( &NIF );
241 return 1;
243 } /* end SMapInit */
245 int _start ( int iArgC,char** ppcArgV ) {
247 IPAddr IP;
248 IPAddr NM;
249 IPAddr GW;
251 if ( iArgC >= 4 ) {
253 IP.addr = inet_addr( ppcArgV[ 1 ] );
254 NM.addr = inet_addr( ppcArgV[ 2 ] );
255 GW.addr = inet_addr (ppcArgV[ 3 ] );
257 } else {
259 IP4_ADDR( &IP, 192, 168, 0, 80 );
260 IP4_ADDR( &NM, 255, 255, 255, 0 );
261 IP4_ADDR( &GW, 192, 168, 0, 1 );
263 } /* end else */
265 return !SMapInit( IP, NM, GW );
267 } /* end _start */