2 * Broadcom 53xx RoboSwitch device driver.
4 * Copyright (C) 2011, Broadcom Corporation. All Rights Reserved.
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
13 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
15 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
16 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 * $Id: bcmrobo.c 336121 2012-05-31 23:04:23Z $
29 #include <bcmendian.h>
30 #include <bcmparams.h>
34 #include <proto/ethernet.h>
38 #define ET_ERROR(args) printf args
40 #define ET_ERROR(args)
44 #define VARG(var, len) (((len) == 1) ? *((uint8 *)(var)) : \
45 ((len) == 2) ? *((uint16 *)(var)) : \
49 * Switch can be programmed through SPI interface, which
50 * has a rreg and a wreg functions to read from and write to
54 /* MII access registers */
55 #define PSEUDO_PHYAD 0x1E /* MII Pseudo PHY address */
56 #define REG_MII_CTRL 0x00 /* 53115 MII control register */
57 #define REG_MII_CLAUSE_45_CTL1 0xd /* 53125 MII Clause 45 control 1 */
58 #define REG_MII_CLAUSE_45_CTL2 0xe /* 53125 MII Clause 45 control 2 */
59 #define REG_MII_PAGE 0x10 /* MII Page register */
60 #define REG_MII_ADDR 0x11 /* MII Address register */
61 #define REG_MII_DATA0 0x18 /* MII Data register 0 */
62 #define REG_MII_DATA1 0x19 /* MII Data register 1 */
63 #define REG_MII_DATA2 0x1a /* MII Data register 2 */
64 #define REG_MII_DATA3 0x1b /* MII Data register 3 */
65 #define REG_MII_AUX_STATUS2 0x1b /* Auxiliary status 2 register */
66 #define REG_MII_AUTO_PWRDOWN 0x1c /* 53115 Auto power down register */
67 #define REG_MII_BRCM_TEST 0x1f /* Broadcom test register */
70 #define PAGE_CTRL 0x00 /* Control page */
71 #define PAGE_STATUS 0x01 /* Status page */
72 #define PAGE_MMR 0x02 /* 5397 Management/Mirroring page */
73 #define PAGE_VTBL 0x05 /* ARL/VLAN Table access page */
74 #define PAGE_VLAN 0x34 /* VLAN page */
76 /* Control page registers */
77 #define REG_CTRL_PORT0 0x00 /* Port 0 traffic control register */
78 #define REG_CTRL_PORT1 0x01 /* Port 1 traffic control register */
79 #define REG_CTRL_PORT2 0x02 /* Port 2 traffic control register */
80 #define REG_CTRL_PORT3 0x03 /* Port 3 traffic control register */
81 #define REG_CTRL_PORT4 0x04 /* Port 4 traffic control register */
82 #define REG_CTRL_PORT5 0x05 /* Port 5 traffic control register */
83 #define REG_CTRL_PORT6 0x06 /* Port 6 traffic control register */
84 #define REG_CTRL_PORT7 0x07 /* Port 7 traffic control register */
85 #define REG_CTRL_IMP 0x08 /* IMP port traffic control register */
86 #define REG_CTRL_MODE 0x0B /* Switch Mode register */
87 #define REG_CTRL_MIIPO 0x0E /* 5325: MII Port Override register */
88 #define REG_CTRL_PWRDOWN 0x0F /* 5325: Power Down Mode register */
89 #define REG_CTRL_SRST 0x79 /* Software reset control register */
91 /* Status Page Registers */
92 #define REG_STATUS_LINK 0x00 /* Link Status Summary */
93 #define REG_STATUS_REV 0x50 /* Revision Register */
95 #define REG_DEVICE_ID 0x30 /* 539x Device id: */
97 /* VLAN page registers */
98 #define REG_VLAN_CTRL0 0x00 /* VLAN Control 0 register */
99 #define REG_VLAN_CTRL1 0x01 /* VLAN Control 1 register */
100 #define REG_VLAN_CTRL4 0x04 /* VLAN Control 4 register */
101 #define REG_VLAN_CTRL5 0x05 /* VLAN Control 5 register */
102 #define REG_VLAN_ACCESS 0x06 /* VLAN Table Access register */
103 #define REG_VLAN_WRITE 0x08 /* VLAN Write register */
104 #define REG_VLAN_READ 0x0C /* VLAN Read register */
105 #define REG_VLAN_PTAG0 0x10 /* VLAN Default Port Tag register - port 0 */
106 #define REG_VLAN_PTAG1 0x12 /* VLAN Default Port Tag register - port 1 */
107 #define REG_VLAN_PTAG2 0x14 /* VLAN Default Port Tag register - port 2 */
108 #define REG_VLAN_PTAG3 0x16 /* VLAN Default Port Tag register - port 3 */
109 #define REG_VLAN_PTAG4 0x18 /* VLAN Default Port Tag register - port 4 */
110 #define REG_VLAN_PTAG5 0x1a /* VLAN Default Port Tag register - port 5 */
111 #define REG_VLAN_PTAG6 0x1c /* VLAN Default Port Tag register - port 6 */
112 #define REG_VLAN_PTAG7 0x1e /* VLAN Default Port Tag register - port 7 */
113 #define REG_VLAN_PTAG8 0x20 /* 539x: VLAN Default Port Tag register - IMP port */
114 #define REG_VLAN_PMAP 0x20 /* 5325: VLAN Priority Re-map register */
116 #define VLAN_NUMVLANS 16 /* # of VLANs */
119 /* ARL/VLAN Table Access page registers */
120 #define REG_VTBL_CTRL 0x00 /* ARL Read/Write Control */
121 #define REG_VTBL_MINDX 0x02 /* MAC Address Index */
122 #define REG_VTBL_VINDX 0x08 /* VID Table Index */
123 #define REG_VTBL_ARL_E0 0x10 /* ARL Entry 0 */
124 #define REG_VTBL_ARL_E1 0x18 /* ARL Entry 1 */
125 #define REG_VTBL_DAT_E0 0x18 /* ARL Table Data Entry 0 */
126 #define REG_VTBL_SCTRL 0x20 /* ARL Search Control */
127 #define REG_VTBL_SADDR 0x22 /* ARL Search Address */
128 #define REG_VTBL_SRES 0x24 /* ARL Search Result */
129 #define REG_VTBL_SREXT 0x2c /* ARL Search Result */
130 #define REG_VTBL_VID_E0 0x30 /* VID Entry 0 */
131 #define REG_VTBL_VID_E1 0x32 /* VID Entry 1 */
132 #define REG_VTBL_PREG 0xFF /* Page Register */
133 #define REG_VTBL_ACCESS 0x60 /* VLAN table access register */
134 #define REG_VTBL_INDX 0x61 /* VLAN table address index register */
135 #define REG_VTBL_ENTRY 0x63 /* VLAN table entry register */
136 #define REG_VTBL_ACCESS_5395 0x80 /* VLAN table access register */
137 #define REG_VTBL_INDX_5395 0x81 /* VLAN table address index register */
138 #define REG_VTBL_ENTRY_5395 0x83 /* VLAN table entry register */
142 #define REG_SPI_PAGE 0xff /* SPI Page register */
144 /* Access switch registers through GPIO/SPI */
146 /* Minimum timing constants */
147 #define SCK_EDGE_TIME 2 /* clock edge duration - 2us */
148 #define MOSI_SETUP_TIME 1 /* input setup duration - 1us */
149 #define SS_SETUP_TIME 1 /* select setup duration - 1us */
151 /* misc. constants */
152 #define SPI_MAX_RETRY 100
154 /* Enable GPIO access to the chip */
156 gpio_enable(robo_info_t
*robo
)
158 /* Enable GPIO outputs with SCK and MOSI low, SS high */
159 si_gpioout(robo
->sih
, robo
->ss
| robo
->sck
| robo
->mosi
, robo
->ss
, GPIO_DRV_PRIORITY
);
160 si_gpioouten(robo
->sih
, robo
->ss
| robo
->sck
| robo
->mosi
,
161 robo
->ss
| robo
->sck
| robo
->mosi
, GPIO_DRV_PRIORITY
);
164 /* Disable GPIO access to the chip */
166 gpio_disable(robo_info_t
*robo
)
168 /* Disable GPIO outputs with all their current values */
169 si_gpioouten(robo
->sih
, robo
->ss
| robo
->sck
| robo
->mosi
, 0, GPIO_DRV_PRIORITY
);
172 /* Write a byte stream to the chip thru SPI */
174 spi_write(robo_info_t
*robo
, uint8
*buf
, uint len
)
179 /* Byte bang from LSB to MSB */
180 for (i
= 0; i
< len
; i
++) {
181 /* Bit bang from MSB to LSB */
182 for (mask
= 0x80; mask
; mask
>>= 1) {
184 si_gpioout(robo
->sih
, robo
->sck
, 0, GPIO_DRV_PRIORITY
);
185 OSL_DELAY(SCK_EDGE_TIME
);
187 /* Sample on rising edge */
189 si_gpioout(robo
->sih
, robo
->mosi
, robo
->mosi
, GPIO_DRV_PRIORITY
);
191 si_gpioout(robo
->sih
, robo
->mosi
, 0, GPIO_DRV_PRIORITY
);
192 OSL_DELAY(MOSI_SETUP_TIME
);
195 si_gpioout(robo
->sih
, robo
->sck
, robo
->sck
, GPIO_DRV_PRIORITY
);
196 OSL_DELAY(SCK_EDGE_TIME
);
203 /* Read a byte stream from the chip thru SPI */
205 spi_read(robo_info_t
*robo
, uint8
*buf
, uint len
)
208 uint8 rack
, mask
, byte
;
210 /* Timeout after 100 tries without RACK */
211 for (i
= 0, rack
= 0, timeout
= SPI_MAX_RETRY
; i
< len
&& timeout
;) {
212 /* Bit bang from MSB to LSB */
213 for (mask
= 0x80, byte
= 0; mask
; mask
>>= 1) {
215 si_gpioout(robo
->sih
, robo
->sck
, 0, GPIO_DRV_PRIORITY
);
216 OSL_DELAY(SCK_EDGE_TIME
);
218 /* Sample on falling edge */
219 if (si_gpioin(robo
->sih
) & robo
->miso
)
223 si_gpioout(robo
->sih
, robo
->sck
, robo
->sck
, GPIO_DRV_PRIORITY
);
224 OSL_DELAY(SCK_EDGE_TIME
);
226 /* RACK when bit 0 is high */
232 /* Byte bang from LSB to MSB */
238 ET_ERROR(("spi_read: timeout"));
245 /* Enable/disable SPI access */
247 spi_select(robo_info_t
*robo
, uint8 spi
)
250 /* Enable SPI access */
251 si_gpioout(robo
->sih
, robo
->ss
, 0, GPIO_DRV_PRIORITY
);
253 /* Disable SPI access */
254 si_gpioout(robo
->sih
, robo
->ss
, robo
->ss
, GPIO_DRV_PRIORITY
);
256 OSL_DELAY(SS_SETUP_TIME
);
260 /* Select chip and page */
262 spi_goto(robo_info_t
*robo
, uint8 page
)
264 uint8 reg8
= REG_SPI_PAGE
; /* page select register */
267 /* Issue the command only when we are on a different page */
268 if (robo
->page
== page
)
273 /* Enable SPI access */
276 /* Select new page with CID 0 */
277 cmd8
= ((6 << 4) | /* normal SPI */
279 spi_write(robo
, &cmd8
, 1);
280 spi_write(robo
, ®8
, 1);
281 spi_write(robo
, &page
, 1);
283 /* Disable SPI access */
287 /* Write register thru SPI */
289 spi_wreg(robo_info_t
*robo
, uint8 page
, uint8 addr
, void *val
, int len
)
299 /* validate value length and buffer address */
300 ASSERT(len
== 1 || (len
== 2 && !((int)val
& 1)) ||
301 (len
== 4 && !((int)val
& 3)));
303 /* Select chip and page */
304 spi_goto(robo
, page
);
306 /* Enable SPI access */
309 /* Write with CID 0 */
310 cmd8
= ((6 << 4) | /* normal SPI */
312 spi_write(robo
, &cmd8
, 1);
313 spi_write(robo
, &addr
, 1);
316 bytes
.val8
= *(uint8
*)val
;
319 bytes
.val16
= htol16(*(uint16
*)val
);
322 bytes
.val32
= htol32(*(uint32
*)val
);
325 spi_write(robo
, (uint8
*)val
, len
);
327 ET_MSG(("%s: [0x%x-0x%x] := 0x%x (len %d)\n", __FUNCTION__
, page
, addr
,
328 *(uint16
*)val
, len
));
329 /* Disable SPI access */
334 /* Read register thru SPI in fast SPI mode */
336 spi_rreg(robo_info_t
*robo
, uint8 page
, uint8 addr
, void *val
, int len
)
346 /* validate value length and buffer address */
347 ASSERT(len
== 1 || (len
== 2 && !((int)val
& 1)) ||
348 (len
== 4 && !((int)val
& 3)));
350 /* Select chip and page */
351 spi_goto(robo
, page
);
353 /* Enable SPI access */
356 /* Fast SPI read with CID 0 and byte offset 0 */
357 cmd8
= (1 << 4); /* fast SPI */
358 spi_write(robo
, &cmd8
, 1);
359 spi_write(robo
, &addr
, 1);
360 status
= spi_read(robo
, (uint8
*)&bytes
, len
);
363 *(uint8
*)val
= bytes
.val8
;
366 *(uint16
*)val
= ltoh16(bytes
.val16
);
369 *(uint32
*)val
= ltoh32(bytes
.val32
);
373 ET_MSG(("%s: [0x%x-0x%x] => 0x%x (len %d)\n", __FUNCTION__
, page
, addr
,
374 *(uint16
*)val
, len
));
376 /* Disable SPI access */
381 /* SPI/gpio interface functions */
382 static dev_ops_t spigpio
= {
392 /* Access switch registers through MII (MDC/MDIO) */
394 #define MII_MAX_RETRY 100
396 /* Write register thru MDC/MDIO */
398 mii_wreg(robo_info_t
*robo
, uint8 page
, uint8 reg
, void *val
, int len
)
403 uint8
*ptr
= (uint8
*)val
;
405 /* validate value length and buffer address */
406 ASSERT(len
== 1 || len
== 6 || len
== 8 ||
407 ((len
== 2) && !((int)val
& 1)) || ((len
== 4) && !((int)val
& 3)));
409 ET_MSG(("%s: [0x%x-0x%x] := 0x%x (len %d)\n", __FUNCTION__
, page
, reg
,
410 VARG(val
, len
), len
));
412 /* set page number - MII register 0x10 */
413 if (robo
->page
!= page
) {
414 cmd16
= ((page
<< 8) | /* page number */
415 1); /* mdc/mdio access enable */
416 robo
->miiwr(h
, PSEUDO_PHYAD
, REG_MII_PAGE
, cmd16
);
423 val16
= ((val16
<< 8) | ptr
[6]);
424 robo
->miiwr(h
, PSEUDO_PHYAD
, REG_MII_DATA3
, val16
);
429 val16
= ((val16
<< 8) | ptr
[4]);
430 robo
->miiwr(h
, PSEUDO_PHYAD
, REG_MII_DATA2
, val16
);
432 val16
= ((val16
<< 8) | ptr
[2]);
433 robo
->miiwr(h
, PSEUDO_PHYAD
, REG_MII_DATA1
, val16
);
435 val16
= ((val16
<< 8) | ptr
[0]);
436 robo
->miiwr(h
, PSEUDO_PHYAD
, REG_MII_DATA0
, val16
);
440 val16
= (uint16
)((*(uint32
*)val
) >> 16);
441 robo
->miiwr(h
, PSEUDO_PHYAD
, REG_MII_DATA1
, val16
);
442 val16
= (uint16
)(*(uint32
*)val
);
443 robo
->miiwr(h
, PSEUDO_PHYAD
, REG_MII_DATA0
, val16
);
447 val16
= *(uint16
*)val
;
448 robo
->miiwr(h
, PSEUDO_PHYAD
, REG_MII_DATA0
, val16
);
452 val16
= *(uint8
*)val
;
453 robo
->miiwr(h
, PSEUDO_PHYAD
, REG_MII_DATA0
, val16
);
457 /* set register address - MII register 0x11 */
458 cmd16
= ((reg
<< 8) | /* register address */
459 1); /* opcode write */
460 robo
->miiwr(h
, PSEUDO_PHYAD
, REG_MII_ADDR
, cmd16
);
462 /* is operation finished? */
463 for (i
= MII_MAX_RETRY
; i
> 0; i
--) {
464 val16
= robo
->miird(h
, PSEUDO_PHYAD
, REG_MII_ADDR
);
465 if ((val16
& 3) == 0)
471 ET_ERROR(("mii_wreg: timeout"));
477 /* Read register thru MDC/MDIO */
479 mii_rreg(robo_info_t
*robo
, uint8 page
, uint8 reg
, void *val
, int len
)
484 uint8
*ptr
= (uint8
*)val
;
486 /* validate value length and buffer address */
487 ASSERT(len
== 1 || len
== 6 || len
== 8 ||
488 ((len
== 2) && !((int)val
& 1)) || ((len
== 4) && !((int)val
& 3)));
490 /* set page number - MII register 0x10 */
491 if (robo
->page
!= page
) {
492 cmd16
= ((page
<< 8) | /* page number */
493 1); /* mdc/mdio access enable */
494 robo
->miiwr(h
, PSEUDO_PHYAD
, REG_MII_PAGE
, cmd16
);
498 /* set register address - MII register 0x11 */
499 cmd16
= ((reg
<< 8) | /* register address */
500 2); /* opcode read */
501 robo
->miiwr(h
, PSEUDO_PHYAD
, REG_MII_ADDR
, cmd16
);
503 /* is operation finished? */
504 for (i
= MII_MAX_RETRY
; i
> 0; i
--) {
505 val16
= robo
->miird(h
, PSEUDO_PHYAD
, REG_MII_ADDR
);
506 if ((val16
& 3) == 0)
511 ET_ERROR(("mii_rreg: timeout"));
517 val16
= robo
->miird(h
, PSEUDO_PHYAD
, REG_MII_DATA3
);
518 ptr
[7] = (val16
>> 8);
519 ptr
[6] = (val16
& 0xff);
523 val16
= robo
->miird(h
, PSEUDO_PHYAD
, REG_MII_DATA2
);
524 ptr
[5] = (val16
>> 8);
525 ptr
[4] = (val16
& 0xff);
526 val16
= robo
->miird(h
, PSEUDO_PHYAD
, REG_MII_DATA1
);
527 ptr
[3] = (val16
>> 8);
528 ptr
[2] = (val16
& 0xff);
529 val16
= robo
->miird(h
, PSEUDO_PHYAD
, REG_MII_DATA0
);
530 ptr
[1] = (val16
>> 8);
531 ptr
[0] = (val16
& 0xff);
535 val16
= robo
->miird(h
, PSEUDO_PHYAD
, REG_MII_DATA1
);
536 *(uint32
*)val
= (((uint32
)val16
) << 16);
537 val16
= robo
->miird(h
, PSEUDO_PHYAD
, REG_MII_DATA0
);
538 *(uint32
*)val
|= val16
;
542 val16
= robo
->miird(h
, PSEUDO_PHYAD
, REG_MII_DATA0
);
543 *(uint16
*)val
= val16
;
547 val16
= robo
->miird(h
, PSEUDO_PHYAD
, REG_MII_DATA0
);
548 *(uint8
*)val
= (uint8
)(val16
& 0xff);
552 ET_MSG(("%s: [0x%x-0x%x] => 0x%x (len %d)\n", __FUNCTION__
, page
, reg
,
553 VARG(val
, len
), len
));
558 /* MII interface functions */
559 static dev_ops_t mdcmdio
= {
567 /* High level switch configuration functions. */
569 /* Get access to the RoboSwitch */
571 bcm_robo_attach(si_t
*sih
, void *h
, char *vars
, miird_f miird
, miiwr_f miiwr
)
576 const char *et1port
, *et1phyaddr
;
577 int mdcport
= 0, phyaddr
= 0;
579 int lan_portenable
= 0;
581 /* Allocate and init private state */
582 if (!(robo
= MALLOC(si_osh(sih
), sizeof(robo_info_t
)))) {
583 ET_ERROR(("robo_attach: out of memory, malloced %d bytes",
584 MALLOCED(si_osh(sih
))));
587 bzero(robo
, sizeof(robo_info_t
));
596 /* Enable center tap voltage for LAN ports using gpio23. Usefull in case when
597 * romboot CFE loads linux over WAN port and Linux enables LAN ports later
599 if ((lan_portenable
= getgpiopin(robo
->vars
, "lanports_enable", GPIO_PIN_NOTDEFINED
)) !=
600 GPIO_PIN_NOTDEFINED
) {
601 lan_portenable
= 1 << lan_portenable
;
602 si_gpioouten(sih
, lan_portenable
, lan_portenable
, GPIO_DRV_PRIORITY
);
603 si_gpioout(sih
, lan_portenable
, lan_portenable
, GPIO_DRV_PRIORITY
);
607 /* Trigger external reset by nvram variable existance */
608 if ((reset
= getgpiopin(robo
->vars
, "robo_reset", GPIO_PIN_NOTDEFINED
)) !=
609 GPIO_PIN_NOTDEFINED
) {
611 * Reset sequence: RESET low(50ms)->high(20ms)
613 * We have to perform a full sequence for we don't know how long
614 * it has been from power on till now.
616 ET_MSG(("%s: Using external reset in gpio pin %d\n", __FUNCTION__
, reset
));
619 /* Keep RESET low for 50 ms */
620 si_gpioout(sih
, reset
, 0, GPIO_DRV_PRIORITY
);
621 si_gpioouten(sih
, reset
, reset
, GPIO_DRV_PRIORITY
);
624 /* Keep RESET high for at least 20 ms */
625 si_gpioout(sih
, reset
, reset
, GPIO_DRV_PRIORITY
);
628 /* In case we need it */
629 idx
= si_coreidx(sih
);
631 if (si_setcore(sih
, ROBO_CORE_ID
, 0)) {
632 /* If we have an internal robo core, reset it using si_core_reset */
633 ET_MSG(("%s: Resetting internal robo core\n", __FUNCTION__
));
634 si_core_reset(sih
, 0, 0);
635 robo
->corerev
= si_corerev(sih
);
637 else if (sih
->chip
== BCM5356_CHIP_ID
) {
638 /* Testing chipid is a temporary hack. We need to really
639 * figure out how to treat non-cores in ai chips.
644 mii_rreg(robo
, PAGE_STATUS
, REG_STATUS_REV
, &robo
->corerev
, 1);
646 si_setcoreidx(sih
, idx
);
647 ET_MSG(("%s: Internal robo rev %d\n", __FUNCTION__
, robo
->corerev
));
650 if (miird
&& miiwr
) {
652 int rc
, retry_count
= 0;
654 /* Read the PHY ID */
655 tmp
= miird(h
, PSEUDO_PHYAD
, 2);
657 /* WAR: Enable mdc/mdio access to the switch registers. Unless
658 * a write to bit 0 of pseudo phy register 16 is done we are
659 * unable to talk to the switch on a customer ref design.
662 miiwr(h
, PSEUDO_PHYAD
, 16, 1);
663 tmp
= miird(h
, PSEUDO_PHYAD
, 2);
668 rc
= mii_rreg(robo
, PAGE_MMR
, REG_DEVICE_ID
,
669 &robo
->devid
, sizeof(uint16
));
673 } while ((robo
->devid
== 0) && (retry_count
< 10));
675 ET_MSG(("%s: devid read %ssuccesfully via mii: 0x%x\n",
676 __FUNCTION__
, rc
? "un" : "", robo
->devid
));
677 ET_MSG(("%s: mii access to switch works\n", __FUNCTION__
));
678 robo
->ops
= &mdcmdio
;
679 if ((rc
!= 0) || (robo
->devid
== 0)) {
680 ET_MSG(("%s: error reading devid, assuming 5325e\n",
682 robo
->devid
= DEVID5325
;
685 ET_MSG(("%s: devid: 0x%x\n", __FUNCTION__
, robo
->devid
));
688 if ((robo
->devid
== DEVID5395
) ||
689 (robo
->devid
== DEVID5397
) ||
690 (robo
->devid
== DEVID5398
)) {
693 /* If it is a 539x switch, use the soft reset register */
694 ET_MSG(("%s: Resetting 539x robo switch\n", __FUNCTION__
));
696 /* Reset the 539x switch core and register file */
698 mii_wreg(robo
, PAGE_CTRL
, REG_CTRL_SRST
, &srst_ctrl
, sizeof(uint8
));
700 mii_wreg(robo
, PAGE_CTRL
, REG_CTRL_SRST
, &srst_ctrl
, sizeof(uint8
));
703 /* Enable switch leds */
704 if (sih
->chip
== BCM5356_CHIP_ID
) {
705 si_pmu_chipcontrol(sih
, 2, (1 << 25), (1 << 25));
706 /* also enable fast MII clocks */
707 si_pmu_chipcontrol(sih
, 0, (1 << 1), (1 << 1));
708 } else if ((sih
->chip
== BCM5357_CHIP_ID
) || (sih
->chip
== BCM53572_CHIP_ID
)) {
709 uint32 led_gpios
= 0;
712 if (((sih
->chip
== BCM5357_CHIP_ID
) && (sih
->chippkg
!= BCM47186_PKG_ID
)) ||
713 ((sih
->chip
== BCM53572_CHIP_ID
) && (sih
->chippkg
!= BCM47188_PKG_ID
)))
715 var
= getvar(vars
, "et_swleds");
717 led_gpios
= bcm_strtoul(var
, NULL
, 0);
719 si_pmu_chipcontrol(sih
, 2, (0x3ff << 8), (led_gpios
<< 8));
724 int mosi
, miso
, ss
, sck
;
726 robo
->ops
= &spigpio
;
727 robo
->devid
= DEVID5325
;
729 /* Init GPIO mapping. Default 2, 3, 4, 5 */
730 ss
= getgpiopin(vars
, "robo_ss", 2);
731 if (ss
== GPIO_PIN_NOTDEFINED
) {
732 ET_ERROR(("robo_attach: robo_ss gpio fail: GPIO 2 in use"));
736 sck
= getgpiopin(vars
, "robo_sck", 3);
737 if (sck
== GPIO_PIN_NOTDEFINED
) {
738 ET_ERROR(("robo_attach: robo_sck gpio fail: GPIO 3 in use"));
741 robo
->sck
= 1 << sck
;
742 mosi
= getgpiopin(vars
, "robo_mosi", 4);
743 if (mosi
== GPIO_PIN_NOTDEFINED
) {
744 ET_ERROR(("robo_attach: robo_mosi gpio fail: GPIO 4 in use"));
747 robo
->mosi
= 1 << mosi
;
748 miso
= getgpiopin(vars
, "robo_miso", 5);
749 if (miso
== GPIO_PIN_NOTDEFINED
) {
750 ET_ERROR(("robo_attach: robo_miso gpio fail: GPIO 5 in use"));
753 robo
->miso
= 1 << miso
;
754 ET_MSG(("%s: ss %d sck %d mosi %d miso %d\n", __FUNCTION__
,
755 ss
, sck
, mosi
, miso
));
761 ASSERT(robo
->ops
->write_reg
);
762 ASSERT(robo
->ops
->read_reg
);
763 ASSERT((robo
->devid
== DEVID5325
) ||
764 (robo
->devid
== DEVID5395
) ||
765 (robo
->devid
== DEVID5397
) ||
766 (robo
->devid
== DEVID5398
) ||
767 (robo
->devid
== DEVID53115
) ||
768 (robo
->devid
== DEVID53125
));
771 /* nvram variable switch_mode controls the power save mode on the switch
772 * set the default value in the beginning
774 robo
->pwrsave_mode_manual
= getintvar(robo
->vars
, "switch_mode_manual");
775 robo
->pwrsave_mode_auto
= getintvar(robo
->vars
, "switch_mode_auto");
777 /* Determining what all phys need to be included in
778 * power save operation
780 et1port
= getvar(vars
, "et1mdcport");
782 mdcport
= bcm_atoi(et1port
);
784 et1phyaddr
= getvar(vars
, "et1phyaddr");
786 phyaddr
= bcm_atoi(et1phyaddr
);
788 if ((mdcport
== 0) && (phyaddr
== 4))
789 /* For 5325F switch we need to do only phys 0-3 */
790 robo
->pwrsave_phys
= 0xf;
792 /* By default all 5 phys are put into power save if there is no link */
793 robo
->pwrsave_phys
= 0x1f;
800 bcm_robo_detach(robo
);
805 /* Release access to the RoboSwitch */
807 bcm_robo_detach(robo_info_t
*robo
)
809 MFREE(si_osh(robo
->sih
), robo
, sizeof(robo_info_t
));
812 /* Enable the device and set it to a known good state */
814 bcm_robo_enable_device(robo_info_t
*robo
)
816 uint8 reg_offset
, reg_val
;
819 /* Enable management interface access */
820 if (robo
->ops
->enable_mgmtif
)
821 robo
->ops
->enable_mgmtif(robo
);
823 if (robo
->devid
== DEVID5398
) {
824 /* Disable unused ports: port 6 and 7 */
825 for (reg_offset
= REG_CTRL_PORT6
; reg_offset
<= REG_CTRL_PORT7
; reg_offset
++) {
826 /* Set bits [1:0] to disable RX and TX */
828 robo
->ops
->write_reg(robo
, PAGE_CTRL
, reg_offset
, ®_val
,
833 if (robo
->devid
== DEVID5325
) {
834 /* Must put the switch into Reverse MII mode! */
836 /* MII port state override (page 0 register 14) */
837 robo
->ops
->read_reg(robo
, PAGE_CTRL
, REG_CTRL_MIIPO
, ®_val
, sizeof(reg_val
));
839 /* Bit 4 enables reverse MII mode */
840 if (!(reg_val
& (1 << 4))) {
843 robo
->ops
->write_reg(robo
, PAGE_CTRL
, REG_CTRL_MIIPO
, ®_val
,
847 robo
->ops
->read_reg(robo
, PAGE_CTRL
, REG_CTRL_MIIPO
, ®_val
,
849 if (!(reg_val
& (1 << 4))) {
850 ET_ERROR(("robo_enable_device: enabling RvMII mode failed\n"));
856 /* Disable management interface access */
857 if (robo
->ops
->disable_mgmtif
)
858 robo
->ops
->disable_mgmtif(robo
);
864 #define FLAG_TAGGED 't' /* output tagged (external ports only) */
865 #define FLAG_UNTAG 'u' /* input & output untagged (CPU port only, for OS (linux, ...) */
866 #define FLAG_LAN '*' /* input & output untagged (CPU port only, for CFE */
868 /* port descriptor */
870 uint32 untag
; /* untag enable bit (Page 0x05 Address 0x63-0x66 Bit[17:9]) */
871 uint32 member
; /* vlan member bit (Page 0x05 Address 0x63-0x66 Bit[7:0]) */
872 uint8 ptagr
; /* port tag register address (Page 0x34 Address 0x10-0x1F) */
873 uint8 cpu
; /* is this cpu port? */
876 pdesc_t pdesc97
[] = {
877 /* 5395/5397/5398/53115S is 0 ~ 7. port 8 is IMP port. */
878 /* port 0 */ {1 << 9, 1 << 0, REG_VLAN_PTAG0
, 0},
879 /* port 1 */ {1 << 10, 1 << 1, REG_VLAN_PTAG1
, 0},
880 /* port 2 */ {1 << 11, 1 << 2, REG_VLAN_PTAG2
, 0},
881 /* port 3 */ {1 << 12, 1 << 3, REG_VLAN_PTAG3
, 0},
882 /* port 4 */ {1 << 13, 1 << 4, REG_VLAN_PTAG4
, 0},
883 /* port 5 */ {1 << 14, 1 << 5, REG_VLAN_PTAG5
, 0},
884 /* port 6 */ {1 << 15, 1 << 6, REG_VLAN_PTAG6
, 0},
885 /* port 7 */ {1 << 16, 1 << 7, REG_VLAN_PTAG7
, 0},
886 /* mii port */ {1 << 17, 1 << 8, REG_VLAN_PTAG8
, 1},
889 pdesc_t pdesc25
[] = {
890 /* port 0 */ {1 << 6, 1 << 0, REG_VLAN_PTAG0
, 0},
891 /* port 1 */ {1 << 7, 1 << 1, REG_VLAN_PTAG1
, 0},
892 /* port 2 */ {1 << 8, 1 << 2, REG_VLAN_PTAG2
, 0},
893 /* port 3 */ {1 << 9, 1 << 3, REG_VLAN_PTAG3
, 0},
894 /* port 4 */ {1 << 10, 1 << 4, REG_VLAN_PTAG4
, 0},
895 /* mii port */ {1 << 11, 1 << 5, REG_VLAN_PTAG5
, 1},
898 /* Configure the VLANs */
900 bcm_robo_config_vlan(robo_info_t
*robo
, uint8
*mac_addr
)
908 uint8 arl_entry
[8] = { 0 }, arl_entry1
[8] = { 0 };
910 /* Enable management interface access */
911 if (robo
->ops
->enable_mgmtif
)
912 robo
->ops
->enable_mgmtif(robo
);
914 /* setup global vlan configuration */
915 /* VLAN Control 0 Register (Page 0x34, Address 0) */
916 robo
->ops
->read_reg(robo
, PAGE_VLAN
, REG_VLAN_CTRL0
, &val8
, sizeof(val8
));
917 val8
|= ((1 << 7) | /* enable 802.1Q VLAN */
918 (3 << 5)); /* individual VLAN learning mode */
919 if (robo
->devid
== DEVID5325
)
920 val8
&= ~(1 << 1); /* must clear reserved bit 1 */
921 robo
->ops
->write_reg(robo
, PAGE_VLAN
, REG_VLAN_CTRL0
, &val8
, sizeof(val8
));
922 /* VLAN Control 1 Register (Page 0x34, Address 1) */
923 robo
->ops
->read_reg(robo
, PAGE_VLAN
, REG_VLAN_CTRL1
, &val8
, sizeof(val8
));
924 val8
|= ((1 << 2) | /* enable RSV multicast V Fwdmap */
925 (1 << 3)); /* enable RSV multicast V Untagmap */
926 if (robo
->devid
== DEVID5325
)
927 val8
|= (1 << 1); /* enable RSV multicast V Tagging */
928 robo
->ops
->write_reg(robo
, PAGE_VLAN
, REG_VLAN_CTRL1
, &val8
, sizeof(val8
));
930 arl_entry
[0] = mac_addr
[5];
931 arl_entry
[1] = mac_addr
[4];
932 arl_entry
[2] = mac_addr
[3];
933 arl_entry
[3] = mac_addr
[2];
934 arl_entry
[4] = mac_addr
[1];
935 arl_entry
[5] = mac_addr
[0];
937 if (robo
->devid
== DEVID5325
) {
938 /* Init the entry 1 of the bin */
939 robo
->ops
->write_reg(robo
, PAGE_VTBL
, REG_VTBL_ARL_E1
,
940 arl_entry1
, sizeof(arl_entry1
));
941 robo
->ops
->write_reg(robo
, PAGE_VTBL
, REG_VTBL_VID_E1
,
944 /* Init the entry 0 of the bin */
945 arl_entry
[6] = 0x8; /* Port Id: MII */
946 arl_entry
[7] = 0xc0; /* Static Entry, Valid */
948 robo
->ops
->write_reg(robo
, PAGE_VTBL
, REG_VTBL_ARL_E0
,
949 arl_entry
, sizeof(arl_entry
));
950 robo
->ops
->write_reg(robo
, PAGE_VTBL
, REG_VTBL_MINDX
,
951 arl_entry
, ETHER_ADDR_LEN
);
953 /* VLAN Control 4 Register (Page 0x34, Address 4) */
954 val8
= (1 << 6); /* drop frame with VID violation */
955 robo
->ops
->write_reg(robo
, PAGE_VLAN
, REG_VLAN_CTRL4
, &val8
, sizeof(val8
));
957 /* VLAN Control 5 Register (Page 0x34, Address 5) */
958 val8
= (1 << 3); /* drop frame when miss V table */
959 robo
->ops
->write_reg(robo
, PAGE_VLAN
, REG_VLAN_CTRL5
, &val8
, sizeof(val8
));
962 pdescsz
= sizeof(pdesc25
) / sizeof(pdesc_t
);
964 /* Initialize the MAC Addr Index Register */
965 robo
->ops
->write_reg(robo
, PAGE_VTBL
, REG_VTBL_MINDX
,
966 arl_entry
, ETHER_ADDR_LEN
);
969 pdescsz
= sizeof(pdesc97
) / sizeof(pdesc_t
);
972 /* setup each vlan. max. 16 vlans. */
973 /* force vlan id to be equal to vlan number */
974 for (vid
= 0; vid
< VLAN_NUMVLANS
; vid
++) {
975 char vlanports
[] = "vlanXXXXports";
976 char port
[] = "XXXX", *next
;
977 const char *ports
, *cur
;
982 /* no members if VLAN id is out of limitation */
983 if (vid
> VLAN_MAXVID
)
986 /* get vlan member ports from nvram */
987 sprintf(vlanports
, "vlan%dports", vid
);
988 ports
= getvar(robo
->vars
, vlanports
);
990 /* In 539x vid == 0 us invalid?? */
991 if ((robo
->devid
!= DEVID5325
) && (vid
== 0)) {
993 ET_ERROR(("VID 0 is set in nvram, Ignoring\n"));
997 /* disable this vlan if not defined */
1002 * setup each port in the vlan. cpu port needs special handing
1003 * (with or without output tagging) to support linux/pmon/cfe.
1005 for (cur
= ports
; cur
; cur
= next
) {
1006 /* tokenize the port list */
1009 next
= bcmstrstr(cur
, " ");
1010 len
= next
? next
- cur
: strlen(cur
);
1013 if (len
> sizeof(port
) - 1)
1014 len
= sizeof(port
) - 1;
1015 strncpy(port
, cur
, len
);
1018 /* make sure port # is within the range */
1019 pid
= bcm_atoi(port
);
1020 if (pid
>= pdescsz
) {
1021 ET_ERROR(("robo_config_vlan: port %d in vlan%dports is out "
1022 "of range[0-%d]\n", pid
, vid
, pdescsz
));
1026 /* build VLAN registers values */
1028 if ((!pdesc
[pid
].cpu
&& !strchr(port
, FLAG_TAGGED
)) ||
1029 (pdesc
[pid
].cpu
&& strchr(port
, FLAG_UNTAG
)))
1031 untag
|= pdesc
[pid
].untag
;
1033 member
|= pdesc
[pid
].member
;
1035 /* set port tag - applies to untagged ingress frames */
1036 /* Default Port Tag Register (Page 0x34, Address 0x10-0x1D) */
1040 #define FL FLAG_UNTAG
1042 if (!pdesc
[pid
].cpu
|| strchr(port
, FL
)) {
1043 val16
= ((0 << 13) | /* priority - always 0 */
1045 robo
->ops
->write_reg(robo
, PAGE_VLAN
, pdesc
[pid
].ptagr
,
1046 &val16
, sizeof(val16
));
1050 /* Add static ARL entries */
1051 if (robo
->devid
== DEVID5325
) {
1053 robo
->ops
->write_reg(robo
, PAGE_VTBL
, REG_VTBL_VID_E0
,
1054 &val8
, sizeof(val8
));
1055 robo
->ops
->write_reg(robo
, PAGE_VTBL
, REG_VTBL_VINDX
,
1056 &val8
, sizeof(val8
));
1058 /* Write the entry */
1060 robo
->ops
->write_reg(robo
, PAGE_VTBL
, REG_VTBL_CTRL
,
1061 &val8
, sizeof(val8
));
1062 /* Wait for write to complete */
1063 SPINWAIT((robo
->ops
->read_reg(robo
, PAGE_VTBL
, REG_VTBL_CTRL
,
1064 &val8
, sizeof(val8
)), ((val8
& 0x80) != 0)),
1067 /* Set the VLAN Id in VLAN ID Index Register */
1069 robo
->ops
->write_reg(robo
, PAGE_VTBL
, REG_VTBL_VINDX
,
1070 &val8
, sizeof(val8
));
1072 /* Set the MAC addr and VLAN Id in ARL Table MAC/VID Entry 0
1077 robo
->ops
->write_reg(robo
, PAGE_VTBL
, REG_VTBL_ARL_E0
,
1078 arl_entry
, sizeof(arl_entry
));
1080 /* Set the Static bit , Valid bit and Port ID fields in
1081 * ARL Table Data Entry 0 Register
1084 robo
->ops
->write_reg(robo
, PAGE_VTBL
, REG_VTBL_DAT_E0
,
1085 &val16
, sizeof(val16
));
1087 /* Clear the ARL_R/W bit and set the START/DONE bit in
1088 * the ARL Read/Write Control Register.
1091 robo
->ops
->write_reg(robo
, PAGE_VTBL
, REG_VTBL_CTRL
,
1092 &val8
, sizeof(val8
));
1093 /* Wait for write to complete */
1094 SPINWAIT((robo
->ops
->read_reg(robo
, PAGE_VTBL
, REG_VTBL_CTRL
,
1095 &val8
, sizeof(val8
)), ((val8
& 0x80) != 0)),
1100 /* setup VLAN ID and VLAN memberships */
1102 val32
= (untag
| /* untag enable */
1103 member
); /* vlan members */
1104 if (robo
->devid
== DEVID5325
) {
1105 if (robo
->corerev
< 3) {
1106 val32
|= ((1 << 20) | /* valid write */
1107 ((vid
>> 4) << 12)); /* vlan id bit[11:4] */
1109 val32
|= ((1 << 24) | /* valid write */
1110 (vid
<< 12)); /* vlan id bit[11:4] */
1112 ET_MSG(("bcm_robo_config_vlan: programming REG_VLAN_WRITE %08x\n", val32
));
1114 /* VLAN Write Register (Page 0x34, Address 0x08-0x0B) */
1115 robo
->ops
->write_reg(robo
, PAGE_VLAN
, REG_VLAN_WRITE
, &val32
,
1117 /* VLAN Table Access Register (Page 0x34, Address 0x06-0x07) */
1118 val16
= ((1 << 13) | /* start command */
1119 (1 << 12) | /* write state */
1121 robo
->ops
->write_reg(robo
, PAGE_VLAN
, REG_VLAN_ACCESS
, &val16
,
1124 uint8 vtble
, vtbli
, vtbla
;
1126 if ((robo
->devid
== DEVID5395
) ||
1127 (robo
->devid
== DEVID53115
) ||
1128 (robo
->devid
== DEVID53125
)) {
1129 vtble
= REG_VTBL_ENTRY_5395
;
1130 vtbli
= REG_VTBL_INDX_5395
;
1131 vtbla
= REG_VTBL_ACCESS_5395
;
1133 vtble
= REG_VTBL_ENTRY
;
1134 vtbli
= REG_VTBL_INDX
;
1135 vtbla
= REG_VTBL_ACCESS
;
1138 /* VLAN Table Entry Register (Page 0x05, Address 0x63-0x66/0x83-0x86) */
1139 robo
->ops
->write_reg(robo
, PAGE_VTBL
, vtble
, &val32
,
1141 /* VLAN Table Address Index Reg (Page 0x05, Address 0x61-0x62/0x81-0x82) */
1142 val16
= vid
; /* vlan id */
1143 robo
->ops
->write_reg(robo
, PAGE_VTBL
, vtbli
, &val16
,
1146 /* VLAN Table Access Register (Page 0x34, Address 0x60/0x80) */
1147 val8
= ((1 << 7) | /* start command */
1149 robo
->ops
->write_reg(robo
, PAGE_VTBL
, vtbla
, &val8
,
1154 if (robo
->devid
== DEVID5325
) {
1155 /* setup priority mapping - applies to tagged ingress frames */
1156 /* Priority Re-map Register (Page 0x34, Address 0x20-0x23) */
1157 val32
= ((0 << 0) | /* 0 -> 0 */
1158 (1 << 3) | /* 1 -> 1 */
1159 (2 << 6) | /* 2 -> 2 */
1160 (3 << 9) | /* 3 -> 3 */
1161 (4 << 12) | /* 4 -> 4 */
1162 (5 << 15) | /* 5 -> 5 */
1163 (6 << 18) | /* 6 -> 6 */
1164 (7 << 21)); /* 7 -> 7 */
1165 robo
->ops
->write_reg(robo
, PAGE_VLAN
, REG_VLAN_PMAP
, &val32
, sizeof(val32
));
1168 if (robo
->devid
== DEVID53115
) {
1169 /* Configure the priority system to use to determine the TC of
1170 * ingress frames. Use DiffServ TC mapping, otherwise 802.1p
1171 * TC mapping, otherwise MAC based TC mapping.
1173 val8
= ((0 << 6) | /* Disable port based QoS */
1174 (2 << 2)); /* QoS priority selection */
1175 robo
->ops
->write_reg(robo
, 0x30, 0, &val8
, sizeof(val8
));
1177 /* Configure tx queues scheduling mechanism */
1178 val8
= (3 << 0); /* Strict priority */
1179 robo
->ops
->write_reg(robo
, 0x30, 0x80, &val8
, sizeof(val8
));
1181 /* Enable 802.1p Priority to TC mapping for individual ports */
1183 robo
->ops
->write_reg(robo
, 0x30, 0x4, &val16
, sizeof(val16
));
1185 /* Configure the TC to COS mapping. This determines the egress
1188 val16
= ((1 << 0) | /* Pri 0 mapped to TXQ 1 */
1189 (0 << 2) | /* Pri 1 mapped to TXQ 0 */
1190 (0 << 4) | /* Pri 2 mapped to TXQ 0 */
1191 (1 << 6) | /* Pri 3 mapped to TXQ 1 */
1192 (2 << 8) | /* Pri 4 mapped to TXQ 2 */
1193 (2 << 10) | /* Pri 5 mapped to TXQ 2 */
1194 (3 << 12) | /* Pri 6 mapped to TXQ 3 */
1195 (3 << 14)); /* Pri 7 mapped to TXQ 3 */
1196 robo
->ops
->write_reg(robo
, 0x30, 0x62, &val16
, sizeof(val16
));
1199 /* Drop reserved bit, if any */
1200 robo
->ops
->read_reg(robo
, PAGE_CTRL
, 0x2f, &val8
, sizeof(val8
));
1201 if (/*((robo->devid == DEVID53115) || (robo->devid == DEVID53125)) &&*/
1204 robo
->ops
->write_reg(robo
, PAGE_CTRL
, 0x2f, &val8
, sizeof(val8
));
1207 /* Disable management interface access */
1208 if (robo
->ops
->disable_mgmtif
)
1209 robo
->ops
->disable_mgmtif(robo
);
1214 /* Enable switching/forwarding */
1216 bcm_robo_enable_switch(robo_info_t
*robo
)
1218 int i
, max_port_ind
, ret
= 0;
1221 /* Enable management interface access */
1222 if (robo
->ops
->enable_mgmtif
)
1223 robo
->ops
->enable_mgmtif(robo
);
1225 /* Switch Mode register (Page 0, Address 0x0B) */
1226 robo
->ops
->read_reg(robo
, PAGE_CTRL
, REG_CTRL_MODE
, &val8
, sizeof(val8
));
1228 /* Bit 1 enables switching/forwarding */
1229 if (!(val8
& (1 << 1))) {
1230 /* Set unmanaged mode */
1231 val8
&= (~(1 << 0));
1233 /* Enable forwarding */
1235 robo
->ops
->write_reg(robo
, PAGE_CTRL
, REG_CTRL_MODE
, &val8
, sizeof(val8
));
1238 robo
->ops
->read_reg(robo
, PAGE_CTRL
, REG_CTRL_MODE
, &val8
, sizeof(val8
));
1239 if (!(val8
& (1 << 1))) {
1240 ET_ERROR(("robo_enable_switch: enabling forwarding failed\n"));
1244 /* No spanning tree for unmanaged mode */
1246 max_port_ind
= ((robo
->devid
== DEVID5398
) ? REG_CTRL_PORT7
: REG_CTRL_PORT4
);
1247 for (i
= REG_CTRL_PORT0
; i
<= max_port_ind
; i
++) {
1248 robo
->ops
->write_reg(robo
, PAGE_CTRL
, i
, &val8
, sizeof(val8
));
1251 /* No spanning tree on IMP port too */
1252 robo
->ops
->write_reg(robo
, PAGE_CTRL
, REG_CTRL_IMP
, &val8
, sizeof(val8
));
1255 if (robo
->devid
== DEVID53125
) {
1256 /* Over ride IMP port status to make it link by default */
1258 robo
->ops
->read_reg(robo
, PAGE_CTRL
, REG_CTRL_MIIPO
, &val8
, sizeof(val8
));
1259 val8
|= 0xb1; /* Make Link pass and override it. */
1260 robo
->ops
->write_reg(robo
, PAGE_CTRL
, REG_CTRL_MIIPO
, &val8
, sizeof(val8
));
1261 /* Init the EEE feature */
1262 robo_eee_advertise_init(robo
);
1265 /* Disable management interface access */
1266 if (robo
->ops
->disable_mgmtif
)
1267 robo
->ops
->disable_mgmtif(robo
);
1274 robo_dump_regs(robo_info_t
*robo
, struct bcmstrbuf
*b
)
1283 bcm_bprintf(b
, "%s:\n", robo
->ops
->desc
);
1284 if (robo
->miird
== NULL
) {
1285 bcm_bprintf(b
, "SPI gpio pins: ss %d sck %d mosi %d miso %d\n",
1286 robo
->ss
, robo
->sck
, robo
->mosi
, robo
->miso
);
1289 /* Enable management interface access */
1290 if (robo
->ops
->enable_mgmtif
)
1291 robo
->ops
->enable_mgmtif(robo
);
1293 /* Dump registers interested */
1294 robo
->ops
->read_reg(robo
, PAGE_CTRL
, REG_CTRL_MODE
, &val8
, sizeof(val8
));
1295 bcm_bprintf(b
, "(0x00,0x0B)Switch mode regsiter: 0x%02x\n", val8
);
1296 if (robo
->devid
== DEVID5325
) {
1297 robo
->ops
->read_reg(robo
, PAGE_CTRL
, REG_CTRL_MIIPO
, &val8
, sizeof(val8
));
1298 bcm_bprintf(b
, "(0x00,0x0E)MII port state override regsiter: 0x%02x\n", val8
);
1300 if (robo
->miird
== NULL
)
1302 if (robo
->devid
== DEVID5325
) {
1304 pdescsz
= sizeof(pdesc25
) / sizeof(pdesc_t
);
1307 pdescsz
= sizeof(pdesc97
) / sizeof(pdesc_t
);
1310 robo
->ops
->read_reg(robo
, PAGE_VLAN
, REG_VLAN_CTRL0
, &val8
, sizeof(val8
));
1311 bcm_bprintf(b
, "(0x34,0x00)VLAN control 0 register: 0x%02x\n", val8
);
1312 robo
->ops
->read_reg(robo
, PAGE_VLAN
, REG_VLAN_CTRL1
, &val8
, sizeof(val8
));
1313 bcm_bprintf(b
, "(0x34,0x01)VLAN control 1 register: 0x%02x\n", val8
);
1314 robo
->ops
->read_reg(robo
, PAGE_VLAN
, REG_VLAN_CTRL4
, &val8
, sizeof(val8
));
1315 if (robo
->devid
== DEVID5325
) {
1316 bcm_bprintf(b
, "(0x34,0x04)VLAN control 4 register: 0x%02x\n", val8
);
1317 robo
->ops
->read_reg(robo
, PAGE_VLAN
, REG_VLAN_CTRL5
, &val8
, sizeof(val8
));
1318 bcm_bprintf(b
, "(0x34,0x05)VLAN control 5 register: 0x%02x\n", val8
);
1320 robo
->ops
->read_reg(robo
, PAGE_VLAN
, REG_VLAN_PMAP
, &val32
, sizeof(val32
));
1321 bcm_bprintf(b
, "(0x34,0x20)Prio Re-map: 0x%08x\n", val32
);
1323 for (i
= 0; i
<= VLAN_MAXVID
; i
++) {
1324 val16
= (1 << 13) /* start command */
1326 robo
->ops
->write_reg(robo
, PAGE_VLAN
, REG_VLAN_ACCESS
, &val16
,
1328 robo
->ops
->read_reg(robo
, PAGE_VLAN
, REG_VLAN_READ
, &val32
, sizeof(val32
));
1329 bcm_bprintf(b
, "(0x34,0xc)VLAN %d untag bits: 0x%02x member bits: 0x%02x\n",
1330 i
, (val32
& 0x0fc0) >> 6, (val32
& 0x003f));
1334 for (i
= 0; i
<= VLAN_MAXVID
; i
++) {
1335 /* VLAN Table Address Index Register (Page 0x05, Address 0x61-0x62) */
1336 val16
= i
; /* vlan id */
1337 robo
->ops
->write_reg(robo
, PAGE_VTBL
, REG_VTBL_INDX
, &val16
,
1339 /* VLAN Table Access Register (Page 0x34, Address 0x60) */
1340 val8
= ((1 << 7) | /* start command */
1342 robo
->ops
->write_reg(robo
, PAGE_VTBL
, REG_VTBL_ACCESS
, &val8
,
1344 /* VLAN Table Entry Register (Page 0x05, Address 0x63-0x66) */
1345 robo
->ops
->read_reg(robo
, PAGE_VTBL
, REG_VTBL_ENTRY
, &val32
,
1347 bcm_bprintf(b
, "VLAN %d untag bits: 0x%02x member bits: 0x%02x\n",
1348 i
, (val32
& 0x3fe00) >> 9, (val32
& 0x1ff));
1351 for (i
= 0; i
< pdescsz
; i
++) {
1352 robo
->ops
->read_reg(robo
, PAGE_VLAN
, pdesc
[i
].ptagr
, &val16
, sizeof(val16
));
1353 bcm_bprintf(b
, "(0x34,0x%02x)Port %d Tag: 0x%04x\n", pdesc
[i
].ptagr
, i
, val16
);
1357 /* Disable management interface access */
1358 if (robo
->ops
->disable_mgmtif
)
1359 robo
->ops
->disable_mgmtif(robo
);
1365 * Update the power save configuration for ports that changed link status.
1368 robo_power_save_mode_update(robo_info_t
*robo
)
1372 for (phy
= 0; phy
< MAX_NO_PHYS
; phy
++) {
1373 if (robo
->pwrsave_mode_auto
& (1 << phy
)) {
1374 ET_MSG(("%s: set port %d to auto mode\n",
1375 __FUNCTION__
, phy
));
1376 robo_power_save_mode(robo
, ROBO_PWRSAVE_AUTO
, phy
);
1384 robo_power_save_mode_clear_auto(robo_info_t
*robo
, int32 phy
)
1388 if (robo
->devid
== DEVID53115
) {
1389 /* For 53115 0x1C is the MII address of the auto power
1390 * down register. Bit 5 is enabling the mode
1391 * bits has the following purpose
1392 * 15 - write enable 10-14 shadow register select 01010 for
1393 * auto power 6-9 reserved 5 auto power mode enable
1394 * 4 sleep timer select : 1 means 5.4 sec
1395 * 0-3 wake up timer select: 0xF 1.26 sec
1398 robo
->miiwr(robo
->h
, phy
, REG_MII_AUTO_PWRDOWN
, val16
);
1399 } else if ((robo
->sih
->chip
== BCM5356_CHIP_ID
) || (robo
->sih
->chip
== BCM5357_CHIP_ID
)) {
1400 /* To disable auto power down mode
1401 * clear bit 5 of Aux Status 2 register
1402 * (Shadow reg 0x1b). Shadow register
1403 * access is enabled by writing
1404 * 1 to bit 7 of MII register 0x1f.
1406 val16
= robo
->miird(robo
->h
, phy
, REG_MII_BRCM_TEST
);
1407 robo
->miiwr(robo
->h
, phy
, REG_MII_BRCM_TEST
,
1408 (val16
| (1 << 7)));
1410 /* Disable auto power down by clearing
1411 * bit 5 of to Aux Status 2 reg.
1413 val16
= robo
->miird(robo
->h
, phy
, REG_MII_AUX_STATUS2
);
1414 robo
->miiwr(robo
->h
, phy
, REG_MII_AUX_STATUS2
,
1415 (val16
& ~(1 << 5)));
1417 /* Undo shadow access */
1418 val16
= robo
->miird(robo
->h
, phy
, REG_MII_BRCM_TEST
);
1419 robo
->miiwr(robo
->h
, phy
, REG_MII_BRCM_TEST
,
1420 (val16
& ~(1 << 7)));
1424 robo
->pwrsave_mode_phys
[phy
] &= ~ROBO_PWRSAVE_AUTO
;
1430 robo_power_save_mode_clear_manual(robo_info_t
*robo
, int32 phy
)
1435 if ((robo
->devid
== DEVID53115
) ||
1436 (robo
->sih
->chip
== BCM5356_CHIP_ID
)) {
1437 /* For 53115 0x0 is the MII control register
1438 * Bit 11 is the power down mode bit
1440 val16
= robo
->miird(robo
->h
, phy
, REG_MII_CTRL
);
1442 robo
->miiwr(robo
->h
, phy
, REG_MII_CTRL
, val16
);
1443 } else if (robo
->devid
== DEVID5325
) {
1444 if ((robo
->sih
->chip
== BCM5357_CHIP_ID
) ||
1445 (robo
->sih
->chip
== BCM4749_CHIP_ID
) ||
1446 (robo
->sih
->chip
== BCM53572_CHIP_ID
)) {
1447 robo
->miiwr(robo
->h
, phy
, 0x1f, 0x8b);
1448 robo
->miiwr(robo
->h
, phy
, 0x14, 0x0008);
1449 robo
->miiwr(robo
->h
, phy
, 0x10, 0x0400);
1450 robo
->miiwr(robo
->h
, phy
, 0x11, 0x0000);
1451 robo
->miiwr(robo
->h
, phy
, 0x1f, 0x0b);
1455 /* For 5325 page 0x00 address 0x0F is the power down
1456 * mode register. Bits 1-4 determines which of the
1457 * phys are enabled for this mode
1459 robo
->ops
->read_reg(robo
, PAGE_CTRL
, REG_CTRL_PWRDOWN
,
1460 &val8
, sizeof(val8
));
1461 val8
&= ~(0x1 << phy
);
1462 robo
->ops
->write_reg(robo
, PAGE_CTRL
, REG_CTRL_PWRDOWN
,
1463 &val8
, sizeof(val8
));
1468 robo
->pwrsave_mode_phys
[phy
] &= ~ROBO_PWRSAVE_MANUAL
;
1474 * Function which periodically checks the power save mode on the switch
1477 robo_power_save_toggle(robo_info_t
*robo
, int32 normal
)
1483 /* read the link status of all ports */
1484 robo
->ops
->read_reg(robo
, PAGE_STATUS
, REG_STATUS_LINK
,
1485 &link_status
, sizeof(uint16
));
1486 link_status
&= 0x1f;
1488 /* Take the phys out of the manual mode first so that link status
1489 * can be checked. Once out of that mode check the link status
1490 * and if any of the link is up do not put that phy into
1491 * manual power save mode
1493 for (phy
= 0; phy
< MAX_NO_PHYS
; phy
++) {
1494 /* When auto+manual modes are enabled we toggle between
1495 * manual and auto modes. When only manual mode is enabled
1496 * we toggle between manual and normal modes. When only
1497 * auto mode is enabled there is no need to do anything
1498 * here since auto mode is one time config.
1500 if ((robo
->pwrsave_phys
& (1 << phy
)) &&
1501 (robo
->pwrsave_mode_manual
& (1 << phy
))) {
1503 /* Take the port out of the manual mode */
1504 robo_power_save_mode_clear_manual(robo
, phy
);
1506 /* If the link is down put it back to manual else
1507 * remain in the current state
1509 if (!(link_status
& (1 << phy
))) {
1510 ET_MSG(("%s: link down, set port %d to man mode\n",
1511 __FUNCTION__
, phy
));
1512 robo_power_save_mode(robo
, ROBO_PWRSAVE_MANUAL
, phy
);
1522 * Switch the ports to normal mode.
1525 robo_power_save_mode_normal(robo_info_t
*robo
, int32 phy
)
1529 /* If the phy in the power save mode come out of it */
1530 switch (robo
->pwrsave_mode_phys
[phy
]) {
1531 case ROBO_PWRSAVE_AUTO_MANUAL
:
1532 case ROBO_PWRSAVE_AUTO
:
1533 error
= robo_power_save_mode_clear_auto(robo
, phy
);
1534 if ((error
== -1) ||
1535 (robo
->pwrsave_mode_phys
[phy
] == ROBO_PWRSAVE_AUTO
))
1538 case ROBO_PWRSAVE_MANUAL
:
1539 error
= robo_power_save_mode_clear_manual(robo
, phy
);
1550 * Switch all the inactive ports to auto power down mode.
1553 robo_power_save_mode_auto(robo_info_t
*robo
, int32 phy
)
1557 /* If the switch supports auto power down enable that */
1558 if (robo
->devid
== DEVID53115
) {
1559 /* For 53115 0x1C is the MII address of the auto power
1560 * down register. Bit 5 is enabling the mode
1561 * bits has the following purpose
1562 * 15 - write enable 10-14 shadow register select 01010 for
1563 * auto power 6-9 reserved 5 auto power mode enable
1564 * 4 sleep timer select : 1 means 5.4 sec
1565 * 0-3 wake up timer select: 0xF 1.26 sec
1567 robo
->miiwr(robo
->h
, phy
, REG_MII_AUTO_PWRDOWN
, 0xA83F);
1568 } else if ((robo
->sih
->chip
== BCM5356_CHIP_ID
) || (robo
->sih
->chip
== BCM5357_CHIP_ID
)) {
1569 /* To enable auto power down mode set bit 5 of
1570 * Auxillary Status 2 register (Shadow reg 0x1b)
1571 * Shadow register access is enabled by writing
1572 * 1 to bit 7 of MII register 0x1f.
1574 val16
= robo
->miird(robo
->h
, phy
, REG_MII_BRCM_TEST
);
1575 robo
->miiwr(robo
->h
, phy
, REG_MII_BRCM_TEST
,
1576 (val16
| (1 << 7)));
1578 /* Enable auto power down by writing to Auxillary
1581 val16
= robo
->miird(robo
->h
, phy
, REG_MII_AUX_STATUS2
);
1582 robo
->miiwr(robo
->h
, phy
, REG_MII_AUX_STATUS2
,
1583 (val16
| (1 << 5)));
1585 /* Undo shadow access */
1586 val16
= robo
->miird(robo
->h
, phy
, REG_MII_BRCM_TEST
);
1587 robo
->miiwr(robo
->h
, phy
, REG_MII_BRCM_TEST
,
1588 (val16
& ~(1 << 7)));
1592 robo
->pwrsave_mode_phys
[phy
] |= ROBO_PWRSAVE_AUTO
;
1598 * Switch all the inactive ports to manual power down mode.
1601 robo_power_save_mode_manual(robo_info_t
*robo
, int32 phy
)
1606 /* For both 5325 and 53115 the link status register is the same */
1607 robo
->ops
->read_reg(robo
, PAGE_STATUS
, REG_STATUS_LINK
,
1608 &val16
, sizeof(val16
));
1609 if (val16
& (0x1 << phy
))
1612 /* If the switch supports manual power down enable that */
1613 if ((robo
->devid
== DEVID53115
) ||
1614 (robo
->sih
->chip
== BCM5356_CHIP_ID
)) {
1615 /* For 53115 0x0 is the MII control register bit 11 is the
1616 * power down mode bit
1618 val16
= robo
->miird(robo
->h
, phy
, REG_MII_CTRL
);
1619 robo
->miiwr(robo
->h
, phy
, REG_MII_CTRL
, val16
| 0x800);
1620 } else if (robo
->devid
== DEVID5325
) {
1621 if ((robo
->sih
->chip
== BCM5357_CHIP_ID
) ||
1622 (robo
->sih
->chip
== BCM4749_CHIP_ID
)||
1623 (robo
->sih
->chip
== BCM53572_CHIP_ID
)) {
1624 robo
->miiwr(robo
->h
, phy
, 0x1f, 0x8b);
1625 robo
->miiwr(robo
->h
, phy
, 0x14, 0x6000);
1626 robo
->miiwr(robo
->h
, phy
, 0x10, 0x700);
1627 robo
->miiwr(robo
->h
, phy
, 0x11, 0x1000);
1628 robo
->miiwr(robo
->h
, phy
, 0x1f, 0x0b);
1632 /* For 5325 page 0x00 address 0x0F is the power down mode
1633 * register. Bits 1-4 determines which of the phys are enabled
1636 robo
->ops
->read_reg(robo
, PAGE_CTRL
, REG_CTRL_PWRDOWN
, &val8
,
1639 robo
->ops
->write_reg(robo
, PAGE_CTRL
, REG_CTRL_PWRDOWN
, &val8
,
1645 robo
->pwrsave_mode_phys
[phy
] |= ROBO_PWRSAVE_MANUAL
;
1651 * Set power save modes on the robo switch
1654 robo_power_save_mode(robo_info_t
*robo
, int32 mode
, int32 phy
)
1658 if (phy
> MAX_NO_PHYS
) {
1659 ET_ERROR(("Passed parameter phy is out of range\n"));
1663 /* Enable management interface access */
1664 if (robo
->ops
->enable_mgmtif
)
1665 robo
->ops
->enable_mgmtif(robo
);
1668 case ROBO_PWRSAVE_NORMAL
:
1669 /* If the phy in the power save mode come out of it */
1670 error
= robo_power_save_mode_normal(robo
, phy
);
1673 case ROBO_PWRSAVE_AUTO_MANUAL
:
1674 /* If the switch supports auto and manual power down
1675 * enable both of them
1677 case ROBO_PWRSAVE_AUTO
:
1678 error
= robo_power_save_mode_auto(robo
, phy
);
1679 if ((error
== -1) || (mode
== ROBO_PWRSAVE_AUTO
))
1682 case ROBO_PWRSAVE_MANUAL
:
1683 error
= robo_power_save_mode_manual(robo
, phy
);
1690 /* Disable management interface access */
1691 if (robo
->ops
->disable_mgmtif
)
1692 robo
->ops
->disable_mgmtif(robo
);
1698 * Get the current power save mode of the switch ports.
1701 robo_power_save_mode_get(robo_info_t
*robo
, int32 phy
)
1705 if (phy
>= MAX_NO_PHYS
)
1708 return robo
->pwrsave_mode_phys
[phy
];
1712 * Configure the power save mode for the switch ports.
1715 robo_power_save_mode_set(robo_info_t
*robo
, int32 mode
, int32 phy
)
1721 if (phy
>= MAX_NO_PHYS
)
1724 error
= robo_power_save_mode(robo
, mode
, phy
);
1729 if (mode
== ROBO_PWRSAVE_NORMAL
) {
1730 robo
->pwrsave_mode_manual
&= ~(1 << phy
);
1731 robo
->pwrsave_mode_auto
&= ~(1 << phy
);
1732 } else if (mode
== ROBO_PWRSAVE_AUTO
) {
1733 robo
->pwrsave_mode_auto
|= (1 << phy
);
1734 robo
->pwrsave_mode_manual
&= ~(1 << phy
);
1735 robo_power_save_mode_clear_manual(robo
, phy
);
1736 } else if (mode
== ROBO_PWRSAVE_MANUAL
) {
1737 robo
->pwrsave_mode_manual
|= (1 << phy
);
1738 robo
->pwrsave_mode_auto
&= ~(1 << phy
);
1739 robo_power_save_mode_clear_auto(robo
, phy
);
1741 robo
->pwrsave_mode_auto
|= (1 << phy
);
1742 robo
->pwrsave_mode_manual
|= (1 << phy
);
1749 /* BCM53125 EEE IOP WAR for some other vendor's wrong EEE implementation. */
1752 robo_link_down(robo_info_t
*robo
, int32 phy
)
1754 if (robo
->devid
!= DEVID53125
)
1757 printf("robo_link_down: applying EEE WAR for 53125 port %d link-down\n", phy
);
1759 robo
->miiwr(robo
->h
, phy
, 0x18, 0x0c00);
1760 robo
->miiwr(robo
->h
, phy
, 0x17, 0x001a);
1761 robo
->miiwr(robo
->h
, phy
, 0x15, 0x0007);
1762 robo
->miiwr(robo
->h
, phy
, 0x18, 0x0400);
1766 robo_link_up(robo_info_t
*robo
, int32 phy
)
1768 if (robo
->devid
!= DEVID53125
)
1771 printf("robo_link_down: applying EEE WAR for 53125 port %d link-up\n", phy
);
1773 robo
->miiwr(robo
->h
, phy
, 0x18, 0x0c00);
1774 robo
->miiwr(robo
->h
, phy
, 0x17, 0x001a);
1775 robo
->miiwr(robo
->h
, phy
, 0x15, 0x0003);
1776 robo
->miiwr(robo
->h
, phy
, 0x18, 0x0400);
1780 robo_watchdog(robo_info_t
*robo
)
1784 static int first
= 1;
1786 if (robo
->devid
!= DEVID53125
)
1789 if (!robo
->eee_status
)
1792 /* read the link status of all ports */
1793 robo
->ops
->read_reg(robo
, PAGE_STATUS
, REG_STATUS_LINK
,
1794 &link_status
, sizeof(uint16
));
1795 link_status
&= 0x1f;
1796 if (first
|| (link_status
!= robo
->prev_status
)) {
1797 for (phy
= 0; phy
< MAX_NO_PHYS
; phy
++) {
1799 if (!(link_status
& (1 << phy
)))
1800 robo_link_down(robo
, phy
);
1801 } else if ((link_status
& (1 << phy
)) != (robo
->prev_status
& (1 << phy
))) {
1802 if (!(link_status
& (1 << phy
)))
1803 robo_link_down(robo
, phy
);
1805 robo_link_up(robo
, phy
);
1808 robo
->prev_status
= link_status
;
1814 robo_eee_advertise_init(robo_info_t
*robo
)
1822 robo
->ops
->read_reg(robo
, 0x92, 0x00, &val16
, sizeof(val16
));
1823 if (val16
== 0x1f) {
1824 robo
->eee_status
= TRUE
;
1825 printf("bcm_robo_enable_switch: EEE is enabled\n");
1827 for (phy
= 0; phy
< MAX_NO_PHYS
; phy
++) {
1828 /* select DEVAD 7 */
1829 robo
->miiwr(robo
->h
, phy
, REG_MII_CLAUSE_45_CTL1
, 0x0007);
1830 /* select register 3Ch */
1831 robo
->miiwr(robo
->h
, phy
, REG_MII_CLAUSE_45_CTL2
, 0x003c);
1833 robo
->miiwr(robo
->h
, phy
, REG_MII_CLAUSE_45_CTL1
, 0xc007);
1835 val16
= robo
->miird(robo
->h
, phy
, REG_MII_CLAUSE_45_CTL2
);
1837 /* select DEVAD 7 */
1838 robo
->miiwr(robo
->h
, phy
, REG_MII_CLAUSE_45_CTL1
, 0x0007);
1839 /* select register 3Ch */
1840 robo
->miiwr(robo
->h
, phy
, REG_MII_CLAUSE_45_CTL2
, 0x003c);
1842 robo
->miiwr(robo
->h
, phy
, REG_MII_CLAUSE_45_CTL1
, 0x4007);
1844 robo
->miiwr(robo
->h
, phy
, REG_MII_CLAUSE_45_CTL2
, val16
);
1846 robo
->eee_status
= FALSE
;
1847 printf("bcm_robo_enable_switch: EEE is disabled\n");