xref: /openbmc/linux/drivers/net/dsa/mv88e6xxx/port.c (revision 5a7921f4)
1 /*
2  * Marvell 88E6xxx Switch Port Registers support
3  *
4  * Copyright (c) 2008 Marvell Semiconductor
5  *
6  * Copyright (c) 2016 Vivien Didelot <vivien.didelot@savoirfairelinux.com>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  */
13 
14 #include "mv88e6xxx.h"
15 #include "port.h"
16 
17 int mv88e6xxx_port_read(struct mv88e6xxx_chip *chip, int port, int reg,
18 			u16 *val)
19 {
20 	int addr = chip->info->port_base_addr + port;
21 
22 	return mv88e6xxx_read(chip, addr, reg, val);
23 }
24 
25 int mv88e6xxx_port_write(struct mv88e6xxx_chip *chip, int port, int reg,
26 			 u16 val)
27 {
28 	int addr = chip->info->port_base_addr + port;
29 
30 	return mv88e6xxx_write(chip, addr, reg, val);
31 }
32 
33 /* Offset 0x04: Port Control Register */
34 
35 static const char * const mv88e6xxx_port_state_names[] = {
36 	[PORT_CONTROL_STATE_DISABLED] = "Disabled",
37 	[PORT_CONTROL_STATE_BLOCKING] = "Blocking/Listening",
38 	[PORT_CONTROL_STATE_LEARNING] = "Learning",
39 	[PORT_CONTROL_STATE_FORWARDING] = "Forwarding",
40 };
41 
42 int mv88e6xxx_port_set_state(struct mv88e6xxx_chip *chip, int port, u8 state)
43 {
44 	u16 reg;
45 	int err;
46 
47 	err = mv88e6xxx_port_read(chip, port, PORT_CONTROL, &reg);
48 	if (err)
49 		return err;
50 
51 	reg &= ~PORT_CONTROL_STATE_MASK;
52 	reg |= state;
53 
54 	err = mv88e6xxx_port_write(chip, port, PORT_CONTROL, reg);
55 	if (err)
56 		return err;
57 
58 	netdev_dbg(chip->ds->ports[port].netdev, "PortState set to %s\n",
59 		   mv88e6xxx_port_state_names[state]);
60 
61 	return 0;
62 }
63 
64 /* Offset 0x06: Port Based VLAN Map */
65 
66 int mv88e6xxx_port_set_vlan_map(struct mv88e6xxx_chip *chip, int port, u16 map)
67 {
68 	const u16 mask = GENMASK(mv88e6xxx_num_ports(chip) - 1, 0);
69 	u16 reg;
70 	int err;
71 
72 	err = mv88e6xxx_port_read(chip, port, PORT_BASE_VLAN, &reg);
73 	if (err)
74 		return err;
75 
76 	reg &= ~mask;
77 	reg |= map & mask;
78 
79 	err = mv88e6xxx_port_write(chip, port, PORT_BASE_VLAN, reg);
80 	if (err)
81 		return err;
82 
83 	netdev_dbg(chip->ds->ports[port].netdev, "VLANTable set to %.3x\n",
84 		   map);
85 
86 	return 0;
87 }
88