blob: c6a22ae2318137e37fe21bf55cb079f7d1dccbfd [file] [log] [blame]
Vivien Didelot18abed22016-11-04 03:23:26 +01001/*
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
17int 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
25int 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}
Vivien Didelote28def332016-11-04 03:23:27 +010032
33/* Offset 0x04: Port Control Register */
34
35static 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
42int 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}
Vivien Didelot5a7921f2016-11-04 03:23:28 +010063
64/* Offset 0x06: Port Based VLAN Map */
65
66int 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}