adding i18n strings
[open-ps2-loader.git] / modules / network / SMSMAP / smap.c
blob840b36b1c0079912f6f412abd419468fb1ef9843
1 /*
2 smap.c
4 Copyright (c)2001 Sony Computer Entertainment Inc.
5 Copyright (c)2001 YAEGASHI Takeshi
6 Copyright (2)2002 Dan Potter
7 Copyright (c)2003 T Lindstrom
8 Copyright (c)2003 adresd
9 License: GPL
11 $Id: smap.c 1105 2005-05-21 12:43:39Z pixel $
14 /* Pulled from the eCos port */
16 // $Id: smap.c 1105 2005-05-21 12:43:39Z pixel $
17 // many routines are taken from drivers/ps2/smap.c of PS2 Linux kernel (GPL).
20 #include "smap.h"
21 #include "stddef.h"
22 #include "stdio.h"
23 #include "intrman.h"
24 #include "loadcore.h"
25 #include "thbase.h"
26 #include "dev9.h"
27 #include "ps2ip.h"
29 #include "smsutils.h"
31 #define SET 1
32 #define CLEAR 0
33 #define TRUE 1
34 #define FALSE 0
35 #define ENABLE 1
36 #define DISABLE 0
37 #define START 1
38 #define STOP 0
39 #define RESET_ONLY 1
40 #define RESET_INIT 0
43 //Flags
44 #define SMAP_F_OPENED (1<<0)
45 #define SMAP_F_LINKESTABLISH (1<<1)
46 #define SMAP_F_LINKVALID (1<<2)
47 #define SMAP_F_CHECK_FORCE100M (1<<3)
48 #define SMAP_F_CHECK_FORCE10M (1<<4)
49 #define SMAP_F_TXDNV_DISABLE (1<<16)
50 #define SMAP_F_RXDNV_DISABLE (1<<17)
51 #define SMAP_F_PRINT_PKT (1<<30)
52 #define SMAP_F_PRINT_MSG (1<<31)
55 #define SMAP_TXBUFBASE 0x1000
56 #define SMAP_TXBUFSIZE (4*1024)
57 #define SMAP_RXBUFBASE 0x4000
58 #define SMAP_RXBUFSIZE (16*1024)
60 #define SMAP_ALIGN 16
61 #define SMAP_TXMAXSIZE (6+6+2+1500)
62 #define SMAP_TXMAXTAILPAD 4
63 #define SMAP_TXMAXPKTSZ_INFIFO (SMAP_TXMAXSIZE+2) //Multiple of 4
64 #define SMAP_RXMAXSIZE (6+6+2+1500+4)
65 #define SMAP_RXMINSIZE 14 //Ethernet header size
66 #define SMAP_RXMAXTAILPAD 4
68 #define SMAP_LOOP_COUNT 10000
69 #define SMAP_AUTONEGO_TIMEOUT 3000
70 #define SMAP_AUTONEGO_RETRY 3
71 #define SMAP_FORCEMODE_WAIT 2000
72 #define SMAP_FORCEMODE_TIMEOUT 1000
73 #define SMAP_LINK_WAIT 5000
76 //Buffer Descriptor(BD) Offset and Definitions
77 #define SMAP_BD_BASE 0x3000
78 #define SMAP_BD_BASE_TX (SMAP_BD_BASE+0x0000)
79 #define SMAP_BD_BASE_RX (SMAP_BD_BASE+0x0200)
80 #define SMAP_BD_SIZE 512
81 #define SMAP_BD_MAX_ENTRY 64
83 #define SMAP_BD_NEXT(x) (x)=(x)<(SMAP_BD_MAX_ENTRY-1) ? (x)+1:0
85 //TX Control
86 #define SMAP_BD_TX_READY (1<<15) //set:driver, clear:HW
87 #define SMAP_BD_TX_GENFCS (1<<9) //generate FCS
88 #define SMAP_BD_TX_GENPAD (1<<8) //generate padding
89 #define SMAP_BD_TX_INSSA (1<<7) //insert source address
90 #define SMAP_BD_TX_RPLSA (1<<6) //replace source address
91 #define SMAP_BD_TX_INSVLAN (1<<5) //insert VLAN Tag
92 #define SMAP_BD_TX_RPLVLAN (1<<4) //replace VLAN Tag
94 //TX Status
95 #define SMAP_BD_TX_READY (1<<15) //set:driver, clear:HW
96 #define SMAP_BD_TX_BADFCS (1<<9) //bad FCS
97 #define SMAP_BD_TX_BADPKT (1<<8) //bad previous pkt in dependent mode
98 #define SMAP_BD_TX_LOSSCR (1<<7) //loss of carrior sense
99 #define SMAP_BD_TX_EDEFER (1<<6) //excessive deferal
100 #define SMAP_BD_TX_ECOLL (1<<5) //excessive collision
101 #define SMAP_BD_TX_LCOLL (1<<4) //late collision
102 #define SMAP_BD_TX_MCOLL (1<<3) //multiple collision
103 #define SMAP_BD_TX_SCOLL (1<<2) //single collision
104 #define SMAP_BD_TX_UNDERRUN (1<<1) //underrun
105 #define SMAP_BD_TX_SQE (1<<0) //SQE
106 #define SMAP_BD_TX_ERRMASK (SMAP_BD_TX_BADFCS|SMAP_BD_TX_BADPKT|SMAP_BD_TX_LOSSCR|SMAP_BD_TX_EDEFER|SMAP_BD_TX_ECOLL| \
107 SMAP_BD_TX_LCOLL|SMAP_BD_TX_MCOLL|SMAP_BD_TX_SCOLL|SMAP_BD_TX_UNDERRUN|SMAP_BD_TX_SQE)
109 //RX Control
110 #define SMAP_BD_RX_EMPTY (1<<15) //set:driver, clear:HW
112 //RX Status
113 #define SMAP_BD_RX_EMPTY (1<<15) //set:driver, clear:HW
114 #define SMAP_BD_RX_OVERRUN (1<<9) //overrun
115 #define SMAP_BD_RX_PFRM (1<<8) //pause frame
116 #define SMAP_BD_RX_BADFRM (1<<7) //bad frame
117 #define SMAP_BD_RX_RUNTFRM (1<<6) //runt frame
118 #define SMAP_BD_RX_SHORTEVNT (1<<5) //short event
119 #define SMAP_BD_RX_ALIGNERR (1<<4) //alignment error
120 #define SMAP_BD_RX_BADFCS (1<<3) //bad FCS
121 #define SMAP_BD_RX_FRMTOOLONG (1<<2) //frame too long
122 #define SMAP_BD_RX_OUTRANGE (1<<1) //out of range error
123 #define SMAP_BD_RX_INRANGE (1<<0) //in range error
124 #define SMAP_BD_RX_ERRMASK (SMAP_BD_RX_OVERRUN|SMAP_BD_RX_PFRM|SMAP_BD_RX_BADFRM|SMAP_BD_RX_RUNTFRM|SMAP_BD_RX_SHORTEVNT| \
125 SMAP_BD_RX_ALIGNERR|SMAP_BD_RX_BADFCS|SMAP_BD_RX_FRMTOOLONG|SMAP_BD_RX_OUTRANGE| \
126 SMAP_BD_RX_INRANGE)
129 struct smapbd
131 u16 ctrl_stat;
132 u16 reserved; //Must be zero
133 u16 length; //Number of bytes in pkt
134 u16 pointer;
137 typedef struct smapbd volatile SMapBD;
140 typedef struct SMapCircularBuffer
142 SMapBD* pBD;
143 u16 u16PTRStart;
144 u16 u16PTREnd;
145 u8 u8IndexStart;
146 u8 u8IndexEnd;
147 } SMapCB;
149 typedef struct SMap
151 u32 u32Flags;
152 u8 volatile* pu8Base;
153 u8 au8HWAddr[6];
154 u32 u32TXMode;
155 u8 u8PPWC;
156 SMapCB TX;
157 u8 u8RXIndex;
158 u16 u16RXPTR;
159 SMapBD* pRXBD;
160 #ifndef FORCE_100M_FD
161 struct SMapPhySpecific *phy_specific;
162 #endif
163 } SMap;
166 * PHY specific functions
168 #ifndef FORCE_100M_FD
169 struct SMapPhySpecific {
170 int (* get_link_status) (SMap*);
171 int (* get_speed) (SMap *);
172 int (* get_duplex) (SMap *);
174 #endif
176 //Register Offset and Definitions
177 #define SMAP_PIOPORT_DIR 0x2C
178 #define SMAP_PIOPORT_IN 0x2E
179 #define SMAP_PIOPORT_OUT 0x2E
180 #define PP_DOUT (1<<4) //Data output, read port
181 #define PP_DIN (1<<5) //Data input, write port
182 #define PP_SCLK (1<<6) //Clock, write port
183 #define PP_CSEL (1<<7) //Chip select, write port
184 //operation code
185 #define PP_OP_READ 2 //2b'10
186 #define PP_OP_WRITE 1 //2b'01
187 #define PP_OP_EWEN 0 //2b'00
188 #define PP_OP_EWDS 0 //2b'00
190 #define SMAP_BASE 0xb0000000
192 #define SPD_R_REV_1 0x02
194 #define SMAP_INTR_STAT 0x28
195 #define SMAP_INTR_CLR 0x128
196 #define SMAP_INTR_ENABLE 0x2A
197 #define SMAP_BD_MODE 0x102
198 #define BD_SWAP (1<<0)
200 #define SMAP_TXFIFO_CTRL 0x1000
201 #define TXFIFO_RESET (1<<0)
202 #define TXFIFO_DMAEN (1<<1)
203 #define SMAP_TXFIFO_WR_PTR 0x1004
204 #define SMAP_TXFIFO_SIZE 0x1008
205 #define SMAP_TXFIFO_FRAME_CNT 0x100C
206 #define SMAP_TXFIFO_FRAME_INC 0x1010
207 #define SMAP_TXFIFO_DATA 0x1100
209 #define SMAP_RXFIFO_CTRL 0x1030
210 #define RXFIFO_RESET (1<<0)
211 #define RXFIFO_DMAEN (1<<1)
212 #define SMAP_RXFIFO_RD_PTR 0x1034
213 #define SMAP_RXFIFO_SIZE 0x1038
214 #define SMAP_RXFIFO_FRAME_CNT 0x103C
215 #define SMAP_RXFIFO_FRAME_DEC 0x1040
216 #define SMAP_RXFIFO_DATA 0x1200
218 #define SMAP_FIFO_ADDR 0x1300
219 #define FIFO_CMD_READ (1<<1)
220 #define FIFO_DATA_SWAP (1<<0)
221 #define SMAP_FIFO_DATA 0x1308
223 #define SMAP_REG8(pSMap,Offset) (*(u8 volatile*)((pSMap)->pu8Base+(Offset)))
224 #define SMAP_REG16(pSMap,Offset) (*(u16 volatile*)((pSMap)->pu8Base+(Offset)))
225 #define SMAP_REG32(pSMap,Offset) (*(u32 volatile*)((pSMap)->pu8Base+(Offset)))
227 #define SMAP_EEPROM_WRITE_WAIT 100000
228 #define SMAP_PP_GET_Q(pSMap) ((SMAP_REG8((pSMap),SMAP_PIOPORT_IN)>>4)&1)
229 #define SMAP_PP_SET_D(pSMap,D) ((pSMap)->u8PPWC=(D) ? ((pSMap)->u8PPWC|PP_DIN):((pSMap)->u8PPWC&~PP_DIN))
230 #define SMAP_PP_SET_S(pSMap,S) ((pSMap)->u8PPWC=(S) ? ((pSMap)->u8PPWC|PP_CSEL):((pSMap)->u8PPWC&~PP_CSEL))
231 #define SMAP_PP_CLK_OUT(pSMap,C) {(pSMap)->u8PPWC=(C) ? ((pSMap)->u8PPWC|PP_SCLK):((pSMap)->u8PPWC&~PP_SCLK); \
232 SMAP_REG8((pSMap),SMAP_PIOPORT_OUT)=(pSMap)->u8PPWC;}
234 //EMAC3 Register Offset and Definitions
235 #define SMAP_EMAC3_BASE 0x2000
236 #define SMAP_EMAC3_MODE0 (SMAP_EMAC3_BASE+0x00)
237 #define E3_RXMAC_IDLE (1<<31)
238 #define E3_TXMAC_IDLE (1<<30)
239 #define E3_SOFT_RESET (1<<29)
240 #define E3_TXMAC_ENABLE (1<<28)
241 #define E3_RXMAC_ENABLE (1<<27)
242 #define E3_WAKEUP_ENABLE (1<<26)
244 #define SMAP_EMAC3_MODE1 (SMAP_EMAC3_BASE+0x04)
245 #define E3_FDX_ENABLE (1<<31)
246 #define E3_INLPBK_ENABLE (1<<30) //internal loop back
247 #define E3_VLAN_ENABLE (1<<29)
248 #define E3_FLOWCTRL_ENABLE (1<<28) //integrated flow ctrl(pause frame)
249 #define E3_ALLOW_PF (1<<27) //allow pause frame
250 #define E3_ALLOW_EXTMNGIF (1<<25) //allow external management IF
251 #define E3_IGNORE_SQE (1<<24)
252 #define E3_MEDIA_FREQ_BITSFT (22)
253 #define E3_MEDIA_10M (0<<22)
254 #define E3_MEDIA_100M (1<<22)
255 #define E3_MEDIA_1000M (2<<22)
256 #define E3_MEDIA_MSK (3<<22)
257 #define E3_RXFIFO_SIZE_BITSFT (20)
258 #define E3_RXFIFO_512 (0<<20)
259 #define E3_RXFIFO_1K (1<<20)
260 #define E3_RXFIFO_2K (2<<20)
261 #define E3_RXFIFO_4K (3<<20)
262 #define E3_TXFIFO_SIZE_BITSFT (18)
263 #define E3_TXFIFO_512 (0<<18)
264 #define E3_TXFIFO_1K (1<<18)
265 #define E3_TXFIFO_2K (2<<18)
266 #define E3_TXREQ0_BITSFT (15)
267 #define E3_TXREQ0_SINGLE (0<<15)
268 #define E3_TXREQ0_MULTI (1<<15)
269 #define E3_TXREQ0_DEPEND (2<<15)
270 #define E3_TXREQ1_BITSFT (13)
271 #define E3_TXREQ1_SINGLE (0<<13)
272 #define E3_TXREQ1_MULTI (1<<13)
273 #define E3_TXREQ1_DEPEND (2<<13)
274 #define E3_JUMBO_ENABLE (1<<12)
276 #define SMAP_EMAC3_TxMODE0 (SMAP_EMAC3_BASE+0x08)
277 #define E3_TX_GNP_0 (1<<31) //get new packet
278 #define E3_TX_GNP_1 (1<<30) //get new packet
279 #define E3_TX_GNP_DEPEND (1<<29) //get new packet
280 #define E3_TX_FIRST_CHANNEL (1<<28)
282 #define SMAP_EMAC3_TxMODE1 (SMAP_EMAC3_BASE+0x0C)
283 #define E3_TX_LOW_REQ_MSK (0x1F) //low priority request
284 #define E3_TX_LOW_REQ_BITSFT (27) //low priority request
285 #define E3_TX_URG_REQ_MSK (0xFF) //urgent priority request
286 #define E3_TX_URG_REQ_BITSFT (16) //urgent priority request
288 #define SMAP_EMAC3_RxMODE (SMAP_EMAC3_BASE+0x10)
289 #define E3_RX_STRIP_PAD (1<<31)
290 #define E3_RX_STRIP_FCS (1<<30)
291 #define E3_RX_RX_RUNT_FRAME (1<<29)
292 #define E3_RX_RX_FCS_ERR (1<<28)
293 #define E3_RX_RX_TOO_LONG_ERR (1<<27)
294 #define E3_RX_RX_IN_RANGE_ERR (1<<26)
295 #define E3_RX_PROP_PF (1<<25) //propagate pause frame
296 #define E3_RX_PROMISC (1<<24)
297 #define E3_RX_PROMISC_MCAST (1<<23)
298 #define E3_RX_INDIVID_ADDR (1<<22)
299 #define E3_RX_INDIVID_HASH (1<<21)
300 #define E3_RX_BCAST (1<<20)
301 #define E3_RX_MCAST (1<<19)
303 #define SMAP_EMAC3_INTR_STAT (SMAP_EMAC3_BASE+0x14)
304 #define SMAP_EMAC3_INTR_ENABLE (SMAP_EMAC3_BASE+0x18)
305 #define E3_INTR_OVERRUN (1<<25) //this bit does NOT WORKED
306 #define E3_INTR_PF (1<<24)
307 #define E3_INTR_BAD_FRAME (1<<23)
308 #define E3_INTR_RUNT_FRAME (1<<22)
309 #define E3_INTR_SHORT_EVENT (1<<21)
310 #define E3_INTR_ALIGN_ERR (1<<20)
311 #define E3_INTR_BAD_FCS (1<<19)
312 #define E3_INTR_TOO_LONG (1<<18)
313 #define E3_INTR_OUT_RANGE_ERR (1<<17)
314 #define E3_INTR_IN_RANGE_ERR (1<<16)
315 #define E3_INTR_DEAD_DEPEND (1<<9)
316 #define E3_INTR_DEAD_0 (1<<8)
317 #define E3_INTR_SQE_ERR_0 (1<<7)
318 #define E3_INTR_TX_ERR_0 (1<<6)
319 #define E3_INTR_DEAD_1 (1<<5)
320 #define E3_INTR_SQE_ERR_1 (1<<4)
321 #define E3_INTR_TX_ERR_1 (1<<3)
322 #define E3_INTR_MMAOP_SUCCESS (1<<1)
323 #define E3_INTR_MMAOP_FAIL (1<<0)
324 #define E3_INTR_ALL (E3_INTR_OVERRUN|E3_INTR_PF|E3_INTR_BAD_FRAME|E3_INTR_RUNT_FRAME|E3_INTR_SHORT_EVENT| \
325 E3_INTR_ALIGN_ERR|E3_INTR_BAD_FCS|E3_INTR_TOO_LONG|E3_INTR_OUT_RANGE_ERR| \
326 E3_INTR_IN_RANGE_ERR|E3_INTR_DEAD_DEPEND|E3_INTR_DEAD_0| E3_INTR_SQE_ERR_0| \
327 E3_INTR_TX_ERR_0|E3_INTR_DEAD_1|E3_INTR_SQE_ERR_1|E3_INTR_TX_ERR_1| \
328 E3_INTR_MMAOP_SUCCESS|E3_INTR_MMAOP_FAIL)
329 #define E3_DEAD_ALL (E3_INTR_DEAD_DEPEND|E3_INTR_DEAD_0| E3_INTR_DEAD_1)
331 #define SMAP_EMAC3_ADDR_HI (SMAP_EMAC3_BASE+0x1C)
332 #define SMAP_EMAC3_ADDR_LO (SMAP_EMAC3_BASE+0x20)
334 #define SMAP_EMAC3_VLAN_TPID (SMAP_EMAC3_BASE+0x24)
335 #define E3_VLAN_ID_MSK 0xFFFF
337 #define SMAP_EMAC3_VLAN_TCI (SMAP_EMAC3_BASE+0x28)
338 #define E3_VLAN_TCITAG_MSK 0xFFFF
340 #define SMAP_EMAC3_PAUSE_TIMER (SMAP_EMAC3_BASE+0x2C)
341 #define E3_PTIMER_MSK 0xFFFF
343 #define SMAP_EMAC3_INDIVID_HASH1 (SMAP_EMAC3_BASE+0x30)
344 #define SMAP_EMAC3_INDIVID_HASH2 (SMAP_EMAC3_BASE+0x34)
345 #define SMAP_EMAC3_INDIVID_HASH3 (SMAP_EMAC3_BASE+0x38)
346 #define SMAP_EMAC3_INDIVID_HASH4 (SMAP_EMAC3_BASE+0x3C)
347 #define SMAP_EMAC3_GROUP_HASH1 (SMAP_EMAC3_BASE+0x40)
348 #define SMAP_EMAC3_GROUP_HASH2 (SMAP_EMAC3_BASE+0x44)
349 #define SMAP_EMAC3_GROUP_HASH3 (SMAP_EMAC3_BASE+0x48)
350 #define SMAP_EMAC3_GROUP_HASH4 (SMAP_EMAC3_BASE+0x4C)
351 #define E3_HASH_MSK 0xFFFF
353 #define SMAP_EMAC3_LAST_SA_HI (SMAP_EMAC3_BASE+0x50)
354 #define SMAP_EMAC3_LAST_SA_LO (SMAP_EMAC3_BASE+0x54)
356 #define SMAP_EMAC3_INTER_FRAME_GAP (SMAP_EMAC3_BASE+0x58)
357 #define E3_IFGAP_MSK 0x3F
359 #define SMAP_EMAC3_STA_CTRL (SMAP_EMAC3_BASE+0x5C)
360 #define E3_PHY_DATA_MSK (0xFFFF)
361 #define E3_PHY_DATA_BITSFT (16)
362 #define E3_PHY_OP_COMP (1<<15) //operation complete
363 #define E3_PHY_ERR_READ (1<<14)
364 #define E3_PHY_STA_CMD_BITSFT (12)
365 #define E3_PHY_READ (1<<12)
366 #define E3_PHY_WRITE (2<<12)
367 #define E3_PHY_OPBCLCK_BITSFT (10)
368 #define E3_PHY_50M (0<<10)
369 #define E3_PHY_66M (1<<10)
370 #define E3_PHY_83M (2<<10)
371 #define E3_PHY_100M (3<<10)
372 #define E3_PHY_ADDR_MSK (0x1F)
373 #define E3_PHY_ADDR_BITSFT (5)
374 #define E3_PHY_REG_ADDR_MSK (0x1F)
376 #define SMAP_EMAC3_TX_THRESHOLD (SMAP_EMAC3_BASE+0x60)
377 #define E3_TX_THRESHLD_MSK (0x1F)
378 #define E3_TX_THRESHLD_BITSFT (27)
380 #define SMAP_EMAC3_RX_WATERMARK (SMAP_EMAC3_BASE+0x64)
381 #define E3_RX_LO_WATER_MSK (0x1FF)
382 #define E3_RX_LO_WATER_BITSFT (23)
383 #define E3_RX_HI_WATER_MSK (0x1FF)
384 #define E3_RX_HI_WATER_BITSFT (7)
386 #define SMAP_EMAC3_TX_OCTETS (SMAP_EMAC3_BASE+0x68)
387 #define SMAP_EMAC3_RX_OCTETS (SMAP_EMAC3_BASE+0x6C)
390 //PHY Register Offset
391 #define NS_OUI 0x080017
392 #define DsPHYTER_ADDRESS 0x1
393 #define DsPHYTER_BMCR 0x00
394 #define PHY_BMCR_RST (1<<15) //ReSeT
395 #define PHY_BMCR_LPBK (1<<14) //LooPBacK
396 #define PHY_BMCR_100M (1<<13) //speed select, 1:100M, 0:10M
397 #define PHY_BMCR_10M (0<<13) //speed select, 1:100M, 0:10M
398 #define PHY_BMCR_ANEN (1<<12) //Auto-Negotiation ENable
399 #define PHY_BMCR_PWDN (1<<11) //PoWer DowN
400 #define PHY_BMCR_ISOL (1<<10) //ISOLate
401 #define PHY_BMCR_RSAN (1<<9) //ReStart Auto-Negotiation
402 #define PHY_BMCR_DUPM (1<<8) //DUPlex Mode, 1:FDX, 0:HDX
403 #define PHY_BMCR_COLT (1<<7) //COLlision Test
404 #define DsPHYTER_BMSR 0x01
405 #define PHY_BMSR_ANCP (1<<5) //Auto-Negotiation ComPlete
406 #define PHY_BMSR_LINK (1<<2) //LINK status
407 #define DsPHYTER_PHYIDR1 0x02
408 #define PHY_IDR1_VAL (((NS_OUI<<2)>>8)&0xffff)
409 #define DsPHYTER_PHYIDR2 0x03
410 #define PHY_IDR2_VMDL 0x2 //Vendor MoDeL number
411 #define PHY_IDR2_VAL (((NS_OUI<<10)&0xFC00)|((PHY_IDR2_VMDL<<4)&0x3F0))
412 #define PHY_IDR2_MSK 0xFFF0
414 #define DsPHYTER_ANAR 0x04
415 #define DsPHYTER_ANLPAR 0x05
416 #define DsPHYTER_ANLPARNP 0x05
417 #define DsPHYTER_ANER 0x06
418 #define DsPHYTER_ANNPTR 0x07
419 //Extended registers
420 #define DsPHYTER_PHYSTS 0x10
421 #define PHY_STS_REL (1<<13) //Receive Error Latch
422 #define PHY_STS_POST (1<<12) //POlarity STatus
423 #define PHY_STS_FCSL (1<<11) //False Carrier Sense Latch
424 #define PHY_STS_SD (1<<10) //100BT unconditional Signal Detect
425 #define PHY_STS_DSL (1<<9) //100BT DeScrambler Lock
426 #define PHY_STS_PRCV (1<<8) //Page ReCeiVed
427 #define PHY_STS_RFLT (1<<6) //Remote FauLT
428 #define PHY_STS_JBDT (1<<5) //JaBber DetecT
429 #define PHY_STS_ANCP (1<<4) //Auto-Negotiation ComPlete
430 #define PHY_STS_LPBK (1<<3) //LooPBacK status
431 #define PHY_STS_DUPS (1<<2) //DUPlex Status,1:FDX,0:HDX
432 #define PHY_STS_FDX (1<<2) //Full Duplex
433 #define PHY_STS_HDX (0<<2) //Half Duplex
434 #define PHY_STS_SPDS (1<<1) //SpeeD Status
435 #define PHY_STS_10M (1<<1) //10Mbps
436 #define PHY_STS_100M (0<<1) //100Mbps
437 #define PHY_STS_LINK (1<<0) //LINK status
438 #define DsPHYTER_FCSCR 0x14
439 #define DsPHYTER_RECR 0x15
440 #define DsPHYTER_PCSR 0x16
441 #define DsPHYTER_PHYCTRL 0x19
442 #define DsPHYTER_10BTSCR 0x1A
443 #define DsPHYTER_CDCTRL 0x1B
446 * STEPHY1 10/100 Fast Ethernet 3.3V Transceiver (used in SCPH-10281)
448 #define ST_OUI 0x0080E1
449 #define STEPHY1_XCR 0x00
450 #define STEPHY1_XSR 0x01
451 #define STEPHY1_PID1 0x02
452 #define STEPHY1_IDR1_VAL 0x1c04
453 #define STEPHY1_PID2 0x03
454 #define STEPHY1_ANA 0x04
455 #define STEPHY1_ANLPA 0x05
456 #define STEPHY1_ANE 0x06
457 /* extended registers */
458 #define STEPHY1_XCIIS 0x11 /* XCVR Configuration Information and Interrupt Status Register */
459 #define STEPHY1_XCIIS_100M (1 << 9)
460 #define STEPHY1_XCIIS_FDX (1 << 8)
461 #define STEPHY1_XCIIS_LINK (1 << 4)
462 #define STEPHY1_XIE 0x12 /* XCVR Interrupt Enable Register */
463 #define STEPHY1_100CTR 0x13 /* 100Base-TX PHY Control Status Register */
464 #define STEPHY1_XMC 0x14 /* XCVR Mode Control Register */
466 static SMap SMap0;
467 extern struct netif NIF;
469 /*--------------------------------------------------------------------------*/
471 static void TXRXEnable(SMap* pSMap,int iEnable);
472 static int FIFOReset(SMap* pSMap);
473 static int EMAC3SoftReset(SMap* pSMap);
474 static void EMAC3SetDefValue(SMap* pSMap);
475 static int EMAC3Init(SMap* pSMap,int iReset);
476 static void EMAC3ReInit(SMap* pSMap);
477 static int PhyInit(SMap* pSMap,int iReset);
478 static int PhyReset(SMap* pSMap);
479 #ifdef FORCE_100M_FD
480 static int __ForceSPD100M_FD(SMap* pSMap);
481 #else
482 static void PhySetSpecific(SMap* pSMap);
483 static int AutoNegotiation(SMap* pSMap,int iEnableAutoNego);
484 static int ConfirmAutoNegotiation(SMap* pSMap);
485 static int PhyGetSpeed(SMap* pSMap);
486 static int PhyGetDuplex(SMap* pSMap);
487 static void ForceSPD100M(SMap* pSMap);
488 static void ForceSPD10M(SMap* pSMap);
489 static void ConfirmForceSPD(SMap* pSMap);
490 #endif
491 static void PhySetDSP(SMap* pSMap);
492 static int Reset(SMap* pSMap,int iReset);
493 static int GetNodeAddr(SMap* pSMap);
494 static void BaseInit(SMap* pSMap);
496 #ifndef FORCE_100M_FD
497 /* NS DP83847 specific functions */
498 static int DsPHYTER_get_link_status(SMap* pSMap);
499 static int DsPHYTER_get_speed(SMap* pSMap);
500 static int DsPHYTER_get_duplex(SMap* pSMap);
502 /* ST STEPHY1 specific functions */
503 static int STEPHY1_get_link_status(SMap* pSMap);
504 static int STEPHY1_get_speed(SMap* pSMap);
505 static int STEPHY1_get_duplex(SMap* pSMap);
507 static struct SMapPhySpecific DsPHYTER_phy = {
508 DsPHYTER_get_link_status,
509 DsPHYTER_get_speed,
510 DsPHYTER_get_duplex
513 static struct SMapPhySpecific STEPHY1_phy = {
514 STEPHY1_get_link_status,
515 STEPHY1_get_speed,
516 STEPHY1_get_duplex
518 #endif
520 /*--------------------------------------------------------------------------*/
521 static inline u32 EMAC3REG_READ ( SMap* pSMap,u32 u32Offset ) {
523 u32 hi = SMAP_REG16( pSMap, u32Offset );
524 u32 lo = SMAP_REG16( pSMap, u32Offset + 2 );
526 return ( hi << 16 ) | lo;
528 } /* end EMAC3REG_READ */
530 static inline void EMAC3REG_WRITE ( SMap* pSMap, u32 u32Offset,u32 u32V ) {
532 SMAP_REG16( pSMap, u32Offset ) = ( u32V >> 16 ) & 0xFFFF;
533 SMAP_REG16( pSMap, u32Offset + 2 ) = u32V & 0xFFFF;
535 } /* end EMAC3REG_WRITE */
537 static u16 ComputeFreeSize ( SMapCB const* pCB ) {
539 u16 u16Start = pCB -> u16PTRStart;
540 u16 u16End = pCB -> u16PTREnd;
542 return u16Start > u16End ? ( SMAP_TXBUFSIZE + u16End - u16Start )
543 : ( SMAP_TXBUFSIZE - u16End + u16Start );
544 } /* end ComputeFreeSize */
546 extern void SMAP_CopyFromFIFO ( SMap*, struct pbuf* );
548 /*--------------------------------------------------------------------------*/
549 static void
550 TXRXEnable(SMap* pSMap,int iEnable)
552 if (iEnable)
555 //Enable tx/rx.
557 EMAC3REG_WRITE(pSMap,SMAP_EMAC3_MODE0,E3_TXMAC_ENABLE|E3_RXMAC_ENABLE);
559 else
561 int iA;
562 u32 u32Val;
564 //Disable tx/rx.
566 EMAC3REG_WRITE(pSMap,SMAP_EMAC3_MODE0,EMAC3REG_READ(pSMap,SMAP_EMAC3_MODE0)&(~(E3_TXMAC_ENABLE|E3_RXMAC_ENABLE)));
568 //Check EMAC3 idle status.
570 for (iA=SMAP_LOOP_COUNT;iA!=0;--iA)
572 u32Val=EMAC3REG_READ(pSMap,SMAP_EMAC3_MODE0);
573 if ((u32Val&E3_RXMAC_IDLE)&&(u32Val&E3_TXMAC_IDLE))
575 return;
578 dbgprintf("TXRXEnable: EMAC3 is still running(%x).\n",u32Val);
582 extern void _smap_phy_write ( int, int );
583 __asm__(
584 ".set noreorder\n\t"
585 ".set nomacro\n\t"
586 ".set noat\n\t"
587 ".text\n\t"
588 "_smap_phy_write:\n\t"
589 "addiu $sp, $sp, -12\n\t"
590 "andi $a0, $a0, 0x1F\n\t"
591 "sw $ra, 0($sp)\n\t"
592 "sw $s0, 4($sp)\n\t"
593 "lui $s0, 0xB000\n\t"
594 "andi $a1, $a1, 0xFFFF\n\t"
595 "ori $a0, $a0, 0x2020\n\t"
596 "ori $s0, $s0, 0x205C\n\t"
597 "sll $a0, $a0, 16\n\t"
598 "sw $s1, 8($sp)\n\t"
599 "or $a0, $a0, $a1\n\t"
600 "addiu $s1, $zero, 100\n\t"
601 "sw $a0, 0($s0)\n\t"
602 "lw $a0, 0($s0)\n\t"
603 "lw $a0, 0($s0)\n\t"
604 "1:\n\t"
605 "nop\n\t"
606 "srl $a0, $a0, 16\n\t"
607 "andi $a0, $a0, 0x8000\n\t"
608 "bnez $a0, 2f\n\t"
609 "addiu $s1, $s1, -1\n\t"
610 "jal DelayThread\n\t"
611 "addiu $a0, $zero, 1000\n\t"
612 "bgtz $s1, 1b\n\t"
613 "lw $a0, 0($s0)\n\t"
614 "2:\n\t"
615 "lw $ra, 0($sp)\n\t"
616 "lw $s0, 4($sp)\n\t"
617 "lw $s1, 8($sp)\n\t"
618 "jr $ra\n\t"
619 "addiu $sp, $sp, 12\n\t"
620 ".set at\n\t"
621 ".set macro\n\t"
622 ".set reorder\n\t"
625 extern int _smap_phy_read ( int );
626 __asm__(
627 ".set noreorder\n\t"
628 ".set nomacro\n\t"
629 ".set noat\n\t"
630 ".text\n\t"
631 "_smap_phy_read:\n\t"
632 "addiu $sp, $sp, -12\n\t"
633 "andi $a0, $a0, 0x1F\n\t"
634 "sw $ra, 0($sp)\n\t"
635 "sw $s0, 4($sp)\n\t"
636 "lui $s0, 0xB000\n\t"
637 "ori $a0, $a0, 0x1020\n\t"
638 "ori $s0, $s0, 0x205C\n\t"
639 "sll $a0, $a0, 16\n\t"
640 "sw $s1, 8($sp)\n\t"
641 "addiu $s1, $zero, 100\n\t"
642 "sw $a0, 0($s0)\n\t"
643 "lw $a0, 0($s0)\n\t"
644 "lw $a0, 0($s0)\n\t"
645 "1:\n\t"
646 "nop\n\t"
647 "sll $v0, $a0, 16\n\t"
648 "srl $a0, $a0, 16\n\t"
649 "andi $a0, $a0, 0x8000\n\t"
650 "bnez $a0, 2f\n\t"
651 "srl $v0, $v0, 16\n\t"
652 "addiu $s1, $s1, -1\n\t"
653 "jal DelayThread\n\t"
654 "addiu $a0, $zero, 1000\n\t"
655 "bgtz $s1, 1b\n\t"
656 "lw $a0, 0($s0)\n\t"
657 "sll $a0, $a0, 16\n\t"
658 "srl $v0, $a0, 16\n\t"
659 "2:\n\t"
660 "lw $ra, 0($sp)\n\t"
661 "lw $s0, 4($sp)\n\t"
662 "lw $s1, 8($sp)\n\t"
663 "jr $ra\n\t"
664 "addiu $sp, $sp, 12\n\t"
665 ".set at\n\t"
666 ".set macro\n\t"
667 ".set reorder\n\t"
670 extern void _smap_bd_init ( void );
671 __asm__(
672 ".set noreorder\n\t"
673 ".set nomacro\n\t"
674 ".set noat\n\t"
675 ".text\n\t"
676 "_smap_bd_init:\n\t"
677 "lui $v0, 0xB000\n\t"
678 "addiu $at, $zero, 64\n\t"
679 "ori $v1, $v0, 0x3200\n\t"
680 "ori $v0, $v0, 0x3000\n\t"
681 "ori $a0, $zero, 0x8000\n\t"
682 "1:\n\t"
683 "sh $zero, 0($v0)\n\t"
684 "sh $zero, 2($v0)\n\t"
685 "sh $zero, 4($v0)\n\t"
686 "sh $zero, 6($v0)\n\t"
687 "addiu $v0, $v0, 8\n\t"
688 "addiu $at, $at, -1\n\t"
689 "sh $a0, 0($v1)\n\t"
690 "sh $zero, 2($v1)\n\t"
691 "sh $zero, 4($v1)\n\t"
692 "sh $zero, 6($v1)\n\t"
693 "bgtz $at, 1b\n\t"
694 "addiu $v1, $v1, 8\n\t"
695 "jr $ra\n\t"
696 "nop\n\t"
697 ".set at\n\t"
698 ".set macro\n\t"
699 ".set reorder\n\t"
702 static int
703 FIFOReset(SMap* pSMap)
705 int iA;
706 int iRetVal=0;
708 //Reset TX FIFO.
710 SMAP_REG8(pSMap,SMAP_TXFIFO_CTRL)=TXFIFO_RESET;
712 //Reset RX FIFO.
714 SMAP_REG8(pSMap,SMAP_RXFIFO_CTRL)=RXFIFO_RESET;
716 //Confirm reset done.
718 for (iA=SMAP_LOOP_COUNT;iA!=0;--iA)
720 if (!(SMAP_REG8(pSMap,SMAP_TXFIFO_CTRL)&TXFIFO_RESET))
722 break;
725 if (iA==0)
727 iRetVal|=1;
730 for (iA=SMAP_LOOP_COUNT;iA!=0;--iA)
732 if (!(SMAP_REG8(pSMap,SMAP_RXFIFO_CTRL)&RXFIFO_RESET))
734 break;
737 if (iA==0)
739 iRetVal|=2;
741 return iRetVal;
744 static int
745 EMAC3SoftReset(SMap* pSMap)
747 int iA;
749 EMAC3REG_WRITE(pSMap,SMAP_EMAC3_MODE0,E3_SOFT_RESET);
750 for (iA=SMAP_LOOP_COUNT;iA!=0;--iA)
752 if (!(EMAC3REG_READ(pSMap,SMAP_EMAC3_MODE0)&E3_SOFT_RESET))
754 return 0;
757 dbgprintf("EMAC3SoftReset: EMAC3 reset is in progress\n");
758 return -1;
762 static void
763 EMAC3SetDefValue(SMap* pSMap)
765 //Set HW address.
767 EMAC3REG_WRITE(pSMap,SMAP_EMAC3_ADDR_HI,((pSMap->au8HWAddr[0]<<8)|pSMap->au8HWAddr[1]));
768 EMAC3REG_WRITE(pSMap,SMAP_EMAC3_ADDR_LO,((pSMap->au8HWAddr[2]<<24)|(pSMap->au8HWAddr[3]<<16)|(pSMap->au8HWAddr[4]<<8)|
769 pSMap->au8HWAddr[5]));
771 //Inter-frame GAP.
773 EMAC3REG_WRITE(pSMap,SMAP_EMAC3_INTER_FRAME_GAP,4);
775 //Rx mode.
777 EMAC3REG_WRITE(pSMap,SMAP_EMAC3_RxMODE,(E3_RX_STRIP_PAD|E3_RX_STRIP_FCS|E3_RX_INDIVID_ADDR|E3_RX_BCAST));
779 //Tx fifo value for request priority. low = 7*8=56, urgent = 15*8=120.
781 EMAC3REG_WRITE(pSMap,SMAP_EMAC3_TxMODE1,((7<<E3_TX_LOW_REQ_BITSFT)|(15<<E3_TX_URG_REQ_BITSFT)));
783 //TX threshold, (12+1)*64=832.
785 EMAC3REG_WRITE(pSMap,SMAP_EMAC3_TX_THRESHOLD,((12&E3_TX_THRESHLD_MSK)<<E3_TX_THRESHLD_BITSFT));
787 //Rx watermark, low = 16*8=128, hi = 128*8=1024.
789 EMAC3REG_WRITE(pSMap,SMAP_EMAC3_RX_WATERMARK,((16&E3_RX_LO_WATER_MSK)<<E3_RX_LO_WATER_BITSFT)|
790 ((128&E3_RX_HI_WATER_MSK)<<E3_RX_HI_WATER_BITSFT));
792 //Enable all EMAC3 interrupts.
794 EMAC3REG_WRITE(pSMap,SMAP_EMAC3_INTR_ENABLE,E3_INTR_ALL);
798 static int
799 EMAC3Init(SMap* pSMap,int iReset)
802 //Reset EMAC3.
804 EMAC3SoftReset(pSMap);
806 //EMAC3 operating MODE.
808 EMAC3REG_WRITE(pSMap,SMAP_EMAC3_MODE1,(E3_FDX_ENABLE|E3_IGNORE_SQE|E3_MEDIA_100M|E3_RXFIFO_2K|E3_TXFIFO_1K|E3_TXREQ0_SINGLE|
809 E3_TXREQ1_SINGLE));
811 //phy init.
813 if (PhyInit(pSMap,iReset)<0)
815 dbgprintf("EMAC3Init: Phy init error\n");
816 return -1;
819 //This flag may be set when unloading
821 if (iReset)
823 return -2;
826 dev9IntrDisable ( INTR_BITMSK );
828 SMap_ClearIRQ(INTR_BITMSK);
830 //Permanently set to default value.
832 EMAC3SetDefValue(pSMap);
834 return 0;
837 static void EMAC3ReInit ( SMap* pSMap ) {
839 EMAC3SoftReset ( pSMap );
840 EMAC3REG_WRITE( pSMap, SMAP_EMAC3_MODE1, pSMap -> u32TXMode );
841 EMAC3SetDefValue ( pSMap );
843 } /* end EMAC3ReInit */
845 static int PhyInit ( SMap* pSMap, int iReset ) {
847 int iVal = PhyReset ( pSMap );
849 if ( iVal < 0 ) return iVal;
850 if ( iReset ) return 0;
852 #ifndef FORCE_100M_FD
853 PhySetSpecific(pSMap);
854 #endif
856 #ifdef FORCE_100M_FD
857 iVal = __ForceSPD100M_FD(pSMap);
858 if ( iVal < 0 ) return iVal;
859 #else
860 iVal = AutoNegotiation ( pSMap, DISABLE );
862 if ( iVal == 0 ) {
864 pSMap -> u32Flags |= SMAP_F_LINKESTABLISH;
865 PhySetDSP ( pSMap );
867 return 0;
869 } /* end if */
871 ForceSPD100M ( pSMap );
872 #endif
874 return 0;
876 } /* end PhyInit */
878 static int PhyReset ( SMap* pSMap ) {
880 int i;
882 _smap_phy_write ( DsPHYTER_BMCR, PHY_BMCR_RST | PHY_BMCR_100M | PHY_BMCR_ANEN | PHY_BMCR_DUPM );
884 DelayThread ( 300 );
886 for ( i = SMAP_LOOP_COUNT; i; --i ) {
888 if ( !( _smap_phy_read ( DsPHYTER_BMCR ) & PHY_BMCR_RST ) ) return 0;
890 DelayThread ( 300 );
892 } /* end for */
894 return -1;
896 } /* end PhyReset */
898 #ifndef FORCE_100M_FD
899 static void
900 PhySetSpecific(SMap* pSMap)
902 int iID1;
904 iID1 = _smap_phy_read ( DsPHYTER_PHYIDR1 );
905 switch (iID1) {
906 case PHY_IDR1_VAL:
908 pSMap->phy_specific = &DsPHYTER_phy;
909 break;
911 case STEPHY1_IDR1_VAL:
913 pSMap->phy_specific = &STEPHY1_phy;
914 break;
916 default:
918 pSMap->phy_specific = NULL;
919 break;
924 static int
925 AutoNegotiation(SMap* pSMap,int iEnableAutoNego)
927 int iA;
929 if (iEnableAutoNego)
931 _smap_phy_write ( DsPHYTER_BMCR,PHY_BMCR_100M|PHY_BMCR_ANEN|PHY_BMCR_DUPM);
934 if (ConfirmAutoNegotiation(pSMap)>=0)
936 return 0;
938 for (iA=SMAP_AUTONEGO_RETRY;iA!=0;--iA)
940 _smap_phy_write ( DsPHYTER_BMCR,PHY_BMCR_100M|PHY_BMCR_ANEN|PHY_BMCR_DUPM|PHY_BMCR_RSAN);
942 if (ConfirmAutoNegotiation(pSMap)>=0)
944 return 0;
948 return -1;
950 #endif
952 #ifndef FORCE_100M_FD
953 static int
954 ConfirmAutoNegotiation(SMap* pSMap)
956 int iA;
957 int iPhyVal;
958 int spdrev;
959 int link_up_flag = 0;
960 int full_duplex_flag = 0;
961 int speed_100m_flag = 0;
963 for (iA=SMAP_AUTONEGO_TIMEOUT;iA!=0;--iA)
965 //Auto nego timeout is 3s.
966 iPhyVal = _smap_phy_read(DsPHYTER_BMSR);
967 if ((link_up_flag == 0) && (iPhyVal & PHY_BMSR_LINK))
968 link_up_flag = 1;
969 if (iPhyVal & PHY_BMSR_ANCP)
971 break;
973 DelayThread(1000); //wait 1ms
975 if (iA==0)
977 return -1;
980 // **ARGH: UGLY HACK! FIXME! **
981 spdrev = SMAP_REG16(pSMap, SPD_R_REV_1);
983 if (spdrev >= 0x13)
985 dbgprintf("Disabling autonegotiation sync on v12 - seems to work anyway - beware, hack inside.\n");
986 return 0;
989 //Confirm speed & duplex mode.
990 for (iA=SMAP_LOOP_COUNT;iA!=0;--iA)
992 iPhyVal = _smap_phy_read ( DsPHYTER_BMSR );
993 if ((link_up_flag == 0) && (iPhyVal & PHY_BMSR_LINK))
994 link_up_flag = 1;
995 if ((iPhyVal & PHY_BMSR_ANCP) && link_up_flag == 1) {
996 speed_100m_flag = PhyGetSpeed(pSMap);
997 full_duplex_flag = PhyGetDuplex(pSMap);
998 break;
1000 DelayThread(1000);
1002 if (iA==0)
1004 //Error.
1005 dbgprintf("ConfirmAutoNegotiation: Auto-negotiation error?? (BMSR=%x, link_up_flag=%d)\n", iPhyVal, link_up_flag);
1007 else
1009 u32 u32E3Val=EMAC3REG_READ(pSMap,SMAP_EMAC3_MODE1);
1011 dbgprintf("ConfirmAutoNegotiation: Auto-negotiation complete. %s %s duplex mode.\n",
1012 (speed_100m_flag == 0) ? "10Mbps":"100Mbps",(full_duplex_flag != 0) ? "Full":"Half");
1014 if (full_duplex_flag)
1016 //Full duplex mode.
1017 u32E3Val|=(E3_FDX_ENABLE|E3_FLOWCTRL_ENABLE|E3_ALLOW_PF);
1019 else
1021 //Half duplex mode.
1022 u32E3Val&=~(E3_FDX_ENABLE|E3_FLOWCTRL_ENABLE|E3_ALLOW_PF);
1023 if (speed_100m_flag == 0)
1025 u32E3Val&=~E3_IGNORE_SQE;
1028 u32E3Val&=~E3_MEDIA_MSK;
1029 u32E3Val|=speed_100m_flag==0 ? E3_MEDIA_10M:E3_MEDIA_100M;
1031 EMAC3REG_WRITE(pSMap,SMAP_EMAC3_MODE1,u32E3Val);
1033 return 0;
1036 static int
1037 DsPHYTER_get_link_status(SMap* pSMap)
1039 int iPhyVal;
1041 iPhyVal = _smap_phy_read(DsPHYTER_PHYSTS);
1043 if (iPhyVal & PHY_STS_LINK)
1044 return 1;
1046 return 0;
1049 static int
1050 DsPHYTER_get_speed(SMap* pSMap)
1052 int iPhyVal;
1054 iPhyVal = _smap_phy_read(DsPHYTER_PHYSTS);
1056 if (iPhyVal & PHY_STS_100M)
1057 return 1;
1059 return 0;
1062 static int
1063 DsPHYTER_get_duplex(SMap* pSMap)
1065 int iPhyVal;
1067 iPhyVal = _smap_phy_read(DsPHYTER_PHYSTS);
1069 if (iPhyVal & PHY_STS_FDX)
1070 return 1;
1072 return 0;
1075 static int
1076 STEPHY1_get_link_status(SMap* pSMap)
1078 int iPhyVal;
1080 iPhyVal = _smap_phy_read(STEPHY1_XCIIS);
1082 if (!(iPhyVal & STEPHY1_XCIIS_LINK))
1083 return 1;
1085 return 0;
1089 static int
1090 STEPHY1_get_speed(SMap* pSMap)
1092 int iPhyVal;
1094 iPhyVal = _smap_phy_read(STEPHY1_XCIIS);
1096 if (iPhyVal & STEPHY1_XCIIS_100M)
1097 return 1;
1099 return 0;
1102 static int
1103 STEPHY1_get_duplex(SMap* pSMap)
1105 int iPhyVal;
1107 iPhyVal = _smap_phy_read(STEPHY1_XCIIS);
1109 if (iPhyVal & STEPHY1_XCIIS_FDX)
1110 return 1;
1112 return 0;
1115 static int
1116 PhyGetSpeed(SMap* pSMap)
1118 return pSMap->phy_specific->get_speed(pSMap);
1121 static int
1122 PhyGetDuplex(SMap* pSMap)
1124 return pSMap->phy_specific->get_duplex(pSMap);
1126 #endif
1128 #ifdef FORCE_100M_FD
1129 static int __ForceSPD100M_FD(SMap* pSMap)
1131 int iA;
1133 /* Confirm link status */
1134 for (iA=SMAP_LINK_WAIT;iA!=0;--iA)
1136 int phy = _smap_phy_read(DsPHYTER_BMSR);
1137 if (phy & PHY_BMSR_LINK)
1138 break;
1139 DelayThread(1000);
1141 if (iA == 0)
1143 return -1;
1146 _smap_phy_write(DsPHYTER_BMCR, PHY_BMCR_100M|PHY_BMCR_DUPM);
1147 pSMap->u32Flags |= SMAP_F_CHECK_FORCE100M;
1149 iA = SMAP_FORCEMODE_WAIT;
1150 while (--iA)
1151 DelayThread(1000);
1153 /* Force 100 Mbps full duplex mode */
1154 u32 u32E3Val = EMAC3REG_READ(pSMap, SMAP_EMAC3_MODE1);
1155 u32E3Val |= (E3_FDX_ENABLE|E3_FLOWCTRL_ENABLE|E3_ALLOW_PF);
1156 u32E3Val &= ~E3_MEDIA_MSK;
1157 u32E3Val |= E3_MEDIA_100M;
1158 EMAC3REG_WRITE(pSMap, SMAP_EMAC3_MODE1, u32E3Val);
1159 pSMap->u32Flags &= ~(SMAP_F_CHECK_FORCE100M|SMAP_F_CHECK_FORCE10M);
1160 pSMap->u32Flags |= SMAP_F_LINKESTABLISH;
1161 PhySetDSP(pSMap);
1163 return 0;
1165 #endif
1167 #ifndef FORCE_100M_FD
1168 static void ForceSPD100M ( SMap* apSMap ) {
1170 int i;
1172 _smap_phy_write ( DsPHYTER_BMCR, PHY_BMCR_100M );
1174 apSMap -> u32Flags |= SMAP_F_CHECK_FORCE100M;
1176 for ( i = SMAP_FORCEMODE_WAIT; i; --i ) DelayThread ( 1000 );
1178 ConfirmForceSPD ( apSMap );
1180 } /* end ForceSPD100M */
1181 #endif
1183 #ifndef FORCE_100M_FD
1184 static void
1185 ForceSPD10M(SMap* pSMap)
1187 int iA;
1189 _smap_phy_write ( DsPHYTER_BMCR,PHY_BMCR_10M);
1191 pSMap->u32Flags|=SMAP_F_CHECK_FORCE10M;
1192 for (iA=SMAP_FORCEMODE_WAIT;iA!=0;--iA)
1194 DelayThread(1000);
1196 ConfirmForceSPD(pSMap);
1198 #endif
1200 #ifndef FORCE_100M_FD
1201 static void
1202 ConfirmForceSPD(SMap* pSMap)
1204 int iA;
1205 int iPhyVal;
1207 //Confirm link status, wait 1s is needed.
1209 for (iA=SMAP_FORCEMODE_TIMEOUT;iA!=0;--iA)
1212 iPhyVal = _smap_phy_read ( DsPHYTER_BMSR );
1214 if (iPhyVal&PHY_BMSR_LINK)
1216 break;
1218 DelayThread(1000);
1220 if (iA!=0)
1222 u32 u32E3Val;
1224 validlink:
1225 u32E3Val=EMAC3REG_READ(pSMap,SMAP_EMAC3_MODE1);
1226 u32E3Val&=~(E3_FDX_ENABLE|E3_FLOWCTRL_ENABLE|E3_ALLOW_PF|E3_MEDIA_MSK);
1227 if (pSMap->u32Flags&SMAP_F_CHECK_FORCE100M)
1229 dbgprintf("ConfirmForceSPD: 100Mbps Half duplex mode\n");
1230 u32E3Val|=E3_MEDIA_100M;
1232 else if (pSMap->u32Flags&SMAP_F_CHECK_FORCE10M)
1234 dbgprintf("ConfirmForceSPD: 10Mbps Half duplex mode\n");
1235 u32E3Val&=~E3_IGNORE_SQE;
1236 u32E3Val|=E3_MEDIA_10M;
1238 EMAC3REG_WRITE(pSMap,SMAP_EMAC3_MODE1,u32E3Val);
1239 pSMap->u32Flags&=~(SMAP_F_CHECK_FORCE100M|SMAP_F_CHECK_FORCE10M);
1240 pSMap->u32Flags|=SMAP_F_LINKESTABLISH;
1241 PhySetDSP(pSMap);
1242 return; //success
1245 if (pSMap->u32Flags&SMAP_F_CHECK_FORCE100M)
1247 pSMap->u32Flags&=~SMAP_F_CHECK_FORCE100M;
1248 ForceSPD10M(pSMap);
1250 else if (pSMap->u32Flags&SMAP_F_CHECK_FORCE10M)
1252 pSMap->u32Flags&=~SMAP_F_CHECK_FORCE10M;
1254 iPhyVal = _smap_phy_read ( DsPHYTER_PHYSTS );
1256 if (iPhyVal&PHY_STS_LINK)
1258 //Valid link.
1260 pSMap->u32Flags|=SMAP_F_CHECK_FORCE10M;
1261 goto validlink;
1265 #endif
1267 static void
1268 PhySetDSP(SMap* pSMap)
1270 int iID1;
1271 int iID2;
1272 int iPhyVal;
1274 if (!(pSMap->u32Flags&SMAP_F_LINKESTABLISH))
1277 //Link not established.
1279 return;
1282 //Tvalue is used in emac3 re-init without phy init.
1284 pSMap->u32TXMode=EMAC3REG_READ(pSMap,SMAP_EMAC3_MODE1);
1286 iID1 = _smap_phy_read ( DsPHYTER_PHYIDR1 );
1287 iID2 = _smap_phy_read ( DsPHYTER_PHYIDR2 );
1289 if (!((iID1==PHY_IDR1_VAL)&&((iID2&PHY_IDR2_MSK)==PHY_IDR2_VAL)))
1291 pSMap->u32Flags|=SMAP_F_LINKVALID;
1292 return;
1295 if (iID1 == STEPHY1_IDR1_VAL)
1297 pSMap->u32Flags|=SMAP_F_LINKVALID;
1298 return;
1301 if (pSMap->u32Flags&SMAP_F_LINKVALID)
1303 return;
1306 _smap_phy_write ( 0x13, 0x0001 );
1307 _smap_phy_write ( 0x19, 0x1898 );
1308 _smap_phy_write ( 0x1F, 0x0000 );
1309 _smap_phy_write ( 0x1D, 0x5040 );
1310 _smap_phy_write ( 0x1E, 0x008C );
1311 _smap_phy_write ( 0x13, 0x0000 );
1313 iPhyVal = _smap_phy_read ( DsPHYTER_PHYSTS );
1315 if ((iPhyVal&(PHY_STS_DUPS|PHY_STS_SPDS|PHY_STS_LINK))==(PHY_STS_HDX|PHY_STS_10M|PHY_STS_LINK))
1317 _smap_phy_write ( 0x1A, 0x0104 );
1320 pSMap->u32Flags|=SMAP_F_LINKVALID;
1323 static int Reset ( SMap* pSMap, int iReset ) {
1325 dev9IntrDisable ( INTR_BITMSK );
1326 SMap_ClearIRQ ( INTR_BITMSK );
1328 SMAP_REG8( pSMap, SMAP_BD_MODE ) = 0;
1330 FIFOReset ( pSMap );
1331 if (EMAC3Init ( pSMap, iReset ) < 0)
1333 return -1;
1336 return 0;
1337 } /* end Reset */
1339 static int
1340 GetNodeAddr(SMap* pSMap)
1342 int iA;
1343 u16 u16Sum = 0;
1344 u16 u16MAC[4];
1346 mips_memset(pSMap->au8HWAddr, 0, 6);
1348 if ((dev9GetEEPROM(&u16MAC[0]) < 0) || (!u16MAC[0] && !u16MAC[1] && !u16MAC[2]))
1349 return -1;
1351 for (iA=0; iA<3; iA++)
1352 u16Sum += u16MAC[iA];
1354 if (u16Sum != u16MAC[3])
1355 return -1;
1357 mips_memcpy(pSMap->au8HWAddr, &u16MAC[0], 6);
1359 return 0;
1362 static void BaseInit ( SMap* apSMap ) {
1364 apSMap -> pu8Base = ( u8 volatile* )SMAP_BASE;
1365 apSMap -> TX.pBD = ( SMapBD* )( apSMap -> pu8Base + SMAP_BD_BASE_TX );
1366 apSMap -> pRXBD = ( SMapBD* )( apSMap -> pu8Base + SMAP_BD_BASE_RX );
1368 } /* end BaseInit */
1370 u8 const*
1371 SMap_GetMACAddress(void)
1373 SMap* pSMap=&SMap0;
1375 return pSMap->au8HWAddr;
1378 int SMap_GetIRQ ( void ) {
1379 SMap* pSMap=&SMap0;
1381 return SMAP_REG16(pSMap,SMAP_INTR_STAT)&INTR_BITMSK;
1385 void
1386 SMap_ClearIRQ(int iFlags)
1388 SMap* pSMap=&SMap0;
1390 SMAP_REG16(pSMap,SMAP_INTR_CLR)=iFlags&INTR_BITMSK;
1391 if (iFlags&INTR_EMAC3)
1393 EMAC3REG_WRITE(pSMap,SMAP_EMAC3_INTR_STAT,E3_INTR_ALL);
1399 SMap_Init(void)
1401 SMap* pSMap=&SMap0;
1403 mips_memset(pSMap,0,sizeof(*pSMap));
1405 BaseInit(pSMap);
1406 if (GetNodeAddr(pSMap)<0)
1408 return FALSE;
1411 if (Reset(pSMap,RESET_INIT) < 0)
1413 return FALSE;
1416 TXRXEnable(pSMap,DISABLE);
1418 pSMap -> TX.u16PTRStart = 0;
1419 pSMap -> TX.u16PTREnd = 0;
1420 pSMap -> TX.u8IndexStart = 0;
1421 pSMap -> TX.u8IndexEnd = 0;
1422 pSMap -> u16RXPTR = 0;
1423 pSMap -> u8RXIndex = 0;
1424 _smap_bd_init ();
1426 if (pSMap->u32Flags&SMAP_F_PRINT_MSG)
1428 dbgprintf("SMap_Init: PlayStation 2 SMAP open\n");
1431 if (!(pSMap->u32Flags&SMAP_F_LINKVALID))
1433 dbgprintf("SMap_Init: Waiting for link to stabilize...\n");
1434 // XXX: we have to add a linkvalid thread (chk linux smap.c)!!!!
1435 // while (!(smap->u32Flags & SMAP_F_LINKVALID)) {
1436 // delay();
1438 FIFOReset(pSMap);
1439 EMAC3ReInit(pSMap);
1440 pSMap -> TX.u16PTRStart = 0;
1441 pSMap -> TX.u16PTREnd = 0;
1442 pSMap -> TX.u8IndexStart = 0;
1443 pSMap -> TX.u8IndexEnd = 0;
1444 pSMap -> u16RXPTR = 0;
1445 pSMap -> u8RXIndex = 0;
1446 _smap_bd_init ();
1447 return TRUE;
1451 void
1452 SMap_Start(void)
1454 SMap* pSMap=&SMap0;
1456 if (pSMap->u32Flags&SMAP_F_OPENED)
1458 return;
1461 SMap_ClearIRQ(INTR_BITMSK);
1462 TXRXEnable(pSMap,ENABLE);
1463 dev9IntrEnable ( INTR_BITMSK );
1465 pSMap->u32Flags|=SMAP_F_OPENED;
1469 void
1470 SMap_Stop(void)
1472 SMap* pSMap=&SMap0;
1474 TXRXEnable(pSMap,DISABLE);
1476 dev9IntrDisable(INTR_BITMSK);
1477 SMap_ClearIRQ(INTR_BITMSK);
1479 pSMap->u32Flags&=~SMAP_F_OPENED;
1482 extern void SMAP_CopyToFIFO ( SMap*, u32*, int );
1484 static int inline IsEMACReady ( SMap* apSMap ) {
1485 return !( EMAC3REG_READ( apSMap, SMAP_EMAC3_TxMODE0 ) & E3_TX_GNP_0 );
1486 } /* end IsEMACReady */
1488 SMapStatus SMap_Send ( struct pbuf* apPacket ) {
1490 static u32 sl_TXBuf[ ( SMAP_TXMAXSIZE + SMAP_TXMAXTAILPAD + 3 ) / 4 ];
1492 SMap* lpSMap = &SMap0;
1493 SMapBD* pTXBD = &lpSMap -> TX.pBD[ lpSMap -> TX.u8IndexEnd ];
1494 int iTotalLen = apPacket -> tot_len;
1495 int lTXLen;
1496 u32* lpSrc;
1498 if ( !( lpSMap -> u32Flags & SMAP_F_LINKVALID ) ) return SMap_Con;
1500 if ( iTotalLen > SMAP_TXMAXSIZE ) return SMap_Err;
1502 lTXLen = ( iTotalLen + 3 ) & ~3;
1504 if ( lTXLen > ComputeFreeSize ( &lpSMap -> TX ) ) return SMap_TX;
1505 if ( !IsEMACReady ( lpSMap ) ) return SMap_TX;
1507 if ( !apPacket -> next )
1508 lpSrc = apPacket -> payload;
1509 else {
1510 u8* lpDst = ( u8* )sl_TXBuf;
1511 while ( apPacket ) {
1512 int lLen = apPacket -> len;
1513 mips_memcpy ( lpDst, apPacket -> payload, lLen );
1514 lpDst += apPacket -> len;
1515 apPacket = apPacket -> next;
1516 } /* end while */
1517 lpSrc = sl_TXBuf;
1518 } /* end else */
1520 SMAP_CopyToFIFO ( lpSMap, lpSrc, lTXLen );
1522 pTXBD -> length = iTotalLen;
1523 pTXBD -> pointer = lpSMap -> TX.u16PTREnd + SMAP_TXBUFBASE;
1524 SMAP_REG8( lpSMap, SMAP_TXFIFO_FRAME_INC ) = 1;
1525 pTXBD -> ctrl_stat = SMAP_BD_TX_READY | SMAP_BD_TX_GENFCS | SMAP_BD_TX_GENPAD;
1526 EMAC3REG_WRITE( lpSMap, SMAP_EMAC3_TxMODE0, E3_TX_GNP_0 );
1528 lpSMap -> TX.u16PTREnd = ( lpSMap -> TX.u16PTREnd + lTXLen ) % SMAP_TXBUFSIZE;
1529 SMAP_BD_NEXT( lpSMap -> TX.u8IndexEnd );
1531 return SMap_OK;
1533 } /* end SMap_Send */
1535 int SMap_HandleTXInterrupt ( int iFlags ) {
1537 SMap* lpSMap = &SMap0;
1538 int iNoError = 1;
1540 SMap_ClearIRQ ( iFlags );
1542 while ( lpSMap -> TX.u8IndexStart != lpSMap -> TX.u8IndexEnd ) {
1544 SMapBD* pBD = &lpSMap -> TX.pBD[ lpSMap -> TX.u8IndexStart ];
1545 int iStatus = pBD -> ctrl_stat;
1547 if ( iStatus & SMAP_BD_TX_ERRMASK ) iNoError = 0;
1548 if ( iStatus & SMAP_BD_TX_READY ) goto end;
1550 lpSMap -> TX.u16PTRStart = ( lpSMap -> TX.u16PTRStart + ( ( pBD -> length + 3 ) & ~3 ) ) % SMAP_TXBUFSIZE;
1551 SMAP_BD_NEXT( lpSMap -> TX.u8IndexStart );
1553 pBD -> length = 0;
1554 pBD -> pointer = 0;
1555 pBD -> ctrl_stat = 0;
1557 } /* end while */
1559 lpSMap -> TX.u16PTRStart = lpSMap -> TX.u16PTREnd;
1560 end:
1561 return iNoError;
1563 } /* end SMap_HandleTXInterrupt */
1565 int SMap_HandleRXEMACInterrupt ( int iFlags ) {
1567 int iNoError = 1;
1568 SMap* lpSMap = &SMap0;
1570 if ( iFlags & ( INTR_RXDNV | INTR_RXEND ) ) {
1572 iFlags &= INTR_RXDNV | INTR_RXEND;
1573 SMap_ClearIRQ ( iFlags );
1575 while ( 1 ) {
1577 SMapBD* pRXBD = &lpSMap -> pRXBD[ lpSMap -> u8RXIndex ];
1578 int iStatus = pRXBD -> ctrl_stat;
1579 int iPKTLen;
1581 if ( iStatus & SMAP_BD_RX_EMPTY ) break;
1583 iPKTLen = pRXBD -> length;
1585 if ( !( iStatus & SMAP_BD_RX_ERRMASK ) && ( iPKTLen >= SMAP_RXMINSIZE && iPKTLen <= SMAP_RXMAXSIZE ) ) {
1587 struct pbuf* pBuf = ( struct pbuf* )pbuf_alloc ( PBUF_RAW, iPKTLen, PBUF_POOL );
1589 if ( pBuf ) {
1591 lpSMap -> u16RXPTR = ( ( pRXBD -> pointer - SMAP_RXBUFBASE ) % SMAP_RXBUFSIZE ) & ~3;
1593 SMAP_CopyFromFIFO ( lpSMap, pBuf );
1595 ps2ip_input ( pBuf, &NIF );
1597 } else iNoError = 0;
1599 } else iNoError = 0;
1601 SMAP_REG8( lpSMap, SMAP_RXFIFO_FRAME_DEC ) = 1;
1602 pRXBD -> ctrl_stat = SMAP_BD_RX_EMPTY;
1603 SMAP_BD_NEXT( lpSMap -> u8RXIndex );
1605 } /* end while */
1607 iFlags = SMap_GetIRQ ();
1609 } /* end if */
1611 if ( iFlags & INTR_EMAC3 ) {
1613 u32 lSts = EMAC3REG_READ( lpSMap, SMAP_EMAC3_INTR_STAT );
1615 EMAC3REG_WRITE( lpSMap, SMAP_EMAC3_INTR_STAT, lSts );
1616 SMap_ClearIRQ ( INTR_EMAC3 );
1618 } /* end if */
1620 return iNoError;
1622 } /* end SMap_HandleRXEMACInterrupt */