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
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).
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)
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
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
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)
110 #define SMAP_BD_RX_EMPTY (1<<15) //set:driver, clear:HW
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| \
132 u16 reserved
; //Must be zero
133 u16 length
; //Number of bytes in pkt
137 typedef struct smapbd
volatile SMapBD
;
140 typedef struct SMapCircularBuffer
152 u8
volatile* pu8Base
;
160 #ifndef FORCE_100M_FD
161 struct SMapPhySpecific
*phy_specific
;
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
*);
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
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
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 */
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
);
480 static int __ForceSPD100M_FD(SMap
* pSMap
);
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
);
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
,
513 static struct SMapPhySpecific STEPHY1_phy
= {
514 STEPHY1_get_link_status
,
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 /*--------------------------------------------------------------------------*/
550 TXRXEnable(SMap
* pSMap
,int iEnable
)
557 EMAC3REG_WRITE(pSMap
,SMAP_EMAC3_MODE0
,E3_TXMAC_ENABLE
|E3_RXMAC_ENABLE
);
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
))
578 dbgprintf("TXRXEnable: EMAC3 is still running(%x).\n",u32Val
);
582 extern void _smap_phy_write ( int, int );
588 "_smap_phy_write:\n\t"
589 "addiu $sp, $sp, -12\n\t"
590 "andi $a0, $a0, 0x1F\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"
599 "or $a0, $a0, $a1\n\t"
600 "addiu $s1, $zero, 100\n\t"
606 "srl $a0, $a0, 16\n\t"
607 "andi $a0, $a0, 0x8000\n\t"
609 "addiu $s1, $s1, -1\n\t"
610 "jal DelayThread\n\t"
611 "addiu $a0, $zero, 1000\n\t"
619 "addiu $sp, $sp, 12\n\t"
625 extern int _smap_phy_read ( int );
631 "_smap_phy_read:\n\t"
632 "addiu $sp, $sp, -12\n\t"
633 "andi $a0, $a0, 0x1F\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"
641 "addiu $s1, $zero, 100\n\t"
647 "sll $v0, $a0, 16\n\t"
648 "srl $a0, $a0, 16\n\t"
649 "andi $a0, $a0, 0x8000\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"
657 "sll $a0, $a0, 16\n\t"
658 "srl $v0, $a0, 16\n\t"
664 "addiu $sp, $sp, 12\n\t"
670 extern void _smap_bd_init ( void );
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"
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"
690 "sh $zero, 2($v1)\n\t"
691 "sh $zero, 4($v1)\n\t"
692 "sh $zero, 6($v1)\n\t"
694 "addiu $v1, $v1, 8\n\t"
703 FIFOReset(SMap
* pSMap
)
710 SMAP_REG8(pSMap
,SMAP_TXFIFO_CTRL
)=TXFIFO_RESET
;
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
))
730 for (iA
=SMAP_LOOP_COUNT
;iA
!=0;--iA
)
732 if (!(SMAP_REG8(pSMap
,SMAP_RXFIFO_CTRL
)&RXFIFO_RESET
))
745 EMAC3SoftReset(SMap
* pSMap
)
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
))
757 dbgprintf("EMAC3SoftReset: EMAC3 reset is in progress\n");
763 EMAC3SetDefValue(SMap
* pSMap
)
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]));
773 EMAC3REG_WRITE(pSMap
,SMAP_EMAC3_INTER_FRAME_GAP
,4);
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
);
799 EMAC3Init(SMap
* pSMap
,int iReset
)
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
|
813 if (PhyInit(pSMap
,iReset
)<0)
815 dbgprintf("EMAC3Init: Phy init error\n");
819 //This flag may be set when unloading
826 dev9IntrDisable ( INTR_BITMSK
);
828 SMap_ClearIRQ(INTR_BITMSK
);
830 //Permanently set to default value.
832 EMAC3SetDefValue(pSMap
);
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
);
857 iVal
= __ForceSPD100M_FD(pSMap
);
858 if ( iVal
< 0 ) return iVal
;
860 iVal
= AutoNegotiation ( pSMap
, DISABLE
);
864 pSMap
-> u32Flags
|= SMAP_F_LINKESTABLISH
;
871 ForceSPD100M ( pSMap
);
878 static int PhyReset ( SMap
* pSMap
) {
882 _smap_phy_write ( DsPHYTER_BMCR
, PHY_BMCR_RST
| PHY_BMCR_100M
| PHY_BMCR_ANEN
| PHY_BMCR_DUPM
);
886 for ( i
= SMAP_LOOP_COUNT
; i
; --i
) {
888 if ( !( _smap_phy_read ( DsPHYTER_BMCR
) & PHY_BMCR_RST
) ) return 0;
898 #ifndef FORCE_100M_FD
900 PhySetSpecific(SMap
* pSMap
)
904 iID1
= _smap_phy_read ( DsPHYTER_PHYIDR1
);
908 pSMap
->phy_specific
= &DsPHYTER_phy
;
911 case STEPHY1_IDR1_VAL
:
913 pSMap
->phy_specific
= &STEPHY1_phy
;
918 pSMap
->phy_specific
= NULL
;
925 AutoNegotiation(SMap
* pSMap
,int iEnableAutoNego
)
931 _smap_phy_write ( DsPHYTER_BMCR
,PHY_BMCR_100M
|PHY_BMCR_ANEN
|PHY_BMCR_DUPM
);
934 if (ConfirmAutoNegotiation(pSMap
)>=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)
952 #ifndef FORCE_100M_FD
954 ConfirmAutoNegotiation(SMap
* pSMap
)
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
))
969 if (iPhyVal
& PHY_BMSR_ANCP
)
973 DelayThread(1000); //wait 1ms
980 // **ARGH: UGLY HACK! FIXME! **
981 spdrev
= SMAP_REG16(pSMap
, SPD_R_REV_1
);
985 dbgprintf("Disabling autonegotiation sync on v12 - seems to work anyway - beware, hack inside.\n");
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
))
995 if ((iPhyVal
& PHY_BMSR_ANCP
) && link_up_flag
== 1) {
996 speed_100m_flag
= PhyGetSpeed(pSMap
);
997 full_duplex_flag
= PhyGetDuplex(pSMap
);
1005 dbgprintf("ConfirmAutoNegotiation: Auto-negotiation error?? (BMSR=%x, link_up_flag=%d)\n", iPhyVal
, link_up_flag
);
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
)
1017 u32E3Val
|=(E3_FDX_ENABLE
|E3_FLOWCTRL_ENABLE
|E3_ALLOW_PF
);
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
);
1037 DsPHYTER_get_link_status(SMap
* pSMap
)
1041 iPhyVal
= _smap_phy_read(DsPHYTER_PHYSTS
);
1043 if (iPhyVal
& PHY_STS_LINK
)
1050 DsPHYTER_get_speed(SMap
* pSMap
)
1054 iPhyVal
= _smap_phy_read(DsPHYTER_PHYSTS
);
1056 if (iPhyVal
& PHY_STS_100M
)
1063 DsPHYTER_get_duplex(SMap
* pSMap
)
1067 iPhyVal
= _smap_phy_read(DsPHYTER_PHYSTS
);
1069 if (iPhyVal
& PHY_STS_FDX
)
1076 STEPHY1_get_link_status(SMap
* pSMap
)
1080 iPhyVal
= _smap_phy_read(STEPHY1_XCIIS
);
1082 if (!(iPhyVal
& STEPHY1_XCIIS_LINK
))
1090 STEPHY1_get_speed(SMap
* pSMap
)
1094 iPhyVal
= _smap_phy_read(STEPHY1_XCIIS
);
1096 if (iPhyVal
& STEPHY1_XCIIS_100M
)
1103 STEPHY1_get_duplex(SMap
* pSMap
)
1107 iPhyVal
= _smap_phy_read(STEPHY1_XCIIS
);
1109 if (iPhyVal
& STEPHY1_XCIIS_FDX
)
1116 PhyGetSpeed(SMap
* pSMap
)
1118 return pSMap
->phy_specific
->get_speed(pSMap
);
1122 PhyGetDuplex(SMap
* pSMap
)
1124 return pSMap
->phy_specific
->get_duplex(pSMap
);
1128 #ifdef FORCE_100M_FD
1129 static int __ForceSPD100M_FD(SMap
* pSMap
)
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
)
1146 _smap_phy_write(DsPHYTER_BMCR
, PHY_BMCR_100M
|PHY_BMCR_DUPM
);
1147 pSMap
->u32Flags
|= SMAP_F_CHECK_FORCE100M
;
1149 iA
= SMAP_FORCEMODE_WAIT
;
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
;
1167 #ifndef FORCE_100M_FD
1168 static void ForceSPD100M ( SMap
* apSMap
) {
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 */
1183 #ifndef FORCE_100M_FD
1185 ForceSPD10M(SMap
* pSMap
)
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
)
1196 ConfirmForceSPD(pSMap
);
1200 #ifndef FORCE_100M_FD
1202 ConfirmForceSPD(SMap
* pSMap
)
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
)
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
;
1245 if (pSMap
->u32Flags
&SMAP_F_CHECK_FORCE100M
)
1247 pSMap
->u32Flags
&=~SMAP_F_CHECK_FORCE100M
;
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
)
1260 pSMap
->u32Flags
|=SMAP_F_CHECK_FORCE10M
;
1268 PhySetDSP(SMap
* pSMap
)
1274 if (!(pSMap
->u32Flags
&SMAP_F_LINKESTABLISH
))
1277 //Link not established.
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
;
1295 if (iID1
== STEPHY1_IDR1_VAL
)
1297 pSMap
->u32Flags
|=SMAP_F_LINKVALID
;
1301 if (pSMap
->u32Flags
&SMAP_F_LINKVALID
)
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)
1340 GetNodeAddr(SMap
* pSMap
)
1346 mips_memset(pSMap
->au8HWAddr
, 0, 6);
1348 if ((dev9GetEEPROM(&u16MAC
[0]) < 0) || (!u16MAC
[0] && !u16MAC
[1] && !u16MAC
[2]))
1351 for (iA
=0; iA
<3; iA
++)
1352 u16Sum
+= u16MAC
[iA
];
1354 if (u16Sum
!= u16MAC
[3])
1357 mips_memcpy(pSMap
->au8HWAddr
, &u16MAC
[0], 6);
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 */
1371 SMap_GetMACAddress(void)
1375 return pSMap
->au8HWAddr
;
1378 int SMap_GetIRQ ( void ) {
1381 return SMAP_REG16(pSMap
,SMAP_INTR_STAT
)&INTR_BITMSK
;
1386 SMap_ClearIRQ(int iFlags
)
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
);
1403 mips_memset(pSMap
,0,sizeof(*pSMap
));
1406 if (GetNodeAddr(pSMap
)<0)
1411 if (Reset(pSMap
,RESET_INIT
) < 0)
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;
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)) {
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;
1456 if (pSMap
->u32Flags
&SMAP_F_OPENED
)
1461 SMap_ClearIRQ(INTR_BITMSK
);
1462 TXRXEnable(pSMap
,ENABLE
);
1463 dev9IntrEnable ( INTR_BITMSK
);
1465 pSMap
->u32Flags
|=SMAP_F_OPENED
;
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
;
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
;
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
;
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
);
1533 } /* end SMap_Send */
1535 int SMap_HandleTXInterrupt ( int iFlags
) {
1537 SMap
* lpSMap
= &SMap0
;
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
);
1555 pBD
-> ctrl_stat
= 0;
1559 lpSMap
-> TX
.u16PTRStart
= lpSMap
-> TX
.u16PTREnd
;
1563 } /* end SMap_HandleTXInterrupt */
1565 int SMap_HandleRXEMACInterrupt ( int iFlags
) {
1568 SMap
* lpSMap
= &SMap0
;
1570 if ( iFlags
& ( INTR_RXDNV
| INTR_RXEND
) ) {
1572 iFlags
&= INTR_RXDNV
| INTR_RXEND
;
1573 SMap_ClearIRQ ( iFlags
);
1577 SMapBD
* pRXBD
= &lpSMap
-> pRXBD
[ lpSMap
-> u8RXIndex
];
1578 int iStatus
= pRXBD
-> ctrl_stat
;
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
);
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
);
1607 iFlags
= SMap_GetIRQ ();
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
);
1622 } /* end SMap_HandleRXEMACInterrupt */