diff mbox series

[net-next,2/3] net: dsa: mv88e6xxx: return error instead of lane in .serdes_get_lane

Message ID 20200819153816.30834-3-marek.behun@nic.cz
State Changes Requested
Delegated to: David Miller
Headers show
Series net: dsa: mv88e6xxx: Add Amethyst 88E6393X | expand

Commit Message

Marek Behún Aug. 19, 2020, 3:38 p.m. UTC
Currently the .serdes_get_lane method gets the lane as the result of the
method, returning 0 if no SERDES is on given port.

This was okay till now, because on no mv88e6xxx switch were it possible
to have SERDES on port/lane 0. But it becomes incompatible with
88E6393X, on which the SERDES ports are ports 0, 9 and 10 with lanes
0, 9 and 10, respectively.

This patch therefore changes the .serdes_get_lane method API so that it
returns 0 on success (if a lane is found) and -ENODEV otherwise. The
lane itself is stored into a place pointed to by a parameter.

Signed-off-by: Marek Behún <marek.behun@nic.cz>
---
 drivers/net/dsa/mv88e6xxx/chip.c   | 33 +++++++------
 drivers/net/dsa/mv88e6xxx/chip.h   |  2 +-
 drivers/net/dsa/mv88e6xxx/port.c   | 10 ++--
 drivers/net/dsa/mv88e6xxx/serdes.c | 78 +++++++++++++++---------------
 drivers/net/dsa/mv88e6xxx/serdes.h | 16 +++---
 5 files changed, 72 insertions(+), 67 deletions(-)

Comments

kernel test robot Aug. 19, 2020, 10:12 p.m. UTC | #1
Hi "Marek,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on net-next/master]

