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, ®); 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, ®); 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