2 * Copyright (c) Tord Lindstrom (pukko@home.se)
3 * Copyright (c) adresd ( adresd_ps2dev@yahoo.com )
21 #define UNKN_1464 *(u16 volatile*)0xbf801464
26 #define TIMER_INTERVAL (100*1000)
27 #define TIMEOUT (300*1000)
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;
41 static PBuf
* apReqQueue
[MAX_REQ_CNT
];
42 static int iTimeoutCNT
=0;
58 static SMapStatus
AddToQueue ( PBuf
* pBuf
) {
63 CpuSuspendIntr ( &iIntFlags
);
67 Ret
= SMap_Send ( pBuf
);
69 if ( Ret
== SMap_TX
) {
76 } else if ( iReqCNT
< MAX_REQ_CNT
) {
78 apReqQueue
[ ( iReqNR
+ iReqCNT
) % MAX_REQ_CNT
] = pBuf
;
86 CpuResumeIntr ( iIntFlags
);
90 } /* end AddToQueue */
92 static void SendRequests ( void ) {
94 while ( iReqCNT
> 0 ) {
96 PBuf
* lpReq
= apReqQueue
[ iReqNR
];
97 SMapStatus lSts
= SMap_Send ( lpReq
);
101 if ( lSts
== SMap_TX
) return;
105 iReqNR
= ( iReqNR
+ 1 ) % MAX_REQ_CNT
;
110 } /* end SendRequests */
112 static void QueueHandler ( void ) {
116 if ( iSendReq
>= 0 ) {
118 iSignalSema ( iSendReq
);
119 iSendReq
= 0x80000000;
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
) );
135 iFlags
= SMap_GetIRQ ();
139 if ( iFlags
& ( INTR_EMAC3
| INTR_RXDNV
| INTR_RXEND
) )
141 SMap_HandleRXEMACInterrupt ( iFlags
& ( INTR_EMAC3
| INTR_RXDNV
| INTR_RXEND
) );
145 } /* end SMapInterrupt */
147 static unsigned int Timer ( void* pvArg
) {
151 iTimeoutCNT
+= TIMER_INTERVAL
;
153 if ( iTimeoutCNT
>= TIMEOUT
&& iTimeoutCNT
< ( TIMEOUT
+ TIMER_INTERVAL
) ) QueueHandler ();
157 return ( unsigned int )pvArg
;
161 static err_t
SMapLowLevelOutput ( NetIF
* pNetIF
, PBuf
* pOutput
) {
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
);
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
) {
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 );
216 } /* end SMapIFInit */
218 static int SMapInit ( IPAddr IP
, IPAddr NM
, IPAddr GW
) {
221 iop_sys_clock_t ClockTicks
;
223 dev9IntrDisable ( INTR_BITMSK
);
224 EnableIntr ( IOP_IRQ_DEV9
);
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
);
245 int _start ( int iArgC
,char** ppcArgV
) {
253 IP
.addr
= inet_addr( ppcArgV
[ 1 ] );
254 NM
.addr
= inet_addr( ppcArgV
[ 2 ] );
255 GW
.addr
= inet_addr (ppcArgV
[ 3 ] );
259 IP4_ADDR( &IP
, 192, 168, 0, 80 );
260 IP4_ADDR( &NM
, 255, 255, 255, 0 );
261 IP4_ADDR( &GW
, 192, 168, 0, 1 );
265 return !SMapInit( IP
, NM
, GW
);