2 * Broadcom 53xx RoboSwitch device driver.
4 * Copyright 2007, Broadcom Corporation
7 * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
8 * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
9 * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
10 * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
22 #include <bcmendian.h>
23 #include <bcmparams.h>
27 #include <proto/ethernet.h>
29 #define ET_ERROR(args)
33 * Switch can be programmed through SPI interface, which
34 * has a rreg and a wreg functions to read from and write to
38 /* MII access registers */
39 #define PSEUDO_PHYAD 0x1E /* MII Pseudo PHY address */
40 #define REG_MII_PAGE 0x10 /* MII Page register */
41 #define REG_MII_ADDR 0x11 /* MII Address register */
42 #define REG_MII_DATA0 0x18 /* MII Data register 0 */
43 #define REG_MII_DATA1 0x19 /* MII Data register 1 */
44 #define REG_MII_DATA2 0x1a /* MII Data register 2 */
45 #define REG_MII_DATA3 0x1b /* MII Data register 3 */
48 #define PAGE_CTRL 0x00 /* Control page */
49 #define PAGE_STATUS 0x01 /* Status page */ /*Foxconn added by EricHuang, 09/27/2006*/
50 #define PAGE_MMR 0x02 /* 5397 Management/Mirroring page */
51 #define PAGE_VTBL 0x05 /* ARL/VLAN Table access page */
52 #define PAGE_VLAN 0x34 /* VLAN page */
54 /* Control page registers */
55 #define REG_CTRL_PORT0 0x00 /* Port 0 traffic control register */
56 #define REG_CTRL_PORT1 0x01 /* Port 1 traffic control register */
57 #define REG_CTRL_PORT2 0x02 /* Port 2 traffic control register */
58 #define REG_CTRL_PORT3 0x03 /* Port 3 traffic control register */
59 #define REG_CTRL_PORT4 0x04 /* Port 4 traffic control register */
60 #define REG_CTRL_PORT5 0x05 /* Port 5 traffic control register */
61 #define REG_CTRL_PORT6 0x06 /* Port 6 traffic control register */
62 #define REG_CTRL_PORT7 0x07 /* Port 7 traffic control register */
63 #define REG_CTRL_MODE 0x0B /* Switch Mode register */
64 #define REG_CTRL_MIIPO 0x0E /* 5325: MII Port Override register */
65 #define REG_CTRL_SRST 0x79 /* Software reset control register */
67 /* Foxconn added start by EricHuang, 09/27/2006 */
68 /* Status page registers */
69 #define REG_LINK_SUM 0x00 /* Link Status summary register, 16-bit */
70 #define REG_SPEED_SUM 0x04 /* Port speed summary register, 16-bit */
71 #define REG_DUPLEX_SUM 0x06 /* Duplex status summary register, 16-bit */
72 /* Foxconn added end by EricHuang, 09/27/2006 */
74 #define REG_DEVICE_ID 0x30 /* 539x Device id: */
75 #define DEVID5325 0x25 /* 5325 (Not really be we fake it) */
76 #define DEVID5395 0x95 /* 5395 */
77 #define DEVID5397 0x97 /* 5397 */
78 #define DEVID5398 0x98 /* 5398 */
80 /* VLAN page registers */
81 #define REG_VLAN_CTRL0 0x00 /* VLAN Control 0 register */
82 #define REG_VLAN_CTRL1 0x01 /* VLAN Control 1 register */
83 #define REG_VLAN_CTRL4 0x04 /* VLAN Control 4 register */
84 #define REG_VLAN_CTRL5 0x05 /* VLAN Control 5 register */
85 #define REG_VLAN_ACCESS 0x06 /* VLAN Table Access register */
86 #define REG_VLAN_ACCESS_5365 0x08 /* 5365 VLAN Table Access register */
87 #define REG_VLAN_WRITE 0x08 /* VLAN Write register */
88 #define REG_VLAN_WRITE_5365 0x0A /* 5365 VLAN Write register */
89 #define REG_VLAN_READ 0x0C /* VLAN Read register */
90 #define REG_VLAN_PTAG0 0x10 /* VLAN Default Port Tag register - port 0 */
91 #define REG_VLAN_PTAG1 0x12 /* VLAN Default Port Tag register - port 1 */
92 #define REG_VLAN_PTAG2 0x14 /* VLAN Default Port Tag register - port 2 */
93 #define REG_VLAN_PTAG3 0x16 /* VLAN Default Port Tag register - port 3 */
94 #define REG_VLAN_PTAG4 0x18 /* VLAN Default Port Tag register - port 4 */
95 #define REG_VLAN_PTAG5 0x1a /* VLAN Default Port Tag register - port 5 */
96 #define REG_VLAN_PTAG6 0x1c /* VLAN Default Port Tag register - port 6 */
97 #define REG_VLAN_PTAG7 0x1e /* VLAN Default Port Tag register - port 7 */
98 #define REG_VLAN_PTAG8 0x20 /* 539x: VLAN Default Port Tag register - IMP port */
99 #define REG_VLAN_PMAP 0x20 /* 5325: VLAN Priority Re-map register */
101 #define VLAN_NUMVLANS 16 /* # of VLANs */
104 /* ARL/VLAN Table Access page registers */
105 #define REG_VTBL_CTRL 0x00 /* ARL Read/Write Control */
106 #define REG_VTBL_MINDX 0x02 /* MAC Address Index */
107 #define REG_VTBL_VINDX 0x08 /* VID Table Index */
108 #define REG_VTBL_ARL_E0 0x10 /* ARL Entry 0 */
109 #define REG_VTBL_ARL_E1 0x18 /* ARL Entry 1 */
110 #define REG_VTBL_DAT_E0 0x18 /* ARL Table Data Entry 0 */
111 #define REG_VTBL_SCTRL 0x20 /* ARL Search Control */
112 #define REG_VTBL_SADDR 0x22 /* ARL Search Address */
113 #define REG_VTBL_SRES 0x24 /* ARL Search Result */
114 #define REG_VTBL_SREXT 0x2c /* ARL Search Result */
115 #define REG_VTBL_VID_E0 0x30 /* VID Entry 0 */
116 #define REG_VTBL_VID_E1 0x32 /* VID Entry 1 */
117 #define REG_VTBL_PREG 0xFF /* Page Register */
118 #define REG_VTBL_ACCESS 0x60 /* VLAN table access register */
119 #define REG_VTBL_INDX 0x61 /* VLAN table address index register */
120 #define REG_VTBL_ENTRY 0x63 /* VLAN table entry register */
121 #define REG_VTBL_ACCESS_5395 0x80 /* VLAN table access register */
122 #define REG_VTBL_INDX_5395 0x81 /* VLAN table address index register */
123 #define REG_VTBL_ENTRY_5395 0x83 /* VLAN table entry register */
126 #define REG_SPI_PAGE 0xff /* SPI Page register */
128 /* Access switch registers through GPIO/SPI */
130 /* Minimum timing constants */
131 #define SCK_EDGE_TIME 2 /* clock edge duration - 2us */
132 #define MOSI_SETUP_TIME 1 /* input setup duration - 1us */
133 #define SS_SETUP_TIME 1 /* select setup duration - 1us */
135 /* misc. constants */
136 #define SPI_MAX_RETRY 100
138 static robo_info_t
*robo_ptr
= NULL
; /* Foxconn added by EricHuang, 09/27/2006 */
140 int bcm_robo_check_link_status(void);
144 extern int lan_led_control(int port
, int status
);
148 /* Enable GPIO access to the chip */
150 gpio_enable(robo_info_t
*robo
)
152 /* Enable GPIO outputs with SCK and MOSI low, SS high */
153 sb_gpioout(robo
->sbh
, robo
->ss
| robo
->sck
| robo
->mosi
, robo
->ss
, GPIO_DRV_PRIORITY
);
154 sb_gpioouten(robo
->sbh
, robo
->ss
| robo
->sck
| robo
->mosi
,
155 robo
->ss
| robo
->sck
| robo
->mosi
, GPIO_DRV_PRIORITY
);
158 /* Disable GPIO access to the chip */
160 gpio_disable(robo_info_t
*robo
)
162 /* Disable GPIO outputs with all their current values */
163 sb_gpioouten(robo
->sbh
, robo
->ss
| robo
->sck
| robo
->mosi
, 0, GPIO_DRV_PRIORITY
);
166 /* Write a byte stream to the chip thru SPI */
168 spi_write(robo_info_t
*robo
, uint8
*buf
, uint len
)
173 /* Byte bang from LSB to MSB */
174 for (i
= 0; i
< len
; i
++) {
175 /* Bit bang from MSB to LSB */
176 for (mask
= 0x80; mask
; mask
>>= 1) {
178 sb_gpioout(robo
->sbh
, robo
->sck
, 0, GPIO_DRV_PRIORITY
);
179 OSL_DELAY(SCK_EDGE_TIME
);
181 /* Sample on rising edge */
183 sb_gpioout(robo
->sbh
, robo
->mosi
, robo
->mosi
, GPIO_DRV_PRIORITY
);
185 sb_gpioout(robo
->sbh
, robo
->mosi
, 0, GPIO_DRV_PRIORITY
);
186 OSL_DELAY(MOSI_SETUP_TIME
);
189 sb_gpioout(robo
->sbh
, robo
->sck
, robo
->sck
, GPIO_DRV_PRIORITY
);
190 OSL_DELAY(SCK_EDGE_TIME
);
197 /* Read a byte stream from the chip thru SPI */
199 spi_read(robo_info_t
*robo
, uint8
*buf
, uint len
)
202 uint8 rack
, mask
, byte
;
204 /* Timeout after 100 tries without RACK */
205 for (i
= 0, rack
= 0, timeout
= SPI_MAX_RETRY
; i
< len
&& timeout
;) {
206 /* Bit bang from MSB to LSB */
207 for (mask
= 0x80, byte
= 0; mask
; mask
>>= 1) {
209 sb_gpioout(robo
->sbh
, robo
->sck
, 0, GPIO_DRV_PRIORITY
);
210 OSL_DELAY(SCK_EDGE_TIME
);
212 /* Sample on falling edge */
213 if (sb_gpioin(robo
->sbh
) & robo
->miso
)
217 sb_gpioout(robo
->sbh
, robo
->sck
, robo
->sck
, GPIO_DRV_PRIORITY
);
218 OSL_DELAY(SCK_EDGE_TIME
);
220 /* RACK when bit 0 is high */
226 /* Byte bang from LSB to MSB */
232 ET_ERROR(("spi_read: timeout"));
239 /* Enable/disable SPI access */
241 spi_select(robo_info_t
*robo
, uint8 spi
)
244 /* Enable SPI access */
245 sb_gpioout(robo
->sbh
, robo
->ss
, 0, GPIO_DRV_PRIORITY
);
247 /* Disable SPI access */
248 sb_gpioout(robo
->sbh
, robo
->ss
, robo
->ss
, GPIO_DRV_PRIORITY
);
250 OSL_DELAY(SS_SETUP_TIME
);
254 /* Select chip and page */
256 spi_goto(robo_info_t
*robo
, uint8 page
)
258 uint8 reg8
= REG_SPI_PAGE
; /* page select register */
261 /* Issue the command only when we are on a different page */
262 if (robo
->page
== page
)
267 /* Enable SPI access */
270 /* Select new page with CID 0 */
271 cmd8
= ((6 << 4) | /* normal SPI */
273 spi_write(robo
, &cmd8
, 1);
274 spi_write(robo
, ®8
, 1);
275 spi_write(robo
, &page
, 1);
277 /* Disable SPI access */
281 /* Write register thru SPI */
283 spi_wreg(robo_info_t
*robo
, uint8 page
, uint8 addr
, void *val
, int len
)
293 /* validate value length and buffer address */
294 ASSERT(len
== 1 || (len
== 2 && !((int)val
& 1)) ||
295 (len
== 4 && !((int)val
& 3)));
297 /* Select chip and page */
298 spi_goto(robo
, page
);
300 /* Enable SPI access */
303 /* Write with CID 0 */
304 cmd8
= ((6 << 4) | /* normal SPI */
306 spi_write(robo
, &cmd8
, 1);
307 spi_write(robo
, &addr
, 1);
310 bytes
.val8
= *(uint8
*)val
;
313 bytes
.val16
= htol16(*(uint16
*)val
);
316 bytes
.val32
= htol32(*(uint32
*)val
);
319 spi_write(robo
, (uint8
*)val
, len
);
321 ET_MSG(("%s: [0x%x-0x%x] := 0x%x (len %d)\n", __FUNCTION__
, page
, addr
,
322 *(uint16
*)val
, len
));
323 /* Disable SPI access */
328 /* Read register thru SPI in fast SPI mode */
330 spi_rreg(robo_info_t
*robo
, uint8 page
, uint8 addr
, void *val
, int len
)
340 /* validate value length and buffer address */
341 ASSERT(len
== 1 || (len
== 2 && !((int)val
& 1)) ||
342 (len
== 4 && !((int)val
& 3)));
344 /* Select chip and page */
345 spi_goto(robo
, page
);
347 /* Enable SPI access */
350 /* Fast SPI read with CID 0 and byte offset 0 */
351 cmd8
= (1 << 4); /* fast SPI */
352 spi_write(robo
, &cmd8
, 1);
353 spi_write(robo
, &addr
, 1);
354 status
= spi_read(robo
, (uint8
*)&bytes
, len
);
357 *(uint8
*)val
= bytes
.val8
;
360 *(uint16
*)val
= ltoh16(bytes
.val16
);
363 *(uint32
*)val
= ltoh32(bytes
.val32
);
367 ET_MSG(("%s: [0x%x-0x%x] => 0x%x (len %d)\n", __FUNCTION__
, page
, addr
,
368 *(uint16
*)val
, len
));
370 /* Disable SPI access */
375 /* SPI/gpio interface functions */
376 static dev_ops_t spigpio
= {
385 /* Access switch registers through MII (MDC/MDIO) */
387 #define MII_MAX_RETRY 100
389 /* Write register thru MDC/MDIO */
391 mii_wreg(robo_info_t
*robo
, uint8 page
, uint8 reg
, void *val
, int len
)
396 uint8
*ptr
= (uint8
*)val
;
398 /* validate value length and buffer address */
399 ASSERT(len
== 1 || len
== 6 || len
== 8 ||
400 ((len
== 2) && !((int)val
& 1)) || ((len
== 4) && !((int)val
& 3)));
402 ET_MSG(("%s: [0x%x-0x%x] := 0x%x (len %d)\n", __FUNCTION__
, page
, reg
,
403 *(uint16
*)val
, len
));
405 /* set page number - MII register 0x10 */
406 if (robo
->page
!= page
) {
407 cmd16
= ((page
<< 8) | /* page number */
408 1); /* mdc/mdio access enable */
409 robo
->miiwr(h
, PSEUDO_PHYAD
, REG_MII_PAGE
, cmd16
);
416 val16
= ((val16
<< 8) | ptr
[6]);
417 robo
->miiwr(h
, PSEUDO_PHYAD
, REG_MII_DATA3
, val16
);
422 val16
= ((val16
<< 8) | ptr
[4]);
423 robo
->miiwr(h
, PSEUDO_PHYAD
, REG_MII_DATA2
, val16
);
425 val16
= ((val16
<< 8) | ptr
[2]);
426 robo
->miiwr(h
, PSEUDO_PHYAD
, REG_MII_DATA1
, val16
);
428 val16
= ((val16
<< 8) | ptr
[0]);
429 robo
->miiwr(h
, PSEUDO_PHYAD
, REG_MII_DATA0
, val16
);
433 val16
= (uint16
)((*(uint32
*)val
) >> 16);
434 robo
->miiwr(h
, PSEUDO_PHYAD
, REG_MII_DATA1
, val16
);
435 val16
= (uint16
)(*(uint32
*)val
);
436 robo
->miiwr(h
, PSEUDO_PHYAD
, REG_MII_DATA0
, val16
);
440 val16
= *(uint16
*)val
;
441 robo
->miiwr(h
, PSEUDO_PHYAD
, REG_MII_DATA0
, val16
);
445 val16
= *(uint8
*)val
;
446 robo
->miiwr(h
, PSEUDO_PHYAD
, REG_MII_DATA0
, val16
);
450 /* set register address - MII register 0x11 */
451 cmd16
= ((reg
<< 8) | /* register address */
452 1); /* opcode write */
453 robo
->miiwr(h
, PSEUDO_PHYAD
, REG_MII_ADDR
, cmd16
);
455 /* is operation finished? */
456 for (i
= MII_MAX_RETRY
; i
> 0; i
--) {
457 val16
= robo
->miird(h
, PSEUDO_PHYAD
, REG_MII_ADDR
);
458 if ((val16
& 3) == 0)
464 ET_ERROR(("mii_wreg: timeout"));
470 /* Read register thru MDC/MDIO */
472 mii_rreg(robo_info_t
*robo
, uint8 page
, uint8 reg
, void *val
, int len
)
477 uint8
*ptr
= (uint8
*)val
;
479 /* validate value length and buffer address */
480 ASSERT(len
== 1 || len
== 6 || len
== 8 ||
481 ((len
== 2) && !((int)val
& 1)) || ((len
== 4) && !((int)val
& 3)));
483 /* set page number - MII register 0x10 */
484 if (robo
->page
!= page
) {
485 cmd16
= ((page
<< 8) | /* page number */
486 1); /* mdc/mdio access enable */
487 robo
->miiwr(h
, PSEUDO_PHYAD
, REG_MII_PAGE
, cmd16
);
491 /* set register address - MII register 0x11 */
492 cmd16
= ((reg
<< 8) | /* register address */
493 2); /* opcode read */
494 robo
->miiwr(h
, PSEUDO_PHYAD
, REG_MII_ADDR
, cmd16
);
496 /* is operation finished? */
497 for (i
= MII_MAX_RETRY
; i
> 0; i
--) {
498 val16
= robo
->miird(h
, PSEUDO_PHYAD
, REG_MII_ADDR
);
499 if ((val16
& 3) == 0)
504 ET_ERROR(("mii_rreg: timeout"));
508 ET_MSG(("%s: [0x%x-0x%x] => 0x%x (len %d)\n", __FUNCTION__
, page
, reg
, val16
, len
));
512 val16
= robo
->miird(h
, PSEUDO_PHYAD
, REG_MII_DATA3
);
513 ptr
[7] = (val16
>> 8);
514 ptr
[6] = (val16
& 0xff);
518 val16
= robo
->miird(h
, PSEUDO_PHYAD
, REG_MII_DATA2
);
519 ptr
[5] = (val16
>> 8);
520 ptr
[4] = (val16
& 0xff);
521 val16
= robo
->miird(h
, PSEUDO_PHYAD
, REG_MII_DATA1
);
522 ptr
[3] = (val16
>> 8);
523 ptr
[2] = (val16
& 0xff);
524 val16
= robo
->miird(h
, PSEUDO_PHYAD
, REG_MII_DATA0
);
525 ptr
[1] = (val16
>> 8);
526 ptr
[0] = (val16
& 0xff);
530 val16
= robo
->miird(h
, PSEUDO_PHYAD
, REG_MII_DATA1
);
531 *(uint32
*)val
= (((uint32
)val16
) << 16);
532 val16
= robo
->miird(h
, PSEUDO_PHYAD
, REG_MII_DATA0
);
533 *(uint32
*)val
|= val16
;
537 val16
= robo
->miird(h
, PSEUDO_PHYAD
, REG_MII_DATA0
);
538 *(uint16
*)val
= val16
;
542 val16
= robo
->miird(h
, PSEUDO_PHYAD
, REG_MII_DATA0
);
543 *(uint8
*)val
= (uint8
)(val16
& 0xff);
550 /* MII interface functions */
551 static dev_ops_t mdcmdio
= {
559 /* High level switch configuration functions. */
561 /* Get access to the RoboSwitch */
563 bcm_robo_attach(sb_t
*sbh
, void *h
, char *vars
, miird_f miird
, miiwr_f miiwr
)
568 /* Allocate and init private state */
569 if (!(robo
= MALLOC(sb_osh(sbh
), sizeof(robo_info_t
)))) {
570 ET_ERROR(("robo_attach: out of memory, malloced %d bytes", MALLOCED(sb_osh(sbh
))));
573 bzero(robo
, sizeof(robo_info_t
));
582 /* Trigger external reset by nvram variable existance */
583 if ((reset
= getgpiopin(robo
->vars
, "robo_reset", GPIO_PIN_NOTDEFINED
)) !=
584 GPIO_PIN_NOTDEFINED
) {
586 * Reset sequence: RESET low(50ms)->high(20ms)
588 * We have to perform a full sequence for we don't know how long
589 * it has been from power on till now.
591 ET_MSG(("%s: Using external reset in gpio pin %d\n", __FUNCTION__
, reset
));
594 /* Keep RESET low for 50 ms */
595 sb_gpioout(robo
->sbh
, reset
, 0, GPIO_DRV_PRIORITY
);
596 sb_gpioouten(robo
->sbh
, reset
, reset
, GPIO_DRV_PRIORITY
);
599 /* Keep RESET high for at least 20 ms */
600 sb_gpioout(robo
->sbh
, reset
, reset
, GPIO_DRV_PRIORITY
);
603 /* In case we need it */
604 idx
= sb_coreidx(robo
->sbh
);
606 if (sb_setcore(robo
->sbh
, SB_ROBO
, 0)) {
607 /* If we have an internal robo core, reset it using sb_core_reset */
608 ET_MSG(("%s: Resetting internal robo core\n", __FUNCTION__
));
609 sb_core_reset(robo
->sbh
, 0, 0);
612 sb_setcoreidx(robo
->sbh
, idx
);
615 if (miird
&& miiwr
) {
617 int rc
, retry_count
= 0;
619 /* Read the PHY ID */
620 tmp
= miird(h
, PSEUDO_PHYAD
, 2);
623 rc
= mii_rreg(robo
, PAGE_MMR
, REG_DEVICE_ID
, \
624 &robo
->devid
, sizeof(uint16
));
628 } while ((robo
->devid
== 0) && (retry_count
< 10));
630 ET_MSG(("%s: devid read %ssuccesfully via mii: 0x%x\n", __FUNCTION__
, \
631 rc
? "un" : "", robo
->devid
));
632 ET_MSG(("%s: mii access to switch works\n", __FUNCTION__
));
633 robo
->ops
= &mdcmdio
;
634 if ((rc
!= 0) || (robo
->devid
== 0)) {
635 ET_MSG(("%s: error reading devid, assuming 5325e\n", __FUNCTION__
));
636 robo
->devid
= DEVID5325
;
638 ET_MSG(("%s: devid: 0x%x\n", __FUNCTION__
, robo
->devid
));
642 if ((robo
->devid
== DEVID5395
) ||
643 (robo
->devid
== DEVID5397
) ||
644 (robo
->devid
== DEVID5398
)) {
647 /* If it is a 539x switch, use the soft reset register */
648 ET_MSG(("%s: Resetting 539x robo switch\n", __FUNCTION__
));
650 /* Reset the 539x switch core and register file */
652 mii_wreg(robo
, PAGE_CTRL
, REG_CTRL_SRST
, &srst_ctrl
, sizeof(uint8
));
654 mii_wreg(robo
, PAGE_CTRL
, REG_CTRL_SRST
, &srst_ctrl
, sizeof(uint8
));
658 int mosi
, miso
, ss
, sck
;
660 robo
->ops
= &spigpio
;
661 robo
->devid
= DEVID5325
;
663 /* Init GPIO mapping. Default 2, 3, 4, 5 */
664 ss
= getgpiopin(vars
, "robo_ss", 2);
665 if (ss
== GPIO_PIN_NOTDEFINED
) {
666 ET_ERROR(("robo_attach: robo_ss gpio fail: GPIO 2 in use"));
670 sck
= getgpiopin(vars
, "robo_sck", 3);
671 if (sck
== GPIO_PIN_NOTDEFINED
) {
672 ET_ERROR(("robo_attach: robo_sck gpio fail: GPIO 3 in use"));
675 robo
->sck
= 1 << sck
;
676 mosi
= getgpiopin(vars
, "robo_mosi", 4);
677 if (mosi
== GPIO_PIN_NOTDEFINED
) {
678 ET_ERROR(("robo_attach: robo_mosi gpio fail: GPIO 4 in use"));
681 robo
->mosi
= 1 << mosi
;
682 miso
= getgpiopin(vars
, "robo_miso", 5);
683 if (miso
== GPIO_PIN_NOTDEFINED
) {
684 ET_ERROR(("robo_attach: robo_miso gpio fail: GPIO 5 in use"));
687 robo
->miso
= 1 << miso
;
688 ET_MSG(("%s: ss %d sck %d mosi %d miso %d\n", __FUNCTION__
,
689 ss
, sck
, mosi
, miso
));
694 ASSERT(robo
->ops
->write_reg
);
695 ASSERT(robo
->ops
->read_reg
);
696 ASSERT((robo
->devid
== DEVID5325
) ||
697 (robo
->devid
== DEVID5395
) ||
698 (robo
->devid
== DEVID5397
) ||
699 (robo
->devid
== DEVID5398
));
701 /* Foxconn added start by EricHuang, 09/27/2006 */
702 /* Store pointer to robo */
706 /* Foxconn added end by EricHuang, 09/27/2006 */
711 bcm_robo_detach(robo
);
715 /* Release access to the RoboSwitch */
717 bcm_robo_detach(robo_info_t
*robo
)
719 MFREE(sb_osh(robo
->sbh
), robo
, sizeof(robo_info_t
));
722 /* Enable the device and set it to a known good state */
724 bcm_robo_enable_device(robo_info_t
*robo
)
726 uint8 reg_offset
, reg_val
;
729 /* Enable management interface access */
730 if (robo
->ops
->enable_mgmtif
)
731 robo
->ops
->enable_mgmtif(robo
);
733 if (robo
->devid
== DEVID5398
) {
734 /* Disable unused ports: port 6 and 7 */
735 for (reg_offset
= REG_CTRL_PORT6
; reg_offset
<= REG_CTRL_PORT7
; reg_offset
++) {
736 /* Set bits [1:0] to disable RX and TX */
738 robo
->ops
->write_reg(robo
, PAGE_CTRL
, reg_offset
, ®_val
,
743 if (robo
->devid
== DEVID5325
) {
744 /* Must put the switch into Reverse MII mode! */
746 /* MII port state override (page 0 register 14) */
747 robo
->ops
->read_reg(robo
, PAGE_CTRL
, REG_CTRL_MIIPO
, ®_val
, sizeof(reg_val
));
749 /* Bit 4 enables reverse MII mode */
750 if (!(reg_val
& (1 << 4))) {
753 robo
->ops
->write_reg(robo
, PAGE_CTRL
, REG_CTRL_MIIPO
, ®_val
,
757 robo
->ops
->read_reg(robo
, PAGE_CTRL
, REG_CTRL_MIIPO
, ®_val
,
759 if (!(reg_val
& (1 << 4))) {
760 ET_ERROR(("robo_enable_device: enabling RvMII mode failed\n"));
766 /* Disable management interface access */
767 if (robo
->ops
->disable_mgmtif
)
768 robo
->ops
->disable_mgmtif(robo
);
774 #define FLAG_TAGGED 't' /* output tagged (external ports only) */
775 #define FLAG_UNTAG 'u' /* input & output untagged (CPU port only, for OS (linux, ...) */
776 #define FLAG_LAN '*' /* input & output untagged (CPU port only, for CFE */
778 /* port descriptor */
780 uint32 untag
; /* untag enable bit (Page 0x05 Address 0x63-0x66 Bit[17:9]) */
781 uint32 member
; /* vlan member bit (Page 0x05 Address 0x63-0x66 Bit[7:0]) */
782 uint8 ptagr
; /* port tag register address (Page 0x34 Address 0x10-0x1F) */
783 uint8 cpu
; /* is this cpu port? */
786 pdesc_t pdesc97
[] = {
787 /* 5395/5397/5398 is 0 ~ 7. port 8 is IMP port. */
788 /* port 0 */ {1 << 9, 1 << 0, REG_VLAN_PTAG0
, 0},
789 /* port 1 */ {1 << 10, 1 << 1, REG_VLAN_PTAG1
, 0},
790 /* port 2 */ {1 << 11, 1 << 2, REG_VLAN_PTAG2
, 0},
791 /* port 3 */ {1 << 12, 1 << 3, REG_VLAN_PTAG3
, 0},
792 /* port 4 */ {1 << 13, 1 << 4, REG_VLAN_PTAG4
, 0},
793 /* port 5 */ {1 << 14, 1 << 5, REG_VLAN_PTAG5
, 0},
794 /* port 6 */ {1 << 15, 1 << 6, REG_VLAN_PTAG6
, 0},
795 /* port 7 */ {1 << 16, 1 << 7, REG_VLAN_PTAG7
, 0},
796 /* mii port */ {1 << 17, 1 << 8, REG_VLAN_PTAG8
, 1},
799 pdesc_t pdesc25
[] = {
800 /* port 0 */ {1 << 6, 1 << 0, REG_VLAN_PTAG0
, 0},
801 /* port 1 */ {1 << 7, 1 << 1, REG_VLAN_PTAG1
, 0},
802 /* port 2 */ {1 << 8, 1 << 2, REG_VLAN_PTAG2
, 0},
803 /* port 3 */ {1 << 9, 1 << 3, REG_VLAN_PTAG3
, 0},
804 /* port 4 */ {1 << 10, 1 << 4, REG_VLAN_PTAG4
, 0},
805 /* mii port */ {1 << 11, 1 << 5, REG_VLAN_PTAG5
, 1},
808 /* Configure the VLANs */
810 bcm_robo_config_vlan(robo_info_t
*robo
, uint8
*mac_addr
)
818 uint8 arl_entry
[8] = { 0 }, arl_entry1
[8] = { 0 };
820 /* Enable management interface access */
821 if (robo
->ops
->enable_mgmtif
)
822 robo
->ops
->enable_mgmtif(robo
);
824 /* setup global vlan configuration */
825 /* VLAN Control 0 Register (Page 0x34, Address 0) */
826 val8
= ((1 << 7) | /* enable 802.1Q VLAN */
827 (3 << 5)); /* individual VLAN learning mode */
828 robo
->ops
->write_reg(robo
, PAGE_VLAN
, REG_VLAN_CTRL0
, &val8
, sizeof(val8
));
830 /* VLAN Control 1 Register (Page 0x34, Address 1) */
831 val8
= ((1 << 2) | /* enable RSV multicast V Fwdmap */
832 (1 << 3)); /* enable RSV multicast V Untagmap */
833 if (robo
->devid
== DEVID5325
)
834 val8
|= (1 << 1); /* enable RSV multicast V Tagging */
835 robo
->ops
->write_reg(robo
, PAGE_VLAN
, REG_VLAN_CTRL1
, &val8
, sizeof(val8
));
837 arl_entry
[0] = mac_addr
[5];
838 arl_entry
[1] = mac_addr
[4];
839 arl_entry
[2] = mac_addr
[3];
840 arl_entry
[3] = mac_addr
[2];
841 arl_entry
[4] = mac_addr
[1];
842 arl_entry
[5] = mac_addr
[0];
844 if (robo
->devid
== DEVID5325
) {
845 /* Init the entry 1 of the bin */
846 robo
->ops
->write_reg(robo
, PAGE_VTBL
, REG_VTBL_ARL_E1
, \
847 arl_entry1
, sizeof(arl_entry1
));
848 robo
->ops
->write_reg(robo
, PAGE_VTBL
, REG_VTBL_VID_E1
, \
851 /* Init the entry 0 of the bin */
852 arl_entry
[6] = 0x8; /* Port Id: MII */
853 arl_entry
[7] = 0xc0; /* Static Entry, Valid */
855 robo
->ops
->write_reg(robo
, PAGE_VTBL
, REG_VTBL_ARL_E0
, \
856 arl_entry
, sizeof(arl_entry
));
857 robo
->ops
->write_reg(robo
, PAGE_VTBL
, REG_VTBL_MINDX
, \
858 arl_entry
, ETHER_ADDR_LEN
);
860 /* VLAN Control 4 Register (Page 0x34, Address 4) */
861 val8
= (1 << 6); /* drop frame with VID violation */
862 robo
->ops
->write_reg(robo
, PAGE_VLAN
, REG_VLAN_CTRL4
, &val8
, sizeof(val8
));
864 /* VLAN Control 5 Register (Page 0x34, Address 5) */
865 val8
= (1 << 3); /* drop frame when miss V table */
866 robo
->ops
->write_reg(robo
, PAGE_VLAN
, REG_VLAN_CTRL5
, &val8
, sizeof(val8
));
869 pdescsz
= sizeof(pdesc25
) / sizeof(pdesc_t
);
871 /* Initialize the MAC Addr Index Register */
872 robo
->ops
->write_reg(robo
, PAGE_VTBL
, REG_VTBL_MINDX
, \
873 arl_entry
, ETHER_ADDR_LEN
);
876 pdescsz
= sizeof(pdesc97
) / sizeof(pdesc_t
);
879 /* setup each vlan. max. 16 vlans. */
880 /* force vlan id to be equal to vlan number */
881 for (vid
= 0; vid
< VLAN_NUMVLANS
; vid
++) {
882 char vlanports
[] = "vlanXXXXports";
883 char port
[] = "XXXX", *ports
, *next
, *cur
;
888 /* no members if VLAN id is out of limitation */
889 if (vid
> VLAN_MAXVID
)
892 /* get vlan member ports from nvram */
893 sprintf(vlanports
, "vlan%dports", vid
);
894 ports
= getvar(robo
->vars
, vlanports
);
896 /* In 539x vid == 0 us invalid?? */
897 if ((robo
->devid
!= DEVID5325
) && (vid
== 0)) {
899 ET_ERROR(("VID 0 is set in nvram, Ignoring\n"));
903 /* disable this vlan if not defined */
908 * setup each port in the vlan. cpu port needs special handing
909 * (with or without output tagging) to support linux/pmon/cfe.
911 for (cur
= ports
; cur
; cur
= next
) {
912 /* tokenize the port list */
915 next
= bcmstrstr(cur
, " ");
916 len
= next
? next
- cur
: strlen(cur
);
919 if (len
> sizeof(port
) - 1)
920 len
= sizeof(port
) - 1;
921 strncpy(port
, cur
, len
);
924 /* make sure port # is within the range */
925 pid
= bcm_atoi(port
);
926 if (pid
>= pdescsz
) {
927 ET_ERROR(("robo_config_vlan: port %d in vlan%dports is out "
928 "of range[0-%d]\n", pid
, vid
, pdescsz
));
932 /* build VLAN registers values */
934 if ((!pdesc
[pid
].cpu
&& !strchr(port
, FLAG_TAGGED
)) ||
935 (pdesc
[pid
].cpu
&& strchr(port
, FLAG_UNTAG
)))
937 untag
|= pdesc
[pid
].untag
;
939 member
|= pdesc
[pid
].member
;
941 /* set port tag - applies to untagged ingress frames */
942 /* Default Port Tag Register (Page 0x34, Address 0x10-0x1D) */
946 #define FL FLAG_UNTAG
948 if (!pdesc
[pid
].cpu
|| strchr(port
, FL
)) {
949 val16
= ((0 << 13) | /* priority - always 0 */
951 robo
->ops
->write_reg(robo
, PAGE_VLAN
, pdesc
[pid
].ptagr
,
952 &val16
, sizeof(val16
));
956 /* Add static ARL entries */
957 if (robo
->devid
== DEVID5325
) {
959 robo
->ops
->write_reg(robo
, PAGE_VTBL
, REG_VTBL_VID_E0
, \
960 &val8
, sizeof(val8
));
961 robo
->ops
->write_reg(robo
, PAGE_VTBL
, REG_VTBL_VINDX
, \
962 &val8
, sizeof(val8
));
964 /* Write the entry */
966 robo
->ops
->write_reg(robo
, PAGE_VTBL
, REG_VTBL_CTRL
, \
967 &val8
, sizeof(val8
));
968 /* Wait for write to complete */
969 SPINWAIT((robo
->ops
->read_reg(robo
, PAGE_VTBL
, REG_VTBL_CTRL
, \
970 &val8
, sizeof(val8
)), ((val8
& 0x80) != 0)),
973 /* Set the VLAN Id in VLAN ID Index Register */
975 robo
->ops
->write_reg(robo
, PAGE_VTBL
, REG_VTBL_VINDX
, \
976 &val8
, sizeof(val8
));
978 /* Set the MAC addr and VLAN Id in ARL Table MAC/VID Entry 0
983 robo
->ops
->write_reg(robo
, PAGE_VTBL
, REG_VTBL_ARL_E0
, \
984 arl_entry
, sizeof(arl_entry
));
986 /* Set the Static bit , Valid bit and Port ID fields in
987 * ARL Table Data Entry 0 Register
990 robo
->ops
->write_reg(robo
, PAGE_VTBL
, REG_VTBL_DAT_E0
, \
991 &val16
, sizeof(val16
));
993 /* Clear the ARL_R/W bit and set the START/DONE bit in
994 * the ARL Read/Write Control Register.
997 robo
->ops
->write_reg(robo
, PAGE_VTBL
, REG_VTBL_CTRL
, \
998 &val8
, sizeof(val8
));
999 /* Wait for write to complete */
1000 SPINWAIT((robo
->ops
->read_reg(robo
, PAGE_VTBL
, REG_VTBL_CTRL
, \
1001 &val8
, sizeof(val8
)), ((val8
& 0x80) != 0)),
1006 /* setup VLAN ID and VLAN memberships */
1008 val32
= (untag
| /* untag enable */
1009 member
); /* vlan members */
1010 if (sb_chip(robo
->sbh
) == BCM5365_CHIP_ID
)
1012 /* VLAN Write Register (Page 0x34, Address 0x0A) */
1013 val32
= ((1 << 14) | /* valid write */
1014 (untag
<< 1) | /* untag enable */
1015 member
); /* vlan members */
1016 robo
->ops
->write_reg(robo
, PAGE_VLAN
, REG_VLAN_WRITE_5365
, &val32
,
1018 /* VLAN Table Access Register (Page 0x34, Address 0x08) */
1019 val16
= ((1 << 13) | /* start command */
1020 (1 << 12) | /* write state */
1022 robo
->ops
->write_reg(robo
, PAGE_VLAN
, REG_VLAN_ACCESS_5365
, &val16
,
1024 } else if (robo
->devid
== DEVID5325
) {
1025 val32
|= ((1 << 20) | /* valid write */
1026 ((vid
>> 4) << 12)); /* vlan id bit[11:4] */
1027 /* VLAN Write Register (Page 0x34, Address 0x08-0x0B) */
1028 robo
->ops
->write_reg(robo
, PAGE_VLAN
, REG_VLAN_WRITE
, &val32
,
1030 /* VLAN Table Access Register (Page 0x34, Address 0x06-0x07) */
1031 val16
= ((1 << 13) | /* start command */
1032 (1 << 12) | /* write state */
1034 robo
->ops
->write_reg(robo
, PAGE_VLAN
, REG_VLAN_ACCESS
, &val16
,
1037 uint8 vtble
, vtbli
, vtbla
;
1039 if (robo
->devid
== DEVID5395
) {
1040 vtble
= REG_VTBL_ENTRY_5395
;
1041 vtbli
= REG_VTBL_INDX_5395
;
1042 vtbla
= REG_VTBL_ACCESS_5395
;
1044 vtble
= REG_VTBL_ENTRY
;
1045 vtbli
= REG_VTBL_INDX
;
1046 vtbla
= REG_VTBL_ACCESS
;
1049 /* VLAN Table Entry Register (Page 0x05, Address 0x63-0x66/0x83-0x86) */
1050 robo
->ops
->write_reg(robo
, PAGE_VTBL
, vtble
, &val32
,
1052 /* VLAN Table Address Index Reg (Page 0x05, Address 0x61-0x62/0x81-0x82) */
1053 val16
= vid
; /* vlan id */
1054 robo
->ops
->write_reg(robo
, PAGE_VTBL
, vtbli
, &val16
,
1057 /* VLAN Table Access Register (Page 0x34, Address 0x60/0x80) */
1058 val8
= ((1 << 7) | /* start command */
1060 robo
->ops
->write_reg(robo
, PAGE_VTBL
, vtbla
, &val8
,
1065 if (robo
->devid
== DEVID5325
) {
1066 /* setup priority mapping - applies to tagged ingress frames */
1067 /* Priority Re-map Register (Page 0x34, Address 0x20-0x23) */
1068 val32
= ((0 << 0) | /* 0 -> 0 */
1069 (1 << 3) | /* 1 -> 1 */
1070 (2 << 6) | /* 2 -> 2 */
1071 (3 << 9) | /* 3 -> 3 */
1072 (4 << 12) | /* 4 -> 4 */
1073 (5 << 15) | /* 5 -> 5 */
1074 (6 << 18) | /* 6 -> 6 */
1075 (7 << 21)); /* 7 -> 7 */
1076 robo
->ops
->write_reg(robo
, PAGE_VLAN
, REG_VLAN_PMAP
, &val32
, sizeof(val32
));
1079 /* Disable management interface access */
1080 if (robo
->ops
->disable_mgmtif
)
1081 robo
->ops
->disable_mgmtif(robo
);
1086 /* Enable switching/forwarding */
1088 bcm_robo_enable_switch(robo_info_t
*robo
)
1090 int i
, max_port_ind
, ret
= 0;
1093 /* Enable management interface access */
1094 if (robo
->ops
->enable_mgmtif
)
1095 robo
->ops
->enable_mgmtif(robo
);
1097 /* Switch Mode register (Page 0, Address 0x0B) */
1098 robo
->ops
->read_reg(robo
, PAGE_CTRL
, REG_CTRL_MODE
, &val8
, sizeof(val8
));
1100 /* Bit 1 enables switching/forwarding */
1101 if (!(val8
& (1 << 1))) {
1102 /* Set unmanaged mode */
1103 val8
&= (~(1 << 0));
1105 /* Enable forwarding */
1107 robo
->ops
->write_reg(robo
, PAGE_CTRL
, REG_CTRL_MODE
, &val8
, sizeof(val8
));
1110 robo
->ops
->read_reg(robo
, PAGE_CTRL
, REG_CTRL_MODE
, &val8
, sizeof(val8
));
1111 if (!(val8
& (1 << 1))) {
1112 ET_ERROR(("robo_enable_switch: enabling forwarding failed\n"));
1116 /* No spanning tree for unmanaged mode */
1118 max_port_ind
= ((robo
->devid
== DEVID5398
) ? REG_CTRL_PORT7
: REG_CTRL_PORT4
);
1119 for (i
= REG_CTRL_PORT0
; i
<= max_port_ind
; i
++) {
1120 robo
->ops
->write_reg(robo
, PAGE_CTRL
, i
, &val8
, sizeof(val8
));
1124 /* Enable WAN port (#0) on the asus wl-500g deluxe boxes */
1126 robo
->ops
->write_reg(robo
, PAGE_CTRL
, REG_CTRL_PORT0
, &val8
, sizeof(val8
));
1128 /* Disable management interface access */
1129 if (robo
->ops
->disable_mgmtif
)
1130 robo
->ops
->disable_mgmtif(robo
);
1135 /* Foxconn added start by EricHuang, 09/27/2006 */
1137 /* WAN/LAN link status monitor */
1138 static void bcm_robo_port_monitor(int gpio
, int on_off
)
1140 robo_info_t
*robo
= robo_ptr
;
1144 sb_gpioouten(robo
->sbh
, (unsigned long) 1 << gpio
, (unsigned long) 1 << gpio
, GPIO_APP_PRIORITY
);
1145 sb_gpioout(robo
->sbh
, (unsigned long)1 << gpio
,(unsigned long) on_off
<< gpio
, GPIO_APP_PRIORITY
);
1150 int bcm_robo_check_link_status(void)
1152 robo_info_t
*robo
= robo_ptr
;
1155 int port_speed
, port_link
;
1163 /* Read link status summary register */
1164 robo
->ops
->read_reg(robo
, PAGE_STATUS
, REG_LINK_SUM
, ®_link
, sizeof(reg_link
));
1166 /* Read port speed summary register */
1167 robo
->ops
->read_reg(robo
, PAGE_STATUS
, REG_SPEED_SUM
, ®_speed
, sizeof(reg_speed
));
1169 //printf("status:0x%x, speed:0x%x\n", reg_link, reg_speed);
1173 port_link
= (reg_link
>> i
) & 0x1;
1176 port_speed
= (reg_speed
>> i
) & 0x1;
1177 //printf("PORT %d is up, speed is %d\n", i, port_speed);
1178 /* WAN port: 0 LAN port: 1-4 */
1181 /* it don't need to check WAN led in bootcode, always amber in color.*/
1182 //lan_led_control(4, !port_speed);
1186 lan_led_control(i
-1, !port_speed
);
1195 /* Add Linux API to read link status */
1196 int robo_read_link_status(int lan_wan
, int *link
, int *speed
, int *duplex
)
1198 #define ROBO_WAN_PORT 0
1199 #define ROBO_INVALID_PORT_SPEED 0x3
1201 robo_info_t
*robo
= robo_ptr
;
1202 uint16 reg_link
, reg_duplex
;
1204 int port_speed
, port_link
;
1211 /* Read link status summary register */
1212 robo
->ops
->read_reg(robo
, PAGE_STATUS
, REG_LINK_SUM
, ®_link
, sizeof(reg_link
));
1214 /* Read port speed summary register */
1215 robo
->ops
->read_reg(robo
, PAGE_STATUS
, REG_SPEED_SUM
, ®_speed
, sizeof(reg_speed
));
1217 /* Read duplex status summary register */
1218 robo
->ops
->read_reg(robo
, PAGE_STATUS
, REG_DUPLEX_SUM
, ®_duplex
, sizeof(reg_duplex
));
1220 if (lan_wan
== 0) /*lan status*/
1223 *link
= (reg_link
& 0x1E);
1225 /* Check speed of link "up" ports only */
1226 for (i
=1; i
<5; i
++) {
1227 port_link
= (reg_link
>> i
) & 0x1;
1228 port_speed
= (reg_speed
>> i
) & 0x1;
1229 if (port_link
&& port_speed
> *speed
)
1230 *speed
= port_speed
;
1233 *duplex
= reg_duplex
& *link
;
1237 *link
= (reg_link
>> ROBO_WAN_PORT
) & 0x1;
1238 *speed
= (reg_speed
>> ROBO_WAN_PORT
) & 0x01;
1239 *duplex
= (reg_duplex
>> ROBO_WAN_PORT
) & 0x01;
1245 /* disable/enable switch ports */
1246 void robo_enable_port(int port
, int on_off
)
1249 robo_info_t
*robo
= robo_ptr
;
1251 if (robo
== NULL
) return;
1253 val
= robo
->miird(robo
->h
, port
, 0x1e);
1257 val
&= ~(1 << 3); /* super isolate bit */
1259 else if (on_off
== 0) /*disable*/
1261 val
|= (1 << 3); /* super isolate bit */
1264 robo
->miiwr(robo
->h
, port
, 0x1e, val
);
1267 int robo_read_lan_speed(int *speed
)
1269 robo_info_t
*robo
= robo_ptr
;
1270 uint32 reg_speed
= 0, reg_link
= 0;
1275 /* Read port speed summary register */
1276 robo
->ops
->read_reg(robo
, PAGE_STATUS
, REG_SPEED_SUM
, ®_speed
, sizeof(reg_speed
));
1278 /* Read link status summary register */
1279 robo
->ops
->read_reg(robo
, PAGE_STATUS
, REG_LINK_SUM
, ®_link
, sizeof(reg_link
));
1281 *speed
= ( reg_speed
| ~reg_link
); /* if link down, speed returns 1 (100M) */
1284 #endif /* ! _CFE_ */