2 * Freescale Three Speed Ethernet Controller driver
4 * This software may be used and distributed according to the
5 * terms of the GNU Public License, Version 2, incorporated
8 * Copyright 2004, 2007 Freescale Semiconductor, Inc.
9 * (C) Copyright 2003, Motorola, Inc.
20 #if defined(CONFIG_TSEC_ENET)
24 DECLARE_GLOBAL_DATA_PTR
;
28 static uint rxIdx
; /* index of the current RX buffer */
29 static uint txIdx
; /* index of the current TX buffer */
31 typedef volatile struct rtxbd
{
32 txbd8_t txbd
[TX_BUF_CNT
];
33 rxbd8_t rxbd
[PKTBUFSRX
];
36 struct tsec_info_struct
{
39 unsigned int phyregidx
;
42 /* The tsec_info structure contains 3 values which the
43 * driver uses to determine how to operate a given ethernet
44 * device. The information needed is:
45 * phyaddr - The address of the PHY which is attached to
48 * flags - This variable indicates whether the device
49 * supports gigabit speed ethernet, and whether it should be
52 * phyregidx - This variable specifies which ethernet device
53 * controls the MII Management registers which are connected
54 * to the PHY. For now, only TSEC1 (index 0) has
55 * access to the PHYs, so all of the entries have "0".
57 * The values specified in the table are taken from the board's
58 * config file in include/configs/. When implementing a new
59 * board with ethernet capability, it is necessary to define:
63 * for n = 1,2,3, etc. And for FEC:
67 static struct tsec_info_struct tsec_info
[] = {
68 #if defined(CONFIG_TSEC1)
69 #if defined(CONFIG_MPC8544DS) || defined(CONFIG_MPC8641HPCN)
70 {TSEC1_PHY_ADDR
, TSEC_GIGABIT
| TSEC_REDUCED
, TSEC1_PHYIDX
},
72 {TSEC1_PHY_ADDR
, TSEC_GIGABIT
, TSEC1_PHYIDX
},
76 #if defined(CONFIG_TSEC2)
77 #if defined(CONFIG_MPC8641HPCN)
78 {TSEC2_PHY_ADDR
, TSEC_GIGABIT
| TSEC_REDUCED
, TSEC2_PHYIDX
},
80 {TSEC2_PHY_ADDR
, TSEC_GIGABIT
, TSEC2_PHYIDX
},
84 #ifdef CONFIG_MPC85XX_FEC
85 {FEC_PHY_ADDR
, 0, FEC_PHYIDX
},
87 #if defined(CONFIG_TSEC3)
88 {TSEC3_PHY_ADDR
, TSEC_GIGABIT
| TSEC_REDUCED
, TSEC3_PHYIDX
},
92 #if defined(CONFIG_TSEC4)
93 {TSEC4_PHY_ADDR
, TSEC_GIGABIT
| TSEC_REDUCED
, TSEC4_PHYIDX
},
100 #define MAXCONTROLLERS (4)
102 static int relocated
= 0;
104 static struct tsec_private
*privlist
[MAXCONTROLLERS
];
107 static RTXBD rtx
__attribute__ ((aligned(8)));
109 #error "rtx must be 64-bit aligned"
112 static int tsec_send(struct eth_device
*dev
,
113 volatile void *packet
, int length
);
114 static int tsec_recv(struct eth_device
*dev
);
115 static int tsec_init(struct eth_device
*dev
, bd_t
* bd
);
116 static void tsec_halt(struct eth_device
*dev
);
117 static void init_registers(volatile tsec_t
* regs
);
118 static void startup_tsec(struct eth_device
*dev
);
119 static int init_phy(struct eth_device
*dev
);
120 void write_phy_reg(struct tsec_private
*priv
, uint regnum
, uint value
);
121 uint
read_phy_reg(struct tsec_private
*priv
, uint regnum
);
122 struct phy_info
*get_phy_info(struct eth_device
*dev
);
123 void phy_run_commands(struct tsec_private
*priv
, struct phy_cmd
*cmd
);
124 static void adjust_link(struct eth_device
*dev
);
125 static void relocate_cmds(void);
126 static int tsec_miiphy_write(char *devname
, unsigned char addr
,
127 unsigned char reg
, unsigned short value
);
128 static int tsec_miiphy_read(char *devname
, unsigned char addr
,
129 unsigned char reg
, unsigned short *value
);
131 /* Initialize device structure. Returns success if PHY
132 * initialization succeeded (i.e. if it recognizes the PHY)
134 int tsec_initialize(bd_t
* bis
, int index
, char *devname
)
136 struct eth_device
*dev
;
138 struct tsec_private
*priv
;
140 dev
= (struct eth_device
*)malloc(sizeof *dev
);
145 memset(dev
, 0, sizeof *dev
);
147 priv
= (struct tsec_private
*)malloc(sizeof(*priv
));
152 privlist
[index
] = priv
;
153 priv
->regs
= (volatile tsec_t
*)(TSEC_BASE_ADDR
+ index
* TSEC_SIZE
);
154 priv
->phyregs
= (volatile tsec_t
*)(TSEC_BASE_ADDR
+
155 tsec_info
[index
].phyregidx
*
158 priv
->phyaddr
= tsec_info
[index
].phyaddr
;
159 priv
->flags
= tsec_info
[index
].flags
;
161 sprintf(dev
->name
, devname
);
164 dev
->init
= tsec_init
;
165 dev
->halt
= tsec_halt
;
166 dev
->send
= tsec_send
;
167 dev
->recv
= tsec_recv
;
169 /* Tell u-boot to get the addr from the env */
170 for (i
= 0; i
< 6; i
++)
171 dev
->enetaddr
[i
] = 0;
176 priv
->regs
->maccfg1
|= MACCFG1_SOFT_RESET
;
177 priv
->regs
->maccfg1
&= ~(MACCFG1_SOFT_RESET
);
179 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) \
180 && !defined(BITBANGMII)
181 miiphy_register(dev
->name
, tsec_miiphy_read
, tsec_miiphy_write
);
184 /* Try to initialize PHY here, and return */
185 return init_phy(dev
);
188 /* Initializes data structures and registers for the controller,
189 * and brings the interface up. Returns the link status, meaning
190 * that it returns success if the link is up, failure otherwise.
191 * This allows u-boot to find the first active controller.
193 int tsec_init(struct eth_device
*dev
, bd_t
* bd
)
196 char tmpbuf
[MAC_ADDR_LEN
];
198 struct tsec_private
*priv
= (struct tsec_private
*)dev
->priv
;
199 volatile tsec_t
*regs
= priv
->regs
;
201 /* Make sure the controller is stopped */
204 /* Init MACCFG2. Defaults to GMII */
205 regs
->maccfg2
= MACCFG2_INIT_SETTINGS
;
208 regs
->ecntrl
= ECNTRL_INIT_SETTINGS
;
210 /* Copy the station address into the address registers.
211 * Backwards, because little endian MACS are dumb */
212 for (i
= 0; i
< MAC_ADDR_LEN
; i
++) {
213 tmpbuf
[MAC_ADDR_LEN
- 1 - i
] = dev
->enetaddr
[i
];
215 regs
->macstnaddr1
= *((uint
*) (tmpbuf
));
217 tempval
= *((uint
*) (tmpbuf
+ 4));
219 regs
->macstnaddr2
= tempval
;
221 /* reset the indices to zero */
225 /* Clear out (for the most part) the other registers */
226 init_registers(regs
);
228 /* Ready the device for tx/rx */
231 /* If there's no link, fail */
236 /* Write value to the device's PHY through the registers
237 * specified in priv, modifying the register specified in regnum.
238 * It will wait for the write to be done (or for a timeout to
239 * expire) before exiting
241 void write_phy_reg(struct tsec_private
*priv
, uint regnum
, uint value
)
243 volatile tsec_t
*regbase
= priv
->phyregs
;
244 uint phyid
= priv
->phyaddr
;
245 int timeout
= 1000000;
247 regbase
->miimadd
= (phyid
<< 8) | regnum
;
248 regbase
->miimcon
= value
;
252 while ((regbase
->miimind
& MIIMIND_BUSY
) && timeout
--) ;
255 /* Reads register regnum on the device's PHY through the
256 * registers specified in priv. It lowers and raises the read
257 * command, and waits for the data to become valid (miimind
258 * notvalid bit cleared), and the bus to cease activity (miimind
259 * busy bit cleared), and then returns the value
261 uint
read_phy_reg(struct tsec_private
*priv
, uint regnum
)
264 volatile tsec_t
*regbase
= priv
->phyregs
;
265 uint phyid
= priv
->phyaddr
;
267 /* Put the address of the phy, and the register
268 * number into MIIMADD */
269 regbase
->miimadd
= (phyid
<< 8) | regnum
;
271 /* Clear the command register, and wait */
272 regbase
->miimcom
= 0;
275 /* Initiate a read command, and wait */
276 regbase
->miimcom
= MIIM_READ_COMMAND
;
279 /* Wait for the the indication that the read is done */
280 while ((regbase
->miimind
& (MIIMIND_NOTVALID
| MIIMIND_BUSY
))) ;
282 /* Grab the value read from the PHY */
283 value
= regbase
->miimstat
;
288 /* Discover which PHY is attached to the device, and configure it
289 * properly. If the PHY is not recognized, then return 0
290 * (failure). Otherwise, return 1
292 static int init_phy(struct eth_device
*dev
)
294 struct tsec_private
*priv
= (struct tsec_private
*)dev
->priv
;
295 struct phy_info
*curphy
;
296 volatile tsec_t
*regs
= (volatile tsec_t
*)(TSEC_BASE_ADDR
);
298 /* Assign a Physical address to the TBI */
299 regs
->tbipa
= TBIPA_VALUE
;
300 regs
= (volatile tsec_t
*)(TSEC_BASE_ADDR
+ TSEC_SIZE
);
301 regs
->tbipa
= TBIPA_VALUE
;
304 /* Reset MII (due to new addresses) */
305 priv
->phyregs
->miimcfg
= MIIMCFG_RESET
;
307 priv
->phyregs
->miimcfg
= MIIMCFG_INIT_VALUE
;
309 while (priv
->phyregs
->miimind
& MIIMIND_BUSY
) ;
314 /* Get the cmd structure corresponding to the attached
316 curphy
= get_phy_info(dev
);
318 if (curphy
== NULL
) {
319 priv
->phyinfo
= NULL
;
320 printf("%s: No PHY found\n", dev
->name
);
325 priv
->phyinfo
= curphy
;
327 phy_run_commands(priv
, priv
->phyinfo
->config
);
333 * Returns which value to write to the control register.
334 * For 10/100, the value is slightly different
336 uint
mii_cr_init(uint mii_reg
, struct tsec_private
* priv
)
338 if (priv
->flags
& TSEC_GIGABIT
)
339 return MIIM_CONTROL_INIT
;
344 /* Parse the status register for link, and then do
347 uint
mii_parse_sr(uint mii_reg
, struct tsec_private
* priv
)
350 * Wait if PHY is capable of autonegotiation and autonegotiation
353 mii_reg
= read_phy_reg(priv
, MIIM_STATUS
);
354 if ((mii_reg
& PHY_BMSR_AUTN_ABLE
)
355 && !(mii_reg
& PHY_BMSR_AUTN_COMP
)) {
358 puts("Waiting for PHY auto negotiation to complete");
359 while (!((mii_reg
& PHY_BMSR_AUTN_COMP
)
360 && (mii_reg
& MIIM_STATUS_LINK
))) {
364 if (i
> PHY_AUTONEGOTIATE_TIMEOUT
) {
365 puts(" TIMEOUT !\n");
370 if ((i
++ % 1000) == 0) {
373 udelay(1000); /* 1 ms */
374 mii_reg
= read_phy_reg(priv
, MIIM_STATUS
);
378 udelay(500000); /* another 500 ms (results in faster booting) */
386 /* Generic function which updates the speed and duplex. If
387 * autonegotiation is enabled, it uses the AND of the link
388 * partner's advertised capabilities and our advertised
389 * capabilities. If autonegotiation is disabled, we use the
390 * appropriate bits in the control register.
392 * Stolen from Linux's mii.c and phy_device.c
394 uint
mii_parse_link(uint mii_reg
, struct tsec_private
*priv
)
396 /* We're using autonegotiation */
397 if (mii_reg
& PHY_BMSR_AUTN_ABLE
) {
401 /* Check for gigabit capability */
402 if (mii_reg
& PHY_BMSR_EXT
) {
403 /* We want a list of states supported by
404 * both PHYs in the link
406 gblpa
= read_phy_reg(priv
, PHY_1000BTSR
);
407 gblpa
&= read_phy_reg(priv
, PHY_1000BTCR
) << 2;
410 /* Set the baseline so we only have to set them
411 * if they're different
416 /* Check the gigabit fields */
417 if (gblpa
& (PHY_1000BTSR_1000FD
| PHY_1000BTSR_1000HD
)) {
420 if (gblpa
& PHY_1000BTSR_1000FD
)
427 lpa
= read_phy_reg(priv
, PHY_ANAR
);
428 lpa
&= read_phy_reg(priv
, PHY_ANLPAR
);
430 if (lpa
& (PHY_ANLPAR_TXFD
| PHY_ANLPAR_TX
)) {
433 if (lpa
& PHY_ANLPAR_TXFD
)
436 } else if (lpa
& PHY_ANLPAR_10FD
)
439 uint bmcr
= read_phy_reg(priv
, PHY_BMCR
);
444 if (bmcr
& PHY_BMCR_DPLX
)
447 if (bmcr
& PHY_BMCR_1000_MBPS
)
449 else if (bmcr
& PHY_BMCR_100_MBPS
)
457 * Parse the BCM54xx status register for speed and duplex information.
458 * The linux sungem_phy has this information, but in a table format.
460 uint
mii_parse_BCM54xx_sr(uint mii_reg
, struct tsec_private
*priv
)
463 switch((mii_reg
& MIIM_BCM54xx_AUXSTATUS_LINKMODE_MASK
) >> MIIM_BCM54xx_AUXSTATUS_LINKMODE_SHIFT
){
466 printf("Enet starting in 10BT/HD\n");
472 printf("Enet starting in 10BT/FD\n");
478 printf("Enet starting in 100BT/HD\n");
484 printf("Enet starting in 100BT/FD\n");
490 printf("Enet starting in 1000BT/HD\n");
496 printf("Enet starting in 1000BT/FD\n");
502 printf("Auto-neg error, defaulting to 10BT/HD\n");
511 /* Parse the 88E1011's status register for speed and duplex
514 uint
mii_parse_88E1011_psr(uint mii_reg
, struct tsec_private
* priv
)
518 mii_reg
= read_phy_reg(priv
, MIIM_88E1011_PHY_STATUS
);
520 if (!((mii_reg
& MIIM_88E1011_PHYSTAT_SPDDONE
) &&
521 (mii_reg
& MIIM_88E1011_PHYSTAT_LINK
))) {
524 puts("Waiting for PHY realtime link");
525 while (!((mii_reg
& MIIM_88E1011_PHYSTAT_SPDDONE
) &&
526 (mii_reg
& MIIM_88E1011_PHYSTAT_LINK
))) {
530 if (i
> PHY_AUTONEGOTIATE_TIMEOUT
) {
531 puts(" TIMEOUT !\n");
536 if ((i
++ % 1000) == 0) {
539 udelay(1000); /* 1 ms */
540 mii_reg
= read_phy_reg(priv
, MIIM_88E1011_PHY_STATUS
);
543 udelay(500000); /* another 500 ms (results in faster booting) */
546 if (mii_reg
& MIIM_88E1011_PHYSTAT_DUPLEX
)
551 speed
= (mii_reg
& MIIM_88E1011_PHYSTAT_SPEED
);
554 case MIIM_88E1011_PHYSTAT_GBIT
:
557 case MIIM_88E1011_PHYSTAT_100
:
567 /* Parse the cis8201's status register for speed and duplex
570 uint
mii_parse_cis8201(uint mii_reg
, struct tsec_private
* priv
)
574 if (mii_reg
& MIIM_CIS8201_AUXCONSTAT_DUPLEX
)
579 speed
= mii_reg
& MIIM_CIS8201_AUXCONSTAT_SPEED
;
581 case MIIM_CIS8201_AUXCONSTAT_GBIT
:
584 case MIIM_CIS8201_AUXCONSTAT_100
:
595 /* Parse the vsc8244's status register for speed and duplex
598 uint
mii_parse_vsc8244(uint mii_reg
, struct tsec_private
* priv
)
602 if (mii_reg
& MIIM_VSC8244_AUXCONSTAT_DUPLEX
)
607 speed
= mii_reg
& MIIM_VSC8244_AUXCONSTAT_SPEED
;
609 case MIIM_VSC8244_AUXCONSTAT_GBIT
:
612 case MIIM_VSC8244_AUXCONSTAT_100
:
623 /* Parse the DM9161's status register for speed and duplex
626 uint
mii_parse_dm9161_scsr(uint mii_reg
, struct tsec_private
* priv
)
628 if (mii_reg
& (MIIM_DM9161_SCSR_100F
| MIIM_DM9161_SCSR_100H
))
633 if (mii_reg
& (MIIM_DM9161_SCSR_100F
| MIIM_DM9161_SCSR_10F
))
642 * Hack to write all 4 PHYs with the LED values
644 uint
mii_cis8204_fixled(uint mii_reg
, struct tsec_private
* priv
)
647 volatile tsec_t
*regbase
= priv
->phyregs
;
648 int timeout
= 1000000;
650 for (phyid
= 0; phyid
< 4; phyid
++) {
651 regbase
->miimadd
= (phyid
<< 8) | mii_reg
;
652 regbase
->miimcon
= MIIM_CIS8204_SLEDCON_INIT
;
656 while ((regbase
->miimind
& MIIMIND_BUSY
) && timeout
--) ;
659 return MIIM_CIS8204_SLEDCON_INIT
;
662 uint
mii_cis8204_setmode(uint mii_reg
, struct tsec_private
* priv
)
664 if (priv
->flags
& TSEC_REDUCED
)
665 return MIIM_CIS8204_EPHYCON_INIT
| MIIM_CIS8204_EPHYCON_RGMII
;
667 return MIIM_CIS8204_EPHYCON_INIT
;
670 /* Initialized required registers to appropriate values, zeroing
671 * those we don't care about (unless zero is bad, in which case,
672 * choose a more appropriate value)
674 static void init_registers(volatile tsec_t
* regs
)
677 regs
->ievent
= IEVENT_INIT_CLEAR
;
679 regs
->imask
= IMASK_INIT_CLEAR
;
681 regs
->hash
.iaddr0
= 0;
682 regs
->hash
.iaddr1
= 0;
683 regs
->hash
.iaddr2
= 0;
684 regs
->hash
.iaddr3
= 0;
685 regs
->hash
.iaddr4
= 0;
686 regs
->hash
.iaddr5
= 0;
687 regs
->hash
.iaddr6
= 0;
688 regs
->hash
.iaddr7
= 0;
690 regs
->hash
.gaddr0
= 0;
691 regs
->hash
.gaddr1
= 0;
692 regs
->hash
.gaddr2
= 0;
693 regs
->hash
.gaddr3
= 0;
694 regs
->hash
.gaddr4
= 0;
695 regs
->hash
.gaddr5
= 0;
696 regs
->hash
.gaddr6
= 0;
697 regs
->hash
.gaddr7
= 0;
699 regs
->rctrl
= 0x00000000;
701 /* Init RMON mib registers */
702 memset((void *)&(regs
->rmon
), 0, sizeof(rmon_mib_t
));
704 regs
->rmon
.cam1
= 0xffffffff;
705 regs
->rmon
.cam2
= 0xffffffff;
707 regs
->mrblr
= MRBLR_INIT_SETTINGS
;
709 regs
->minflr
= MINFLR_INIT_SETTINGS
;
711 regs
->attr
= ATTR_INIT_SETTINGS
;
712 regs
->attreli
= ATTRELI_INIT_SETTINGS
;
716 /* Configure maccfg2 based on negotiated speed and duplex
717 * reported by PHY handling code
719 static void adjust_link(struct eth_device
*dev
)
721 struct tsec_private
*priv
= (struct tsec_private
*)dev
->priv
;
722 volatile tsec_t
*regs
= priv
->regs
;
725 if (priv
->duplexity
!= 0)
726 regs
->maccfg2
|= MACCFG2_FULL_DUPLEX
;
728 regs
->maccfg2
&= ~(MACCFG2_FULL_DUPLEX
);
730 switch (priv
->speed
) {
732 regs
->maccfg2
= ((regs
->maccfg2
& ~(MACCFG2_IF
))
737 regs
->maccfg2
= ((regs
->maccfg2
& ~(MACCFG2_IF
))
740 /* Set R100 bit in all modes although
741 * it is only used in RGMII mode
743 if (priv
->speed
== 100)
744 regs
->ecntrl
|= ECNTRL_R100
;
746 regs
->ecntrl
&= ~(ECNTRL_R100
);
749 printf("%s: Speed was bad\n", dev
->name
);
753 printf("Speed: %d, %s duplex\n", priv
->speed
,
754 (priv
->duplexity
) ? "full" : "half");
757 printf("%s: No link.\n", dev
->name
);
761 /* Set up the buffers and their descriptors, and bring up the
764 static void startup_tsec(struct eth_device
*dev
)
767 struct tsec_private
*priv
= (struct tsec_private
*)dev
->priv
;
768 volatile tsec_t
*regs
= priv
->regs
;
770 /* Point to the buffer descriptors */
771 regs
->tbase
= (unsigned int)(&rtx
.txbd
[txIdx
]);
772 regs
->rbase
= (unsigned int)(&rtx
.rxbd
[rxIdx
]);
774 /* Initialize the Rx Buffer descriptors */
775 for (i
= 0; i
< PKTBUFSRX
; i
++) {
776 rtx
.rxbd
[i
].status
= RXBD_EMPTY
;
777 rtx
.rxbd
[i
].length
= 0;
778 rtx
.rxbd
[i
].bufPtr
= (uint
) NetRxPackets
[i
];
780 rtx
.rxbd
[PKTBUFSRX
- 1].status
|= RXBD_WRAP
;
782 /* Initialize the TX Buffer Descriptors */
783 for (i
= 0; i
< TX_BUF_CNT
; i
++) {
784 rtx
.txbd
[i
].status
= 0;
785 rtx
.txbd
[i
].length
= 0;
786 rtx
.txbd
[i
].bufPtr
= 0;
788 rtx
.txbd
[TX_BUF_CNT
- 1].status
|= TXBD_WRAP
;
790 /* Start up the PHY */
792 phy_run_commands(priv
, priv
->phyinfo
->startup
);
796 /* Enable Transmit and Receive */
797 regs
->maccfg1
|= (MACCFG1_RX_EN
| MACCFG1_TX_EN
);
799 /* Tell the DMA it is clear to go */
800 regs
->dmactrl
|= DMACTRL_INIT_SETTINGS
;
801 regs
->tstat
= TSTAT_CLEAR_THALT
;
802 regs
->dmactrl
&= ~(DMACTRL_GRS
| DMACTRL_GTS
);
805 /* This returns the status bits of the device. The return value
806 * is never checked, and this is what the 8260 driver did, so we
807 * do the same. Presumably, this would be zero if there were no
810 static int tsec_send(struct eth_device
*dev
, volatile void *packet
, int length
)
814 struct tsec_private
*priv
= (struct tsec_private
*)dev
->priv
;
815 volatile tsec_t
*regs
= priv
->regs
;
817 /* Find an empty buffer descriptor */
818 for (i
= 0; rtx
.txbd
[txIdx
].status
& TXBD_READY
; i
++) {
819 if (i
>= TOUT_LOOP
) {
820 debug("%s: tsec: tx buffers full\n", dev
->name
);
825 rtx
.txbd
[txIdx
].bufPtr
= (uint
) packet
;
826 rtx
.txbd
[txIdx
].length
= length
;
827 rtx
.txbd
[txIdx
].status
|=
828 (TXBD_READY
| TXBD_LAST
| TXBD_CRC
| TXBD_INTERRUPT
);
830 /* Tell the DMA to go */
831 regs
->tstat
= TSTAT_CLEAR_THALT
;
833 /* Wait for buffer to be transmitted */
834 for (i
= 0; rtx
.txbd
[txIdx
].status
& TXBD_READY
; i
++) {
835 if (i
>= TOUT_LOOP
) {
836 debug("%s: tsec: tx error\n", dev
->name
);
841 txIdx
= (txIdx
+ 1) % TX_BUF_CNT
;
842 result
= rtx
.txbd
[txIdx
].status
& TXBD_STATS
;
847 static int tsec_recv(struct eth_device
*dev
)
850 struct tsec_private
*priv
= (struct tsec_private
*)dev
->priv
;
851 volatile tsec_t
*regs
= priv
->regs
;
853 while (!(rtx
.rxbd
[rxIdx
].status
& RXBD_EMPTY
)) {
855 length
= rtx
.rxbd
[rxIdx
].length
;
857 /* Send the packet up if there were no errors */
858 if (!(rtx
.rxbd
[rxIdx
].status
& RXBD_STATS
)) {
859 NetReceive(NetRxPackets
[rxIdx
], length
- 4);
861 printf("Got error %x\n",
862 (rtx
.rxbd
[rxIdx
].status
& RXBD_STATS
));
865 rtx
.rxbd
[rxIdx
].length
= 0;
867 /* Set the wrap bit if this is the last element in the list */
868 rtx
.rxbd
[rxIdx
].status
=
869 RXBD_EMPTY
| (((rxIdx
+ 1) == PKTBUFSRX
) ? RXBD_WRAP
: 0);
871 rxIdx
= (rxIdx
+ 1) % PKTBUFSRX
;
874 if (regs
->ievent
& IEVENT_BSY
) {
875 regs
->ievent
= IEVENT_BSY
;
876 regs
->rstat
= RSTAT_CLEAR_RHALT
;
883 /* Stop the interface */
884 static void tsec_halt(struct eth_device
*dev
)
886 struct tsec_private
*priv
= (struct tsec_private
*)dev
->priv
;
887 volatile tsec_t
*regs
= priv
->regs
;
889 regs
->dmactrl
&= ~(DMACTRL_GRS
| DMACTRL_GTS
);
890 regs
->dmactrl
|= (DMACTRL_GRS
| DMACTRL_GTS
);
892 while (!(regs
->ievent
& (IEVENT_GRSC
| IEVENT_GTSC
))) ;
894 regs
->maccfg1
&= ~(MACCFG1_TX_EN
| MACCFG1_RX_EN
);
896 /* Shut down the PHY, as needed */
898 phy_run_commands(priv
, priv
->phyinfo
->shutdown
);
901 /* The 5411 id is 0x206070, the 5421 is 0x2060e0 */
902 struct phy_info phy_info_BCM5461S
= {
903 0x02060c1, /* 5461 ID */
905 0, /* not clear to me what minor revisions we can shift away */
906 (struct phy_cmd
[]) { /* config */
907 /* Reset and configure the PHY */
908 {MIIM_CONTROL
, MIIM_CONTROL_RESET
, NULL
},
909 {MIIM_GBIT_CONTROL
, MIIM_GBIT_CONTROL_INIT
, NULL
},
910 {MIIM_ANAR
, MIIM_ANAR_INIT
, NULL
},
911 {MIIM_CONTROL
, MIIM_CONTROL_RESET
, NULL
},
912 {MIIM_CONTROL
, MIIM_CONTROL_INIT
, &mii_cr_init
},
915 (struct phy_cmd
[]) { /* startup */
916 /* Status is read once to clear old link state */
917 {MIIM_STATUS
, miim_read
, NULL
},
919 {MIIM_STATUS
, miim_read
, &mii_parse_sr
},
920 /* Read the status */
921 {MIIM_BCM54xx_AUXSTATUS
, miim_read
, &mii_parse_BCM54xx_sr
},
924 (struct phy_cmd
[]) { /* shutdown */
929 struct phy_info phy_info_BCM5464S
= {
930 0x02060b1, /* 5464 ID */
932 0, /* not clear to me what minor revisions we can shift away */
933 (struct phy_cmd
[]) { /* config */
934 /* Reset and configure the PHY */
935 {MIIM_CONTROL
, MIIM_CONTROL_RESET
, NULL
},
936 {MIIM_GBIT_CONTROL
, MIIM_GBIT_CONTROL_INIT
, NULL
},
937 {MIIM_ANAR
, MIIM_ANAR_INIT
, NULL
},
938 {MIIM_CONTROL
, MIIM_CONTROL_RESET
, NULL
},
939 {MIIM_CONTROL
, MIIM_CONTROL_INIT
, &mii_cr_init
},
942 (struct phy_cmd
[]) { /* startup */
943 /* Status is read once to clear old link state */
944 {MIIM_STATUS
, miim_read
, NULL
},
946 {MIIM_STATUS
, miim_read
, &mii_parse_sr
},
947 /* Read the status */
948 {MIIM_BCM54xx_AUXSTATUS
, miim_read
, &mii_parse_BCM54xx_sr
},
951 (struct phy_cmd
[]) { /* shutdown */
956 struct phy_info phy_info_M88E1011S
= {
960 (struct phy_cmd
[]){ /* config */
961 /* Reset and configure the PHY */
962 {MIIM_CONTROL
, MIIM_CONTROL_RESET
, NULL
},
964 {0x1e, 0x200c, NULL
},
968 {MIIM_GBIT_CONTROL
, MIIM_GBIT_CONTROL_INIT
, NULL
},
969 {MIIM_ANAR
, MIIM_ANAR_INIT
, NULL
},
970 {MIIM_CONTROL
, MIIM_CONTROL_RESET
, NULL
},
971 {MIIM_CONTROL
, MIIM_CONTROL_INIT
, &mii_cr_init
},
974 (struct phy_cmd
[]){ /* startup */
975 /* Status is read once to clear old link state */
976 {MIIM_STATUS
, miim_read
, NULL
},
978 {MIIM_STATUS
, miim_read
, &mii_parse_sr
},
979 /* Read the status */
980 {MIIM_88E1011_PHY_STATUS
, miim_read
,
981 &mii_parse_88E1011_psr
},
984 (struct phy_cmd
[]){ /* shutdown */
989 struct phy_info phy_info_M88E1111S
= {
993 (struct phy_cmd
[]){ /* config */
994 /* Reset and configure the PHY */
995 {MIIM_CONTROL
, MIIM_CONTROL_RESET
, NULL
},
996 {0x14, 0x0cd2, NULL
}, /* Delay RGMII TX and RX */
997 {MIIM_GBIT_CONTROL
, MIIM_GBIT_CONTROL_INIT
, NULL
},
998 {MIIM_ANAR
, MIIM_ANAR_INIT
, NULL
},
999 {MIIM_CONTROL
, MIIM_CONTROL_RESET
, NULL
},
1000 {MIIM_CONTROL
, MIIM_CONTROL_INIT
, &mii_cr_init
},
1003 (struct phy_cmd
[]){ /* startup */
1004 /* Status is read once to clear old link state */
1005 {MIIM_STATUS
, miim_read
, NULL
},
1006 /* Auto-negotiate */
1007 {MIIM_STATUS
, miim_read
, &mii_parse_sr
},
1008 /* Read the status */
1009 {MIIM_88E1011_PHY_STATUS
, miim_read
,
1010 &mii_parse_88E1011_psr
},
1013 (struct phy_cmd
[]){ /* shutdown */
1018 static unsigned int m88e1145_setmode(uint mii_reg
, struct tsec_private
*priv
)
1020 uint mii_data
= read_phy_reg(priv
, mii_reg
);
1022 /* Setting MIIM_88E1145_PHY_EXT_CR */
1023 if (priv
->flags
& TSEC_REDUCED
)
1025 MIIM_M88E1145_RGMII_RX_DELAY
| MIIM_M88E1145_RGMII_TX_DELAY
;
1030 static struct phy_info phy_info_M88E1145
= {
1034 (struct phy_cmd
[]){ /* config */
1036 {MIIM_CONTROL
, MIIM_CONTROL_RESET
, NULL
},
1044 /* Configure the PHY */
1045 {MIIM_GBIT_CONTROL
, MIIM_GBIT_CONTROL_INIT
, NULL
},
1046 {MIIM_ANAR
, MIIM_ANAR_INIT
, NULL
},
1047 {MIIM_88E1011_PHY_SCR
, MIIM_88E1011_PHY_MDI_X_AUTO
,
1049 {MIIM_88E1145_PHY_EXT_CR
, 0, &m88e1145_setmode
},
1050 {MIIM_CONTROL
, MIIM_CONTROL_RESET
, NULL
},
1051 {MIIM_CONTROL
, MIIM_CONTROL_INIT
, NULL
},
1054 (struct phy_cmd
[]){ /* startup */
1055 /* Status is read once to clear old link state */
1056 {MIIM_STATUS
, miim_read
, NULL
},
1057 /* Auto-negotiate */
1058 {MIIM_STATUS
, miim_read
, &mii_parse_sr
},
1059 {MIIM_88E1111_PHY_LED_CONTROL
,
1060 MIIM_88E1111_PHY_LED_DIRECT
, NULL
},
1061 /* Read the Status */
1062 {MIIM_88E1011_PHY_STATUS
, miim_read
,
1063 &mii_parse_88E1011_psr
},
1066 (struct phy_cmd
[]){ /* shutdown */
1071 struct phy_info phy_info_cis8204
= {
1075 (struct phy_cmd
[]){ /* config */
1076 /* Override PHY config settings */
1077 {MIIM_CIS8201_AUX_CONSTAT
,
1078 MIIM_CIS8201_AUXCONSTAT_INIT
, NULL
},
1079 /* Configure some basic stuff */
1080 {MIIM_CONTROL
, MIIM_CONTROL_INIT
, &mii_cr_init
},
1081 {MIIM_CIS8204_SLED_CON
, MIIM_CIS8204_SLEDCON_INIT
,
1082 &mii_cis8204_fixled
},
1083 {MIIM_CIS8204_EPHY_CON
, MIIM_CIS8204_EPHYCON_INIT
,
1084 &mii_cis8204_setmode
},
1087 (struct phy_cmd
[]){ /* startup */
1088 /* Read the Status (2x to make sure link is right) */
1089 {MIIM_STATUS
, miim_read
, NULL
},
1090 /* Auto-negotiate */
1091 {MIIM_STATUS
, miim_read
, &mii_parse_sr
},
1092 /* Read the status */
1093 {MIIM_CIS8201_AUX_CONSTAT
, miim_read
,
1094 &mii_parse_cis8201
},
1097 (struct phy_cmd
[]){ /* shutdown */
1103 struct phy_info phy_info_cis8201
= {
1107 (struct phy_cmd
[]){ /* config */
1108 /* Override PHY config settings */
1109 {MIIM_CIS8201_AUX_CONSTAT
,
1110 MIIM_CIS8201_AUXCONSTAT_INIT
, NULL
},
1111 /* Set up the interface mode */
1112 {MIIM_CIS8201_EXT_CON1
, MIIM_CIS8201_EXTCON1_INIT
,
1114 /* Configure some basic stuff */
1115 {MIIM_CONTROL
, MIIM_CONTROL_INIT
, &mii_cr_init
},
1118 (struct phy_cmd
[]){ /* startup */
1119 /* Read the Status (2x to make sure link is right) */
1120 {MIIM_STATUS
, miim_read
, NULL
},
1121 /* Auto-negotiate */
1122 {MIIM_STATUS
, miim_read
, &mii_parse_sr
},
1123 /* Read the status */
1124 {MIIM_CIS8201_AUX_CONSTAT
, miim_read
,
1125 &mii_parse_cis8201
},
1128 (struct phy_cmd
[]){ /* shutdown */
1132 struct phy_info phy_info_VSC8244
= {
1136 (struct phy_cmd
[]){ /* config */
1137 /* Override PHY config settings */
1138 /* Configure some basic stuff */
1139 {MIIM_CONTROL
, MIIM_CONTROL_INIT
, &mii_cr_init
},
1142 (struct phy_cmd
[]){ /* startup */
1143 /* Read the Status (2x to make sure link is right) */
1144 {MIIM_STATUS
, miim_read
, NULL
},
1145 /* Auto-negotiate */
1146 {MIIM_STATUS
, miim_read
, &mii_parse_sr
},
1147 /* Read the status */
1148 {MIIM_VSC8244_AUX_CONSTAT
, miim_read
,
1149 &mii_parse_vsc8244
},
1152 (struct phy_cmd
[]){ /* shutdown */
1157 struct phy_info phy_info_dm9161
= {
1161 (struct phy_cmd
[]){ /* config */
1162 {MIIM_CONTROL
, MIIM_DM9161_CR_STOP
, NULL
},
1163 /* Do not bypass the scrambler/descrambler */
1164 {MIIM_DM9161_SCR
, MIIM_DM9161_SCR_INIT
, NULL
},
1165 /* Clear 10BTCSR to default */
1166 {MIIM_DM9161_10BTCSR
, MIIM_DM9161_10BTCSR_INIT
,
1168 /* Configure some basic stuff */
1169 {MIIM_CONTROL
, MIIM_CR_INIT
, NULL
},
1170 /* Restart Auto Negotiation */
1171 {MIIM_CONTROL
, MIIM_DM9161_CR_RSTAN
, NULL
},
1174 (struct phy_cmd
[]){ /* startup */
1175 /* Status is read once to clear old link state */
1176 {MIIM_STATUS
, miim_read
, NULL
},
1177 /* Auto-negotiate */
1178 {MIIM_STATUS
, miim_read
, &mii_parse_sr
},
1179 /* Read the status */
1180 {MIIM_DM9161_SCSR
, miim_read
,
1181 &mii_parse_dm9161_scsr
},
1184 (struct phy_cmd
[]){ /* shutdown */
1188 /* a generic flavor. */
1189 struct phy_info phy_info_generic
= {
1191 "Unknown/Generic PHY",
1193 (struct phy_cmd
[]) { /* config */
1194 {PHY_BMCR
, PHY_BMCR_RESET
, NULL
},
1195 {PHY_BMCR
, PHY_BMCR_AUTON
|PHY_BMCR_RST_NEG
, NULL
},
1198 (struct phy_cmd
[]) { /* startup */
1199 {PHY_BMSR
, miim_read
, NULL
},
1200 {PHY_BMSR
, miim_read
, &mii_parse_sr
},
1201 {PHY_BMSR
, miim_read
, &mii_parse_link
},
1204 (struct phy_cmd
[]) { /* shutdown */
1210 uint
mii_parse_lxt971_sr2(uint mii_reg
, struct tsec_private
*priv
)
1214 speed
= mii_reg
& MIIM_LXT971_SR2_SPEED_MASK
;
1217 case MIIM_LXT971_SR2_10HDX
:
1219 priv
->duplexity
= 0;
1221 case MIIM_LXT971_SR2_10FDX
:
1223 priv
->duplexity
= 1;
1225 case MIIM_LXT971_SR2_100HDX
:
1227 priv
->duplexity
= 0;
1230 priv
->duplexity
= 1;
1235 priv
->duplexity
= 0;
1241 static struct phy_info phy_info_lxt971
= {
1245 (struct phy_cmd
[]){ /* config */
1246 {MIIM_CR
, MIIM_CR_INIT
, mii_cr_init
}, /* autonegotiate */
1249 (struct phy_cmd
[]){ /* startup - enable interrupts */
1250 /* { 0x12, 0x00f2, NULL }, */
1251 {MIIM_STATUS
, miim_read
, NULL
},
1252 {MIIM_STATUS
, miim_read
, &mii_parse_sr
},
1253 {MIIM_LXT971_SR2
, miim_read
, &mii_parse_lxt971_sr2
},
1256 (struct phy_cmd
[]){ /* shutdown - disable interrupts */
1261 /* Parse the DP83865's link and auto-neg status register for speed and duplex
1264 uint
mii_parse_dp83865_lanr(uint mii_reg
, struct tsec_private
*priv
)
1266 switch (mii_reg
& MIIM_DP83865_SPD_MASK
) {
1268 case MIIM_DP83865_SPD_1000
:
1272 case MIIM_DP83865_SPD_100
:
1282 if (mii_reg
& MIIM_DP83865_DPX_FULL
)
1283 priv
->duplexity
= 1;
1285 priv
->duplexity
= 0;
1290 struct phy_info phy_info_dp83865
= {
1294 (struct phy_cmd
[]){ /* config */
1295 {MIIM_CONTROL
, MIIM_DP83865_CR_INIT
, NULL
},
1298 (struct phy_cmd
[]){ /* startup */
1299 /* Status is read once to clear old link state */
1300 {MIIM_STATUS
, miim_read
, NULL
},
1301 /* Auto-negotiate */
1302 {MIIM_STATUS
, miim_read
, &mii_parse_sr
},
1303 /* Read the link and auto-neg status */
1304 {MIIM_DP83865_LANR
, miim_read
,
1305 &mii_parse_dp83865_lanr
},
1308 (struct phy_cmd
[]){ /* shutdown */
1313 struct phy_info
*phy_info
[] = {
1318 &phy_info_M88E1011S
,
1319 &phy_info_M88E1111S
,
1329 /* Grab the identifier of the device's PHY, and search through
1330 * all of the known PHYs to see if one matches. If so, return
1331 * it, if not, return NULL
1333 struct phy_info
*get_phy_info(struct eth_device
*dev
)
1335 struct tsec_private
*priv
= (struct tsec_private
*)dev
->priv
;
1336 uint phy_reg
, phy_ID
;
1338 struct phy_info
*theInfo
= NULL
;
1340 /* Grab the bits from PHYIR1, and put them in the upper half */
1341 phy_reg
= read_phy_reg(priv
, MIIM_PHYIR1
);
1342 phy_ID
= (phy_reg
& 0xffff) << 16;
1344 /* Grab the bits from PHYIR2, and put them in the lower half */
1345 phy_reg
= read_phy_reg(priv
, MIIM_PHYIR2
);
1346 phy_ID
|= (phy_reg
& 0xffff);
1348 /* loop through all the known PHY types, and find one that */
1349 /* matches the ID we read from the PHY. */
1350 for (i
= 0; phy_info
[i
]; i
++) {
1351 if (phy_info
[i
]->id
== (phy_ID
>> phy_info
[i
]->shift
)) {
1352 theInfo
= phy_info
[i
];
1357 if (theInfo
== NULL
) {
1358 printf("%s: PHY id %x is not supported!\n", dev
->name
, phy_ID
);
1361 debug("%s: PHY is %s (%x)\n", dev
->name
, theInfo
->name
, phy_ID
);
1367 /* Execute the given series of commands on the given device's
1368 * PHY, running functions as necessary
1370 void phy_run_commands(struct tsec_private
*priv
, struct phy_cmd
*cmd
)
1374 volatile tsec_t
*phyregs
= priv
->phyregs
;
1376 phyregs
->miimcfg
= MIIMCFG_RESET
;
1378 phyregs
->miimcfg
= MIIMCFG_INIT_VALUE
;
1380 while (phyregs
->miimind
& MIIMIND_BUSY
) ;
1382 for (i
= 0; cmd
->mii_reg
!= miim_end
; i
++) {
1383 if (cmd
->mii_data
== miim_read
) {
1384 result
= read_phy_reg(priv
, cmd
->mii_reg
);
1386 if (cmd
->funct
!= NULL
)
1387 (*(cmd
->funct
)) (result
, priv
);
1390 if (cmd
->funct
!= NULL
)
1391 result
= (*(cmd
->funct
)) (cmd
->mii_reg
, priv
);
1393 result
= cmd
->mii_data
;
1395 write_phy_reg(priv
, cmd
->mii_reg
, result
);
1402 /* Relocate the function pointers in the phy cmd lists */
1403 static void relocate_cmds(void)
1405 struct phy_cmd
**cmdlistptr
;
1406 struct phy_cmd
*cmd
;
1409 for (i
= 0; phy_info
[i
]; i
++) {
1410 /* First thing's first: relocate the pointers to the
1411 * PHY command structures (the structs were done) */
1412 phy_info
[i
] = (struct phy_info
*)((uint
) phy_info
[i
]
1414 phy_info
[i
]->name
+= gd
->reloc_off
;
1415 phy_info
[i
]->config
=
1416 (struct phy_cmd
*)((uint
) phy_info
[i
]->config
1418 phy_info
[i
]->startup
=
1419 (struct phy_cmd
*)((uint
) phy_info
[i
]->startup
1421 phy_info
[i
]->shutdown
=
1422 (struct phy_cmd
*)((uint
) phy_info
[i
]->shutdown
1425 cmdlistptr
= &phy_info
[i
]->config
;
1427 for (; cmdlistptr
<= &phy_info
[i
]->shutdown
; cmdlistptr
++) {
1429 for (cmd
= *cmdlistptr
;
1430 cmd
->mii_reg
!= miim_end
;
1432 /* Only relocate non-NULL pointers */
1434 cmd
->funct
+= gd
->reloc_off
;
1445 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) \
1446 && !defined(BITBANGMII)
1448 struct tsec_private
*get_priv_for_phy(unsigned char phyaddr
)
1452 for (i
= 0; i
< MAXCONTROLLERS
; i
++) {
1453 if (privlist
[i
]->phyaddr
== phyaddr
)
1461 * Read a MII PHY register.
1466 static int tsec_miiphy_read(char *devname
, unsigned char addr
,
1467 unsigned char reg
, unsigned short *value
)
1470 struct tsec_private
*priv
= get_priv_for_phy(addr
);
1473 printf("Can't read PHY at address %d\n", addr
);
1477 ret
= (unsigned short)read_phy_reg(priv
, reg
);
1484 * Write a MII PHY register.
1489 static int tsec_miiphy_write(char *devname
, unsigned char addr
,
1490 unsigned char reg
, unsigned short value
)
1492 struct tsec_private
*priv
= get_priv_for_phy(addr
);
1495 printf("Can't write PHY at address %d\n", addr
);
1499 write_phy_reg(priv
, reg
, value
);
1506 #endif /* CONFIG_TSEC_ENET */