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.
23 DECLARE_GLOBAL_DATA_PTR
;
27 static uint rxIdx
; /* index of the current RX buffer */
28 static uint txIdx
; /* index of the current TX buffer */
30 typedef volatile struct rtxbd
{
31 txbd8_t txbd
[TX_BUF_CNT
];
32 rxbd8_t rxbd
[PKTBUFSRX
];
35 #define MAXCONTROLLERS (8)
37 static int relocated
= 0;
39 static struct tsec_private
*privlist
[MAXCONTROLLERS
];
40 static int num_tsecs
= 0;
43 static RTXBD rtx
__attribute__ ((aligned(8)));
45 #error "rtx must be 64-bit aligned"
48 static int tsec_send(struct eth_device
*dev
,
49 volatile void *packet
, int length
);
50 static int tsec_recv(struct eth_device
*dev
);
51 static int tsec_init(struct eth_device
*dev
, bd_t
* bd
);
52 static void tsec_halt(struct eth_device
*dev
);
53 static void init_registers(volatile tsec_t
* regs
);
54 static void startup_tsec(struct eth_device
*dev
);
55 static int init_phy(struct eth_device
*dev
);
56 void write_phy_reg(struct tsec_private
*priv
, uint regnum
, uint value
);
57 uint
read_phy_reg(struct tsec_private
*priv
, uint regnum
);
58 struct phy_info
*get_phy_info(struct eth_device
*dev
);
59 void phy_run_commands(struct tsec_private
*priv
, struct phy_cmd
*cmd
);
60 static void adjust_link(struct eth_device
*dev
);
61 static void relocate_cmds(void);
62 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) \
63 && !defined(BITBANGMII)
64 static int tsec_miiphy_write(char *devname
, unsigned char addr
,
65 unsigned char reg
, unsigned short value
);
66 static int tsec_miiphy_read(char *devname
, unsigned char addr
,
67 unsigned char reg
, unsigned short *value
);
69 #ifdef CONFIG_MCAST_TFTP
70 static int tsec_mcast_addr (struct eth_device
*dev
, u8 mcast_mac
, u8 set
);
73 /* Default initializations for TSEC controllers. */
75 static struct tsec_info_struct tsec_info
[] = {
77 STD_TSEC_INFO(1), /* TSEC1 */
80 STD_TSEC_INFO(2), /* TSEC2 */
82 #ifdef CONFIG_MPC85XX_FEC
84 .regs
= (tsec_t
*)(TSEC_BASE_ADDR
+ 0x2000),
85 .miiregs
= (tsec_t
*)(TSEC_BASE_ADDR
),
86 .devname
= CONFIG_MPC85XX_FEC_NAME
,
87 .phyaddr
= FEC_PHY_ADDR
,
92 STD_TSEC_INFO(3), /* TSEC3 */
95 STD_TSEC_INFO(4), /* TSEC4 */
99 int tsec_eth_init(bd_t
*bis
, struct tsec_info_struct
*tsecs
, int num
)
103 for (i
= 0; i
< num
; i
++)
104 tsec_initialize(bis
, &tsecs
[i
]);
109 int tsec_standard_init(bd_t
*bis
)
111 return tsec_eth_init(bis
, tsec_info
, ARRAY_SIZE(tsec_info
));
114 /* Initialize device structure. Returns success if PHY
115 * initialization succeeded (i.e. if it recognizes the PHY)
117 int tsec_initialize(bd_t
* bis
, struct tsec_info_struct
*tsec_info
)
119 struct eth_device
*dev
;
121 struct tsec_private
*priv
;
123 dev
= (struct eth_device
*)malloc(sizeof *dev
);
128 memset(dev
, 0, sizeof *dev
);
130 priv
= (struct tsec_private
*)malloc(sizeof(*priv
));
135 privlist
[num_tsecs
++] = priv
;
136 priv
->regs
= tsec_info
->regs
;
137 priv
->phyregs
= tsec_info
->miiregs
;
139 priv
->phyaddr
= tsec_info
->phyaddr
;
140 priv
->flags
= tsec_info
->flags
;
142 sprintf(dev
->name
, tsec_info
->devname
);
145 dev
->init
= tsec_init
;
146 dev
->halt
= tsec_halt
;
147 dev
->send
= tsec_send
;
148 dev
->recv
= tsec_recv
;
149 #ifdef CONFIG_MCAST_TFTP
150 dev
->mcast
= tsec_mcast_addr
;
153 /* Tell u-boot to get the addr from the env */
154 for (i
= 0; i
< 6; i
++)
155 dev
->enetaddr
[i
] = 0;
160 priv
->regs
->maccfg1
|= MACCFG1_SOFT_RESET
;
161 priv
->regs
->maccfg1
&= ~(MACCFG1_SOFT_RESET
);
163 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) \
164 && !defined(BITBANGMII)
165 miiphy_register(dev
->name
, tsec_miiphy_read
, tsec_miiphy_write
);
168 /* Try to initialize PHY here, and return */
169 return init_phy(dev
);
172 /* Initializes data structures and registers for the controller,
173 * and brings the interface up. Returns the link status, meaning
174 * that it returns success if the link is up, failure otherwise.
175 * This allows u-boot to find the first active controller.
177 int tsec_init(struct eth_device
*dev
, bd_t
* bd
)
180 char tmpbuf
[MAC_ADDR_LEN
];
182 struct tsec_private
*priv
= (struct tsec_private
*)dev
->priv
;
183 volatile tsec_t
*regs
= priv
->regs
;
185 /* Make sure the controller is stopped */
188 /* Init MACCFG2. Defaults to GMII */
189 regs
->maccfg2
= MACCFG2_INIT_SETTINGS
;
192 regs
->ecntrl
= ECNTRL_INIT_SETTINGS
;
194 /* Copy the station address into the address registers.
195 * Backwards, because little endian MACS are dumb */
196 for (i
= 0; i
< MAC_ADDR_LEN
; i
++) {
197 tmpbuf
[MAC_ADDR_LEN
- 1 - i
] = dev
->enetaddr
[i
];
199 regs
->macstnaddr1
= *((uint
*) (tmpbuf
));
201 tempval
= *((uint
*) (tmpbuf
+ 4));
203 regs
->macstnaddr2
= tempval
;
205 /* reset the indices to zero */
209 /* Clear out (for the most part) the other registers */
210 init_registers(regs
);
212 /* Ready the device for tx/rx */
215 /* If there's no link, fail */
216 return (priv
->link
? 0 : -1);
219 /* Write value to the device's PHY through the registers
220 * specified in priv, modifying the register specified in regnum.
221 * It will wait for the write to be done (or for a timeout to
222 * expire) before exiting
224 void write_any_phy_reg(struct tsec_private
*priv
, uint phyid
, uint regnum
, uint value
)
226 volatile tsec_t
*regbase
= priv
->phyregs
;
227 int timeout
= 1000000;
229 regbase
->miimadd
= (phyid
<< 8) | regnum
;
230 regbase
->miimcon
= value
;
234 while ((regbase
->miimind
& MIIMIND_BUSY
) && timeout
--) ;
237 /* #define to provide old write_phy_reg functionality without duplicating code */
238 #define write_phy_reg(priv, regnum, value) write_any_phy_reg(priv,priv->phyaddr,regnum,value)
240 /* Reads register regnum on the device's PHY through the
241 * registers specified in priv. It lowers and raises the read
242 * command, and waits for the data to become valid (miimind
243 * notvalid bit cleared), and the bus to cease activity (miimind
244 * busy bit cleared), and then returns the value
246 uint
read_any_phy_reg(struct tsec_private
*priv
, uint phyid
, uint regnum
)
249 volatile tsec_t
*regbase
= priv
->phyregs
;
251 /* Put the address of the phy, and the register
252 * number into MIIMADD */
253 regbase
->miimadd
= (phyid
<< 8) | regnum
;
255 /* Clear the command register, and wait */
256 regbase
->miimcom
= 0;
259 /* Initiate a read command, and wait */
260 regbase
->miimcom
= MIIM_READ_COMMAND
;
263 /* Wait for the the indication that the read is done */
264 while ((regbase
->miimind
& (MIIMIND_NOTVALID
| MIIMIND_BUSY
))) ;
266 /* Grab the value read from the PHY */
267 value
= regbase
->miimstat
;
272 /* #define to provide old read_phy_reg functionality without duplicating code */
273 #define read_phy_reg(priv,regnum) read_any_phy_reg(priv,priv->phyaddr,regnum)
275 /* Discover which PHY is attached to the device, and configure it
276 * properly. If the PHY is not recognized, then return 0
277 * (failure). Otherwise, return 1
279 static int init_phy(struct eth_device
*dev
)
281 struct tsec_private
*priv
= (struct tsec_private
*)dev
->priv
;
282 struct phy_info
*curphy
;
283 volatile tsec_t
*regs
= (volatile tsec_t
*)(TSEC_BASE_ADDR
);
285 /* Assign a Physical address to the TBI */
286 regs
->tbipa
= CFG_TBIPA_VALUE
;
287 regs
= (volatile tsec_t
*)(TSEC_BASE_ADDR
+ TSEC_SIZE
);
288 regs
->tbipa
= CFG_TBIPA_VALUE
;
291 /* Reset MII (due to new addresses) */
292 priv
->phyregs
->miimcfg
= MIIMCFG_RESET
;
294 priv
->phyregs
->miimcfg
= MIIMCFG_INIT_VALUE
;
296 while (priv
->phyregs
->miimind
& MIIMIND_BUSY
) ;
301 /* Get the cmd structure corresponding to the attached
303 curphy
= get_phy_info(dev
);
305 if (curphy
== NULL
) {
306 priv
->phyinfo
= NULL
;
307 printf("%s: No PHY found\n", dev
->name
);
312 priv
->phyinfo
= curphy
;
314 phy_run_commands(priv
, priv
->phyinfo
->config
);
320 * Returns which value to write to the control register.
321 * For 10/100, the value is slightly different
323 uint
mii_cr_init(uint mii_reg
, struct tsec_private
* priv
)
325 if (priv
->flags
& TSEC_GIGABIT
)
326 return MIIM_CONTROL_INIT
;
331 /* Parse the status register for link, and then do
334 uint
mii_parse_sr(uint mii_reg
, struct tsec_private
* priv
)
337 * Wait if the link is up, and autonegotiation is in progress
338 * (ie - we're capable and it's not done)
340 mii_reg
= read_phy_reg(priv
, MIIM_STATUS
);
341 if ((mii_reg
& MIIM_STATUS_LINK
) && (mii_reg
& PHY_BMSR_AUTN_ABLE
)
342 && !(mii_reg
& PHY_BMSR_AUTN_COMP
)) {
345 puts("Waiting for PHY auto negotiation to complete");
346 while (!(mii_reg
& PHY_BMSR_AUTN_COMP
)) {
350 if (i
> PHY_AUTONEGOTIATE_TIMEOUT
) {
351 puts(" TIMEOUT !\n");
356 if ((i
++ % 1000) == 0) {
359 udelay(1000); /* 1 ms */
360 mii_reg
= read_phy_reg(priv
, MIIM_STATUS
);
364 udelay(500000); /* another 500 ms (results in faster booting) */
366 if (mii_reg
& MIIM_STATUS_LINK
)
375 /* Generic function which updates the speed and duplex. If
376 * autonegotiation is enabled, it uses the AND of the link
377 * partner's advertised capabilities and our advertised
378 * capabilities. If autonegotiation is disabled, we use the
379 * appropriate bits in the control register.
381 * Stolen from Linux's mii.c and phy_device.c
383 uint
mii_parse_link(uint mii_reg
, struct tsec_private
*priv
)
385 /* We're using autonegotiation */
386 if (mii_reg
& PHY_BMSR_AUTN_ABLE
) {
390 /* Check for gigabit capability */
391 if (mii_reg
& PHY_BMSR_EXT
) {
392 /* We want a list of states supported by
393 * both PHYs in the link
395 gblpa
= read_phy_reg(priv
, PHY_1000BTSR
);
396 gblpa
&= read_phy_reg(priv
, PHY_1000BTCR
) << 2;
399 /* Set the baseline so we only have to set them
400 * if they're different
405 /* Check the gigabit fields */
406 if (gblpa
& (PHY_1000BTSR_1000FD
| PHY_1000BTSR_1000HD
)) {
409 if (gblpa
& PHY_1000BTSR_1000FD
)
416 lpa
= read_phy_reg(priv
, PHY_ANAR
);
417 lpa
&= read_phy_reg(priv
, PHY_ANLPAR
);
419 if (lpa
& (PHY_ANLPAR_TXFD
| PHY_ANLPAR_TX
)) {
422 if (lpa
& PHY_ANLPAR_TXFD
)
425 } else if (lpa
& PHY_ANLPAR_10FD
)
428 uint bmcr
= read_phy_reg(priv
, PHY_BMCR
);
433 if (bmcr
& PHY_BMCR_DPLX
)
436 if (bmcr
& PHY_BMCR_1000_MBPS
)
438 else if (bmcr
& PHY_BMCR_100_MBPS
)
446 * Parse the BCM54xx status register for speed and duplex information.
447 * The linux sungem_phy has this information, but in a table format.
449 uint
mii_parse_BCM54xx_sr(uint mii_reg
, struct tsec_private
*priv
)
452 switch((mii_reg
& MIIM_BCM54xx_AUXSTATUS_LINKMODE_MASK
) >> MIIM_BCM54xx_AUXSTATUS_LINKMODE_SHIFT
){
455 printf("Enet starting in 10BT/HD\n");
461 printf("Enet starting in 10BT/FD\n");
467 printf("Enet starting in 100BT/HD\n");
473 printf("Enet starting in 100BT/FD\n");
479 printf("Enet starting in 1000BT/HD\n");
485 printf("Enet starting in 1000BT/FD\n");
491 printf("Auto-neg error, defaulting to 10BT/HD\n");
500 /* Parse the 88E1011's status register for speed and duplex
503 uint
mii_parse_88E1011_psr(uint mii_reg
, struct tsec_private
* priv
)
507 mii_reg
= read_phy_reg(priv
, MIIM_88E1011_PHY_STATUS
);
509 if ((mii_reg
& MIIM_88E1011_PHYSTAT_LINK
) &&
510 !(mii_reg
& MIIM_88E1011_PHYSTAT_SPDDONE
)) {
513 puts("Waiting for PHY realtime link");
514 while (!(mii_reg
& MIIM_88E1011_PHYSTAT_SPDDONE
)) {
515 /* Timeout reached ? */
516 if (i
> PHY_AUTONEGOTIATE_TIMEOUT
) {
517 puts(" TIMEOUT !\n");
522 if ((i
++ % 1000) == 0) {
525 udelay(1000); /* 1 ms */
526 mii_reg
= read_phy_reg(priv
, MIIM_88E1011_PHY_STATUS
);
529 udelay(500000); /* another 500 ms (results in faster booting) */
531 if (mii_reg
& MIIM_88E1011_PHYSTAT_LINK
)
537 if (mii_reg
& MIIM_88E1011_PHYSTAT_DUPLEX
)
542 speed
= (mii_reg
& MIIM_88E1011_PHYSTAT_SPEED
);
545 case MIIM_88E1011_PHYSTAT_GBIT
:
548 case MIIM_88E1011_PHYSTAT_100
:
558 /* Parse the RTL8211B's status register for speed and duplex
561 uint
mii_parse_RTL8211B_sr(uint mii_reg
, struct tsec_private
* priv
)
565 mii_reg
= read_phy_reg(priv
, MIIM_RTL8211B_PHY_STATUS
);
566 if (!(mii_reg
& MIIM_RTL8211B_PHYSTAT_SPDDONE
)) {
569 /* in case of timeout ->link is cleared */
571 puts("Waiting for PHY realtime link");
572 while (!(mii_reg
& MIIM_RTL8211B_PHYSTAT_SPDDONE
)) {
573 /* Timeout reached ? */
574 if (i
> PHY_AUTONEGOTIATE_TIMEOUT
) {
575 puts(" TIMEOUT !\n");
580 if ((i
++ % 1000) == 0) {
583 udelay(1000); /* 1 ms */
584 mii_reg
= read_phy_reg(priv
, MIIM_RTL8211B_PHY_STATUS
);
587 udelay(500000); /* another 500 ms (results in faster booting) */
589 if (mii_reg
& MIIM_RTL8211B_PHYSTAT_LINK
)
595 if (mii_reg
& MIIM_RTL8211B_PHYSTAT_DUPLEX
)
600 speed
= (mii_reg
& MIIM_RTL8211B_PHYSTAT_SPEED
);
603 case MIIM_RTL8211B_PHYSTAT_GBIT
:
606 case MIIM_RTL8211B_PHYSTAT_100
:
616 /* Parse the cis8201's status register for speed and duplex
619 uint
mii_parse_cis8201(uint mii_reg
, struct tsec_private
* priv
)
623 if (mii_reg
& MIIM_CIS8201_AUXCONSTAT_DUPLEX
)
628 speed
= mii_reg
& MIIM_CIS8201_AUXCONSTAT_SPEED
;
630 case MIIM_CIS8201_AUXCONSTAT_GBIT
:
633 case MIIM_CIS8201_AUXCONSTAT_100
:
644 /* Parse the vsc8244's status register for speed and duplex
647 uint
mii_parse_vsc8244(uint mii_reg
, struct tsec_private
* priv
)
651 if (mii_reg
& MIIM_VSC8244_AUXCONSTAT_DUPLEX
)
656 speed
= mii_reg
& MIIM_VSC8244_AUXCONSTAT_SPEED
;
658 case MIIM_VSC8244_AUXCONSTAT_GBIT
:
661 case MIIM_VSC8244_AUXCONSTAT_100
:
672 /* Parse the DM9161's status register for speed and duplex
675 uint
mii_parse_dm9161_scsr(uint mii_reg
, struct tsec_private
* priv
)
677 if (mii_reg
& (MIIM_DM9161_SCSR_100F
| MIIM_DM9161_SCSR_100H
))
682 if (mii_reg
& (MIIM_DM9161_SCSR_100F
| MIIM_DM9161_SCSR_10F
))
691 * Hack to write all 4 PHYs with the LED values
693 uint
mii_cis8204_fixled(uint mii_reg
, struct tsec_private
* priv
)
696 volatile tsec_t
*regbase
= priv
->phyregs
;
697 int timeout
= 1000000;
699 for (phyid
= 0; phyid
< 4; phyid
++) {
700 regbase
->miimadd
= (phyid
<< 8) | mii_reg
;
701 regbase
->miimcon
= MIIM_CIS8204_SLEDCON_INIT
;
705 while ((regbase
->miimind
& MIIMIND_BUSY
) && timeout
--) ;
708 return MIIM_CIS8204_SLEDCON_INIT
;
711 uint
mii_cis8204_setmode(uint mii_reg
, struct tsec_private
* priv
)
713 if (priv
->flags
& TSEC_REDUCED
)
714 return MIIM_CIS8204_EPHYCON_INIT
| MIIM_CIS8204_EPHYCON_RGMII
;
716 return MIIM_CIS8204_EPHYCON_INIT
;
719 uint
mii_m88e1111s_setmode(uint mii_reg
, struct tsec_private
*priv
)
721 uint mii_data
= read_phy_reg(priv
, mii_reg
);
723 if (priv
->flags
& TSEC_REDUCED
)
724 mii_data
= (mii_data
& 0xfff0) | 0x000b;
728 /* Initialized required registers to appropriate values, zeroing
729 * those we don't care about (unless zero is bad, in which case,
730 * choose a more appropriate value)
732 static void init_registers(volatile tsec_t
* regs
)
735 regs
->ievent
= IEVENT_INIT_CLEAR
;
737 regs
->imask
= IMASK_INIT_CLEAR
;
739 regs
->hash
.iaddr0
= 0;
740 regs
->hash
.iaddr1
= 0;
741 regs
->hash
.iaddr2
= 0;
742 regs
->hash
.iaddr3
= 0;
743 regs
->hash
.iaddr4
= 0;
744 regs
->hash
.iaddr5
= 0;
745 regs
->hash
.iaddr6
= 0;
746 regs
->hash
.iaddr7
= 0;
748 regs
->hash
.gaddr0
= 0;
749 regs
->hash
.gaddr1
= 0;
750 regs
->hash
.gaddr2
= 0;
751 regs
->hash
.gaddr3
= 0;
752 regs
->hash
.gaddr4
= 0;
753 regs
->hash
.gaddr5
= 0;
754 regs
->hash
.gaddr6
= 0;
755 regs
->hash
.gaddr7
= 0;
757 regs
->rctrl
= 0x00000000;
759 /* Init RMON mib registers */
760 memset((void *)&(regs
->rmon
), 0, sizeof(rmon_mib_t
));
762 regs
->rmon
.cam1
= 0xffffffff;
763 regs
->rmon
.cam2
= 0xffffffff;
765 regs
->mrblr
= MRBLR_INIT_SETTINGS
;
767 regs
->minflr
= MINFLR_INIT_SETTINGS
;
769 regs
->attr
= ATTR_INIT_SETTINGS
;
770 regs
->attreli
= ATTRELI_INIT_SETTINGS
;
774 /* Configure maccfg2 based on negotiated speed and duplex
775 * reported by PHY handling code
777 static void adjust_link(struct eth_device
*dev
)
779 struct tsec_private
*priv
= (struct tsec_private
*)dev
->priv
;
780 volatile tsec_t
*regs
= priv
->regs
;
783 if (priv
->duplexity
!= 0)
784 regs
->maccfg2
|= MACCFG2_FULL_DUPLEX
;
786 regs
->maccfg2
&= ~(MACCFG2_FULL_DUPLEX
);
788 switch (priv
->speed
) {
790 regs
->maccfg2
= ((regs
->maccfg2
& ~(MACCFG2_IF
))
795 regs
->maccfg2
= ((regs
->maccfg2
& ~(MACCFG2_IF
))
798 /* Set R100 bit in all modes although
799 * it is only used in RGMII mode
801 if (priv
->speed
== 100)
802 regs
->ecntrl
|= ECNTRL_R100
;
804 regs
->ecntrl
&= ~(ECNTRL_R100
);
807 printf("%s: Speed was bad\n", dev
->name
);
811 printf("Speed: %d, %s duplex\n", priv
->speed
,
812 (priv
->duplexity
) ? "full" : "half");
815 printf("%s: No link.\n", dev
->name
);
819 /* Set up the buffers and their descriptors, and bring up the
822 static void startup_tsec(struct eth_device
*dev
)
825 struct tsec_private
*priv
= (struct tsec_private
*)dev
->priv
;
826 volatile tsec_t
*regs
= priv
->regs
;
828 /* Point to the buffer descriptors */
829 regs
->tbase
= (unsigned int)(&rtx
.txbd
[txIdx
]);
830 regs
->rbase
= (unsigned int)(&rtx
.rxbd
[rxIdx
]);
832 /* Initialize the Rx Buffer descriptors */
833 for (i
= 0; i
< PKTBUFSRX
; i
++) {
834 rtx
.rxbd
[i
].status
= RXBD_EMPTY
;
835 rtx
.rxbd
[i
].length
= 0;
836 rtx
.rxbd
[i
].bufPtr
= (uint
) NetRxPackets
[i
];
838 rtx
.rxbd
[PKTBUFSRX
- 1].status
|= RXBD_WRAP
;
840 /* Initialize the TX Buffer Descriptors */
841 for (i
= 0; i
< TX_BUF_CNT
; i
++) {
842 rtx
.txbd
[i
].status
= 0;
843 rtx
.txbd
[i
].length
= 0;
844 rtx
.txbd
[i
].bufPtr
= 0;
846 rtx
.txbd
[TX_BUF_CNT
- 1].status
|= TXBD_WRAP
;
848 /* Start up the PHY */
850 phy_run_commands(priv
, priv
->phyinfo
->startup
);
854 /* Enable Transmit and Receive */
855 regs
->maccfg1
|= (MACCFG1_RX_EN
| MACCFG1_TX_EN
);
857 /* Tell the DMA it is clear to go */
858 regs
->dmactrl
|= DMACTRL_INIT_SETTINGS
;
859 regs
->tstat
= TSTAT_CLEAR_THALT
;
860 regs
->rstat
= RSTAT_CLEAR_RHALT
;
861 regs
->dmactrl
&= ~(DMACTRL_GRS
| DMACTRL_GTS
);
864 /* This returns the status bits of the device. The return value
865 * is never checked, and this is what the 8260 driver did, so we
866 * do the same. Presumably, this would be zero if there were no
869 static int tsec_send(struct eth_device
*dev
, volatile void *packet
, int length
)
873 struct tsec_private
*priv
= (struct tsec_private
*)dev
->priv
;
874 volatile tsec_t
*regs
= priv
->regs
;
876 /* Find an empty buffer descriptor */
877 for (i
= 0; rtx
.txbd
[txIdx
].status
& TXBD_READY
; i
++) {
878 if (i
>= TOUT_LOOP
) {
879 debug("%s: tsec: tx buffers full\n", dev
->name
);
884 rtx
.txbd
[txIdx
].bufPtr
= (uint
) packet
;
885 rtx
.txbd
[txIdx
].length
= length
;
886 rtx
.txbd
[txIdx
].status
|=
887 (TXBD_READY
| TXBD_LAST
| TXBD_CRC
| TXBD_INTERRUPT
);
889 /* Tell the DMA to go */
890 regs
->tstat
= TSTAT_CLEAR_THALT
;
892 /* Wait for buffer to be transmitted */
893 for (i
= 0; rtx
.txbd
[txIdx
].status
& TXBD_READY
; i
++) {
894 if (i
>= TOUT_LOOP
) {
895 debug("%s: tsec: tx error\n", dev
->name
);
900 txIdx
= (txIdx
+ 1) % TX_BUF_CNT
;
901 result
= rtx
.txbd
[txIdx
].status
& TXBD_STATS
;
906 static int tsec_recv(struct eth_device
*dev
)
909 struct tsec_private
*priv
= (struct tsec_private
*)dev
->priv
;
910 volatile tsec_t
*regs
= priv
->regs
;
912 while (!(rtx
.rxbd
[rxIdx
].status
& RXBD_EMPTY
)) {
914 length
= rtx
.rxbd
[rxIdx
].length
;
916 /* Send the packet up if there were no errors */
917 if (!(rtx
.rxbd
[rxIdx
].status
& RXBD_STATS
)) {
918 NetReceive(NetRxPackets
[rxIdx
], length
- 4);
920 printf("Got error %x\n",
921 (rtx
.rxbd
[rxIdx
].status
& RXBD_STATS
));
924 rtx
.rxbd
[rxIdx
].length
= 0;
926 /* Set the wrap bit if this is the last element in the list */
927 rtx
.rxbd
[rxIdx
].status
=
928 RXBD_EMPTY
| (((rxIdx
+ 1) == PKTBUFSRX
) ? RXBD_WRAP
: 0);
930 rxIdx
= (rxIdx
+ 1) % PKTBUFSRX
;
933 if (regs
->ievent
& IEVENT_BSY
) {
934 regs
->ievent
= IEVENT_BSY
;
935 regs
->rstat
= RSTAT_CLEAR_RHALT
;
942 /* Stop the interface */
943 static void tsec_halt(struct eth_device
*dev
)
945 struct tsec_private
*priv
= (struct tsec_private
*)dev
->priv
;
946 volatile tsec_t
*regs
= priv
->regs
;
948 regs
->dmactrl
&= ~(DMACTRL_GRS
| DMACTRL_GTS
);
949 regs
->dmactrl
|= (DMACTRL_GRS
| DMACTRL_GTS
);
951 while (!(regs
->ievent
& (IEVENT_GRSC
| IEVENT_GTSC
))) ;
953 regs
->maccfg1
&= ~(MACCFG1_TX_EN
| MACCFG1_RX_EN
);
955 /* Shut down the PHY, as needed */
957 phy_run_commands(priv
, priv
->phyinfo
->shutdown
);
960 struct phy_info phy_info_M88E1149S
= {
964 (struct phy_cmd
[]){ /* config */
965 /* Reset and configure the PHY */
966 {MIIM_CONTROL
, MIIM_CONTROL_RESET
, NULL
},
968 {0x1e, 0x200c, NULL
},
972 {MIIM_GBIT_CONTROL
, MIIM_GBIT_CONTROL_INIT
, NULL
},
973 {MIIM_ANAR
, MIIM_ANAR_INIT
, NULL
},
974 {MIIM_CONTROL
, MIIM_CONTROL_RESET
, NULL
},
975 {MIIM_CONTROL
, MIIM_CONTROL_INIT
, &mii_cr_init
},
978 (struct phy_cmd
[]){ /* startup */
979 /* Status is read once to clear old link state */
980 {MIIM_STATUS
, miim_read
, NULL
},
982 {MIIM_STATUS
, miim_read
, &mii_parse_sr
},
983 /* Read the status */
984 {MIIM_88E1011_PHY_STATUS
, miim_read
,
985 &mii_parse_88E1011_psr
},
988 (struct phy_cmd
[]){ /* shutdown */
993 /* The 5411 id is 0x206070, the 5421 is 0x2060e0 */
994 struct phy_info phy_info_BCM5461S
= {
995 0x02060c1, /* 5461 ID */
997 0, /* not clear to me what minor revisions we can shift away */
998 (struct phy_cmd
[]) { /* config */
999 /* Reset and configure the PHY */
1000 {MIIM_CONTROL
, MIIM_CONTROL_RESET
, NULL
},
1001 {MIIM_GBIT_CONTROL
, MIIM_GBIT_CONTROL_INIT
, NULL
},
1002 {MIIM_ANAR
, MIIM_ANAR_INIT
, NULL
},
1003 {MIIM_CONTROL
, MIIM_CONTROL_RESET
, NULL
},
1004 {MIIM_CONTROL
, MIIM_CONTROL_INIT
, &mii_cr_init
},
1007 (struct phy_cmd
[]) { /* startup */
1008 /* Status is read once to clear old link state */
1009 {MIIM_STATUS
, miim_read
, NULL
},
1010 /* Auto-negotiate */
1011 {MIIM_STATUS
, miim_read
, &mii_parse_sr
},
1012 /* Read the status */
1013 {MIIM_BCM54xx_AUXSTATUS
, miim_read
, &mii_parse_BCM54xx_sr
},
1016 (struct phy_cmd
[]) { /* shutdown */
1021 struct phy_info phy_info_BCM5464S
= {
1022 0x02060b1, /* 5464 ID */
1023 "Broadcom BCM5464S",
1024 0, /* not clear to me what minor revisions we can shift away */
1025 (struct phy_cmd
[]) { /* config */
1026 /* Reset and configure the PHY */
1027 {MIIM_CONTROL
, MIIM_CONTROL_RESET
, NULL
},
1028 {MIIM_GBIT_CONTROL
, MIIM_GBIT_CONTROL_INIT
, NULL
},
1029 {MIIM_ANAR
, MIIM_ANAR_INIT
, NULL
},
1030 {MIIM_CONTROL
, MIIM_CONTROL_RESET
, NULL
},
1031 {MIIM_CONTROL
, MIIM_CONTROL_INIT
, &mii_cr_init
},
1034 (struct phy_cmd
[]) { /* startup */
1035 /* Status is read once to clear old link state */
1036 {MIIM_STATUS
, miim_read
, NULL
},
1037 /* Auto-negotiate */
1038 {MIIM_STATUS
, miim_read
, &mii_parse_sr
},
1039 /* Read the status */
1040 {MIIM_BCM54xx_AUXSTATUS
, miim_read
, &mii_parse_BCM54xx_sr
},
1043 (struct phy_cmd
[]) { /* shutdown */
1048 struct phy_info phy_info_M88E1011S
= {
1052 (struct phy_cmd
[]){ /* config */
1053 /* Reset and configure the PHY */
1054 {MIIM_CONTROL
, MIIM_CONTROL_RESET
, NULL
},
1056 {0x1e, 0x200c, NULL
},
1059 {0x1e, 0x100, NULL
},
1060 {MIIM_GBIT_CONTROL
, MIIM_GBIT_CONTROL_INIT
, NULL
},
1061 {MIIM_ANAR
, MIIM_ANAR_INIT
, NULL
},
1062 {MIIM_CONTROL
, MIIM_CONTROL_RESET
, NULL
},
1063 {MIIM_CONTROL
, MIIM_CONTROL_INIT
, &mii_cr_init
},
1066 (struct phy_cmd
[]){ /* startup */
1067 /* Status is read once to clear old link state */
1068 {MIIM_STATUS
, miim_read
, NULL
},
1069 /* Auto-negotiate */
1070 {MIIM_STATUS
, miim_read
, &mii_parse_sr
},
1071 /* Read the status */
1072 {MIIM_88E1011_PHY_STATUS
, miim_read
,
1073 &mii_parse_88E1011_psr
},
1076 (struct phy_cmd
[]){ /* shutdown */
1081 struct phy_info phy_info_M88E1111S
= {
1085 (struct phy_cmd
[]){ /* config */
1086 /* Reset and configure the PHY */
1087 {MIIM_CONTROL
, MIIM_CONTROL_RESET
, NULL
},
1088 {0x1b, 0x848f, &mii_m88e1111s_setmode
},
1089 {0x14, 0x0cd2, NULL
}, /* Delay RGMII TX and RX */
1090 {MIIM_GBIT_CONTROL
, MIIM_GBIT_CONTROL_INIT
, NULL
},
1091 {MIIM_ANAR
, MIIM_ANAR_INIT
, NULL
},
1092 {MIIM_CONTROL
, MIIM_CONTROL_RESET
, NULL
},
1093 {MIIM_CONTROL
, MIIM_CONTROL_INIT
, &mii_cr_init
},
1096 (struct phy_cmd
[]){ /* startup */
1097 /* Status is read once to clear old link state */
1098 {MIIM_STATUS
, miim_read
, NULL
},
1099 /* Auto-negotiate */
1100 {MIIM_STATUS
, miim_read
, &mii_parse_sr
},
1101 /* Read the status */
1102 {MIIM_88E1011_PHY_STATUS
, miim_read
,
1103 &mii_parse_88E1011_psr
},
1106 (struct phy_cmd
[]){ /* shutdown */
1111 struct phy_info phy_info_M88E1118
= {
1115 (struct phy_cmd
[]){ /* config */
1116 /* Reset and configure the PHY */
1117 {MIIM_CONTROL
, MIIM_CONTROL_RESET
, NULL
},
1118 {0x16, 0x0002, NULL
}, /* Change Page Number */
1119 {0x15, 0x1070, NULL
}, /* Delay RGMII TX and RX */
1120 {MIIM_GBIT_CONTROL
, MIIM_GBIT_CONTROL_INIT
, NULL
},
1121 {MIIM_ANAR
, MIIM_ANAR_INIT
, NULL
},
1122 {MIIM_CONTROL
, MIIM_CONTROL_RESET
, NULL
},
1123 {MIIM_CONTROL
, MIIM_CONTROL_INIT
, &mii_cr_init
},
1126 (struct phy_cmd
[]){ /* startup */
1127 {0x16, 0x0000, NULL
}, /* Change Page Number */
1128 /* Status is read once to clear old link state */
1129 {MIIM_STATUS
, miim_read
, NULL
},
1130 /* Auto-negotiate */
1131 /* Read the status */
1132 {MIIM_88E1011_PHY_STATUS
, miim_read
,
1133 &mii_parse_88E1011_psr
},
1136 (struct phy_cmd
[]){ /* shutdown */
1142 * Since to access LED register we need do switch the page, we
1143 * do LED configuring in the miim_read-like function as follows
1145 uint
mii_88E1121_set_led (uint mii_reg
, struct tsec_private
*priv
)
1149 /* Switch the page to access the led register */
1150 pg
= read_phy_reg(priv
, MIIM_88E1121_PHY_PAGE
);
1151 write_phy_reg(priv
, MIIM_88E1121_PHY_PAGE
, MIIM_88E1121_PHY_LED_PAGE
);
1153 /* Configure leds */
1154 write_phy_reg(priv
, MIIM_88E1121_PHY_LED_CTRL
,
1155 MIIM_88E1121_PHY_LED_DEF
);
1157 /* Restore the page pointer */
1158 write_phy_reg(priv
, MIIM_88E1121_PHY_PAGE
, pg
);
1162 struct phy_info phy_info_M88E1121R
= {
1166 (struct phy_cmd
[]){ /* config */
1167 /* Reset and configure the PHY */
1168 {MIIM_CONTROL
, MIIM_CONTROL_RESET
, NULL
},
1169 {MIIM_GBIT_CONTROL
, MIIM_GBIT_CONTROL_INIT
, NULL
},
1170 {MIIM_ANAR
, MIIM_ANAR_INIT
, NULL
},
1171 /* Configure leds */
1172 {MIIM_88E1121_PHY_LED_CTRL
, miim_read
,
1173 &mii_88E1121_set_led
},
1174 {MIIM_CONTROL
, MIIM_CONTROL_INIT
, &mii_cr_init
},
1177 (struct phy_cmd
[]){ /* startup */
1178 /* Status is read once to clear old link state */
1179 {MIIM_STATUS
, miim_read
, NULL
},
1180 {MIIM_STATUS
, miim_read
, &mii_parse_sr
},
1181 {MIIM_STATUS
, miim_read
, &mii_parse_link
},
1184 (struct phy_cmd
[]){ /* shutdown */
1189 static unsigned int m88e1145_setmode(uint mii_reg
, struct tsec_private
*priv
)
1191 uint mii_data
= read_phy_reg(priv
, mii_reg
);
1193 /* Setting MIIM_88E1145_PHY_EXT_CR */
1194 if (priv
->flags
& TSEC_REDUCED
)
1196 MIIM_M88E1145_RGMII_RX_DELAY
| MIIM_M88E1145_RGMII_TX_DELAY
;
1201 static struct phy_info phy_info_M88E1145
= {
1205 (struct phy_cmd
[]){ /* config */
1207 {MIIM_CONTROL
, MIIM_CONTROL_RESET
, NULL
},
1215 /* Configure the PHY */
1216 {MIIM_GBIT_CONTROL
, MIIM_GBIT_CONTROL_INIT
, NULL
},
1217 {MIIM_ANAR
, MIIM_ANAR_INIT
, NULL
},
1218 {MIIM_88E1011_PHY_SCR
, MIIM_88E1011_PHY_MDI_X_AUTO
,
1220 {MIIM_88E1145_PHY_EXT_CR
, 0, &m88e1145_setmode
},
1221 {MIIM_CONTROL
, MIIM_CONTROL_RESET
, NULL
},
1222 {MIIM_CONTROL
, MIIM_CONTROL_INIT
, NULL
},
1225 (struct phy_cmd
[]){ /* startup */
1226 /* Status is read once to clear old link state */
1227 {MIIM_STATUS
, miim_read
, NULL
},
1228 /* Auto-negotiate */
1229 {MIIM_STATUS
, miim_read
, &mii_parse_sr
},
1230 {MIIM_88E1111_PHY_LED_CONTROL
,
1231 MIIM_88E1111_PHY_LED_DIRECT
, NULL
},
1232 /* Read the Status */
1233 {MIIM_88E1011_PHY_STATUS
, miim_read
,
1234 &mii_parse_88E1011_psr
},
1237 (struct phy_cmd
[]){ /* shutdown */
1242 struct phy_info phy_info_cis8204
= {
1246 (struct phy_cmd
[]){ /* config */
1247 /* Override PHY config settings */
1248 {MIIM_CIS8201_AUX_CONSTAT
,
1249 MIIM_CIS8201_AUXCONSTAT_INIT
, NULL
},
1250 /* Configure some basic stuff */
1251 {MIIM_CONTROL
, MIIM_CONTROL_INIT
, &mii_cr_init
},
1252 {MIIM_CIS8204_SLED_CON
, MIIM_CIS8204_SLEDCON_INIT
,
1253 &mii_cis8204_fixled
},
1254 {MIIM_CIS8204_EPHY_CON
, MIIM_CIS8204_EPHYCON_INIT
,
1255 &mii_cis8204_setmode
},
1258 (struct phy_cmd
[]){ /* startup */
1259 /* Read the Status (2x to make sure link is right) */
1260 {MIIM_STATUS
, miim_read
, NULL
},
1261 /* Auto-negotiate */
1262 {MIIM_STATUS
, miim_read
, &mii_parse_sr
},
1263 /* Read the status */
1264 {MIIM_CIS8201_AUX_CONSTAT
, miim_read
,
1265 &mii_parse_cis8201
},
1268 (struct phy_cmd
[]){ /* shutdown */
1274 struct phy_info phy_info_cis8201
= {
1278 (struct phy_cmd
[]){ /* config */
1279 /* Override PHY config settings */
1280 {MIIM_CIS8201_AUX_CONSTAT
,
1281 MIIM_CIS8201_AUXCONSTAT_INIT
, NULL
},
1282 /* Set up the interface mode */
1283 {MIIM_CIS8201_EXT_CON1
, MIIM_CIS8201_EXTCON1_INIT
,
1285 /* Configure some basic stuff */
1286 {MIIM_CONTROL
, MIIM_CONTROL_INIT
, &mii_cr_init
},
1289 (struct phy_cmd
[]){ /* startup */
1290 /* Read the Status (2x to make sure link is right) */
1291 {MIIM_STATUS
, miim_read
, NULL
},
1292 /* Auto-negotiate */
1293 {MIIM_STATUS
, miim_read
, &mii_parse_sr
},
1294 /* Read the status */
1295 {MIIM_CIS8201_AUX_CONSTAT
, miim_read
,
1296 &mii_parse_cis8201
},
1299 (struct phy_cmd
[]){ /* shutdown */
1303 struct phy_info phy_info_VSC8244
= {
1307 (struct phy_cmd
[]){ /* config */
1308 /* Override PHY config settings */
1309 /* Configure some basic stuff */
1310 {MIIM_CONTROL
, MIIM_CONTROL_INIT
, &mii_cr_init
},
1313 (struct phy_cmd
[]){ /* startup */
1314 /* Read the Status (2x to make sure link is right) */
1315 {MIIM_STATUS
, miim_read
, NULL
},
1316 /* Auto-negotiate */
1317 {MIIM_STATUS
, miim_read
, &mii_parse_sr
},
1318 /* Read the status */
1319 {MIIM_VSC8244_AUX_CONSTAT
, miim_read
,
1320 &mii_parse_vsc8244
},
1323 (struct phy_cmd
[]){ /* shutdown */
1328 struct phy_info phy_info_VSC8601
= {
1332 (struct phy_cmd
[]){ /* config */
1333 /* Override PHY config settings */
1334 /* Configure some basic stuff */
1335 {MIIM_CONTROL
, MIIM_CONTROL_INIT
, &mii_cr_init
},
1336 #ifdef CFG_VSC8601_SKEWFIX
1337 {MIIM_VSC8601_EPHY_CON
,MIIM_VSC8601_EPHY_CON_INIT_SKEW
,NULL
},
1338 #if defined(CFG_VSC8601_SKEW_TX) && defined(CFG_VSC8601_SKEW_RX)
1339 {MIIM_EXT_PAGE_ACCESS
,1,NULL
},
1340 #define VSC8101_SKEW (CFG_VSC8601_SKEW_TX<<14)|(CFG_VSC8601_SKEW_RX<<12)
1341 {MIIM_VSC8601_SKEW_CTRL
,VSC8101_SKEW
,NULL
},
1342 {MIIM_EXT_PAGE_ACCESS
,0,NULL
},
1347 (struct phy_cmd
[]){ /* startup */
1348 /* Read the Status (2x to make sure link is right) */
1349 {MIIM_STATUS
, miim_read
, NULL
},
1350 /* Auto-negotiate */
1351 {MIIM_STATUS
, miim_read
, &mii_parse_sr
},
1352 /* Read the status */
1353 {MIIM_VSC8244_AUX_CONSTAT
, miim_read
,
1354 &mii_parse_vsc8244
},
1357 (struct phy_cmd
[]){ /* shutdown */
1363 struct phy_info phy_info_dm9161
= {
1367 (struct phy_cmd
[]){ /* config */
1368 {MIIM_CONTROL
, MIIM_DM9161_CR_STOP
, NULL
},
1369 /* Do not bypass the scrambler/descrambler */
1370 {MIIM_DM9161_SCR
, MIIM_DM9161_SCR_INIT
, NULL
},
1371 /* Clear 10BTCSR to default */
1372 {MIIM_DM9161_10BTCSR
, MIIM_DM9161_10BTCSR_INIT
,
1374 /* Configure some basic stuff */
1375 {MIIM_CONTROL
, MIIM_CR_INIT
, NULL
},
1376 /* Restart Auto Negotiation */
1377 {MIIM_CONTROL
, MIIM_DM9161_CR_RSTAN
, NULL
},
1380 (struct phy_cmd
[]){ /* startup */
1381 /* Status is read once to clear old link state */
1382 {MIIM_STATUS
, miim_read
, NULL
},
1383 /* Auto-negotiate */
1384 {MIIM_STATUS
, miim_read
, &mii_parse_sr
},
1385 /* Read the status */
1386 {MIIM_DM9161_SCSR
, miim_read
,
1387 &mii_parse_dm9161_scsr
},
1390 (struct phy_cmd
[]){ /* shutdown */
1394 /* a generic flavor. */
1395 struct phy_info phy_info_generic
= {
1397 "Unknown/Generic PHY",
1399 (struct phy_cmd
[]) { /* config */
1400 {PHY_BMCR
, PHY_BMCR_RESET
, NULL
},
1401 {PHY_BMCR
, PHY_BMCR_AUTON
|PHY_BMCR_RST_NEG
, NULL
},
1404 (struct phy_cmd
[]) { /* startup */
1405 {PHY_BMSR
, miim_read
, NULL
},
1406 {PHY_BMSR
, miim_read
, &mii_parse_sr
},
1407 {PHY_BMSR
, miim_read
, &mii_parse_link
},
1410 (struct phy_cmd
[]) { /* shutdown */
1416 uint
mii_parse_lxt971_sr2(uint mii_reg
, struct tsec_private
*priv
)
1420 speed
= mii_reg
& MIIM_LXT971_SR2_SPEED_MASK
;
1423 case MIIM_LXT971_SR2_10HDX
:
1425 priv
->duplexity
= 0;
1427 case MIIM_LXT971_SR2_10FDX
:
1429 priv
->duplexity
= 1;
1431 case MIIM_LXT971_SR2_100HDX
:
1433 priv
->duplexity
= 0;
1437 priv
->duplexity
= 1;
1441 priv
->duplexity
= 0;
1447 static struct phy_info phy_info_lxt971
= {
1451 (struct phy_cmd
[]){ /* config */
1452 {MIIM_CR
, MIIM_CR_INIT
, mii_cr_init
}, /* autonegotiate */
1455 (struct phy_cmd
[]){ /* startup - enable interrupts */
1456 /* { 0x12, 0x00f2, NULL }, */
1457 {MIIM_STATUS
, miim_read
, NULL
},
1458 {MIIM_STATUS
, miim_read
, &mii_parse_sr
},
1459 {MIIM_LXT971_SR2
, miim_read
, &mii_parse_lxt971_sr2
},
1462 (struct phy_cmd
[]){ /* shutdown - disable interrupts */
1467 /* Parse the DP83865's link and auto-neg status register for speed and duplex
1470 uint
mii_parse_dp83865_lanr(uint mii_reg
, struct tsec_private
*priv
)
1472 switch (mii_reg
& MIIM_DP83865_SPD_MASK
) {
1474 case MIIM_DP83865_SPD_1000
:
1478 case MIIM_DP83865_SPD_100
:
1488 if (mii_reg
& MIIM_DP83865_DPX_FULL
)
1489 priv
->duplexity
= 1;
1491 priv
->duplexity
= 0;
1496 struct phy_info phy_info_dp83865
= {
1500 (struct phy_cmd
[]){ /* config */
1501 {MIIM_CONTROL
, MIIM_DP83865_CR_INIT
, NULL
},
1504 (struct phy_cmd
[]){ /* startup */
1505 /* Status is read once to clear old link state */
1506 {MIIM_STATUS
, miim_read
, NULL
},
1507 /* Auto-negotiate */
1508 {MIIM_STATUS
, miim_read
, &mii_parse_sr
},
1509 /* Read the link and auto-neg status */
1510 {MIIM_DP83865_LANR
, miim_read
,
1511 &mii_parse_dp83865_lanr
},
1514 (struct phy_cmd
[]){ /* shutdown */
1519 struct phy_info phy_info_rtl8211b
= {
1523 (struct phy_cmd
[]){ /* config */
1524 /* Reset and configure the PHY */
1525 {MIIM_CONTROL
, MIIM_CONTROL_RESET
, NULL
},
1526 {MIIM_GBIT_CONTROL
, MIIM_GBIT_CONTROL_INIT
, NULL
},
1527 {MIIM_ANAR
, MIIM_ANAR_INIT
, NULL
},
1528 {MIIM_CONTROL
, MIIM_CONTROL_RESET
, NULL
},
1529 {MIIM_CONTROL
, MIIM_CONTROL_INIT
, &mii_cr_init
},
1532 (struct phy_cmd
[]){ /* startup */
1533 /* Status is read once to clear old link state */
1534 {MIIM_STATUS
, miim_read
, NULL
},
1535 /* Auto-negotiate */
1536 {MIIM_STATUS
, miim_read
, &mii_parse_sr
},
1537 /* Read the status */
1538 {MIIM_RTL8211B_PHY_STATUS
, miim_read
, &mii_parse_RTL8211B_sr
},
1541 (struct phy_cmd
[]){ /* shutdown */
1546 struct phy_info
*phy_info
[] = {
1551 &phy_info_M88E1011S
,
1552 &phy_info_M88E1111S
,
1554 &phy_info_M88E1121R
,
1556 &phy_info_M88E1149S
,
1567 /* Grab the identifier of the device's PHY, and search through
1568 * all of the known PHYs to see if one matches. If so, return
1569 * it, if not, return NULL
1571 struct phy_info
*get_phy_info(struct eth_device
*dev
)
1573 struct tsec_private
*priv
= (struct tsec_private
*)dev
->priv
;
1574 uint phy_reg
, phy_ID
;
1576 struct phy_info
*theInfo
= NULL
;
1578 /* Grab the bits from PHYIR1, and put them in the upper half */
1579 phy_reg
= read_phy_reg(priv
, MIIM_PHYIR1
);
1580 phy_ID
= (phy_reg
& 0xffff) << 16;
1582 /* Grab the bits from PHYIR2, and put them in the lower half */
1583 phy_reg
= read_phy_reg(priv
, MIIM_PHYIR2
);
1584 phy_ID
|= (phy_reg
& 0xffff);
1586 /* loop through all the known PHY types, and find one that */
1587 /* matches the ID we read from the PHY. */
1588 for (i
= 0; phy_info
[i
]; i
++) {
1589 if (phy_info
[i
]->id
== (phy_ID
>> phy_info
[i
]->shift
)) {
1590 theInfo
= phy_info
[i
];
1595 if (theInfo
== NULL
) {
1596 printf("%s: PHY id %x is not supported!\n", dev
->name
, phy_ID
);
1599 debug("%s: PHY is %s (%x)\n", dev
->name
, theInfo
->name
, phy_ID
);
1605 /* Execute the given series of commands on the given device's
1606 * PHY, running functions as necessary
1608 void phy_run_commands(struct tsec_private
*priv
, struct phy_cmd
*cmd
)
1612 volatile tsec_t
*phyregs
= priv
->phyregs
;
1614 phyregs
->miimcfg
= MIIMCFG_RESET
;
1616 phyregs
->miimcfg
= MIIMCFG_INIT_VALUE
;
1618 while (phyregs
->miimind
& MIIMIND_BUSY
) ;
1620 for (i
= 0; cmd
->mii_reg
!= miim_end
; i
++) {
1621 if (cmd
->mii_data
== miim_read
) {
1622 result
= read_phy_reg(priv
, cmd
->mii_reg
);
1624 if (cmd
->funct
!= NULL
)
1625 (*(cmd
->funct
)) (result
, priv
);
1628 if (cmd
->funct
!= NULL
)
1629 result
= (*(cmd
->funct
)) (cmd
->mii_reg
, priv
);
1631 result
= cmd
->mii_data
;
1633 write_phy_reg(priv
, cmd
->mii_reg
, result
);
1640 /* Relocate the function pointers in the phy cmd lists */
1641 static void relocate_cmds(void)
1643 struct phy_cmd
**cmdlistptr
;
1644 struct phy_cmd
*cmd
;
1647 for (i
= 0; phy_info
[i
]; i
++) {
1648 /* First thing's first: relocate the pointers to the
1649 * PHY command structures (the structs were done) */
1650 phy_info
[i
] = (struct phy_info
*)((uint
) phy_info
[i
]
1652 phy_info
[i
]->name
+= gd
->reloc_off
;
1653 phy_info
[i
]->config
=
1654 (struct phy_cmd
*)((uint
) phy_info
[i
]->config
1656 phy_info
[i
]->startup
=
1657 (struct phy_cmd
*)((uint
) phy_info
[i
]->startup
1659 phy_info
[i
]->shutdown
=
1660 (struct phy_cmd
*)((uint
) phy_info
[i
]->shutdown
1663 cmdlistptr
= &phy_info
[i
]->config
;
1665 for (; cmdlistptr
<= &phy_info
[i
]->shutdown
; cmdlistptr
++) {
1667 for (cmd
= *cmdlistptr
;
1668 cmd
->mii_reg
!= miim_end
;
1670 /* Only relocate non-NULL pointers */
1672 cmd
->funct
+= gd
->reloc_off
;
1683 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) \
1684 && !defined(BITBANGMII)
1687 * Read a MII PHY register.
1692 static int tsec_miiphy_read(char *devname
, unsigned char addr
,
1693 unsigned char reg
, unsigned short *value
)
1696 struct tsec_private
*priv
= privlist
[0];
1699 printf("Can't read PHY at address %d\n", addr
);
1703 ret
= (unsigned short)read_any_phy_reg(priv
, addr
, reg
);
1710 * Write a MII PHY register.
1715 static int tsec_miiphy_write(char *devname
, unsigned char addr
,
1716 unsigned char reg
, unsigned short value
)
1718 struct tsec_private
*priv
= privlist
[0];
1721 printf("Can't write PHY at address %d\n", addr
);
1725 write_any_phy_reg(priv
, addr
, reg
, value
);
1732 #ifdef CONFIG_MCAST_TFTP
1734 /* CREDITS: linux gianfar driver, slightly adjusted... thanx. */
1736 /* Set the appropriate hash bit for the given addr */
1738 /* The algorithm works like so:
1739 * 1) Take the Destination Address (ie the multicast address), and
1740 * do a CRC on it (little endian), and reverse the bits of the
1742 * 2) Use the 8 most significant bits as a hash into a 256-entry
1743 * table. The table is controlled through 8 32-bit registers:
1744 * gaddr0-7. gaddr0's MSB is entry 0, and gaddr7's LSB is
1745 * gaddr7. This means that the 3 most significant bits in the
1746 * hash index which gaddr register to use, and the 5 other bits
1747 * indicate which bit (assuming an IBM numbering scheme, which
1748 * for PowerPC (tm) is usually the case) in the tregister holds
1751 tsec_mcast_addr (struct eth_device
*dev
, u8 mcast_mac
, u8 set
)
1753 struct tsec_private
*priv
= privlist
[1];
1754 volatile tsec_t
*regs
= priv
->regs
;
1755 volatile u32
*reg_array
, value
;
1756 u8 result
, whichbit
, whichreg
;
1758 result
= (u8
)((ether_crc(MAC_ADDR_LEN
,mcast_mac
) >> 24) & 0xff);
1759 whichbit
= result
& 0x1f; /* the 5 LSB = which bit to set */
1760 whichreg
= result
>> 5; /* the 3 MSB = which reg to set it in */
1761 value
= (1 << (31-whichbit
));
1763 reg_array
= &(regs
->hash
.gaddr0
);
1766 reg_array
[whichreg
] |= value
;
1768 reg_array
[whichreg
] &= ~value
;
1772 #endif /* Multicast TFTP ? */