3 #include <aros/debug.h>
4 #include <asm/amcc440.h>
8 void EMACIRQHandler(struct EMACBase
*EMACBase
, struct EMACUnit
*unit
)
12 D(bug("[EMAC%d] IRQ Handler\n", unit
->eu_UnitNum
));
16 void EMAC_Startup(struct EMACUnit
*unit
)
20 D(bug("[EMAC%d] Startup\n", unit
->eu_UnitNum
));
22 tmp
= inl((uint32_t*)(unit
->eu_IOBase
+ EMAC_IAH
));
24 unit
->eu_DevAddr
[0] = unit
->eu_OrgAddr
[0] = (tmp
>> 8) & 0xff;
25 unit
->eu_DevAddr
[1] = unit
->eu_OrgAddr
[1] = (tmp
>> 0) & 0xff;
27 tmp
= inl((uint32_t*)(unit
->eu_IOBase
+ EMAC_IAL
));
29 unit
->eu_DevAddr
[2] = unit
->eu_OrgAddr
[2] = (tmp
>> 24) & 0xff;
30 unit
->eu_DevAddr
[3] = unit
->eu_OrgAddr
[3] = (tmp
>> 16) & 0xff;
31 unit
->eu_DevAddr
[4] = unit
->eu_OrgAddr
[4] = (tmp
>> 8) & 0xff;
32 unit
->eu_DevAddr
[5] = unit
->eu_OrgAddr
[5] = (tmp
>> 0) & 0xff;
33 D(bug("[EMAC%d] HW addr=%02x:%02x:%02x:%02x:%02x:%02x\n", unit
->eu_UnitNum
,
34 unit
->eu_DevAddr
[0],unit
->eu_DevAddr
[1],
35 unit
->eu_DevAddr
[2],unit
->eu_DevAddr
[3],
36 unit
->eu_DevAddr
[4],unit
->eu_DevAddr
[5]));
39 int EMAC_miiphy_read(struct EMACUnit
*unit
, uint8_t reg
, uint16_t *value
)
41 unsigned long sta_reg
; /* STA scratch area */
44 /* see if it is ready for 1000 nsec */
47 /* see if it is ready for sec */
48 while ((inl (EMAC_STACR
+ unit
->eu_IOBase
) & EMAC_STACR_OC
) == EMAC_STACR_OC_MASK
) {
49 unit
->udelay (unit
, 7);
52 sta_reg
= inl (EMAC_STACR
+ unit
->eu_IOBase
);
53 bug ("[EMAC%d] read : EMAC_STACR=0x%0x\n", unit
->eu_UnitNum
, sta_reg
); /* test-only */
54 bug ("[EMAC%d] read err 1\n", unit
->eu_UnitNum
);
60 sta_reg
= reg
; /* reg address */
62 sta_reg
= (sta_reg
| EMAC_STACR_READ
) & ~EMAC_STACR_CLK_100MHZ
;
64 sta_reg
= sta_reg
| (unit
->eu_PHYAddr
<< 5); /* Phy address */
65 sta_reg
= sta_reg
| EMAC_STACR_OC_MASK
; /* new IBM emac v4 */
66 outl (sta_reg
, EMAC_STACR
+ unit
->eu_IOBase
);
67 D(bug("[EMAC%d] a2: write: EMAC_STACR=0x%0x\n", unit
->eu_UnitNum
, sta_reg
));
69 sta_reg
= inl (EMAC_STACR
+ unit
->eu_IOBase
);
70 D(bug("[EMAC%d] a21: read: EMAC_STACR=0x%0x\n", unit
->eu_UnitNum
, sta_reg
));
72 while ((sta_reg
& EMAC_STACR_OC
) == EMAC_STACR_OC_MASK
) {
73 unit
->udelay (unit
, 7);
78 sta_reg
= inl (EMAC_STACR
+ unit
->eu_IOBase
);
79 D(bug("[EMAC%d] a22: read: EMAC_STACR=0x%0x\n", unit
->eu_UnitNum
, sta_reg
));
81 if ((sta_reg
& EMAC_STACR_PHYE
) != 0) {
85 // *value = *(uint16_t *) (&sta_reg);
86 *value
= sta_reg
>> 16;
90 int EMAC_miiphy_write(struct EMACUnit
*unit
, uint8_t reg
, uint16_t value
)
92 unsigned long sta_reg
; /* STA scratch area */
95 /* see if it is ready for 1000 nsec */
98 while ((inl (EMAC_STACR
+ unit
->eu_IOBase
) & EMAC_STACR_OC
) == EMAC_STACR_OC_MASK
) {
101 unit
->udelay (unit
, 7);
105 sta_reg
= reg
; /* reg address */
107 sta_reg
= (sta_reg
| EMAC_STACR_WRITE
) & ~EMAC_STACR_CLK_100MHZ
;
109 sta_reg
= sta_reg
| ((unsigned long) unit
->eu_PHYAddr
<< 5);/* Phy address */
110 sta_reg
= sta_reg
| EMAC_STACR_OC_MASK
; /* new IBM emac v4 */
111 sta_reg
= ((uint32_t)(value
)) << 16 | sta_reg
;
112 // memcpy (&sta_reg, &value, 2); /* put in data */
114 outl (sta_reg
, EMAC_STACR
+ unit
->eu_IOBase
);
116 /* wait for completion */
118 sta_reg
= inl (EMAC_STACR
+ unit
->eu_IOBase
);
119 D(bug("[EMAC%d] a31: read : EMAC_STACR=0x%0x\n", unit
->eu_UnitNum
, sta_reg
));
121 while ((sta_reg
& EMAC_STACR_OC
) == EMAC_STACR_OC_MASK
) {
122 unit
->udelay (unit
, 7);
126 sta_reg
= inl (EMAC_STACR
+ unit
->eu_IOBase
);
127 D(bug("[EMAC%d] a32: read : EMAC_STACR=0x%0x\n", unit
->eu_UnitNum
, sta_reg
));
130 if ((sta_reg
& EMAC_STACR_PHYE
) != 0)
135 int EMAC_miiphy_reset(struct EMACUnit
*unit
)
140 if (EMAC_miiphy_read (unit
, PHY_BMCR
, ®
) != 0) {
141 D(bug("[EMAC%d] PHY status read failed\n", unit
->eu_UnitNum
));
144 if (EMAC_miiphy_write (unit
, PHY_BMCR
, reg
| 0x8000) != 0) {
145 D(bug("[EMAC%d] PHY reset failed\n", unit
->eu_UnitNum
));
149 unit
->udelay(unit
, 1000);
152 * Poll the control register for the reset bit to go to 0 (it is
153 * auto-clearing). This should happen within 0.5 seconds per the
158 while (((reg
& 0x8000) != 0) && (loop_cnt
++ < 1000000)) {
159 if (EMAC_miiphy_read (unit
, PHY_BMCR
, ®
) != 0) {
160 D(bug("[EMAC%d] PHY status read failed\n", unit
->eu_UnitNum
));
164 if ((reg
& 0x8000) == 0) {
167 D(bug("[EMAC%d] PHY reset timed out\n", unit
->eu_UnitNum
));
173 int EMAC_miiphy_speed(struct EMACUnit
*unit
)
175 uint16_t bmcr
, anlpar
;
177 /* Check Basic Management Control Register first. */
178 if (EMAC_miiphy_read (unit
, PHY_BMCR
, &bmcr
)) {
179 D(bug("[EMAC%d] PHY speed", unit
->eu_UnitNum
));
180 goto miiphy_read_failed
;
182 /* Check if auto-negotiation is on. */
183 if (bmcr
& PHY_BMCR_AUTON
) {
184 /* Get auto-negotiation results. */
185 if (EMAC_miiphy_read (unit
, PHY_ANLPAR
, &anlpar
)) {
186 D(bug("[EMAC%d] PHY AN speed", unit
->eu_UnitNum
));
187 goto miiphy_read_failed
;
189 return (anlpar
& PHY_ANLPAR_100
) ? _100BASET
: _10BASET
;
191 /* Get speed from basic control settings. */
192 return (bmcr
& PHY_BMCR_100MB
) ? _100BASET
: _10BASET
;
195 D(bug(" read failed, assuming 10BASE-T\n"));
199 int EMAC_miiphy_duplex(struct EMACUnit
*unit
)
201 uint16_t bmcr
, anlpar
;
203 /* Check Basic Management Control Register first. */
204 if (EMAC_miiphy_read(unit
, PHY_BMCR
, &bmcr
)) {
205 D(bug("[EMAC%d] PHY duplex", unit
->eu_UnitNum
));
206 goto miiphy_read_failed
;
208 /* Check if auto-negotiation is on. */
209 if (bmcr
& PHY_BMCR_AUTON
) {
210 /* Get auto-negotiation results. */
211 if (EMAC_miiphy_read(unit
, PHY_ANLPAR
, &anlpar
)) {
212 D(bug("[EMAC%d] PHY AN duplex", unit
->eu_UnitNum
));
213 goto miiphy_read_failed
;
215 return (anlpar
& (PHY_ANLPAR_10FD
| PHY_ANLPAR_TXFD
)) ?
218 /* Get speed from basic control settings. */
219 return (bmcr
& PHY_BMCR_DPLX
) ? FULL
: HALF
;
222 D(bug(" read failed, assuming half duplex\n"));
226 int EMAC_miiphy_link(struct EMACUnit
*unit
)
230 EMAC_miiphy_read(unit
, PHY_BMSR
, ®
);
231 if (EMAC_miiphy_read(unit
, PHY_BMSR
, ®
))
233 D(bug("[EMAC%d] PHY_BMSR read failed\n", unit
->eu_UnitNum
));
237 if (reg
& PHY_BMSR_LS
)
243 int EMAC_phy_setup_aneg (struct EMACUnit
*unit
)
245 unsigned short ctl
, adv
;
247 /* Setup standard advertise */
248 EMAC_miiphy_read (unit
, PHY_ANAR
, &adv
);
249 adv
|= (PHY_ANLPAR_ACK
| PHY_ANLPAR_RF
| PHY_ANLPAR_T4
|
250 PHY_ANLPAR_TXFD
| PHY_ANLPAR_TX
| PHY_ANLPAR_10FD
|
252 EMAC_miiphy_write (unit
, PHY_ANAR
, adv
);
254 EMAC_miiphy_read (unit
, PHY_1000BTCR
, &adv
);
256 EMAC_miiphy_write (unit
, PHY_1000BTCR
, adv
);
258 /* Start/Restart aneg */
259 EMAC_miiphy_read (unit
, PHY_BMCR
, &ctl
);
260 ctl
|= (PHY_BMCR_AUTON
| PHY_BMCR_RST_NEG
);
261 EMAC_miiphy_write (unit
, PHY_BMCR
, ctl
);