url:    https://github.com/0day-ci/linux/commits/Marek-Beh-n/net-dsa-mv88e6xxx-Add-Amethyst-88E6393X/20200819-234008
base:   https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git e3ec1e8ca02b7e6c935bba3f9b6da86c2e57d2eb
config: x86_64-randconfig-a006-20200818 (attached as .config)
compiler: clang version 12.0.0 (https://github.com/llvm/llvm-project b34b1e38381fa4d1b1d9751a6b5233b68e734cfe)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install x86_64 cross compiling tool for clang build
        # apt-get install binutils-x86-64-linux-gnu
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=x86_64 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

>> drivers/net/dsa/mv88e6xxx/serdes.c:428:15: warning: result of comparison of constant -1 with expression of type 'u8' (aka 'unsigned char') is always false [-Wtautological-constant-out-of-range-compare]
           return *lane == -1 ? -ENODEV : 0;
                  ~~~~~ ^  ~~
   drivers/net/dsa/mv88e6xxx/serdes.c:451:15: warning: result of comparison of constant -1 with expression of type 'u8' (aka 'unsigned char') is always false [-Wtautological-constant-out-of-range-compare]
           return *lane == -1 ? -ENODEV : 0;
                  ~~~~~ ^  ~~
   drivers/net/dsa/mv88e6xxx/serdes.c:526:15: warning: result of comparison of constant -1 with expression of type 'u8' (aka 'unsigned char') is always false [-Wtautological-constant-out-of-range-compare]
           return *lane == -1 ? -ENODEV : 0;
                  ~~~~~ ^  ~~
   3 warnings generated.

# https://github.com/0day-ci/linux/commit/a63db5e9b7db608109e7a315dfde9e57df682a20
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Marek-Beh-n/net-dsa-mv88e6xxx-Add-Amethyst-88E6393X/20200819-234008
git checkout a63db5e9b7db608109e7a315dfde9e57df682a20
vim +428 drivers/net/dsa/mv88e6xxx/serdes.c

   413	
   414	int mv88e6341_serdes_get_lane(struct mv88e6xxx_chip *chip, int port, u8 *lane)
   415	{
   416		u8 cmode = chip->ports[port].cmode;
   417	
   418		*lane = -1;
   419		switch (port) {
   420		case 5:
   421			if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
   422			    cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
   423			    cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
   424				*lane = MV88E6341_PORT5_LANE;
   425			break;
   426		}
   427	
 > 428		return *lane == -1 ? -ENODEV : 0;
   429	}
   430	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
Dan Carpenter Aug. 31, 2020, 10:11 a.m. UTC | #2
Hi "Marek,

url:    https://github.com/0day-ci/linux/commits/Marek-Beh-n/net-dsa-mv88e6xxx-Add-Amethyst-88E6393X/20200819-234008
base:   https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git e3ec1e8ca02b7e6c935bba3f9b6da86c2e57d2eb
config: openrisc-randconfig-m031-20200827 (attached as .config)
compiler: or1k-linux-gcc (GCC) 9.3.0

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>

smatch warnings:
drivers/net/dsa/mv88e6xxx/serdes.c:428 mv88e6341_serdes_get_lane() warn: impossible condition '(*lane == -1) => (0-255 == (-1))'
drivers/net/dsa/mv88e6xxx/serdes.c:451 mv88e6390_serdes_get_lane() warn: impossible condition '(*lane == -1) => (0-255 == (-1))'
drivers/net/dsa/mv88e6xxx/serdes.c:526 mv88e6390x_serdes_get_lane() warn: impossible condition '(*lane == -1) => (0-255 == (-1))'

# https://github.com/0day-ci/linux/commit/a63db5e9b7db608109e7a315dfde9e57df682a20
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Marek-Beh-n/net-dsa-mv88e6xxx-Add-Amethyst-88E6393X/20200819-234008
git checkout a63db5e9b7db608109e7a315dfde9e57df682a20
vim +428 drivers/net/dsa/mv88e6xxx/serdes.c

a63db5e9b7db60 Marek Behún    2020-08-19  414  int mv88e6341_serdes_get_lane(struct mv88e6xxx_chip *chip, int port, u8 *lane)
                                                                                                                    ^^^^^^^^

d3cf7d8f20b493 Marek Behún    2019-08-26  415  {
d3cf7d8f20b493 Marek Behún    2019-08-26  416  	u8 cmode = chip->ports[port].cmode;
d3cf7d8f20b493 Marek Behún    2019-08-26  417  
a63db5e9b7db60 Marek Behún    2020-08-19  418  	*lane = -1;
5122d4ec9e8053 Vivien Didelot 2019-08-31  419  	switch (port) {
5122d4ec9e8053 Vivien Didelot 2019-08-31  420  	case 5:
3bbb8867f87d91 Marek Behún    2019-08-26  421  		if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
d3cf7d8f20b493 Marek Behún    2019-08-26  422  		    cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
5122d4ec9e8053 Vivien Didelot 2019-08-31  423  		    cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
a63db5e9b7db60 Marek Behún    2020-08-19  424  			*lane = MV88E6341_PORT5_LANE;
5122d4ec9e8053 Vivien Didelot 2019-08-31  425  		break;
d3cf7d8f20b493 Marek Behún    2019-08-26  426  	}
d3cf7d8f20b493 Marek Behún    2019-08-26  427  
a63db5e9b7db60 Marek Behún    2020-08-19 @428  	return *lane == -1 ? -ENODEV : 0;
                                                       ^^^^^^^^^^^
A u8 can't be == -1 #Impossible

d3cf7d8f20b493 Marek Behún    2019-08-26  429  }
d3cf7d8f20b493 Marek Behún    2019-08-26  430  
a63db5e9b7db60 Marek Behún    2020-08-19  431  int mv88e6390_serdes_get_lane(struct mv88e6xxx_chip *chip, int port, u8 *lane)
07ffbd74d1786d Andrew Lunn    2018-08-09  432  {
2d2e1dd29962ce Andrew Lunn    2018-08-09  433  	u8 cmode = chip->ports[port].cmode;
07ffbd74d1786d Andrew Lunn    2018-08-09  434  
a63db5e9b7db60 Marek Behún    2020-08-19  435  	*lane = -1;
07ffbd74d1786d Andrew Lunn    2018-08-09  436  	switch (port) {
07ffbd74d1786d Andrew Lunn    2018-08-09  437  	case 9:
3bbb8867f87d91 Marek Behún    2019-08-26  438  		if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
07ffbd74d1786d Andrew Lunn    2018-08-09  439  		    cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
5122d4ec9e8053 Vivien Didelot 2019-08-31  440  		    cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
a63db5e9b7db60 Marek Behún    2020-08-19  441  			*lane = MV88E6390_PORT9_LANE0;
17deaf5cb37a36 Marek Behún    2019-08-26  442  		break;
07ffbd74d1786d Andrew Lunn    2018-08-09  443  	case 10:
3bbb8867f87d91 Marek Behún    2019-08-26  444  		if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
07ffbd74d1786d Andrew Lunn    2018-08-09  445  		    cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
5122d4ec9e8053 Vivien Didelot 2019-08-31  446  		    cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
a63db5e9b7db60 Marek Behún    2020-08-19  447  			*lane = MV88E6390_PORT10_LANE0;
17deaf5cb37a36 Marek Behún    2019-08-26  448  		break;
07ffbd74d1786d Andrew Lunn    2018-08-09  449  	}
17deaf5cb37a36 Marek Behún    2019-08-26  450  
a63db5e9b7db60 Marek Behún    2020-08-19 @451  	return *lane == -1 ? -ENODEV : 0;
07ffbd74d1786d Andrew Lunn    2018-08-09  452  }
07ffbd74d1786d Andrew Lunn    2018-08-09  453  
a63db5e9b7db60 Marek Behún    2020-08-19  454  int mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port, u8 *lane)
a8c01c0d941d2f Andrew Lunn    2018-08-09  455  {
5122d4ec9e8053 Vivien Didelot 2019-08-31  456  	u8 cmode_port = chip->ports[port].cmode;
5122d4ec9e8053 Vivien Didelot 2019-08-31  457  	u8 cmode_port10 = chip->ports[10].cmode;
5122d4ec9e8053 Vivien Didelot 2019-08-31  458  	u8 cmode_port9 = chip->ports[9].cmode;
a8c01c0d941d2f Andrew Lunn    2018-08-09  459  
a63db5e9b7db60 Marek Behún    2020-08-19  460  	*lane = -1;
a8c01c0d941d2f Andrew Lunn    2018-08-09  461  	switch (port) {
a8c01c0d941d2f Andrew Lunn    2018-08-09  462  	case 2:
3bbb8867f87d91 Marek Behún    2019-08-26  463  		if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
a8c01c0d941d2f Andrew Lunn    2018-08-09  464  		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
5122d4ec9e8053 Vivien Didelot 2019-08-31  465  		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
5122d4ec9e8053 Vivien Didelot 2019-08-31  466  			if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
a63db5e9b7db60 Marek Behún    2020-08-19  467  				*lane = MV88E6390_PORT9_LANE1;
17deaf5cb37a36 Marek Behún    2019-08-26  468  		break;
a8c01c0d941d2f Andrew Lunn    2018-08-09  469  	case 3:
3bbb8867f87d91 Marek Behún    2019-08-26  470  		if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
a8c01c0d941d2f Andrew Lunn    2018-08-09  471  		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
a8c01c0d941d2f Andrew Lunn    2018-08-09  472  		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
5122d4ec9e8053 Vivien Didelot 2019-08-31  473  		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
5122d4ec9e8053 Vivien Didelot 2019-08-31  474  			if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
a63db5e9b7db60 Marek Behún    2020-08-19  475  				*lane = MV88E6390_PORT9_LANE2;
17deaf5cb37a36 Marek Behún    2019-08-26  476  		break;
a8c01c0d941d2f Andrew Lunn    2018-08-09  477  	case 4:
3bbb8867f87d91 Marek Behún    2019-08-26  478  		if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
a8c01c0d941d2f Andrew Lunn    2018-08-09  479  		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
a8c01c0d941d2f Andrew Lunn    2018-08-09  480  		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
5122d4ec9e8053 Vivien Didelot 2019-08-31  481  		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
5122d4ec9e8053 Vivien Didelot 2019-08-31  482  			if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
a63db5e9b7db60 Marek Behún    2020-08-19  483  				*lane = MV88E6390_PORT9_LANE3;
17deaf5cb37a36 Marek Behún    2019-08-26  484  		break;
a8c01c0d941d2f Andrew Lunn    2018-08-09  485  	case 5:
3bbb8867f87d91 Marek Behún    2019-08-26  486  		if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
a8c01c0d941d2f Andrew Lunn    2018-08-09  487  		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
5122d4ec9e8053 Vivien Didelot 2019-08-31  488  		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
5122d4ec9e8053 Vivien Didelot 2019-08-31  489  			if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
a63db5e9b7db60 Marek Behún    2020-08-19  490  				*lane = MV88E6390_PORT10_LANE1;
17deaf5cb37a36 Marek Behún    2019-08-26  491  		break;
a8c01c0d941d2f Andrew Lunn    2018-08-09  492  	case 6:
3bbb8867f87d91 Marek Behún    2019-08-26  493  		if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
a8c01c0d941d2f Andrew Lunn    2018-08-09  494  		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
a8c01c0d941d2f Andrew Lunn    2018-08-09  495  		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
5122d4ec9e8053 Vivien Didelot 2019-08-31  496  		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
5122d4ec9e8053 Vivien Didelot 2019-08-31  497  			if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
a63db5e9b7db60 Marek Behún    2020-08-19  498  				*lane = MV88E6390_PORT10_LANE2;
17deaf5cb37a36 Marek Behún    2019-08-26  499  		break;
a8c01c0d941d2f Andrew Lunn    2018-08-09  500  	case 7:
3bbb8867f87d91 Marek Behún    2019-08-26  501  		if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
a8c01c0d941d2f Andrew Lunn    2018-08-09  502  		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
a8c01c0d941d2f Andrew Lunn    2018-08-09  503  		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
5122d4ec9e8053 Vivien Didelot 2019-08-31  504  		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
5122d4ec9e8053 Vivien Didelot 2019-08-31  505  			if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
a63db5e9b7db60 Marek Behún    2020-08-19  506  				*lane = MV88E6390_PORT10_LANE3;
17deaf5cb37a36 Marek Behún    2019-08-26  507  		break;
a8c01c0d941d2f Andrew Lunn    2018-08-09  508  	case 9:
3bbb8867f87d91 Marek Behún    2019-08-26  509  		if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
a8c01c0d941d2f Andrew Lunn    2018-08-09  510  		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
a8c01c0d941d2f Andrew Lunn    2018-08-09  511  		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
a8c01c0d941d2f Andrew Lunn    2018-08-09  512  		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_XAUI ||
5122d4ec9e8053 Vivien Didelot 2019-08-31  513  		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
a63db5e9b7db60 Marek Behún    2020-08-19  514  			*lane = MV88E6390_PORT9_LANE0;
17deaf5cb37a36 Marek Behún    2019-08-26  515  		break;
a8c01c0d941d2f Andrew Lunn    2018-08-09  516  	case 10:
3bbb8867f87d91 Marek Behún    2019-08-26  517  		if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
a8c01c0d941d2f Andrew Lunn    2018-08-09  518  		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
a8c01c0d941d2f Andrew Lunn    2018-08-09  519  		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
a8c01c0d941d2f Andrew Lunn    2018-08-09  520  		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_XAUI ||
5122d4ec9e8053 Vivien Didelot 2019-08-31  521  		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
a63db5e9b7db60 Marek Behún    2020-08-19  522  			*lane = MV88E6390_PORT10_LANE0;
17deaf5cb37a36 Marek Behún    2019-08-26  523  		break;
a8c01c0d941d2f Andrew Lunn    2018-08-09  524  	}
17deaf5cb37a36 Marek Behún    2019-08-26  525  
a63db5e9b7db60 Marek Behún    2020-08-19 @526  	return *lane == -1 ? -ENODEV : 0;
a8c01c0d941d2f Andrew Lunn    2018-08-09  527  }

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
diff mbox series

