[buildroot] disable sstrip when using musl
[openwrt.git] / target / linux / ubicom32 / files / arch / ubicom32 / mach-common / switch-bcm539x.c
1 /*
2  * arch/ubicom32/mach-common/switch-bcm539x.c
3  *   BCM539X switch driver, SPI mode
4  *
5  * (C) Copyright 2009, Ubicom, Inc.
6  *
7  * This file is part of the Ubicom32 Linux Kernel Port.
8  *
9  * The Ubicom32 Linux Kernel Port is free software: you can redistribute
10  * it and/or modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation, either version 2 of the
12  * License, or (at your option) any later version.
13  *
14  * The Ubicom32 Linux Kernel Port is distributed in the hope that it
15  * will be useful, but WITHOUT ANY WARRANTY; without even the implied
16  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
17  * the GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with the Ubicom32 Linux Kernel Port.  If not,
21  * see <http://www.gnu.org/licenses/>.
22  *
23  * Ubicom32 implementation derived from (with many thanks):
24  *   arch/m68knommu
25  *   arch/blackfin
26  *   arch/parisc
27  */
28
29 #include <linux/platform_device.h>
30 #include <linux/spi/spi.h>
31 #include <linux/gpio.h>
32 #include <linux/delay.h>
33 #include <linux/mii.h>
34
35 #include <asm/switch-dev.h>
36 #include <asm/ubicom32-spi-gpio.h>
37 #include "switch-core.h"
38 #include "switch-bcm539x-reg.h"
39
40 #define DRIVER_NAME "bcm539x-spi"
41 #define DRIVER_VERSION "1.0"
42
43 #undef BCM539X_DEBUG
44 #define BCM539X_SPI_RETRIES     100
45
46 struct bcm539x_data {
47         struct switch_device                    *switch_dev;
48
49         /*
50          * Our private data
51          */
52         struct spi_device                       *spi;
53         struct switch_core_platform_data        *pdata;
54
55         /*
56          * Last page we accessed
57          */
58         u8_t                                    last_page;
59
60         /*
61          * 539x Device ID
62          */
63         u8_t                                    device_id;
64 };
65
66 /*
67  * bcm539x_wait_status
68  *      Waits for the specified bit in the status register to be set/cleared.
69  */
70 static int bcm539x_wait_status(struct bcm539x_data *bd, u8_t mask, int set)
71 {
72         u8_t txbuf[2];
73         u8_t rxbuf;
74         int i;
75         int ret;
76
77         txbuf[0] = BCM539X_CMD_READ;
78         txbuf[1] = BCM539X_GLOBAL_SPI_STATUS;
79         for (i = 0; i < BCM539X_SPI_RETRIES; i++) {
80                 ret = spi_write_then_read(bd->spi, txbuf, 2, &rxbuf, 1);
81                 rxbuf &= mask;
82                 if ((set && rxbuf) || (!set && !rxbuf)) {
83                         return 0;
84                 }
85                 udelay(1);
86         }
87
88         return -EIO;
89 }
90
91 /*
92  * bcm539x_set_page
93  *      Sets the register page for access (only if necessary)
94  */
95 static int bcm539x_set_page(struct bcm539x_data *bd, u8_t page)
96 {
97         u8_t txbuf[3];
98
99         if (page == bd->last_page) {
100                 return 0;
101         }
102
103         bd->last_page = page;
104
105         txbuf[0] = BCM539X_CMD_WRITE;
106         txbuf[1] = BCM539X_GLOBAL_PAGE;
107         txbuf[2] = page;
108
109         return spi_write(bd->spi, txbuf, 3);
110 }
111
112 /*
113  * bcm539x_write_bytes
114  *      Writes a number of bytes to a given page and register
115  */
116 static int bcm539x_write_bytes(struct bcm539x_data *bd, u8_t page,
117                                u8_t reg, void *buf, u8_t len)
118 {
119         int ret;
120         u8_t *txbuf;
121
122         txbuf = kmalloc(2 + len, GFP_KERNEL);
123         if (!txbuf) {
124                 return -ENOMEM;
125         }
126
127         /*
128          * Make sure the chip has finished processing our previous request
129          */
130         ret = bcm539x_wait_status(bd, BCM539X_GLOBAL_SPI_ST_SPIF, 0);
131         if (ret) {
132                 goto done;
133         }
134
135         /*
136          * Set the page
137          */
138         ret = bcm539x_set_page(bd, page);
139         if (ret) {
140                 goto done;
141         }
142
143         /*
144          * Read the data
145          */
146         txbuf[0] = BCM539X_CMD_WRITE;
147         txbuf[1] = reg;
148         memcpy(&txbuf[2], buf, len);
149
150 #ifdef BCM539X_DEBUG
151         {
152                 int i;
153                 printk("write page %02x reg %02x len=%d buf=", page, reg, len);
154                 for (i = 0; i < len + 2; i++) {
155                         printk("%02x ", txbuf[i]);
156                 }
157                 printk("\n");
158         }
159 #endif
160
161         ret = spi_write(bd->spi, txbuf, 2 + len);
162
163 done:
164         kfree(txbuf);
165         return ret;
166 }
167
168 /*
169  * bcm539x_write_32
170  *      Writes 32 bits of data to the given page and register
171  */
172 static inline int bcm539x_write_32(struct bcm539x_data *bd, u8_t page,
173                                    u8_t reg, u32_t data)
174 {
175         data = cpu_to_le32(data);
176         return bcm539x_write_bytes(bd, page, reg, &data, 4);
177 }
178
179 /*
180  * bcm539x_write_16
181  *      Writes 16 bits of data to the given page and register
182  */
183 static inline int bcm539x_write_16(struct bcm539x_data *bd, u8_t page,
184                                    u8_t reg, u16_t data)
185 {
186         data = cpu_to_le16(data);
187         return bcm539x_write_bytes(bd, page, reg, &data, 2);
188 }
189
190 /*
191  * bcm539x_write_8
192  *      Writes 8 bits of data to the given page and register
193  */
194 static inline int bcm539x_write_8(struct bcm539x_data *bd, u8_t page,
195                                   u8_t reg, u8_t data)
196 {
197         return bcm539x_write_bytes(bd, page, reg, &data, 1);
198 }
199
200 /*
201  * bcm539x_read_bytes
202  *      Reads a number of bytes from a given page and register
203  */
204 static int bcm539x_read_bytes(struct bcm539x_data *bd, u8_t page,
205                               u8_t reg, void *buf, u8_t len)
206 {
207         u8_t txbuf[2];
208         int ret;
209
210         /*
211          * (1) Make sure the chip has finished processing our previous request
212          */
213         ret = bcm539x_wait_status(bd, BCM539X_GLOBAL_SPI_ST_SPIF, 0);
214         if (ret) {
215                 return ret;
216         }
217
218         /*
219          * (2) Set the page
220          */
221         ret = bcm539x_set_page(bd, page);
222         if (ret) {
223                 return ret;
224         }
225
226         /*
227          * (3) Kick off the register read
228          */
229         txbuf[0] = BCM539X_CMD_READ;
230         txbuf[1] = reg;
231         ret = spi_write_then_read(bd->spi, txbuf, 2, txbuf, 1);
232         if (ret) {
233                 return ret;
234         }
235
236         /*
237          * (4) Wait for RACK
238          */
239         ret = bcm539x_wait_status(bd, BCM539X_GLOBAL_SPI_ST_RACK, 1);
240         if (ret) {
241                 return ret;
242         }
243
244         /*
245          * (5) Read the data
246          */
247         txbuf[0] = BCM539X_CMD_READ;
248         txbuf[1] = BCM539X_GLOBAL_SPI_DATA0;
249
250         ret = spi_write_then_read(bd->spi, txbuf, 2, buf, len);
251
252 #ifdef BCM539X_DEBUG
253         {
254                 int i;
255                 printk("read page %02x reg %02x len=%d rxbuf=",
256                        page, reg, len);
257                 for (i = 0; i < len; i++) {
258                         printk("%02x ", ((u8_t *)buf)[i]);
259                 }
260                 printk("\n");
261         }
262 #endif
263
264         return ret;
265 }
266
267 /*
268  * bcm539x_read_32
269  *      Reads an 32 bit number from a given page and register
270  */
271 static int bcm539x_read_32(struct bcm539x_data *bd, u8_t page,
272                            u8_t reg, u32_t *buf)
273 {
274         int ret = bcm539x_read_bytes(bd, page, reg, buf, 4);
275         *buf = le32_to_cpu(*buf);
276         return ret;
277 }
278
279 /*
280  * bcm539x_read_16
281  *      Reads an 16 bit number from a given page and register
282  */
283 static int bcm539x_read_16(struct bcm539x_data *bd, u8_t page,
284                            u8_t reg, u16_t *buf)
285 {
286         int ret = bcm539x_read_bytes(bd, page, reg, buf, 2);
287         *buf = le16_to_cpu(*buf);
288         return ret;
289 }
290
291 /*
292  * bcm539x_read_8
293  *      Reads an 8 bit number from a given page and register
294  */
295 static int bcm539x_read_8(struct bcm539x_data *bd, u8_t page,
296                           u8_t reg, u8_t *buf)
297 {
298         return bcm539x_read_bytes(bd, page, reg, buf, 1);
299 }
300
301 /*
302  * bcm539x_set_mode
303  */
304 static int bcm539x_set_mode(struct bcm539x_data *bd, int state)
305 {
306         u8_t buf;
307         int ret;
308
309         ret = bcm539x_read_8(bd, PAGE_PORT_TC, REG_CTRL_MODE, &buf);
310         if (ret) {
311                 return ret;
312         }
313
314         buf &= ~(1 << 1);
315         buf |= state ? (1 << 1) : 0;
316
317         ret = bcm539x_write_8(bd, PAGE_PORT_TC, REG_CTRL_MODE, buf);
318         return ret;
319 }
320
321 /*
322  * bcm539x_handle_reset
323  */
324 static int bcm539x_handle_reset(struct switch_device *dev, char *buf, int inst)
325 {
326         struct bcm539x_data *bd =
327                 (struct bcm539x_data *)switch_get_drvdata(dev);
328         int ret;
329
330         ret = bcm539x_write_8(bd, PAGE_PORT_TC, REG_CTRL_SRST,
331                               (1 << 7) | (1 << 4));
332         if (ret) {
333                 return ret;
334         }
335
336         udelay(20);
337
338         ret = bcm539x_write_8(bd, PAGE_PORT_TC, REG_CTRL_SRST, 0);
339         return ret;
340 }
341
342 /*
343  * bcm539x_handle_vlan_ports_read
344  */
345 static int bcm539x_handle_vlan_ports_read(struct switch_device *dev,
346                                           char *buf, int inst)
347 {
348         struct bcm539x_data *bd =
349                 (struct bcm539x_data *)switch_get_drvdata(dev);
350         int j;
351         int len = 0;
352         u8_t rxbuf8;
353         u32_t rxbuf32;
354         int ret;
355
356         ret = bcm539x_write_16(bd, PAGE_VTBL, REG_VTBL_INDX_5395, inst);
357         if (ret) {
358                 return ret;
359         }
360
361         ret = bcm539x_write_8(bd, PAGE_VTBL, REG_VTBL_ACCESS_5395,
362                               (1 << 7) | 1);
363         if (ret) {
364                 return ret;
365         }
366
367         /*
368          * Wait for completion
369          */
370         for (j = 0; j < BCM539X_SPI_RETRIES; j++) {
371                 ret = bcm539x_read_8(bd, PAGE_VTBL, REG_VTBL_ACCESS_5395,
372                                      &rxbuf8);
373                 if (ret) {
374                         return ret;
375                 }
376                 if (!(rxbuf8 & (1 << 7))) {
377                         break;
378                 }
379         }
380
381         if (j == BCM539X_SPI_RETRIES) {
382                 return -EIO;
383         }
384
385         /*
386          * Read the table entry
387          */
388         ret = bcm539x_read_32(bd, PAGE_VTBL, REG_VTBL_ENTRY_5395, &rxbuf32);
389         if (ret) {
390                 return ret;
391         }
392
393         for (j = 0; j < 9; j++) {
394                 if (rxbuf32 & (1 << j)) {
395                         u16_t rxbuf16;
396                         len += sprintf(buf + len, "%d", j);
397                         if (rxbuf32 & (1 << (j + 9))) {
398                                 buf[len++] = 'u';
399                         } else {
400                                 buf[len++] = 't';
401                         }
402                         ret = bcm539x_read_16(bd, PAGE_VLAN,
403                                               REG_VLAN_PTAG0 + (j << 1),
404                                               &rxbuf16);
405                         if (ret) {
406                                 return ret;
407                         }
408                         if (rxbuf16 == inst) {
409                                 buf[len++] = '*';
410                         }
411                         buf[len++] = '\t';
412                 }
413         }
414
415         len += sprintf(buf + len, "\n");
416         buf[len] = '\0';
417
418         return len;
419 }
420
421 /*
422  * bcm539x_handle_vlan_ports_write
423  */
424 static int bcm539x_handle_vlan_ports_write(struct switch_device *dev,
425                                            char *buf, int inst)
426 {
427         struct bcm539x_data *bd =
428                 (struct bcm539x_data *)switch_get_drvdata(dev);
429         int j;
430         u32_t untag;
431         u32_t ports;
432         u32_t def;
433
434         u8_t rxbuf8;
435         u16_t rxbuf16;
436         int ret;
437
438         switch_parse_vlan_ports(dev, buf, &untag, &ports, &def);
439
440 #ifdef BCM539X_DEBUG
441         printk(KERN_DEBUG "'%s' inst=%d untag=%08x ports=%08x def=%08x\n",
442                 buf, inst, untag, ports, def);
443 #endif
444
445         if (!ports) {
446                 return 0;
447         }
448
449         /*
450          * Change default vlan tag
451          */
452         for (j = 0; j < 9; j++) {
453                 if ((untag | def) & (1 << j)) {
454                         ret = bcm539x_write_16(bd, PAGE_VLAN,
455                                                REG_VLAN_PTAG0 + (j << 1),
456                                                inst);
457                         if (ret) {
458                                 return ret;
459                         }
460                         continue;
461                 }
462
463                 if (!(dev->port_mask[0] & (1 << j))) {
464                         continue;
465                 }
466
467                 /*
468                  * Remove any ports which are not listed anymore as members of
469                  * this vlan
470                  */
471                 ret = bcm539x_read_16(bd, PAGE_VLAN,
472                                       REG_VLAN_PTAG0 + (j << 1), &rxbuf16);
473                 if (ret) {
474                         return ret;
475                 }
476                 if (rxbuf16 == inst) {
477                         ret = bcm539x_write_16(bd, PAGE_VLAN,
478                                                REG_VLAN_PTAG0 + (j << 1), 0);
479                         if (ret) {
480                                 return ret;
481                         }
482                 }
483         }
484
485         /*
486          * Write the VLAN table
487          */
488         ret = bcm539x_write_16(bd, PAGE_VTBL, REG_VTBL_INDX_5395, inst);
489         if (ret) {
490                 return ret;
491         }
492
493         ret = bcm539x_write_32(bd, PAGE_VTBL, REG_VTBL_ENTRY_5395,
494                                (untag << 9) | ports);
495         if (ret) {
496                 return ret;
497         }
498
499         ret = bcm539x_write_8(bd, PAGE_VTBL, REG_VTBL_ACCESS_5395,
500                               (1 << 7) | 0);
501         if (ret) {
502                 return ret;
503         }
504
505         /*
506          * Wait for completion
507          */
508         for (j = 0; j < BCM539X_SPI_RETRIES; j++) {
509                 ret = bcm539x_read_bytes(bd, PAGE_VTBL, REG_VTBL_ACCESS_5395,
510                                          &rxbuf8, 1);
511                 if (ret) {
512                         return ret;
513                 }
514                 if (!(rxbuf8 & (1 << 7))) {
515                         break;
516                 }
517         }
518
519         return (j < BCM539X_SPI_RETRIES) ? 0 : -EIO;
520 }
521
522 /*
523  * Handlers for <this_driver>/vlan/<vlan_id>
524  */
525 static const struct switch_handler bcm539x_switch_handlers_vlan_dir[] = {
526         {
527                 .name   = "ports",
528                 .read   = bcm539x_handle_vlan_ports_read,
529                 .write  = bcm539x_handle_vlan_ports_write,
530         },
531         {
532         },
533 };
534
535 /*
536  * bcm539x_handle_vlan_delete_write
537  */
538 static int bcm539x_handle_vlan_delete_write(struct switch_device *dev,
539                                             char *buf, int inst)
540 {
541         struct bcm539x_data *bd =
542                 (struct bcm539x_data *)switch_get_drvdata(dev);
543         int vid;
544         u8_t rxbuf8;
545         u32_t txbuf;
546         int j;
547         int ret;
548
549         vid = simple_strtoul(buf, NULL, 0);
550         if (!vid) {
551                 return -EINVAL;
552         }
553
554         /*
555          * Disable this VLAN
556          *
557          * Go through the port-based vlan registers and clear the appropriate
558          * ones out
559          */
560         for (j = 0; j < 9; j++) {
561                 u16_t rxbuf16;
562                 ret = bcm539x_read_16(bd, PAGE_VLAN, REG_VLAN_PTAG0 + (j << 1),
563                                       &rxbuf16);
564                 if (ret) {
565                         return ret;
566                 }
567                 if (rxbuf16 == vid) {
568                         txbuf = 0;
569                         ret = bcm539x_write_16(bd, PAGE_VLAN,
570                                                REG_VLAN_PTAG0 + (j << 1),
571                                                txbuf);
572                         if (ret) {
573                                 return ret;
574                         }
575                 }
576         }
577
578         /*
579          * Write the VLAN table
580          */
581         txbuf = vid;
582         ret = bcm539x_write_16(bd, PAGE_VTBL, REG_VTBL_INDX_5395, txbuf);
583         if (ret) {
584                 return ret;
585         }
586
587         txbuf = 0;
588         ret = bcm539x_write_32(bd, PAGE_VTBL, REG_VTBL_ENTRY_5395, txbuf);
589         if (ret) {
590                 return ret;
591         }
592
593         txbuf = (1 << 7) | (0);
594         ret = bcm539x_write_8(bd, PAGE_VTBL, REG_VTBL_ACCESS_5395, txbuf);
595         if (ret) {
596                 return ret;
597         }
598
599         /*
600          * Wait for completion
601          */
602         for (j = 0; j < BCM539X_SPI_RETRIES; j++) {
603                 ret = bcm539x_read_bytes(bd, PAGE_VTBL, REG_VTBL_ACCESS_5395,
604                                          &rxbuf8, 1);
605                 if (ret) {
606                         return ret;
607                 }
608                 if (!(rxbuf8 & (1 << 7))) {
609                         break;
610                 }
611         }
612
613         if (j == BCM539X_SPI_RETRIES) {
614                 return -EIO;
615         }
616
617         return switch_remove_vlan_dir(dev, vid);
618 }
619
620 /*
621  * bcm539x_handle_vlan_create_write
622  */
623 static int bcm539x_handle_vlan_create_write(struct switch_device *dev,
624                                             char *buf, int inst)
625 {
626         int vid;
627
628         vid = simple_strtoul(buf, NULL, 0);
629         if (!vid) {
630                 return -EINVAL;
631         }
632
633         return switch_create_vlan_dir(dev, vid,
634                                       bcm539x_switch_handlers_vlan_dir);
635 }
636
637 /*
638  * bcm539x_handle_enable_read
639  */
640 static int bcm539x_handle_enable_read(struct switch_device *dev,
641                                       char *buf, int inst)
642 {
643         struct bcm539x_data *bd =
644                 (struct bcm539x_data *)switch_get_drvdata(dev);
645         u8_t rxbuf;
646         int ret;
647
648         ret = bcm539x_read_8(bd, PAGE_PORT_TC, REG_CTRL_MODE, &rxbuf);
649         if (ret) {
650                 return ret;
651         }
652         rxbuf = (rxbuf & (1 << 1)) ? 1 : 0;
653
654         return sprintf(buf, "%d\n", rxbuf);
655 }
656
657 /*
658  * bcm539x_handle_enable_write
659  */
660 static int bcm539x_handle_enable_write(struct switch_device *dev,
661                                        char *buf, int inst)
662 {
663         struct bcm539x_data *bd =
664                 (struct bcm539x_data *)switch_get_drvdata(dev);
665
666         return bcm539x_set_mode(bd, buf[0] == '1');
667 }
668
669 /*
670  * bcm539x_handle_enable_vlan_read
671  */
672 static int bcm539x_handle_enable_vlan_read(struct switch_device *dev,
673                                            char *buf, int inst)
674 {
675         struct bcm539x_data *bd =
676                 (struct bcm539x_data *)switch_get_drvdata(dev);
677         u8_t rxbuf;
678         int ret;
679
680         ret = bcm539x_read_8(bd, PAGE_VLAN, REG_VLAN_CTRL0, &rxbuf);
681         if (ret) {
682                 return ret;
683         }
684         rxbuf = (rxbuf & (1 << 7)) ? 1 : 0;
685
686         return sprintf(buf, "%d\n", rxbuf);
687 }
688
689 /*
690  * bcm539x_handle_enable_vlan_write
691  */
692 static int bcm539x_handle_enable_vlan_write(struct switch_device *dev,
693                                             char *buf, int inst)
694 {
695         struct bcm539x_data *bd =
696                 (struct bcm539x_data *)switch_get_drvdata(dev);
697         int ret;
698
699         /*
700          * disable 802.1Q VLANs
701          */
702         if (buf[0] != '1') {
703                 ret = bcm539x_write_8(bd, PAGE_VLAN, REG_VLAN_CTRL0, 0);
704                 return ret;
705         }
706
707         /*
708          * enable 802.1Q VLANs
709          *
710          * Enable 802.1Q | IVL learning
711          */
712         ret = bcm539x_write_8(bd, PAGE_VLAN, REG_VLAN_CTRL0,
713                               (1 << 7) | (3 << 5));
714         if (ret) {
715                 return ret;
716         }
717
718         /*
719          * RSV multicast fwd | RSV multicast chk
720          */
721         ret = bcm539x_write_8(bd, PAGE_VLAN, REG_VLAN_CTRL1,
722                               (1 << 2) | (1 << 3));
723         if (ret) {
724                 return ret;
725         }
726 #if 0
727         /*
728          * Drop invalid VID
729          */
730         ret = bcm539x_write_16(bd, PAGE_VLAN, REG_VLAN_CTRL3, 0x00FF);
731         if (ret) {
732                 return ret;
733         }
734 #endif
735         return 0;
736 }
737
738 /*
739  * bcm539x_handle_port_enable_read
740  */
741 static int bcm539x_handle_port_enable_read(struct switch_device *dev,
742                                            char *buf, int inst)
743 {
744         return sprintf(buf, "%d\n", 1);
745 }
746
747 /*
748  * bcm539x_handle_port_enable_write
749  */
750 static int bcm539x_handle_port_enable_write(struct switch_device *dev,
751                                             char *buf, int inst)
752 {
753         /*
754          * validate port
755          */
756         if (!(dev->port_mask[0] & (1 << inst))) {
757                 return -EIO;
758         }
759
760         if (buf[0] != '1') {
761                 printk(KERN_WARNING "switch port[%d] disabling is not supported\n", inst);
762         }
763         return 0;
764 }
765
766 /*
767  * bcm539x_handle_port_state_read
768  */
769 static int bcm539x_handle_port_state_read(struct switch_device *dev,
770                                            char *buf, int inst)
771 {
772         struct bcm539x_data *bd =
773                 (struct bcm539x_data *)switch_get_drvdata(dev);
774         int ret;
775         u16_t link;
776
777         /*
778          * validate port
779          */
780         if (!(dev->port_mask[0] & (1 << inst))) {
781                 return -EIO;
782         }
783
784         /*
785          * check PHY link state - CPU port (port 8) is always up
786          */
787         ret = bcm539x_read_16(bd, PAGE_STATUS, REG_LINK_STATUS, &link);
788         if (ret) {
789                 return ret;
790         }
791         link |= (1 << 8);
792
793         return sprintf(buf, "%d\n", (link & (1 << inst)) ? 1 : 0);
794 }
795
796 /*
797  * bcm539x_handle_port_media_read
798  */
799 static int bcm539x_handle_port_media_read(struct switch_device *dev,
800                                            char *buf, int inst)
801 {
802         struct bcm539x_data *bd =
803                 (struct bcm539x_data *)switch_get_drvdata(dev);
804         int ret;
805         u16_t link, duplex;
806         u32_t speed;
807
808         /*
809          * validate port
810          */
811         if (!(dev->port_mask[0] & (1 << inst))) {
812                 return -EIO;
813         }
814
815         /*
816          * check PHY link state first - CPU port (port 8) is always up
817          */
818         ret = bcm539x_read_16(bd, PAGE_STATUS, REG_LINK_STATUS, &link);
819         if (ret) {
820                 return ret;
821         }
822         link |= (1 << 8);
823
824         if (!(link & (1 << inst))) {
825                 return sprintf(buf, "UNKNOWN\n");
826         }
827
828         /*
829          * get link speeda dn duplex - CPU port (port 8) is 1000/full
830          */
831         ret = bcm539x_read_32(bd, PAGE_STATUS, 4, &speed);
832         if (ret) {
833                 return ret;
834         }
835         speed |= (2 << 16);
836         speed = (speed >> (2 * inst)) & 3;
837
838         ret = bcm539x_read_16(bd, PAGE_STATUS, 8, &duplex);
839         if (ret) {
840                 return ret;
841         }
842         duplex |= (1 << 8);
843         duplex = (duplex >> inst) & 1;
844
845         return sprintf(buf, "%d%cD\n",
846                 (speed == 0) ? 10 : ((speed == 1) ? 100 : 1000),
847                 duplex ? 'F' : 'H');
848 }
849
850 /*
851  * bcm539x_handle_port_meida_write
852  */
853 static int bcm539x_handle_port_meida_write(struct switch_device *dev,
854                                             char *buf, int inst)
855 {
856         struct bcm539x_data *bd =
857                 (struct bcm539x_data *)switch_get_drvdata(dev);
858         int ret;
859         u16_t ctrl_word, local_cap, local_giga_cap;
860
861         /*
862          * validate port (not for CPU port)
863          */
864         if (!(dev->port_mask[0] & (1 << inst) & ~(1 << 8))) {
865                 return -EIO;
866         }
867
868         /*
869          * Get the maximum capability from status
870          *      SPI reg[0x00] = PHY[0x0] --- MII control
871          *      SPI reg[0x08] = PHY[0x4] --- MII local capability
872          *      SPI reg[0x12] = PHY[0x9] --- GMII control
873          */
874         ret = bcm539x_read_16(bd, REG_MII_PAGE + inst, (MII_ADVERTISE << 1), &local_cap);
875         if (ret) {
876                 return ret;
877         }
878         ret = bcm539x_read_16(bd, REG_MII_PAGE + inst, (MII_CTRL1000 << 1), &local_giga_cap);
879         if (ret) {
880                 return ret;
881         }
882
883         /* Configure to the requested speed */
884         if (strncmp(buf, "1000FD", 6) == 0) {
885                 /* speed */
886                 local_cap &= ~(ADVERTISE_10HALF | ADVERTISE_10FULL);
887                 local_cap &= ~(ADVERTISE_100HALF | ADVERTISE_100FULL);
888                 local_giga_cap |= (ADVERTISE_1000HALF | ADVERTISE_1000FULL);
889                 /* duplex */
890         } else if (strncmp(buf, "100FD", 5) == 0) {
891                 /* speed */
892                 local_cap &= ~(ADVERTISE_10HALF | ADVERTISE_10FULL);
893                 local_cap |= (ADVERTISE_100HALF | ADVERTISE_100FULL);
894                 local_giga_cap &= ~(ADVERTISE_1000HALF | ADVERTISE_1000FULL);
895                 /* duplex */
896                 local_cap &= ~(ADVERTISE_100HALF);
897         } else if (strncmp(buf, "100HD", 5) == 0) {
898                 /* speed */
899                 local_cap &= ~(ADVERTISE_10HALF | ADVERTISE_10FULL);
900                 local_cap |= (ADVERTISE_100HALF | ADVERTISE_100FULL);
901                 local_giga_cap &= ~(ADVERTISE_1000HALF | ADVERTISE_1000FULL);
902                 /* duplex */
903                 local_cap &= ~(ADVERTISE_100FULL);
904         } else if (strncmp(buf, "10FD", 4) == 0) {
905                 /* speed */
906                 local_cap |= (ADVERTISE_10HALF | ADVERTISE_10FULL);
907                 local_cap &= ~(ADVERTISE_100HALF | ADVERTISE_100FULL);
908                 local_giga_cap &= ~(ADVERTISE_1000HALF | ADVERTISE_1000FULL);
909                 /* duplex */
910                 local_cap &= ~(ADVERTISE_10HALF);
911         } else if (strncmp(buf, "10HD", 4) == 0) {
912                 /* speed */
913                 local_cap |= (ADVERTISE_10HALF | ADVERTISE_10FULL);
914                 local_cap &= ~(ADVERTISE_100HALF | ADVERTISE_100FULL);
915                 local_giga_cap &= ~(ADVERTISE_1000HALF | ADVERTISE_1000FULL);
916                 /* duplex */
917                 local_cap &= ~(ADVERTISE_10FULL);
918         } else if (strncmp(buf, "AUTO", 4) == 0) {
919                 /* speed */
920                 local_cap |= (ADVERTISE_10HALF | ADVERTISE_10FULL);
921                 local_cap |= (ADVERTISE_100HALF | ADVERTISE_100FULL);
922                 local_giga_cap |= (ADVERTISE_1000HALF | ADVERTISE_1000FULL);
923         } else {
924                 return -EINVAL;
925         }
926
927         /* Active PHY with the requested speed for auto-negotiation */
928         ret = bcm539x_write_16(bd, REG_MII_PAGE + inst, (MII_ADVERTISE << 1), local_cap);
929         if (ret) {
930                 return ret;
931         }
932         ret = bcm539x_write_16(bd, REG_MII_PAGE + inst, (MII_CTRL1000 << 1), local_giga_cap);
933         if (ret) {
934                 return ret;
935         }
936
937         ret = bcm539x_read_16(bd, REG_MII_PAGE + inst, (MII_BMCR << 1), &ctrl_word);
938         if (ret) {
939                 return ret;
940         }
941         ctrl_word |= (BMCR_ANENABLE | BMCR_ANRESTART);
942         ret = bcm539x_write_16(bd, REG_MII_PAGE + inst, (MII_BMCR << 1), ctrl_word);
943         if (ret) {
944                 return ret;
945         }
946
947         return 0;
948 }
949
950 /*
951  * proc_fs entries for this switch
952  */
953 static const struct switch_handler bcm539x_switch_handlers[] = {
954         {
955                 .name   = "enable",
956                 .read   = bcm539x_handle_enable_read,
957                 .write  = bcm539x_handle_enable_write,
958         },
959         {
960                 .name   = "enable_vlan",
961                 .read   = bcm539x_handle_enable_vlan_read,
962                 .write  = bcm539x_handle_enable_vlan_write,
963         },
964         {
965                 .name   = "reset",
966                 .write  = bcm539x_handle_reset,
967         },
968         {
969         },
970 };
971
972 /*
973  * Handlers for <this_driver>/vlan
974  */
975 static const struct switch_handler bcm539x_switch_handlers_vlan[] = {
976         {
977                 .name   = "delete",
978                 .write  = bcm539x_handle_vlan_delete_write,
979         },
980         {
981                 .name   = "create",
982                 .write  = bcm539x_handle_vlan_create_write,
983         },
984         {
985         },
986 };
987
988 /*
989  * Handlers for <this_driver>/port/<port number>
990  */
991 static const struct switch_handler bcm539x_switch_handlers_port[] = {
992         {
993                 .name   = "enable",
994                 .read   = bcm539x_handle_port_enable_read,
995                 .write  = bcm539x_handle_port_enable_write,
996         },
997         {
998                 .name   = "state",
999                 .read   = bcm539x_handle_port_state_read,
1000         },
1001         {
1002                 .name   = "media",
1003                 .read   = bcm539x_handle_port_media_read,
1004                 .write  = bcm539x_handle_port_meida_write,
1005         },
1006         {
1007         },
1008 };
1009
1010 /*
1011  * bcm539x_probe
1012  */
1013 static int __devinit bcm539x_probe(struct spi_device *spi)
1014 {
1015         struct bcm539x_data *bd;
1016         struct switch_core_platform_data *pdata;
1017         struct switch_device *switch_dev = NULL;
1018         int i, ret;
1019         u8_t txbuf[2];
1020
1021         pdata = spi->dev.platform_data;
1022         if (!pdata) {
1023                 return -EINVAL;
1024         }
1025
1026         ret = spi_setup(spi);
1027         if (ret < 0) {
1028                 return ret;
1029         }
1030
1031         /*
1032          * Reset the chip if requested
1033          */
1034         if (pdata->flags & SWITCH_DEV_FLAG_HW_RESET) {
1035                 ret = gpio_request(pdata->pin_reset, "switch-bcm539x-reset");
1036                 if (ret) {
1037                         printk(KERN_WARNING "Could not request reset\n");
1038                         return -EINVAL;
1039                 }
1040
1041                 gpio_direction_output(pdata->pin_reset, 0);
1042                 udelay(10);
1043                 gpio_set_value(pdata->pin_reset, 1);
1044                 udelay(20);
1045         }
1046
1047         /*
1048          * Allocate our private data structure
1049          */
1050         bd = kzalloc(sizeof(struct bcm539x_data), GFP_KERNEL);
1051         if (!bd) {
1052                 return -ENOMEM;
1053         }
1054
1055         dev_set_drvdata(&spi->dev, bd);
1056         bd->pdata = pdata;
1057         bd->spi = spi;
1058         bd->last_page = 0xFF;
1059
1060         /*
1061          * First perform SW reset if needed
1062          */
1063         if (pdata->flags & SWITCH_DEV_FLAG_SW_RESET) {
1064                 txbuf[0] = (1 << 7) | (1 << 4);
1065                 ret = bcm539x_write_bytes(bd, PAGE_PORT_TC,
1066                                           REG_CTRL_SRST, txbuf, 1);
1067                 if (ret) {
1068                         goto fail;
1069                 }
1070
1071                 udelay(20);
1072
1073                 txbuf[0] = 0;
1074                 ret = bcm539x_write_bytes(bd, PAGE_PORT_TC,
1075                                           REG_CTRL_SRST, txbuf, 1);
1076                 if (ret) {
1077                         goto fail;
1078                 }
1079         }
1080
1081         /*
1082          * See if we can see the chip
1083          */
1084         for (i = 0; i < 10; i++) {
1085                 ret = bcm539x_read_bytes(bd, PAGE_MMR, REG_DEVICE_ID,
1086                                          &bd->device_id, 1);
1087                 if (!ret) {
1088                         break;
1089                 }
1090         }
1091         if (ret) {
1092                 goto fail;
1093         }
1094
1095         /*
1096          * We only support 5395, 5397, 5398
1097          */
1098         if ((bd->device_id != 0x95) && (bd->device_id != 0x97) &&
1099             (bd->device_id != 0x98)) {
1100                 ret = -ENODEV;
1101                 goto fail;
1102         }
1103
1104         /*
1105          *  Override CPU port config: fixed link @1000 with flow control
1106          */
1107         ret = bcm539x_read_8(bd, PAGE_PORT_TC, REG_CTRL_MIIPO, txbuf);
1108         bcm539x_write_8(bd, PAGE_PORT_TC, REG_CTRL_MIIPO, 0xbb);        // Override IMP port config
1109         printk("Broadcom SW CPU port setting: 0x%x -> 0xbb\n", txbuf[0]);
1110
1111         /*
1112          * Setup the switch driver structure
1113          */
1114         switch_dev = switch_alloc();
1115         if (!switch_dev) {
1116                 ret = -ENOMEM;
1117                 goto fail;
1118         }
1119         switch_dev->name = pdata->name;
1120
1121         switch_dev->ports = (bd->device_id == 0x98) ? 9 : 6;
1122         switch_dev->port_mask[0] = (bd->device_id == 0x98) ? 0x1FF : 0x11F;
1123         switch_dev->driver_handlers = bcm539x_switch_handlers;
1124         switch_dev->reg_handlers = NULL;
1125         switch_dev->vlan_handlers = bcm539x_switch_handlers_vlan;
1126         switch_dev->port_handlers = bcm539x_switch_handlers_port;
1127
1128         bd->switch_dev = switch_dev;
1129         switch_set_drvdata(switch_dev, (void *)bd);
1130
1131         ret = switch_register(bd->switch_dev);
1132         if (ret < 0) {
1133                 goto fail;
1134         }
1135
1136         printk(KERN_INFO "bcm53%02x switch chip initialized\n", bd->device_id);
1137
1138         return ret;
1139
1140 fail:
1141         if (switch_dev) {
1142                 switch_release(switch_dev);
1143         }
1144         dev_set_drvdata(&spi->dev, NULL);
1145         kfree(bd);
1146         return ret;
1147 }
1148
1149 static int __attribute__((unused)) bcm539x_remove(struct spi_device *spi)
1150 {
1151         struct bcm539x_data *bd;
1152
1153         bd = dev_get_drvdata(&spi->dev);
1154
1155         if (bd->pdata->flags & SWITCH_DEV_FLAG_HW_RESET) {
1156                 gpio_free(bd->pdata->pin_reset);
1157         }
1158
1159         if (bd->switch_dev) {
1160                 switch_unregister(bd->switch_dev);
1161                 switch_release(bd->switch_dev);
1162         }
1163
1164         dev_set_drvdata(&spi->dev, NULL);
1165
1166         kfree(bd);
1167
1168         return 0;
1169 }
1170
1171 static struct spi_driver bcm539x_driver = {
1172         .driver = {
1173                 .name           = DRIVER_NAME,
1174                 .owner          = THIS_MODULE,
1175         },
1176         .probe          = bcm539x_probe,
1177         .remove         = __devexit_p(bcm539x_remove),
1178 };
1179
1180 static int __init bcm539x_init(void)
1181 {
1182         return spi_register_driver(&bcm539x_driver);
1183 }
1184
1185 module_init(bcm539x_init);
1186
1187 static void __exit bcm539x_exit(void)
1188 {
1189         spi_unregister_driver(&bcm539x_driver);
1190 }
1191 module_exit(bcm539x_exit);
1192
1193 MODULE_AUTHOR("Pat Tjin");
1194 MODULE_LICENSE("GPL v2");
1195 MODULE_DESCRIPTION("bcm539x SPI switch chip driver");