5
5
* Copyright (c) 2015 CMC Electronics, Inc.
6
6
* Added support for VLAN Table Unit operations
7
7
*
8
+ * Copyright (c) 2016 Andrew Lunn <[email protected] >
9
+ *
8
10
* This program is free software; you can redistribute it and/or modify
9
11
* it under the terms of the GNU General Public License as published by
10
12
* the Free Software Foundation; either version 2 of the License, or
17
19
#include <linux/if_bridge.h>
18
20
#include <linux/jiffies.h>
19
21
#include <linux/list.h>
22
+ #include <linux/mdio.h>
20
23
#include <linux/module.h>
21
24
#include <linux/netdevice.h>
22
25
#include <linux/gpio/consumer.h>
@@ -866,6 +869,16 @@ static int mv88e6xxx_read_eeprom_word(struct dsa_switch *ds, int addr)
866
869
return ret ;
867
870
}
868
871
872
+ static int mv88e6xxx_get_eeprom_len (struct dsa_switch * ds )
873
+ {
874
+ struct mv88e6xxx_priv_state * ps = ds_to_priv (ds );
875
+
876
+ if (mv88e6xxx_has (ps , MV88E6XXX_FLAG_EEPROM ))
877
+ return ps -> eeprom_len ;
878
+
879
+ return 0 ;
880
+ }
881
+
869
882
static int mv88e6xxx_get_eeprom (struct dsa_switch * ds ,
870
883
struct ethtool_eeprom * eeprom , u8 * data )
871
884
{
@@ -2579,7 +2592,7 @@ static int mv88e6xxx_switch_reset(struct mv88e6xxx_priv_state *ps)
2579
2592
{
2580
2593
bool ppu_active = mv88e6xxx_has (ps , MV88E6XXX_FLAG_PPU_ACTIVE );
2581
2594
u16 is_reset = (ppu_active ? 0x8800 : 0xc800 );
2582
- struct gpio_desc * gpiod = ps -> ds -> pd -> reset ;
2595
+ struct gpio_desc * gpiod = ps -> reset ;
2583
2596
unsigned long timeout ;
2584
2597
int ret ;
2585
2598
int i ;
@@ -3020,9 +3033,9 @@ static int mv88e6xxx_setup_global(struct mv88e6xxx_priv_state *ps)
3020
3033
for (i = 0 ; i < 32 ; i ++ ) {
3021
3034
int nexthop = 0x1f ;
3022
3035
3023
- if (ps -> ds -> pd -> rtable &&
3036
+ if (ps -> ds -> cd -> rtable &&
3024
3037
i != ps -> ds -> index && i < ps -> ds -> dst -> pd -> nr_chips )
3025
- nexthop = ps -> ds -> pd -> rtable [i ] & 0x1f ;
3038
+ nexthop = ps -> ds -> cd -> rtable [i ] & 0x1f ;
3026
3039
3027
3040
err = _mv88e6xxx_reg_write (
3028
3041
ps , REG_GLOBAL2 ,
@@ -3132,8 +3145,6 @@ static int mv88e6xxx_setup(struct dsa_switch *ds)
3132
3145
3133
3146
ps -> ds = ds ;
3134
3147
3135
- mutex_init (& ps -> smi_mutex );
3136
-
3137
3148
INIT_WORK (& ps -> bridge_work , mv88e6xxx_bridge_work );
3138
3149
3139
3150
if (mv88e6xxx_has (ps , MV88E6XXX_FLAG_EEPROM ))
@@ -3545,9 +3556,9 @@ mv88e6xxx_lookup_info(unsigned int prod_num, const struct mv88e6xxx_info *table,
3545
3556
return NULL ;
3546
3557
}
3547
3558
3548
- static const char * mv88e6xxx_probe (struct device * dsa_dev ,
3549
- struct device * host_dev , int sw_addr ,
3550
- void * * priv )
3559
+ static const char * mv88e6xxx_drv_probe (struct device * dsa_dev ,
3560
+ struct device * host_dev , int sw_addr ,
3561
+ void * * priv )
3551
3562
{
3552
3563
const struct mv88e6xxx_info * info ;
3553
3564
struct mv88e6xxx_priv_state * ps ;
@@ -3580,6 +3591,7 @@ static const char *mv88e6xxx_probe(struct device *dsa_dev,
3580
3591
ps -> bus = bus ;
3581
3592
ps -> sw_addr = sw_addr ;
3582
3593
ps -> info = info ;
3594
+ mutex_init (& ps -> smi_mutex );
3583
3595
3584
3596
* priv = ps ;
3585
3597
@@ -3591,7 +3603,7 @@ static const char *mv88e6xxx_probe(struct device *dsa_dev,
3591
3603
3592
3604
struct dsa_switch_driver mv88e6xxx_switch_driver = {
3593
3605
.tag_protocol = DSA_TAG_PROTO_EDSA ,
3594
- .probe = mv88e6xxx_probe ,
3606
+ .probe = mv88e6xxx_drv_probe ,
3595
3607
.setup = mv88e6xxx_setup ,
3596
3608
.set_addr = mv88e6xxx_set_addr ,
3597
3609
.phy_read = mv88e6xxx_phy_read ,
@@ -3608,6 +3620,7 @@ struct dsa_switch_driver mv88e6xxx_switch_driver = {
3608
3620
.set_temp_limit = mv88e6xxx_set_temp_limit ,
3609
3621
.get_temp_alarm = mv88e6xxx_get_temp_alarm ,
3610
3622
#endif
3623
+ .get_eeprom_len = mv88e6xxx_get_eeprom_len ,
3611
3624
.get_eeprom = mv88e6xxx_get_eeprom ,
3612
3625
.set_eeprom = mv88e6xxx_set_eeprom ,
3613
3626
.get_regs_len = mv88e6xxx_get_regs_len ,
@@ -3626,36 +3639,106 @@ struct dsa_switch_driver mv88e6xxx_switch_driver = {
3626
3639
.port_fdb_dump = mv88e6xxx_port_fdb_dump ,
3627
3640
};
3628
3641
3629
- static int __init mv88e6xxx_init ( void )
3642
+ int mv88e6xxx_probe ( struct mdio_device * mdiodev )
3630
3643
{
3631
- register_switch_driver (& mv88e6xxx_switch_driver );
3644
+ struct device * dev = & mdiodev -> dev ;
3645
+ struct device_node * np = dev -> of_node ;
3646
+ struct mv88e6xxx_priv_state * ps ;
3647
+ int id , prod_num , rev ;
3648
+ struct dsa_switch * ds ;
3649
+ u32 eeprom_len ;
3650
+ int err ;
3651
+
3652
+ ds = devm_kzalloc (dev , sizeof (* ds ) + sizeof (* ps ), GFP_KERNEL );
3653
+ if (!ds )
3654
+ return - ENOMEM ;
3655
+
3656
+ ps = (struct mv88e6xxx_priv_state * )(ds + 1 );
3657
+ ds -> priv = ps ;
3658
+ ds -> dev = dev ;
3659
+ ps -> dev = dev ;
3660
+ ps -> ds = ds ;
3661
+ ps -> bus = mdiodev -> bus ;
3662
+ ps -> sw_addr = mdiodev -> addr ;
3663
+ mutex_init (& ps -> smi_mutex );
3664
+
3665
+ get_device (& ps -> bus -> dev );
3666
+
3667
+ ds -> drv = & mv88e6xxx_switch_driver ;
3668
+
3669
+ id = mv88e6xxx_reg_read (ps , REG_PORT (0 ), PORT_SWITCH_ID );
3670
+ if (id < 0 )
3671
+ return id ;
3672
+
3673
+ prod_num = (id & 0xfff0 ) >> 4 ;
3674
+ rev = id & 0x000f ;
3675
+
3676
+ ps -> info = mv88e6xxx_lookup_info (prod_num , mv88e6xxx_table ,
3677
+ ARRAY_SIZE (mv88e6xxx_table ));
3678
+ if (!ps -> info )
3679
+ return - ENODEV ;
3680
+
3681
+ ps -> reset = devm_gpiod_get (& mdiodev -> dev , "reset" , GPIOD_ASIS );
3682
+ if (IS_ERR (ps -> reset )) {
3683
+ err = PTR_ERR (ps -> reset );
3684
+ if (err == - ENOENT ) {
3685
+ /* Optional, so not an error */
3686
+ ps -> reset = NULL ;
3687
+ } else {
3688
+ return err ;
3689
+ }
3690
+ }
3691
+
3692
+ if (mv88e6xxx_has (ps , MV88E6XXX_FLAG_EEPROM ) &&
3693
+ !of_property_read_u32 (np , "eeprom-length" , & eeprom_len ))
3694
+ ps -> eeprom_len = eeprom_len ;
3695
+
3696
+ dev_set_drvdata (dev , ds );
3697
+
3698
+ dev_info (dev , "switch 0x%x probed: %s, revision %u\n" ,
3699
+ prod_num , ps -> info -> name , rev );
3632
3700
3633
3701
return 0 ;
3634
3702
}
3703
+
3704
+ static void mv88e6xxx_remove (struct mdio_device * mdiodev )
3705
+ {
3706
+ struct dsa_switch * ds = dev_get_drvdata (& mdiodev -> dev );
3707
+ struct mv88e6xxx_priv_state * ps = ds_to_priv (ds );
3708
+
3709
+ put_device (& ps -> bus -> dev );
3710
+ }
3711
+
3712
+ static const struct of_device_id mv88e6xxx_of_match [] = {
3713
+ { .compatible = "marvell,mv88e6085" },
3714
+ { /* sentinel */ },
3715
+ };
3716
+
3717
+ MODULE_DEVICE_TABLE (of , mv88e6xxx_of_match );
3718
+
3719
+ static struct mdio_driver mv88e6xxx_driver = {
3720
+ .probe = mv88e6xxx_probe ,
3721
+ .remove = mv88e6xxx_remove ,
3722
+ .mdiodrv .driver = {
3723
+ .name = "mv88e6085" ,
3724
+ .of_match_table = mv88e6xxx_of_match ,
3725
+ },
3726
+ };
3727
+
3728
+ static int __init mv88e6xxx_init (void )
3729
+ {
3730
+ register_switch_driver (& mv88e6xxx_switch_driver );
3731
+ return mdio_driver_register (& mv88e6xxx_driver );
3732
+ }
3635
3733
module_init (mv88e6xxx_init );
3636
3734
3637
3735
static void __exit mv88e6xxx_cleanup (void )
3638
3736
{
3737
+ mdio_driver_unregister (& mv88e6xxx_driver );
3639
3738
unregister_switch_driver (& mv88e6xxx_switch_driver );
3640
3739
}
3641
3740
module_exit (mv88e6xxx_cleanup );
3642
3741
3643
- MODULE_ALIAS ("platform:mv88e6085" );
3644
- MODULE_ALIAS ("platform:mv88e6095" );
3645
- MODULE_ALIAS ("platform:mv88e6095f" );
3646
- MODULE_ALIAS ("platform:mv88e6123" );
3647
- MODULE_ALIAS ("platform:mv88e6131" );
3648
- MODULE_ALIAS ("platform:mv88e6161" );
3649
- MODULE_ALIAS ("platform:mv88e6165" );
3650
- MODULE_ALIAS ("platform:mv88e6171" );
3651
- MODULE_ALIAS ("platform:mv88e6172" );
3652
- MODULE_ALIAS ("platform:mv88e6175" );
3653
- MODULE_ALIAS ("platform:mv88e6176" );
3654
- MODULE_ALIAS ("platform:mv88e6320" );
3655
- MODULE_ALIAS ("platform:mv88e6321" );
3656
- MODULE_ALIAS ("platform:mv88e6350" );
3657
- MODULE_ALIAS ("platform:mv88e6351" );
3658
- MODULE_ALIAS ("platform:mv88e6352" );
3659
3742
MODULE_AUTHOR (
"Lennert Buytenhek <[email protected] >" );
3660
3743
MODULE_DESCRIPTION ("Driver for Marvell 88E6XXX ethernet switch chips" );
3661
3744
MODULE_LICENSE ("GPL" );
0 commit comments