2 * Broadcom 53xx RoboSwitch device driver.
4 * Copyright (C) 2009, 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.
12 * $Id: bcmrobo.c,v 1.16.2.8 2009/07/22 15:00:48 Exp $
22 #include <bcmendian.h>
23 #include <bcmparams.h>
27 #include <proto/ethernet.h>
30 #define ET_ERROR(args)
33 #define VARG(var, len) (((len) == 1) ? *((uint8 *)(var)) : \
34 ((len) == 2) ? *((uint16 *)(var)) : \
38 * Switch can be programmed through SPI interface, which
39 * has a rreg and a wreg functions to read from and write to
43 /* MII access registers */
44 #define PSEUDO_PHYAD 0x1E /* MII Pseudo PHY address */
45 #define REG_MII_CTRL 0x00 /* 53115 MII control register */
46 #define REG_MII_PAGE 0x10 /* MII Page register */
47 #define REG_MII_ADDR 0x11 /* MII Address register */
48 #define REG_MII_DATA0 0x18 /* MII Data register 0 */
49 #define REG_MII_DATA1 0x19 /* MII Data register 1 */
50 #define REG_MII_DATA2 0x1a /* MII Data register 2 */
51 #define REG_MII_DATA3 0x1b /* MII Data register 3 */
52 #define REG_MII_BRCM_TEST 0x1f /* Broadcom test register */
53 #define REG_MII_AUX_STATUS2 0x1b /* Auxiliary status 2 register */
54 #define REG_MII_AUTO_PWRDOWN 0x1C /* 53115 Auto power down register */
57 #define PAGE_CTRL 0x00 /* Control page */
58 #define PAGE_STATUS 0x01 /* Status page */
59 #define PAGE_MMR 0x02 /* 5397 Management/Mirroring page */
60 #define PAGE_VTBL 0x05 /* ARL/VLAN Table access page */
61 #define PAGE_VLAN 0x34 /* VLAN page */
62 #define PAGE_JUMBO 0x40 /* JUMBO frame page */
64 /* Control page registers */
65 #define REG_CTRL_PORT0 0x00 /* Port 0 traffic control register */
66 #define REG_CTRL_PORT1 0x01 /* Port 1 traffic control register */
67 #define REG_CTRL_PORT2 0x02 /* Port 2 traffic control register */
68 #define REG_CTRL_PORT3 0x03 /* Port 3 traffic control register */
69 #define REG_CTRL_PORT4 0x04 /* Port 4 traffic control register */
70 #define REG_CTRL_PORT5 0x05 /* Port 5 traffic control register */
71 #define REG_CTRL_PORT6 0x06 /* Port 6 traffic control register */
72 #define REG_CTRL_PORT7 0x07 /* Port 7 traffic control register */
73 #define REG_CTRL_IMP 0x08 /* IMP port traffic control register */
74 #define REG_CTRL_MODE 0x0B /* Switch Mode register */
75 #define REG_CTRL_MIIPO 0x0E /* 5325: MII Port Override register */
76 #define REG_CTRL_PWRDOWN 0x0F /* 5325: Power Down Mode register */
77 #define REG_CTRL_SRST 0x79 /* Software reset control register */
79 /* Status Page Registers */
80 #define REG_STATUS_LINK 0x00 /* Link Status Summary */
82 #define REG_DEVICE_ID 0x30 /* 539x Device id: */
84 /* JUMBO Control Register */
85 #define REG_JUMBO_CTRL 0x01
86 #define REG_JUMBO_SIZE 0x05
88 /* Status Page Registers */
89 #define REG_STATUS_LINK 0x00 /* Link Status Summary */
91 /* VLAN page registers */
92 #define REG_VLAN_CTRL0 0x00 /* VLAN Control 0 register */
93 #define REG_VLAN_CTRL1 0x01 /* VLAN Control 1 register */
94 #define REG_VLAN_CTRL4 0x04 /* VLAN Control 4 register */
95 #define REG_VLAN_CTRL5 0x05 /* VLAN Control 5 register */
96 #define REG_VLAN_ACCESS 0x06 /* VLAN Table Access register */
97 #define REG_VLAN_ACCESS_5365 0x08 /* 5365 VLAN Table Access register */
98 #define REG_VLAN_WRITE 0x08 /* VLAN Write register */
99 #define REG_VLAN_WRITE_5365 0x0A /* 5365 VLAN Write register */
100 #define REG_VLAN_READ 0x0C /* VLAN Read register */
101 #define REG_VLAN_PTAG0 0x10 /* VLAN Default Port Tag register - port 0 */
102 #define REG_VLAN_PTAG1 0x12 /* VLAN Default Port Tag register - port 1 */
103 #define REG_VLAN_PTAG2 0x14 /* VLAN Default Port Tag register - port 2 */
104 #define REG_VLAN_PTAG3 0x16 /* VLAN Default Port Tag register - port 3 */
105 #define REG_VLAN_PTAG4 0x18 /* VLAN Default Port Tag register - port 4 */
106 #define REG_VLAN_PTAG5 0x1a /* VLAN Default Port Tag register - port 5 */
107 #define REG_VLAN_PTAG6 0x1c /* VLAN Default Port Tag register - port 6 */
108 #define REG_VLAN_PTAG7 0x1e /* VLAN Default Port Tag register - port 7 */
109 #define REG_VLAN_PTAG8 0x20 /* 539x: VLAN Default Port Tag register - IMP port */
110 #define REG_VLAN_PMAP 0x20 /* 5325: VLAN Priority Re-map register */
112 #define VLAN_NUMVLANS 16 /* # of VLANs */
115 /* ARL/VLAN Table Access page registers */
116 #define REG_VTBL_CTRL 0x00 /* ARL Read/Write Control */
117 #define REG_VTBL_MINDX 0x02 /* MAC Address Index */
118 #define REG_VTBL_VINDX 0x08 /* VID Table Index */
119 #define REG_VTBL_ARL_E0 0x10 /* ARL Entry 0 */
120 #define REG_VTBL_ARL_E1 0x18 /* ARL Entry 1 */
121 #define REG_VTBL_DAT_E0 0x18 /* ARL Table Data Entry 0 */
122 #define REG_VTBL_SCTRL 0x20 /* ARL Search Control */
123 #define REG_VTBL_SADDR 0x22 /* ARL Search Address */
124 #define REG_VTBL_SRES 0x24 /* ARL Search Result */
125 #define REG_VTBL_SREXT 0x2c /* ARL Search Result */
126 #define REG_VTBL_VID_E0 0x30 /* VID Entry 0 */
127 #define REG_VTBL_VID_E1 0x32 /* VID Entry 1 */
128 #define REG_VTBL_PREG 0xFF /* Page Register */
129 #define REG_VTBL_ACCESS 0x60 /* VLAN table access register */
130 #define REG_VTBL_INDX 0x61 /* VLAN table address index register */
131 #define REG_VTBL_ENTRY 0x63 /* VLAN table entry register */
132 #define REG_VTBL_ACCESS_5395 0x80 /* VLAN table access register */
133 #define REG_VTBL_INDX_5395 0x81 /* VLAN table address index register */
134 #define REG_VTBL_ENTRY_5395 0x83 /* VLAN table entry register */
137 #define REG_SPI_PAGE 0xff /* SPI Page register */
139 /* Access switch registers through GPIO/SPI */
141 /* Minimum timing constants */
142 #define SCK_EDGE_TIME 2 /* clock edge duration - 2us */
143 #define MOSI_SETUP_TIME 1 /* input setup duration - 1us */
144 #define SS_SETUP_TIME 1 /* select setup duration - 1us */
146 /* misc. constants */
147 #define SPI_MAX_RETRY 100
149 /* Enable GPIO access to the chip */
151 gpio_enable(robo_info_t
*robo
)
153 /* Enable GPIO outputs with SCK and MOSI low, SS high */
154 si_gpioout(robo
->sih
, robo
->ss
| robo
->sck
| robo
->mosi
, robo
->ss
, GPIO_DRV_PRIORITY
);
155 si_gpioouten(robo
->sih
, robo
->ss
| robo
->sck
| robo
->mosi
,
156 robo
->ss
| robo
->sck
| robo
->mosi
, GPIO_DRV_PRIORITY
);
159 /* Disable GPIO access to the chip */
161 gpio_disable(robo_info_t
*robo
)
163 /* Disable GPIO outputs with all their current values */
164 si_gpioouten(robo
->sih
, robo
->ss
| robo
->sck
| robo
->mosi
, 0, GPIO_DRV_PRIORITY
);
167 /* Write a byte stream to the chip thru SPI */
169 spi_write(robo_info_t
*robo
, uint8
*buf
, uint len
)
174 /* Byte bang from LSB to MSB */
175 for (i
= 0; i
< len
; i
++) {
176 /* Bit bang from MSB to LSB */
177 for (mask
= 0x80; mask
; mask
>>= 1) {
179 si_gpioout(robo
->sih
, robo
->sck
, 0, GPIO_DRV_PRIORITY
);
180 OSL_DELAY(SCK_EDGE_TIME
);
182 /* Sample on rising edge */
184 si_gpioout(robo
->sih
, robo
->mosi
, robo
->mosi
, GPIO_DRV_PRIORITY
);
186 si_gpioout(robo
->sih
, robo
->mosi
, 0, GPIO_DRV_PRIORITY
);
187 OSL_DELAY(MOSI_SETUP_TIME
);
190 si_gpioout(robo
->sih
, robo
->sck
, robo
->sck
, GPIO_DRV_PRIORITY
);
191 OSL_DELAY(SCK_EDGE_TIME
);
198 /* Read a byte stream from the chip thru SPI */
200 spi_read(robo_info_t
*robo
, uint8
*buf
, uint len
)
203 uint8 rack
, mask
, byte
;
205 /* Timeout after 100 tries without RACK */
206 for (i
= 0, rack
= 0, timeout
= SPI_MAX_RETRY
; i
< len
&& timeout
;) {
207 /* Bit bang from MSB to LSB */
208 for (mask
= 0x80, byte
= 0; mask
; mask
>>= 1) {
210 si_gpioout(robo
->sih
, robo
->sck
, 0, GPIO_DRV_PRIORITY
);
211 OSL_DELAY(SCK_EDGE_TIME
);
213 /* Sample on falling edge */
214 if (si_gpioin(robo
->sih
) & robo
->miso
)
218 si_gpioout(robo
->sih
, robo
->sck
, robo
->sck
, GPIO_DRV_PRIORITY
);
219 OSL_DELAY(SCK_EDGE_TIME
);
221 /* RACK when bit 0 is high */
227 /* Byte bang from LSB to MSB */
233 ET_ERROR(("spi_read: timeout"));
240 /* Enable/disable SPI access */
242 spi_select(robo_info_t
*robo
, uint8 spi
)
245 /* Enable SPI access */
246 si_gpioout(robo
->sih
, robo
->ss
, 0, GPIO_DRV_PRIORITY
);
248 /* Disable SPI access */
249 si_gpioout(robo
->sih
, robo
->ss
, robo
->ss
, GPIO_DRV_PRIORITY
);
251 OSL_DELAY(SS_SETUP_TIME
);
255 /* Select chip and page */
257 spi_goto(robo_info_t
*robo
, uint8 page
)
259 uint8 reg8
= REG_SPI_PAGE
; /* page select register */
262 /* Issue the command only when we are on a different page */
263 if (robo
->page
== page
)
268 /* Enable SPI access */
271 /* Select new page with CID 0 */
272 cmd8
= ((6 << 4) | /* normal SPI */
274 spi_write(robo
, &cmd8
, 1);
275 spi_write(robo
, ®8
, 1);
276 spi_write(robo
, &page
, 1);
278 /* Disable SPI access */
282 /* Write register thru SPI */
284 spi_wreg(robo_info_t
*robo
, uint8 page
, uint8 addr
, void *val
, int len
)
294 /* validate value length and buffer address */
295 ASSERT(len
== 1 || (len
== 2 && !((int)val
& 1)) ||
296 (len
== 4 && !((int)val
& 3)));
298 /* Select chip and page */
299 spi_goto(robo
, page
);
301 /* Enable SPI access */
304 /* Write with CID 0 */
305 cmd8
= ((6 << 4) | /* normal SPI */
307 spi_write(robo
, &cmd8
, 1);
308 spi_write(robo
, &addr
, 1);
311 bytes
.val8
= *(uint8
*)val
;
314 bytes
.val16
= htol16(*(uint16
*)val
);
317 bytes
.val32
= htol32(*(uint32
*)val
);
320 spi_write(robo
, (uint8
*)val
, len
);
322 ET_MSG(("%s: [0x%x-0x%x] := 0x%x (len %d)\n", __FUNCTION__
, page
, addr
,
323 *(uint16
*)val
, len
));
324 /* Disable SPI access */
329 /* Read register thru SPI in fast SPI mode */
331 spi_rreg(robo_info_t
*robo
, uint8 page
, uint8 addr
, void *val
, int len
)
341 /* validate value length and buffer address */
342 ASSERT(len
== 1 || (len
== 2 && !((int)val
& 1)) ||
343 (len
== 4 && !((int)val
& 3)));
345 /* Select chip and page */
346 spi_goto(robo
, page
);
348 /* Enable SPI access */
351 /* Fast SPI read with CID 0 and byte offset 0 */
352 cmd8
= (1 << 4); /* fast SPI */
353 spi_write(robo
, &cmd8
, 1);
354 spi_write(robo
, &addr
, 1);
355 status
= spi_read(robo
, (uint8
*)&bytes
, len
);
358 *(uint8
*)val
= bytes
.val8
;
361 *(uint16
*)val
= ltoh16(bytes
.val16
);
364 *(uint32
*)val
= ltoh32(bytes
.val32
);
368 ET_MSG(("%s: [0x%x-0x%x] => 0x%x (len %d)\n", __FUNCTION__
, page
, addr
,
369 *(uint16
*)val
, len
));
371 /* Disable SPI access */
376 /* SPI/gpio interface functions */
377 static dev_ops_t spigpio
= {
386 /* Access switch registers through MII (MDC/MDIO) */
388 #define MII_MAX_RETRY 100
390 /* Write register thru MDC/MDIO */
392 mii_wreg(robo_info_t
*robo
, uint8 page
, uint8 reg
, void *val
, int len
)
397 uint8
*ptr
= (uint8
*)val
;
399 /* validate value length and buffer address */
400 ASSERT(len
== 1 || len
== 6 || len
== 8 ||
401 ((len
== 2) && !((int)val
& 1)) || ((len
== 4) && !((int)val
& 3)));
403 ET_MSG(("%s: [0x%x-0x%x] := 0x%x (len %d)\n", __FUNCTION__
, page
, reg
,
404 VARG(val
, len
), len
));
406 /* set page number - MII register 0x10 */
407 if (robo
->page
!= page
) {
408 cmd16
= ((page
<< 8) | /* page number */
409 1); /* mdc/mdio access enable */
410 robo
->miiwr(h
, PSEUDO_PHYAD
, REG_MII_PAGE
, cmd16
);
417 val16
= ((val16
<< 8) | ptr
[6]);
418 robo
->miiwr(h
, PSEUDO_PHYAD
, REG_MII_DATA3
, val16
);
423 val16
= ((val16
<< 8) | ptr
[4]);
424 robo
->miiwr(h
, PSEUDO_PHYAD
, REG_MII_DATA2
, val16
);
426 val16
= ((val16
<< 8) | ptr
[2]);
427 robo
->miiwr(h
, PSEUDO_PHYAD
, REG_MII_DATA1
, val16
);
429 val16
= ((val16
<< 8) | ptr
[0]);
430 robo
->miiwr(h
, PSEUDO_PHYAD
, REG_MII_DATA0
, val16
);
434 val16
= (uint16
)((*(uint32
*)val
) >> 16);
435 robo
->miiwr(h
, PSEUDO_PHYAD
, REG_MII_DATA1
, val16
);
436 val16
= (uint16
)(*(uint32
*)val
);
437 robo
->miiwr(h
, PSEUDO_PHYAD
, REG_MII_DATA0
, val16
);
441 val16
= *(uint16
*)val
;
442 robo
->miiwr(h
, PSEUDO_PHYAD
, REG_MII_DATA0
, val16
);
446 val16
= *(uint8
*)val
;
447 robo
->miiwr(h
, PSEUDO_PHYAD
, REG_MII_DATA0
, val16
);
451 /* set register address - MII register 0x11 */
452 cmd16
= ((reg
<< 8) | /* register address */
453 1); /* opcode write */
454 robo
->miiwr(h
, PSEUDO_PHYAD
, REG_MII_ADDR
, cmd16
);
456 /* is operation finished? */
457 for (i
= MII_MAX_RETRY
; i
> 0; i
--) {
458 val16
= robo
->miird(h
, PSEUDO_PHYAD
, REG_MII_ADDR
);
459 if ((val16
& 3) == 0)
465 ET_ERROR(("mii_wreg: timeout"));
471 /* Read register thru MDC/MDIO */
473 mii_rreg(robo_info_t
*robo
, uint8 page
, uint8 reg
, void *val
, int len
)
478 uint8
*ptr
= (uint8
*)val
;
480 /* validate value length and buffer address */
481 ASSERT(len
== 1 || len
== 6 || len
== 8 ||
482 ((len
== 2) && !((int)val
& 1)) || ((len
== 4) && !((int)val
& 3)));
484 /* set page number - MII register 0x10 */
485 if (robo
->page
!= page
) {
486 cmd16
= ((page
<< 8) | /* page number */
487 1); /* mdc/mdio access enable */
488 robo
->miiwr(h
, PSEUDO_PHYAD
, REG_MII_PAGE
, cmd16
);
492 /* set register address - MII register 0x11 */
493 cmd16
= ((reg
<< 8) | /* register address */
494 2); /* opcode read */
495 robo
->miiwr(h
, PSEUDO_PHYAD
, REG_MII_ADDR
, cmd16
);
497 /* is operation finished? */
498 for (i
= MII_MAX_RETRY
; i
> 0; i
--) {
499 val16
= robo
->miird(h
, PSEUDO_PHYAD
, REG_MII_ADDR
);
500 if ((val16
& 3) == 0)
505 ET_ERROR(("mii_rreg: timeout"));
511 val16
= robo
->miird(h
, PSEUDO_PHYAD
, REG_MII_DATA3
);
512 ptr
[7] = (val16
>> 8);
513 ptr
[6] = (val16
& 0xff);
517 val16
= robo
->miird(h
, PSEUDO_PHYAD
, REG_MII_DATA2
);
518 ptr
[5] = (val16
>> 8);
519 ptr
[4] = (val16
& 0xff);
520 val16
= robo
->miird(h
, PSEUDO_PHYAD
, REG_MII_DATA1
);
521 ptr
[3] = (val16
>> 8);
522 ptr
[2] = (val16
& 0xff);
523 val16
= robo
->miird(h
, PSEUDO_PHYAD
, REG_MII_DATA0
);
524 ptr
[1] = (val16
>> 8);
525 ptr
[0] = (val16
& 0xff);
529 val16
= robo
->miird(h
, PSEUDO_PHYAD
, REG_MII_DATA1
);
530 *(uint32
*)val
= (((uint32
)val16
) << 16);
531 val16
= robo
->miird(h
, PSEUDO_PHYAD
, REG_MII_DATA0
);
532 *(uint32
*)val
|= val16
;
536 val16
= robo
->miird(h
, PSEUDO_PHYAD
, REG_MII_DATA0
);
537 *(uint16
*)val
= val16
;
541 val16
= robo
->miird(h
, PSEUDO_PHYAD
, REG_MII_DATA0
);
542 *(uint8
*)val
= (uint8
)(val16
& 0xff);
546 ET_MSG(("%s: [0x%x-0x%x] => 0x%x (len %d)\n", __FUNCTION__
, page
, reg
,
547 VARG(val
, len
), len
));
552 /* MII interface functions */
553 static dev_ops_t mdcmdio
= {
561 /* High level switch configuration functions. */
563 /* Get access to the RoboSwitch */
565 bcm_robo_attach(si_t
*sih
, void *h
, char *vars
, miird_f miird
, miiwr_f miiwr
)
569 char *et1port
, *et1phyaddr
;
570 int mdcport
= 0, phyaddr
= 0;
572 /* Allocate and init private state */
573 if (!(robo
= MALLOC(si_osh(sih
), sizeof(robo_info_t
)))) {
574 ET_ERROR(("robo_attach: out of memory, malloced %d bytes",
575 MALLOCED(si_osh(sih
))));
578 bzero(robo
, sizeof(robo_info_t
));
587 /* Trigger external reset by nvram variable existance */
588 if ((reset
= getgpiopin(robo
->vars
, "robo_reset", GPIO_PIN_NOTDEFINED
)) !=
589 GPIO_PIN_NOTDEFINED
) {
591 * Reset sequence: RESET low(50ms)->high(20ms)
593 * We have to perform a full sequence for we don't know how long
594 * it has been from power on till now.
596 ET_MSG(("%s: Using external reset in gpio pin %d\n", __FUNCTION__
, reset
));
599 /* Keep RESET low for 50 ms */
600 si_gpioout(sih
, reset
, 0, GPIO_DRV_PRIORITY
);
601 si_gpioouten(sih
, reset
, reset
, GPIO_DRV_PRIORITY
);
604 /* Keep RESET high for at least 20 ms */
605 si_gpioout(sih
, reset
, reset
, GPIO_DRV_PRIORITY
);
608 /* In case we need it */
609 idx
= si_coreidx(sih
);
611 if (si_setcore(sih
, ROBO_CORE_ID
, 0)) {
612 /* If we have an internal robo core, reset it using si_core_reset */
613 ET_MSG(("%s: Resetting internal robo core\n", __FUNCTION__
));
614 si_core_reset(sih
, 0, 0);
616 si_setcoreidx(sih
, idx
);
619 if (miird
&& miiwr
) {
621 int rc
, retry_count
= 0;
623 /* Read the PHY ID */
624 tmp
= miird(h
, PSEUDO_PHYAD
, 2);
626 /* WAR: Enable mdc/mdio access to the switch registers. Unless
627 * a write to bit 0 of pseudo phy register 16 is done we are
628 * unable to talk to the switch on a customer ref design.
631 miiwr(h
, PSEUDO_PHYAD
, 16, 1);
632 tmp
= miird(h
, PSEUDO_PHYAD
, 2);
637 rc
= mii_rreg(robo
, PAGE_MMR
, REG_DEVICE_ID
,
638 &robo
->devid
, sizeof(uint16
));
642 } while ((robo
->devid
== 0) && (retry_count
< 10));
644 ET_MSG(("%s: devid read %ssuccesfully via mii: 0x%x\n",
645 __FUNCTION__
, rc
? "un" : "", robo
->devid
));
646 ET_MSG(("%s: mii access to switch works\n", __FUNCTION__
));
647 robo
->ops
= &mdcmdio
;
648 if ((rc
!= 0) || (robo
->devid
== 0)) {
649 ET_MSG(("%s: error reading devid, assuming 5325e\n",
651 robo
->devid
= DEVID5325
;
654 ET_MSG(("%s: devid: 0x%x\n", __FUNCTION__
, robo
->devid
));
657 if ((robo
->devid
== DEVID5395
) ||
658 (robo
->devid
== DEVID5397
) ||
659 (robo
->devid
== DEVID5398
)) {
662 /* If it is a 539x switch, use the soft reset register */
663 ET_MSG(("%s: Resetting 539x robo switch\n", __FUNCTION__
));
665 /* Reset the 539x switch core and register file */
667 mii_wreg(robo
, PAGE_CTRL
, REG_CTRL_SRST
, &srst_ctrl
, sizeof(uint8
));
669 mii_wreg(robo
, PAGE_CTRL
, REG_CTRL_SRST
, &srst_ctrl
, sizeof(uint8
));
673 int mosi
, miso
, ss
, sck
;
675 robo
->ops
= &spigpio
;
676 robo
->devid
= DEVID5325
;
678 /* Init GPIO mapping. Default 2, 3, 4, 5 */
679 ss
= getgpiopin(vars
, "robo_ss", 2);
680 if (ss
== GPIO_PIN_NOTDEFINED
) {
681 ET_ERROR(("robo_attach: robo_ss gpio fail: GPIO 2 in use"));
685 sck
= getgpiopin(vars
, "robo_sck", 3);
686 if (sck
== GPIO_PIN_NOTDEFINED
) {
687 ET_ERROR(("robo_attach: robo_sck gpio fail: GPIO 3 in use"));
690 robo
->sck
= 1 << sck
;
691 mosi
= getgpiopin(vars
, "robo_mosi", 4);
692 if (mosi
== GPIO_PIN_NOTDEFINED
) {
693 ET_ERROR(("robo_attach: robo_mosi gpio fail: GPIO 4 in use"));
696 robo
->mosi
= 1 << mosi
;
697 miso
= getgpiopin(vars
, "robo_miso", 5);
698 if (miso
== GPIO_PIN_NOTDEFINED
) {
699 ET_ERROR(("robo_attach: robo_miso gpio fail: GPIO 5 in use"));
702 robo
->miso
= 1 << miso
;
703 ET_MSG(("%s: ss %d sck %d mosi %d miso %d\n", __FUNCTION__
,
704 ss
, sck
, mosi
, miso
));
709 ASSERT(robo
->ops
->write_reg
);
710 ASSERT(robo
->ops
->read_reg
);
711 ASSERT((robo
->devid
== DEVID5325
) ||
712 (robo
->devid
== DEVID5395
) ||
713 (robo
->devid
== DEVID5397
) ||
714 (robo
->devid
== DEVID5398
) ||
715 (robo
->devid
== DEVID53115
));
717 /* nvram variable switch_mode controls the power save mode on the switch
718 * set the default value in the beginning
720 robo
->pwrsave_mode_manual
= getintvar(robo
->vars
, "switch_mode");
721 robo
->pwrsave_mode_auto
= getintvar(robo
->vars
, "switch_mode_auto");
723 /* Determining what all phys need to be included in
724 * power save operation
726 et1port
= getvar(vars
, "et1mdcport");
728 mdcport
= bcm_atoi(et1port
);
730 et1phyaddr
= getvar(vars
, "et1phyaddr");
732 phyaddr
= bcm_atoi(et1phyaddr
);
734 if ((mdcport
== 0) && (phyaddr
== 4))
735 /* For 5325F switch we need to do only phys 0-3 */
736 robo
->pwrsave_phys
= 0xf;
738 /* By default all 5 phys are put into power save if there is no link */
739 robo
->pwrsave_phys
= 0x1f;
744 bcm_robo_detach(robo
);
748 /* Release access to the RoboSwitch */
750 bcm_robo_detach(robo_info_t
*robo
)
752 MFREE(si_osh(robo
->sih
), robo
, sizeof(robo_info_t
));
755 /* Enable the device and set it to a known good state */
757 bcm_robo_enable_device(robo_info_t
*robo
)
759 uint8 reg_offset
, reg_val
;
762 /* Enable management interface access */
763 if (robo
->ops
->enable_mgmtif
)
764 robo
->ops
->enable_mgmtif(robo
);
766 if (robo
->devid
== DEVID5398
) {
767 /* Disable unused ports: port 6 and 7 */
768 for (reg_offset
= REG_CTRL_PORT6
; reg_offset
<= REG_CTRL_PORT7
; reg_offset
++) {
769 /* Set bits [1:0] to disable RX and TX */
771 robo
->ops
->write_reg(robo
, PAGE_CTRL
, reg_offset
, ®_val
,
776 if (robo
->devid
== DEVID5325
) {
777 /* Must put the switch into Reverse MII mode! */
779 /* MII port state override (page 0 register 14) */
780 robo
->ops
->read_reg(robo
, PAGE_CTRL
, REG_CTRL_MIIPO
, ®_val
, sizeof(reg_val
));
782 /* Bit 4 enables reverse MII mode */
783 if (!(reg_val
& (1 << 4))) {
786 robo
->ops
->write_reg(robo
, PAGE_CTRL
, REG_CTRL_MIIPO
, ®_val
,
790 robo
->ops
->read_reg(robo
, PAGE_CTRL
, REG_CTRL_MIIPO
, ®_val
,
792 if (!(reg_val
& (1 << 4))) {
793 ET_ERROR(("robo_enable_device: enabling RvMII mode failed\n"));
799 /* Disable management interface access */
800 if (robo
->ops
->disable_mgmtif
)
801 robo
->ops
->disable_mgmtif(robo
);
807 #define FLAG_TAGGED 't' /* output tagged (external ports only) */
808 #define FLAG_UNTAG 'u' /* input & output untagged (CPU port only, for OS (linux, ...) */
809 #define FLAG_LAN '*' /* input & output untagged (CPU port only, for CFE */
811 /* port descriptor */
813 uint32 untag
; /* untag enable bit (Page 0x05 Address 0x63-0x66 Bit[17:9]) */
814 uint32 member
; /* vlan member bit (Page 0x05 Address 0x63-0x66 Bit[7:0]) */
815 uint8 ptagr
; /* port tag register address (Page 0x34 Address 0x10-0x1F) */
816 uint8 cpu
; /* is this cpu port? */
819 pdesc_t pdesc97
[] = {
820 /* 5395/5397/5398/53115S is 0 ~ 7. port 8 is IMP port. */
821 /* port 0 */ {1 << 9, 1 << 0, REG_VLAN_PTAG0
, 0},
822 /* port 1 */ {1 << 10, 1 << 1, REG_VLAN_PTAG1
, 0},
823 /* port 2 */ {1 << 11, 1 << 2, REG_VLAN_PTAG2
, 0},
824 /* port 3 */ {1 << 12, 1 << 3, REG_VLAN_PTAG3
, 0},
825 /* port 4 */ {1 << 13, 1 << 4, REG_VLAN_PTAG4
, 0},
826 /* port 5 */ {1 << 14, 1 << 5, REG_VLAN_PTAG5
, 0},
827 /* port 6 */ {1 << 15, 1 << 6, REG_VLAN_PTAG6
, 0},
828 /* port 7 */ {1 << 16, 1 << 7, REG_VLAN_PTAG7
, 0},
829 /* mii port */ {1 << 17, 1 << 8, REG_VLAN_PTAG8
, 1},
832 pdesc_t pdesc25
[] = {
833 /* port 0 */ {1 << 6, 1 << 0, REG_VLAN_PTAG0
, 0},
834 /* port 1 */ {1 << 7, 1 << 1, REG_VLAN_PTAG1
, 0},
835 /* port 2 */ {1 << 8, 1 << 2, REG_VLAN_PTAG2
, 0},
836 /* port 3 */ {1 << 9, 1 << 3, REG_VLAN_PTAG3
, 0},
837 /* port 4 */ {1 << 10, 1 << 4, REG_VLAN_PTAG4
, 0},
838 /* mii port */ {1 << 11, 1 << 5, REG_VLAN_PTAG5
, 1},
841 /* Configure the VLANs */
843 bcm_robo_config_vlan(robo_info_t
*robo
, uint8
*mac_addr
)
851 uint8 arl_entry
[8] = { 0 }, arl_entry1
[8] = { 0 };
853 /* Enable management interface access */
854 if (robo
->ops
->enable_mgmtif
)
855 robo
->ops
->enable_mgmtif(robo
);
857 /* setup global vlan configuration */
858 /* VLAN Control 0 Register (Page 0x34, Address 0) */
859 robo
->ops
->read_reg(robo
, PAGE_VLAN
, REG_VLAN_CTRL0
, &val8
, sizeof(val8
));
860 val8
|= ((1 << 7) | /* enable 802.1Q VLAN */
861 (3 << 5)); /* individual VLAN learning mode */
862 if (robo
->devid
== DEVID5325
)
863 val8
&= ~(1 << 1); /* must clear reserved bit 1 */
864 robo
->ops
->write_reg(robo
, PAGE_VLAN
, REG_VLAN_CTRL0
, &val8
, sizeof(val8
));
866 /* VLAN Control 1 Register (Page 0x34, Address 1) */
867 robo
->ops
->read_reg(robo
, PAGE_VLAN
, REG_VLAN_CTRL1
, &val8
, sizeof(val8
));
868 val8
|= ((1 << 2) | /* enable RSV multicast V Fwdmap */
869 (1 << 3)); /* enable RSV multicast V Untagmap */
870 if (robo
->devid
== DEVID5325
)
871 val8
|= (1 << 1); /* enable RSV multicast V Tagging */
872 robo
->ops
->write_reg(robo
, PAGE_VLAN
, REG_VLAN_CTRL1
, &val8
, sizeof(val8
));
874 /* Jumbo Frame control refister (Page 0x40, Address 0x01 */
876 if (nvram_match("jumbo_frame_enable", "1")) {
883 /* Write the size of Packet */
885 // val8 = bcm_atoe(nvram_get("jumbo_frame_size"));
886 // robo->ops->write_reg(robo, PAGE_JUMBO, REG_JUMBO_SIZE, &val8, sizeof(val8));
891 robo
->ops
->write_reg(robo
, PAGE_JUMBO
, REG_JUMBO_CTRL
, &val8
, sizeof(val8
));
893 arl_entry
[0] = mac_addr
[5];
894 arl_entry
[1] = mac_addr
[4];
895 arl_entry
[2] = mac_addr
[3];
896 arl_entry
[3] = mac_addr
[2];
897 arl_entry
[4] = mac_addr
[1];
898 arl_entry
[5] = mac_addr
[0];
900 if (robo
->devid
== DEVID5325
) {
901 /* Init the entry 1 of the bin */
902 robo
->ops
->write_reg(robo
, PAGE_VTBL
, REG_VTBL_ARL_E1
,
903 arl_entry1
, sizeof(arl_entry1
));
904 robo
->ops
->write_reg(robo
, PAGE_VTBL
, REG_VTBL_VID_E1
,
907 /* Init the entry 0 of the bin */
908 arl_entry
[6] = 0x8; /* Port Id: MII */
909 arl_entry
[7] = 0xc0; /* Static Entry, Valid */
911 robo
->ops
->write_reg(robo
, PAGE_VTBL
, REG_VTBL_ARL_E0
,
912 arl_entry
, sizeof(arl_entry
));
913 robo
->ops
->write_reg(robo
, PAGE_VTBL
, REG_VTBL_MINDX
,
914 arl_entry
, ETHER_ADDR_LEN
);
916 /* VLAN Control 4 Register (Page 0x34, Address 4) */
917 val8
= (1 << 6); /* drop frame with VID violation */
918 robo
->ops
->write_reg(robo
, PAGE_VLAN
, REG_VLAN_CTRL4
, &val8
, sizeof(val8
));
920 /* VLAN Control 5 Register (Page 0x34, Address 5) */
921 val8
= (1 << 3); /* drop frame when miss V table */
922 robo
->ops
->write_reg(robo
, PAGE_VLAN
, REG_VLAN_CTRL5
, &val8
, sizeof(val8
));
925 pdescsz
= sizeof(pdesc25
) / sizeof(pdesc_t
);
927 /* Initialize the MAC Addr Index Register */
928 robo
->ops
->write_reg(robo
, PAGE_VTBL
, REG_VTBL_MINDX
,
929 arl_entry
, ETHER_ADDR_LEN
);
932 pdescsz
= sizeof(pdesc97
) / sizeof(pdesc_t
);
935 vid0
= getintvar(robo
->vars
, "vlan0tag");
937 /* setup each vlan. max. 16 vlans. */
938 /* force vlan id to be equal to vlan number */
939 for (vid
= 0; vid
< VLAN_NUMVLANS
; vid
++) {
940 char vlanports
[] = "vlanXXXXports";
941 char port
[] = "XXXX", *ports
, *next
, *cur
;
946 /* no members if VLAN id is out of limitation */
947 if (vid
> VLAN_MAXVID
)
950 /* get vlan member ports from nvram */
951 sprintf(vlanports
, "vlan%dports", vid
);
952 ports
= getvar(robo
->vars
, vlanports
);
954 /* In 539x vid == 0 us invalid?? */
955 if ((robo
->devid
!= DEVID5325
) && (vid
== 0)) {
957 ET_ERROR(("VID 0 is set in nvram, Ignoring\n"));
961 /* disable this vlan if not defined */
966 * setup each port in the vlan. cpu port needs special handing
967 * (with or without output tagging) to support linux/pmon/cfe.
969 for (cur
= ports
; cur
; cur
= next
) {
970 /* tokenize the port list */
973 next
= bcmstrstr(cur
, " ");
974 len
= next
? next
- cur
: strlen(cur
);
977 if (len
> sizeof(port
) - 1)
978 len
= sizeof(port
) - 1;
979 strncpy(port
, cur
, len
);
982 /* make sure port # is within the range */
983 pid
= bcm_atoi(port
);
984 if (pid
>= pdescsz
) {
985 ET_ERROR(("robo_config_vlan: port %d in vlan%dports is out "
986 "of range[0-%d]\n", pid
, vid
, pdescsz
));
990 /* build VLAN registers values */
992 if ((!pdesc
[pid
].cpu
&& !strchr(port
, FLAG_TAGGED
)) ||
993 (pdesc
[pid
].cpu
&& strchr(port
, FLAG_UNTAG
)))
995 untag
|= pdesc
[pid
].untag
;
997 member
|= pdesc
[pid
].member
;
999 /* set port tag - applies to untagged ingress frames */
1000 /* Default Port Tag Register (Page 0x34, Address 0x10-0x1D) */
1004 #define FL FLAG_UNTAG
1006 if ((!pdesc
[pid
].cpu
&& !strchr(port
, FLAG_TAGGED
)) ||
1008 val16
= ((0 << 13) | /* priority - always 0 */
1009 vid0
| vid
); /* vlan id */
1010 robo
->ops
->write_reg(robo
, PAGE_VLAN
, pdesc
[pid
].ptagr
,
1011 &val16
, sizeof(val16
));
1015 /* Add static ARL entries */
1016 if (robo
->devid
== DEVID5325
) {
1018 robo
->ops
->write_reg(robo
, PAGE_VTBL
, REG_VTBL_VID_E0
,
1019 &val8
, sizeof(val8
));
1020 robo
->ops
->write_reg(robo
, PAGE_VTBL
, REG_VTBL_VINDX
,
1021 &val8
, sizeof(val8
));
1023 /* Write the entry */
1025 robo
->ops
->write_reg(robo
, PAGE_VTBL
, REG_VTBL_CTRL
,
1026 &val8
, sizeof(val8
));
1027 /* Wait for write to complete */
1028 SPINWAIT((robo
->ops
->read_reg(robo
, PAGE_VTBL
, REG_VTBL_CTRL
,
1029 &val8
, sizeof(val8
)), ((val8
& 0x80) != 0)),
1032 /* Set the VLAN Id in VLAN ID Index Register */
1034 robo
->ops
->write_reg(robo
, PAGE_VTBL
, REG_VTBL_VINDX
,
1035 &val8
, sizeof(val8
));
1037 /* Set the MAC addr and VLAN Id in ARL Table MAC/VID Entry 0
1042 robo
->ops
->write_reg(robo
, PAGE_VTBL
, REG_VTBL_ARL_E0
,
1043 arl_entry
, sizeof(arl_entry
));
1045 /* Set the Static bit , Valid bit and Port ID fields in
1046 * ARL Table Data Entry 0 Register
1049 robo
->ops
->write_reg(robo
, PAGE_VTBL
, REG_VTBL_DAT_E0
,
1050 &val16
, sizeof(val16
));
1052 /* Clear the ARL_R/W bit and set the START/DONE bit in
1053 * the ARL Read/Write Control Register.
1056 robo
->ops
->write_reg(robo
, PAGE_VTBL
, REG_VTBL_CTRL
,
1057 &val8
, sizeof(val8
));
1058 /* Wait for write to complete */
1059 SPINWAIT((robo
->ops
->read_reg(robo
, PAGE_VTBL
, REG_VTBL_CTRL
,
1060 &val8
, sizeof(val8
)), ((val8
& 0x80) != 0)),
1065 /* setup VLAN ID and VLAN memberships */
1067 val32
= (untag
| /* untag enable */
1068 member
); /* vlan members */
1069 if (robo
->sih
->chip
== BCM5365_CHIP_ID
) {
1070 /* VLAN Write Register (Page 0x34, Address 0x0A) */
1071 val32
= ((1 << 14) | /* valid write */
1072 (untag
<< 1) | /* untag enable */
1073 member
); /* vlan members */
1074 robo
->ops
->write_reg(robo
, PAGE_VLAN
, REG_VLAN_WRITE_5365
, &val32
,
1076 /* VLAN Table Access Register (Page 0x34, Address 0x08) */
1077 val16
= ((1 << 13) | /* start command */
1078 (1 << 12) | /* write state */
1079 vid0
| vid
); /* vlan id */
1080 robo
->ops
->write_reg(robo
, PAGE_VLAN
, REG_VLAN_ACCESS_5365
, &val16
,
1082 } else if (robo
->devid
== DEVID5325
) {
1083 val32
|= ((1 << 20) | /* valid write */
1084 ((vid0
>> 4) << 12)); /* vlan id bit[11:4] */
1086 /* VLAN Write Register (Page 0x34, Address 0x08-0x0B) */
1087 robo
->ops
->write_reg(robo
, PAGE_VLAN
, REG_VLAN_WRITE
, &val32
,
1089 /* VLAN Table Access Register (Page 0x34, Address 0x06-0x07) */
1090 val16
= ((1 << 13) | /* start command */
1091 (1 << 12) | /* write state */
1092 vid0
| vid
); /* vlan id */
1093 robo
->ops
->write_reg(robo
, PAGE_VLAN
, REG_VLAN_ACCESS
, &val16
,
1096 uint8 vtble
, vtbli
, vtbla
;
1098 if ((robo
->devid
== DEVID5395
) || (robo
->devid
== DEVID53115
)) {
1099 vtble
= REG_VTBL_ENTRY_5395
;
1100 vtbli
= REG_VTBL_INDX_5395
;
1101 vtbla
= REG_VTBL_ACCESS_5395
;
1103 vtble
= REG_VTBL_ENTRY
;
1104 vtbli
= REG_VTBL_INDX
;
1105 vtbla
= REG_VTBL_ACCESS
;
1108 /* VLAN Table Entry Register (Page 0x05, Address 0x63-0x66/0x83-0x86) */
1109 robo
->ops
->write_reg(robo
, PAGE_VTBL
, vtble
, &val32
,
1111 /* VLAN Table Address Index Reg (Page 0x05, Address 0x61-0x62/0x81-0x82) */
1112 val16
= vid
; /* vlan id */
1113 robo
->ops
->write_reg(robo
, PAGE_VTBL
, vtbli
, &val16
,
1116 /* VLAN Table Access Register (Page 0x34, Address 0x60/0x80) */
1117 val8
= ((1 << 7) | /* start command */
1119 robo
->ops
->write_reg(robo
, PAGE_VTBL
, vtbla
, &val8
,
1124 if (robo
->devid
== DEVID5325
) {
1125 /* setup priority mapping - applies to tagged ingress frames */
1126 /* Priority Re-map Register (Page 0x34, Address 0x20-0x23) */
1127 val32
= ((0 << 0) | /* 0 -> 0 */
1128 (1 << 3) | /* 1 -> 1 */
1129 (2 << 6) | /* 2 -> 2 */
1130 (3 << 9) | /* 3 -> 3 */
1131 (4 << 12) | /* 4 -> 4 */
1132 (5 << 15) | /* 5 -> 5 */
1133 (6 << 18) | /* 6 -> 6 */
1134 (7 << 21)); /* 7 -> 7 */
1135 robo
->ops
->write_reg(robo
, PAGE_VLAN
, REG_VLAN_PMAP
, &val32
, sizeof(val32
));
1138 /* Disable management interface access */
1139 if (robo
->ops
->disable_mgmtif
)
1140 robo
->ops
->disable_mgmtif(robo
);
1145 /* Enable switching/forwarding */
1147 bcm_robo_enable_switch(robo_info_t
*robo
)
1149 int i
, max_port_ind
, ret
= 0;
1152 /* Enable management interface access */
1153 if (robo
->ops
->enable_mgmtif
)
1154 robo
->ops
->enable_mgmtif(robo
);
1156 /* Switch Mode register (Page 0, Address 0x0B) */
1157 robo
->ops
->read_reg(robo
, PAGE_CTRL
, REG_CTRL_MODE
, &val8
, sizeof(val8
));
1159 /* Bit 1 enables switching/forwarding */
1160 if (!(val8
& (1 << 1))) {
1161 /* Set unmanaged mode */
1162 val8
&= (~(1 << 0));
1164 /* Enable forwarding */
1166 robo
->ops
->write_reg(robo
, PAGE_CTRL
, REG_CTRL_MODE
, &val8
, sizeof(val8
));
1169 robo
->ops
->read_reg(robo
, PAGE_CTRL
, REG_CTRL_MODE
, &val8
, sizeof(val8
));
1170 if (!(val8
& (1 << 1))) {
1171 ET_ERROR(("robo_enable_switch: enabling forwarding failed\n"));
1175 /* No spanning tree for unmanaged mode */
1177 max_port_ind
= ((robo
->devid
== DEVID5398
) ? REG_CTRL_PORT7
: REG_CTRL_PORT4
);
1178 for (i
= REG_CTRL_PORT0
; i
<= max_port_ind
; i
++) {
1179 robo
->ops
->write_reg(robo
, PAGE_CTRL
, i
, &val8
, sizeof(val8
));
1182 /* No spanning tree on IMP port too */
1183 robo
->ops
->write_reg(robo
, PAGE_CTRL
, REG_CTRL_IMP
, &val8
, sizeof(val8
));
1186 /* Enable WAN port (#0) on the asus wl-500g deluxe boxes */
1188 robo
->ops
->write_reg(robo
, PAGE_CTRL
, REG_CTRL_PORT0
, &val8
, sizeof(val8
));
1190 /* Disable management interface access */
1191 if (robo
->ops
->disable_mgmtif
)
1192 robo
->ops
->disable_mgmtif(robo
);
1199 * Update the power save configuration for ports that changed link status.
1202 robo_power_save_mode_update(robo_info_t
*robo
, bool allports
)
1205 uint16 link_status
, update
= 0;
1207 /* read the link status of all ports */
1208 robo
->ops
->read_reg(robo
, PAGE_STATUS
, REG_STATUS_LINK
,
1209 &link_status
, sizeof(uint16
));
1210 link_status
&= 0x1f;
1213 /* return if no change in link status */
1214 if (link_status
== robo
->prev_status
)
1217 ET_MSG(("%s: old link status %x new link status %x\n",
1218 __FUNCTION__
, robo
->prev_status
, link_status
));
1220 /* get the link status bits that changed */
1221 update
= robo
->prev_status
^ link_status
;
1224 robo
->prev_status
= link_status
;
1226 /* when link status changes update the power save configuration
1227 * for the corresponding ports. ports that moved to down state
1228 * are put in to power save mode. ports that moved to up state
1229 * are taken out of power save mode.
1231 for (phy
= 0; phy
< MAX_NO_PHYS
; phy
++) {
1232 if (!allports
&& !((update
& (1 << phy
)) &&
1233 (robo
->pwrsave_phys
& (1 << phy
))))
1236 if (link_status
& (1 << phy
)) {
1237 /* link is up, put the phy in normal mode */
1238 ET_MSG(("%s: link up, set port %d to normal mode\n",
1239 __FUNCTION__
, phy
));
1240 robo_power_save_mode(robo
, ROBO_PWRSAVE_NORMAL
, phy
);
1242 /* link is down, put phys in auto, manual
1243 * or auto+manual mode based on the config.
1245 if (robo
->pwrsave_mode_auto
& (1 << phy
)) {
1246 ET_MSG(("%s: link down, set port %d to auto mode\n",
1247 __FUNCTION__
, phy
));
1248 robo_power_save_mode(robo
, ROBO_PWRSAVE_AUTO
, phy
);
1250 if (robo
->pwrsave_mode_manual
& (1 << phy
)) {
1251 ET_MSG(("%s: link down, set port %d to man mode\n",
1252 __FUNCTION__
, phy
));
1253 robo_power_save_mode(robo
, ROBO_PWRSAVE_MANUAL
, phy
);
1262 robo_power_save_mode_clear_auto(robo_info_t
*robo
, int32 phy
)
1266 if (robo
->devid
== DEVID53115
) {
1267 /* For 53115 0x1C is the MII address of the auto power
1268 * down register. Bit 5 is enabling the mode
1269 * bits has the following purpose
1270 * 15 - write enable 10-14 shadow register select 01010 for
1271 * auto power 6-9 reserved 5 auto power mode enable
1272 * 4 sleep timer select : 1 means 5.4 sec
1273 * 0-3 wake up timer select: 0xF 1.26 sec
1276 robo
->miiwr(robo
->h
, phy
, REG_MII_AUTO_PWRDOWN
, val16
);
1280 robo
->pwrsave_mode_phys
[phy
] &= ~ROBO_PWRSAVE_AUTO
;
1286 robo_power_save_mode_clear_manual(robo_info_t
*robo
, int32 phy
)
1291 if (robo
->devid
== DEVID53115
) {
1292 /* For 53115 0x0 is the MII control register
1293 * Bit 11 is the power down mode bit
1295 val16
= robo
->miird(robo
->h
, phy
, REG_MII_CTRL
);
1297 robo
->miiwr(robo
->h
, phy
, REG_MII_CTRL
, val16
);
1298 } else if (robo
->devid
== DEVID5325
) {
1301 /* For 5325 page 0x00 address 0x0F is the power down
1302 * mode register. Bits 1-4 determines which of the
1303 * phys are enabled for this mode
1305 robo
->ops
->read_reg(robo
, PAGE_CTRL
, REG_CTRL_PWRDOWN
,
1306 &val8
, sizeof(val8
));
1307 val8
&= ~(0x1 << phy
);
1308 robo
->ops
->write_reg(robo
, PAGE_CTRL
, REG_CTRL_PWRDOWN
,
1309 &val8
, sizeof(val8
));
1313 robo
->pwrsave_mode_phys
[phy
] &= ~ROBO_PWRSAVE_MANUAL
;
1319 * Function which periodically checks the power save mode on the switch
1322 robo_power_save_toggle(robo_info_t
*robo
, int32 normal
)
1326 /* Put the phys into the normal mode first so that link status
1327 * can be checked. Once in the normal mode check the link status
1328 * and if any of the link is up do not put that phy into
1329 * manual power save mode
1331 for (phy
= 0; phy
< MAX_NO_PHYS
; phy
++) {
1332 /* When auto+manual modes are enabled we toggle between
1333 * manual and auto modes. When only manual mode is enabled
1334 * we toggle between manual and normal modes. When only
1335 * auto mode is enabled there is no need to do anything
1336 * here since auto mode is one time config.
1338 if ((robo
->pwrsave_phys
& (1 << phy
)) &&
1339 (robo
->pwrsave_mode_manual
& (1 << phy
))) {
1341 if (robo
->pwrsave_mode_auto
& (1 << phy
))
1342 /* auto+manual -> auto */
1343 robo_power_save_mode_clear_manual(robo
, phy
);
1345 /* manual -> normal */
1346 robo_power_save_mode(robo
, ROBO_PWRSAVE_NORMAL
, phy
);
1348 /* normal -> manual / auto+manual */
1349 robo_power_save_mode(robo
, ROBO_PWRSAVE_MANUAL
, phy
);
1357 * Switch the ports to normal mode.
1360 robo_power_save_mode_normal(robo_info_t
*robo
, int32 phy
)
1364 /* If the phy in the power save mode come out of it */
1365 switch (robo
->pwrsave_mode_phys
[phy
]) {
1366 case ROBO_PWRSAVE_AUTO_MANUAL
:
1367 case ROBO_PWRSAVE_AUTO
:
1368 error
= robo_power_save_mode_clear_auto(robo
, phy
);
1369 if ((error
== -1) ||
1370 (robo
->pwrsave_mode_phys
[phy
] == ROBO_PWRSAVE_AUTO
))
1373 case ROBO_PWRSAVE_MANUAL
:
1374 error
= robo_power_save_mode_clear_manual(robo
, phy
);
1385 * Switch all the inactive ports to auto power down mode.
1388 robo_power_save_mode_auto(robo_info_t
*robo
, int32 phy
)
1392 /* For both 5325 and 53115 the link status register
1395 robo
->ops
->read_reg(robo
, PAGE_STATUS
, REG_STATUS_LINK
,
1396 &val16
, sizeof(val16
));
1397 if (val16
& (0x1 << phy
))
1400 /* If the switch supports auto power down enable that */
1401 if (robo
->devid
== DEVID53115
) {
1402 /* For 53115 0x1C is the MII address of the auto power
1403 * down register. Bit 5 is enabling the mode
1404 * bits has the following purpose
1405 * 15 - write enable 10-14 shadow register select 01010 for
1406 * auto power 6-9 reserved 5 auto power mode enable
1407 * 4 sleep timer select : 1 means 5.4 sec
1408 * 0-3 wake up timer select: 0xF 1.26 sec
1410 robo
->miiwr(robo
->h
, phy
, REG_MII_AUTO_PWRDOWN
, 0xA83F);
1414 robo
->pwrsave_mode_phys
[phy
] |= ROBO_PWRSAVE_AUTO
;
1420 * Switch all the inactive ports to manual power down mode.
1423 robo_power_save_mode_manual(robo_info_t
*robo
, int32 phy
)
1428 /* For both 5325 and 53115 the link status register is the same */
1429 robo
->ops
->read_reg(robo
, PAGE_STATUS
, REG_STATUS_LINK
,
1430 &val16
, sizeof(val16
));
1431 if (val16
& (0x1 << phy
))
1434 /* If the switch supports manual power down enable that */
1435 if (robo
->devid
== DEVID53115
) {
1436 /* For 53115 0x0 is the MII control register bit 11 is the
1437 * power down mode bit
1439 val16
= robo
->miird(robo
->h
, phy
, REG_MII_CTRL
);
1440 robo
->miiwr(robo
->h
, phy
, REG_MII_CTRL
, val16
| 0x800);
1441 } else if (robo
->devid
== DEVID5325
) {
1444 /* For 5325 page 0x00 address 0x0F is the power down mode
1445 * register. Bits 1-4 determines which of the phys are enabled
1448 robo
->ops
->read_reg(robo
, PAGE_CTRL
, REG_CTRL_PWRDOWN
, &val8
,
1451 robo
->ops
->write_reg(robo
, PAGE_CTRL
, REG_CTRL_PWRDOWN
, &val8
,
1456 robo
->pwrsave_mode_phys
[phy
] |= ROBO_PWRSAVE_MANUAL
;
1462 * Set power save modes on the robo switch
1465 robo_power_save_mode(robo_info_t
*robo
, int32 mode
, int32 phy
)
1469 if (phy
> MAX_NO_PHYS
) {
1470 ET_ERROR(("Passed parameter phy is out of range\n"));
1474 /* Enable management interface access */
1475 if (robo
->ops
->enable_mgmtif
)
1476 robo
->ops
->enable_mgmtif(robo
);
1479 case ROBO_PWRSAVE_NORMAL
:
1480 /* If the phy in the power save mode come out of it */
1481 error
= robo_power_save_mode_normal(robo
, phy
);
1484 case ROBO_PWRSAVE_AUTO_MANUAL
:
1485 /* If the switch supports auto and manual power down
1486 * enable both of them
1488 case ROBO_PWRSAVE_AUTO
:
1489 error
= robo_power_save_mode_auto(robo
, phy
);
1490 if ((error
== -1) || (mode
== ROBO_PWRSAVE_AUTO
))
1493 case ROBO_PWRSAVE_MANUAL
:
1494 error
= robo_power_save_mode_manual(robo
, phy
);
1501 /* Disable management interface access */
1502 if (robo
->ops
->disable_mgmtif
)
1503 robo
->ops
->disable_mgmtif(robo
);
1509 * Get the current power save mode of the switch ports.
1512 robo_power_save_mode_get(robo_info_t
*robo
, int32 phy
)
1516 if (phy
>= MAX_NO_PHYS
)
1519 return robo
->pwrsave_mode_phys
[phy
];
1523 * Configure the power save mode for the switch ports.
1526 robo_power_save_mode_set(robo_info_t
*robo
, int32 mode
, int32 phy
)
1532 if (phy
>= MAX_NO_PHYS
)
1535 error
= robo_power_save_mode(robo
, mode
, phy
);
1540 if (mode
== ROBO_PWRSAVE_NORMAL
) {
1541 robo
->pwrsave_mode_manual
&= ~(1 << phy
);
1542 robo
->pwrsave_mode_auto
&= ~(1 << phy
);
1543 } else if (mode
== ROBO_PWRSAVE_AUTO
) {
1544 robo
->pwrsave_mode_auto
|= (1 << phy
);
1545 robo
->pwrsave_mode_manual
&= ~(1 << phy
);
1546 robo_power_save_mode_clear_manual(robo
, phy
);
1547 } else if (mode
== ROBO_PWRSAVE_MANUAL
) {
1548 robo
->pwrsave_mode_manual
|= (1 << phy
);
1549 robo
->pwrsave_mode_auto
&= ~(1 << phy
);
1550 robo_power_save_mode_clear_auto(robo
, phy
);
1552 robo
->pwrsave_mode_auto
|= (1 << phy
);
1553 robo
->pwrsave_mode_manual
|= (1 << phy
);