Patch

diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 7a71c9902e73e..0a5e2740a79db 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -487,13 +487,14 @@  static int mv88e6xxx_serdes_pcs_get_state(struct dsa_switch *ds, int port,
 	u8 lane;
 	int err;
 
+	if (!chip->info->ops->serdes_pcs_get_state)
+		return -EOPNOTSUPP;
+
 	mv88e6xxx_reg_lock(chip);
-	lane = mv88e6xxx_serdes_get_lane(chip, port);
-	if (lane && chip->info->ops->serdes_pcs_get_state)
+	err = mv88e6xxx_serdes_get_lane(chip, port, &lane);
+	if (!err)
 		err = chip->info->ops->serdes_pcs_get_state(chip, port, lane,
 							    state);
-	else
-		err = -EOPNOTSUPP;
 	mv88e6xxx_reg_unlock(chip);
 
 	return err;
@@ -505,11 +506,12 @@  static int mv88e6xxx_serdes_pcs_config(struct mv88e6xxx_chip *chip, int port,
 				       const unsigned long *advertise)
 {
 	const struct mv88e6xxx_ops *ops = chip->info->ops;
+	int err;
 	u8 lane;
 
 	if (ops->serdes_pcs_config) {
-		lane = mv88e6xxx_serdes_get_lane(chip, port);
-		if (lane)
+		err = mv88e6xxx_serdes_get_lane(chip, port, &lane);
+		if (!err)
 			return ops->serdes_pcs_config(chip, port, lane, mode,
 						      interface, advertise);
 	}
@@ -528,8 +530,8 @@  static void mv88e6xxx_serdes_pcs_an_restart(struct dsa_switch *ds, int port)
 
 	if (ops->serdes_pcs_an_restart) {
 		mv88e6xxx_reg_lock(chip);
-		lane = mv88e6xxx_serdes_get_lane(chip, port);
-		if (lane)
+		err = mv88e6xxx_serdes_get_lane(chip, port, &lane);
+		if (!err)
 			err = ops->serdes_pcs_an_restart(chip, port, lane);
 		mv88e6xxx_reg_unlock(chip);
 
@@ -543,11 +545,12 @@  static int mv88e6xxx_serdes_pcs_link_up(struct mv88e6xxx_chip *chip, int port,
 					int speed, int duplex)
 {
 	const struct mv88e6xxx_ops *ops = chip->info->ops;
+	int err;
 	u8 lane;
 
 	if (!phylink_autoneg_inband(mode) && ops->serdes_pcs_link_up) {
-		lane = mv88e6xxx_serdes_get_lane(chip, port);
-		if (lane)
+		err = mv88e6xxx_serdes_get_lane(chip, port, &lane);
+		if (!err)
 			return ops->serdes_pcs_link_up(chip, port, lane,
 						       speed, duplex);
 	}
@@ -2423,12 +2426,12 @@  static irqreturn_t mv88e6xxx_serdes_irq_thread_fn(int irq, void *dev_id)
 	struct mv88e6xxx_port *mvp = dev_id;
 	struct mv88e6xxx_chip *chip = mvp->chip;
 	irqreturn_t ret = IRQ_NONE;
-	int port = mvp->port;
+	int port = mvp->port, err;
 	u8 lane;
 
 	mv88e6xxx_reg_lock(chip);
-	lane = mv88e6xxx_serdes_get_lane(chip, port);
-	if (lane)
+	err = mv88e6xxx_serdes_get_lane(chip, port, &lane);
+	if (!err)
 		ret = mv88e6xxx_serdes_irq_status(chip, port, lane);
 	mv88e6xxx_reg_unlock(chip);
 
@@ -2493,8 +2496,8 @@  static int mv88e6xxx_serdes_power(struct mv88e6xxx_chip *chip, int port,
 	u8 lane;
 	int err;
 
-	lane = mv88e6xxx_serdes_get_lane(chip, port);
-	if (!lane)
+	err = mv88e6xxx_serdes_get_lane(chip, port, &lane);
+	if (err)
 		return 0;
 
 	if (on) {
diff --git a/drivers/net/dsa/mv88e6xxx/chip.h b/drivers/net/dsa/mv88e6xxx/chip.h
index 823ae89e5fcac..cc23810438dfe 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.h
+++ b/drivers/net/dsa/mv88e6xxx/chip.h
@@ -494,7 +494,7 @@  struct mv88e6xxx_ops {
 			    bool up);
 
 	/* SERDES lane mapping */
-	u8 (*serdes_get_lane)(struct mv88e6xxx_chip *chip, int port);
+	int (*serdes_get_lane)(struct mv88e6xxx_chip *chip, int port, u8 *lane);
 
 	int (*serdes_pcs_get_state)(struct mv88e6xxx_chip *chip, int port,
 				    u8 lane, struct phylink_link_state *state);
diff --git a/drivers/net/dsa/mv88e6xxx/port.c b/drivers/net/dsa/mv88e6xxx/port.c
index 8128dc607cf46..9d5189f2474ce 100644
--- a/drivers/net/dsa/mv88e6xxx/port.c
+++ b/drivers/net/dsa/mv88e6xxx/port.c
@@ -429,8 +429,8 @@  static int mv88e6xxx_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
 	if (cmode == chip->ports[port].cmode && !force)
 		return 0;
 
-	lane = mv88e6xxx_serdes_get_lane(chip, port);
-	if (lane) {
+	err = mv88e6xxx_serdes_get_lane(chip, port, &lane);
+	if (!err) {
 		if (chip->ports[port].serdes_irq) {
 			err = mv88e6xxx_serdes_irq_disable(chip, port, lane);
 			if (err)
@@ -458,9 +458,9 @@  static int mv88e6xxx_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
 
 		chip->ports[port].cmode = cmode;
 
-		lane = mv88e6xxx_serdes_get_lane(chip, port);
-		if (!lane)
-			return -ENODEV;
+		err = mv88e6xxx_serdes_get_lane(chip, port, &lane);
+		if (err)
+			return err;
 
 		err = mv88e6xxx_serdes_power_up(chip, port, lane);
 		if (err)
diff --git a/drivers/net/dsa/mv88e6xxx/serdes.c b/drivers/net/dsa/mv88e6xxx/serdes.c
index 9c07b4f3d3454..9074d1097b614 100644
--- a/drivers/net/dsa/mv88e6xxx/serdes.c
+++ b/drivers/net/dsa/mv88e6xxx/serdes.c
@@ -230,25 +230,25 @@  int mv88e6352_serdes_pcs_link_up(struct mv88e6xxx_chip *chip, int port,
 	return mv88e6352_serdes_write(chip, MII_BMCR, bmcr);
 }
 
-u8 mv88e6352_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
+int mv88e6352_serdes_get_lane(struct mv88e6xxx_chip *chip, int port, u8 *lane)
 {
 	u8 cmode = chip->ports[port].cmode;
-	u8 lane = 0;
 
 	if ((cmode == MV88E6XXX_PORT_STS_CMODE_100BASEX) ||
 	    (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX) ||
-	    (cmode == MV88E6XXX_PORT_STS_CMODE_SGMII))
-		lane = 0xff; /* Unused */
+	    (cmode == MV88E6XXX_PORT_STS_CMODE_SGMII)) {
+		*lane = 0xff; /* Unused */
+		return 0;
+	}
 
-	return lane;
+	return -ENODEV;
 }
 
 static bool mv88e6352_port_has_serdes(struct mv88e6xxx_chip *chip, int port)
 {
-	if (mv88e6xxx_serdes_get_lane(chip, port))
-		return true;
+	u8 lane;
 
-	return false;
+	return !mv88e6xxx_serdes_get_lane(chip, port, &lane);
 }
 
 struct mv88e6352_serdes_hw_stat {
@@ -411,60 +411,60 @@  void mv88e6352_serdes_get_regs(struct mv88e6xxx_chip *chip, int port, void *_p)
 	}
 }
 
-u8 mv88e6341_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
+int mv88e6341_serdes_get_lane(struct mv88e6xxx_chip *chip, int port, u8 *lane)
 {
 	u8 cmode = chip->ports[port].cmode;
-	u8 lane = 0;
 
+	*lane = -1;
 	switch (port) {
 	case 5:
 		if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
 		    cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
 		    cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
-			lane = MV88E6341_PORT5_LANE;
+			*lane = MV88E6341_PORT5_LANE;
 		break;
 	}
 
-	return lane;
+	return *lane == -1 ? -ENODEV : 0;
 }
 
-u8 mv88e6390_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
+int mv88e6390_serdes_get_lane(struct mv88e6xxx_chip *chip, int port, u8 *lane)
 {
 	u8 cmode = chip->ports[port].cmode;
-	u8 lane = 0;
 
+	*lane = -1;
 	switch (port) {
 	case 9:
 		if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
 		    cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
 		    cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
-			lane = MV88E6390_PORT9_LANE0;
+			*lane = MV88E6390_PORT9_LANE0;
 		break;
 	case 10:
 		if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
 		    cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
 		    cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
-			lane = MV88E6390_PORT10_LANE0;
+			*lane = MV88E6390_PORT10_LANE0;
 		break;
 	}
 
-	return lane;
+	return *lane == -1 ? -ENODEV : 0;
 }
 
-u8 mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
+int mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port, u8 *lane)
 {
 	u8 cmode_port = chip->ports[port].cmode;
 	u8 cmode_port10 = chip->ports[10].cmode;
 	u8 cmode_port9 = chip->ports[9].cmode;
-	u8 lane = 0;
 
+	*lane = -1;
 	switch (port) {
 	case 2:
 		if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
 			if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
-				lane = MV88E6390_PORT9_LANE1;
+				*lane = MV88E6390_PORT9_LANE1;
 		break;
 	case 3:
 		if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
@@ -472,7 +472,7 @@  u8 mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
 			if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
-				lane = MV88E6390_PORT9_LANE2;
+				*lane = MV88E6390_PORT9_LANE2;
 		break;
 	case 4:
 		if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
@@ -480,14 +480,14 @@  u8 mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
 			if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
-				lane = MV88E6390_PORT9_LANE3;
+				*lane = MV88E6390_PORT9_LANE3;
 		break;
 	case 5:
 		if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
 			if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
-				lane = MV88E6390_PORT10_LANE1;
+				*lane = MV88E6390_PORT10_LANE1;
 		break;
 	case 6:
 		if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
@@ -495,7 +495,7 @@  u8 mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
 			if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
-				lane = MV88E6390_PORT10_LANE2;
+				*lane = MV88E6390_PORT10_LANE2;
 		break;
 	case 7:
 		if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
@@ -503,7 +503,7 @@  u8 mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
 			if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
-				lane = MV88E6390_PORT10_LANE3;
+				*lane = MV88E6390_PORT10_LANE3;
 		break;
 	case 9:
 		if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
@@ -511,7 +511,7 @@  u8 mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_XAUI ||
 		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
-			lane = MV88E6390_PORT9_LANE0;
+			*lane = MV88E6390_PORT9_LANE0;
 		break;
 	case 10:
 		if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
@@ -519,11 +519,11 @@  u8 mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_XAUI ||
 		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
-			lane = MV88E6390_PORT10_LANE0;
+			*lane = MV88E6390_PORT10_LANE0;
 		break;
 	}
 
-	return lane;
+	return *lane == -1 ? -ENODEV : 0;
 }
 
 /* Set power up/down for 10GBASE-R and 10GBASE-X4/X2 */
@@ -532,7 +532,6 @@  static int mv88e6390_serdes_power_10g(struct mv88e6xxx_chip *chip, u8 lane,
 {
 	u16 val, new_val;
 	int err;
-
 	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
 				    MV88E6390_10G_CTRL1, &val);
 
@@ -590,7 +589,9 @@  static struct mv88e6390_serdes_hw_stat mv88e6390_serdes_hw_stats[] = {
 
 int mv88e6390_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port)
 {
-	if (mv88e6390_serdes_get_lane(chip, port) == 0)
+	u8 lane;
+
+	if (mv88e6390_serdes_get_lane(chip, port, &lane))
 		return 0;
 
 	return ARRAY_SIZE(mv88e6390_serdes_hw_stats);
@@ -600,9 +601,10 @@  int mv88e6390_serdes_get_strings(struct mv88e6xxx_chip *chip,
 				 int port, uint8_t *data)
 {
 	struct mv88e6390_serdes_hw_stat *stat;
+	u8 lane;
 	int i;
 
-	if (mv88e6390_serdes_get_lane(chip, port) == 0)
+	if (mv88e6390_serdes_get_lane(chip, port, &lane))
 		return 0;
 
 	for (i = 0; i < ARRAY_SIZE(mv88e6390_serdes_hw_stats); i++) {
@@ -635,11 +637,10 @@  int mv88e6390_serdes_get_stats(struct mv88e6xxx_chip *chip, int port,
 			       uint64_t *data)
 {
 	struct mv88e6390_serdes_hw_stat *stat;
-	int lane;
+	u8 lane;
 	int i;
 
-	lane = mv88e6390_serdes_get_lane(chip, port);
-	if (lane == 0)
+	if (mv88e6390_serdes_get_lane(chip, port, &lane))
 		return 0;
 
 	for (i = 0; i < ARRAY_SIZE(mv88e6390_serdes_hw_stats); i++) {
@@ -976,7 +977,9 @@  static const u16 mv88e6390_serdes_regs[] = {
 
 int mv88e6390_serdes_get_regs_len(struct mv88e6xxx_chip *chip, int port)
 {
-	if (mv88e6xxx_serdes_get_lane(chip, port) == 0)
+	u8 lane;
+
+	if (mv88e6xxx_serdes_get_lane(chip, port, &lane))
 		return 0;
 
 	return ARRAY_SIZE(mv88e6390_serdes_regs) * sizeof(u16);
@@ -985,12 +988,11 @@  int mv88e6390_serdes_get_regs_len(struct mv88e6xxx_chip *chip, int port)
 void mv88e6390_serdes_get_regs(struct mv88e6xxx_chip *chip, int port, void *_p)
 {
 	u16 *p = _p;
-	int lane;
 	u16 reg;
+	u8 lane;
 	int i;
 
-	lane = mv88e6xxx_serdes_get_lane(chip, port);
-	if (lane == 0)
+	if (mv88e6xxx_serdes_get_lane(chip, port, &lane))
 		return;
 
 	for (i = 0 ; i < ARRAY_SIZE(mv88e6390_serdes_regs); i++) {
diff --git a/drivers/net/dsa/mv88e6xxx/serdes.h b/drivers/net/dsa/mv88e6xxx/serdes.h
index 14315f26228a3..95d04dab8d251 100644
--- a/drivers/net/dsa/mv88e6xxx/serdes.h
+++ b/drivers/net/dsa/mv88e6xxx/serdes.h
@@ -73,10 +73,10 @@ 
 #define MV88E6390_PG_CONTROL		0xf010
 #define MV88E6390_PG_CONTROL_ENABLE_PC		BIT(0)
 
-u8 mv88e6341_serdes_get_lane(struct mv88e6xxx_chip *chip, int port);
-u8 mv88e6352_serdes_get_lane(struct mv88e6xxx_chip *chip, int port);
-u8 mv88e6390_serdes_get_lane(struct mv88e6xxx_chip *chip, int port);
-u8 mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port);
+int mv88e6341_serdes_get_lane(struct mv88e6xxx_chip *chip, int port, u8 *lane);
+int mv88e6352_serdes_get_lane(struct mv88e6xxx_chip *chip, int port, u8 *lane);
+int mv88e6390_serdes_get_lane(struct mv88e6xxx_chip *chip, int port, u8 *lane);
+int mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port, u8 *lane);
 int mv88e6352_serdes_pcs_config(struct mv88e6xxx_chip *chip, int port,
 				u8 lane, unsigned int mode,
 				phy_interface_t interface,
@@ -130,13 +130,13 @@  int mv88e6390_serdes_get_regs_len(struct mv88e6xxx_chip *chip, int port);
 void mv88e6390_serdes_get_regs(struct mv88e6xxx_chip *chip, int port, void *_p);
 
 /* Return the (first) SERDES lane address a port is using, 0 otherwise. */
-static inline u8 mv88e6xxx_serdes_get_lane(struct mv88e6xxx_chip *chip,
-					   int port)
+static inline int mv88e6xxx_serdes_get_lane(struct mv88e6xxx_chip *chip,
+					    int port, u8 *lane)
 {
 	if (!chip->info->ops->serdes_get_lane)
-		return 0;
+		return -EOPNOTSUPP;
 
-	return chip->info->ops->serdes_get_lane(chip, port);
+	return chip->info->ops->serdes_get_lane(chip, port, lane);
 }
 
 static inline int mv88e6xxx_serdes_power_up(struct mv88e6xxx_chip *chip,