Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / drivers / net / dsa / mv88e6xxx.h
diff --git a/kernel/drivers/net/dsa/mv88e6xxx.h b/kernel/drivers/net/dsa/mv88e6xxx.h
new file mode 100644 (file)
index 0000000..e045154
--- /dev/null
@@ -0,0 +1,339 @@
+/*
+ * net/dsa/mv88e6xxx.h - Marvell 88e6xxx switch chip support
+ * Copyright (c) 2008 Marvell Semiconductor
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __MV88E6XXX_H
+#define __MV88E6XXX_H
+
+#define SMI_CMD                        0x00
+#define SMI_CMD_BUSY           BIT(15)
+#define SMI_CMD_CLAUSE_22      BIT(12)
+#define SMI_CMD_OP_22_WRITE    ((1 << 10) | SMI_CMD_BUSY | SMI_CMD_CLAUSE_22)
+#define SMI_CMD_OP_22_READ     ((2 << 10) | SMI_CMD_BUSY | SMI_CMD_CLAUSE_22)
+#define SMI_CMD_OP_45_WRITE_ADDR       ((0 << 10) | SMI_CMD_BUSY)
+#define SMI_CMD_OP_45_WRITE_DATA       ((1 << 10) | SMI_CMD_BUSY)
+#define SMI_CMD_OP_45_READ_DATA                ((2 << 10) | SMI_CMD_BUSY)
+#define SMI_CMD_OP_45_READ_DATA_INC    ((3 << 10) | SMI_CMD_BUSY)
+#define SMI_DATA               0x01
+
+#define REG_PORT(p)            (0x10 + (p))
+#define PORT_STATUS            0x00
+#define PORT_STATUS_PAUSE_EN   BIT(15)
+#define PORT_STATUS_MY_PAUSE   BIT(14)
+#define PORT_STATUS_HD_FLOW    BIT(13)
+#define PORT_STATUS_PHY_DETECT BIT(12)
+#define PORT_STATUS_LINK       BIT(11)
+#define PORT_STATUS_DUPLEX     BIT(10)
+#define PORT_STATUS_SPEED_MASK 0x0300
+#define PORT_STATUS_SPEED_10   0x0000
+#define PORT_STATUS_SPEED_100  0x0100
+#define PORT_STATUS_SPEED_1000 0x0200
+#define PORT_STATUS_EEE                BIT(6) /* 6352 */
+#define PORT_STATUS_AM_DIS     BIT(6) /* 6165 */
+#define PORT_STATUS_MGMII      BIT(6) /* 6185 */
+#define PORT_STATUS_TX_PAUSED  BIT(5)
+#define PORT_STATUS_FLOW_CTRL  BIT(4)
+#define PORT_PCS_CTRL          0x01
+#define PORT_SWITCH_ID         0x03
+#define PORT_SWITCH_ID_6085    0x04a0
+#define PORT_SWITCH_ID_6095    0x0950
+#define PORT_SWITCH_ID_6123    0x1210
+#define PORT_SWITCH_ID_6123_A1 0x1212
+#define PORT_SWITCH_ID_6123_A2 0x1213
+#define PORT_SWITCH_ID_6131    0x1060
+#define PORT_SWITCH_ID_6131_B2 0x1066
+#define PORT_SWITCH_ID_6152    0x1a40
+#define PORT_SWITCH_ID_6155    0x1a50
+#define PORT_SWITCH_ID_6161    0x1610
+#define PORT_SWITCH_ID_6161_A1 0x1612
+#define PORT_SWITCH_ID_6161_A2 0x1613
+#define PORT_SWITCH_ID_6165    0x1650
+#define PORT_SWITCH_ID_6165_A1 0x1652
+#define PORT_SWITCH_ID_6165_A2 0x1653
+#define PORT_SWITCH_ID_6171    0x1710
+#define PORT_SWITCH_ID_6172    0x1720
+#define PORT_SWITCH_ID_6176    0x1760
+#define PORT_SWITCH_ID_6182    0x1a60
+#define PORT_SWITCH_ID_6185    0x1a70
+#define PORT_SWITCH_ID_6352    0x3520
+#define PORT_SWITCH_ID_6352_A0 0x3521
+#define PORT_SWITCH_ID_6352_A1 0x3522
+#define PORT_CONTROL           0x04
+#define PORT_CONTROL_STATE_MASK                0x03
+#define PORT_CONTROL_STATE_DISABLED    0x00
+#define PORT_CONTROL_STATE_BLOCKING    0x01
+#define PORT_CONTROL_STATE_LEARNING    0x02
+#define PORT_CONTROL_STATE_FORWARDING  0x03
+#define PORT_CONTROL_1         0x05
+#define PORT_BASE_VLAN         0x06
+#define PORT_DEFAULT_VLAN      0x07
+#define PORT_CONTROL_2         0x08
+#define PORT_RATE_CONTROL      0x09
+#define PORT_RATE_CONTROL_2    0x0a
+#define PORT_ASSOC_VECTOR      0x0b
+#define PORT_IN_DISCARD_LO     0x10
+#define PORT_IN_DISCARD_HI     0x11
+#define PORT_IN_FILTERED       0x12
+#define PORT_OUT_FILTERED      0x13
+#define PORT_TAG_REGMAP_0123   0x19
+#define PORT_TAG_REGMAP_4567   0x1a
+
+#define REG_GLOBAL             0x1b
+#define GLOBAL_STATUS          0x00
+#define GLOBAL_STATUS_PPU_STATE BIT(15) /* 6351 and 6171 */
+/* Two bits for 6165, 6185 etc */
+#define GLOBAL_STATUS_PPU_MASK         (0x3 << 14)
+#define GLOBAL_STATUS_PPU_DISABLED_RST (0x0 << 14)
+#define GLOBAL_STATUS_PPU_INITIALIZING (0x1 << 14)
+#define GLOBAL_STATUS_PPU_DISABLED     (0x2 << 14)
+#define GLOBAL_STATUS_PPU_POLLING      (0x3 << 14)
+#define GLOBAL_MAC_01          0x01
+#define GLOBAL_MAC_23          0x02
+#define GLOBAL_MAC_45          0x03
+#define GLOBAL_CONTROL         0x04
+#define GLOBAL_CONTROL_SW_RESET                BIT(15)
+#define GLOBAL_CONTROL_PPU_ENABLE      BIT(14)
+#define GLOBAL_CONTROL_DISCARD_EXCESS  BIT(13) /* 6352 */
+#define GLOBAL_CONTROL_SCHED_PRIO      BIT(11) /* 6152 */
+#define GLOBAL_CONTROL_MAX_FRAME_1632  BIT(10) /* 6152 */
+#define GLOBAL_CONTROL_RELOAD_EEPROM   BIT(9)  /* 6152 */
+#define GLOBAL_CONTROL_DEVICE_EN       BIT(7)
+#define GLOBAL_CONTROL_STATS_DONE_EN   BIT(6)
+#define GLOBAL_CONTROL_VTU_PROBLEM_EN  BIT(5)
+#define GLOBAL_CONTROL_VTU_DONE_EN     BIT(4)
+#define GLOBAL_CONTROL_ATU_PROBLEM_EN  BIT(3)
+#define GLOBAL_CONTROL_ATU_DONE_EN     BIT(2)
+#define GLOBAL_CONTROL_TCAM_EN         BIT(1)
+#define GLOBAL_CONTROL_EEPROM_DONE_EN  BIT(0)
+#define GLOBAL_VTU_OP          0x05
+#define GLOBAL_VTU_VID         0x06
+#define GLOBAL_VTU_DATA_0_3    0x07
+#define GLOBAL_VTU_DATA_4_7    0x08
+#define GLOBAL_VTU_DATA_8_11   0x09
+#define GLOBAL_ATU_CONTROL     0x0a
+#define GLOBAL_ATU_OP          0x0b
+#define GLOBAL_ATU_OP_BUSY     BIT(15)
+#define GLOBAL_ATU_OP_NOP              (0 << 12)
+#define GLOBAL_ATU_OP_FLUSH_ALL                ((1 << 12) | GLOBAL_ATU_OP_BUSY)
+#define GLOBAL_ATU_OP_FLUSH_NON_STATIC ((2 << 12) | GLOBAL_ATU_OP_BUSY)
+#define GLOBAL_ATU_OP_LOAD_DB          ((3 << 12) | GLOBAL_ATU_OP_BUSY)
+#define GLOBAL_ATU_OP_GET_NEXT_DB      ((4 << 12) | GLOBAL_ATU_OP_BUSY)
+#define GLOBAL_ATU_OP_FLUSH_DB         ((5 << 12) | GLOBAL_ATU_OP_BUSY)
+#define GLOBAL_ATU_OP_FLUSH_NON_STATIC_DB ((6 << 12) | GLOBAL_ATU_OP_BUSY)
+#define GLOBAL_ATU_OP_GET_CLR_VIOLATION          ((7 << 12) | GLOBAL_ATU_OP_BUSY)
+#define GLOBAL_ATU_DATA                0x0c
+#define GLOBAL_ATU_DATA_STATE_MASK             0x0f
+#define GLOBAL_ATU_DATA_STATE_UNUSED           0x00
+#define GLOBAL_ATU_DATA_STATE_UC_MGMT          0x0d
+#define GLOBAL_ATU_DATA_STATE_UC_STATIC                0x0e
+#define GLOBAL_ATU_DATA_STATE_UC_PRIO_OVER     0x0f
+#define GLOBAL_ATU_DATA_STATE_MC_NONE_RATE     0x05
+#define GLOBAL_ATU_DATA_STATE_MC_STATIC                0x07
+#define GLOBAL_ATU_DATA_STATE_MC_MGMT          0x0e
+#define GLOBAL_ATU_DATA_STATE_MC_PRIO_OVER     0x0f
+#define GLOBAL_ATU_MAC_01      0x0d
+#define GLOBAL_ATU_MAC_23      0x0e
+#define GLOBAL_ATU_MAC_45      0x0f
+#define GLOBAL_IP_PRI_0                0x10
+#define GLOBAL_IP_PRI_1                0x11
+#define GLOBAL_IP_PRI_2                0x12
+#define GLOBAL_IP_PRI_3                0x13
+#define GLOBAL_IP_PRI_4                0x14
+#define GLOBAL_IP_PRI_5                0x15
+#define GLOBAL_IP_PRI_6                0x16
+#define GLOBAL_IP_PRI_7                0x17
+#define GLOBAL_IEEE_PRI                0x18
+#define GLOBAL_CORE_TAG_TYPE   0x19
+#define GLOBAL_MONITOR_CONTROL 0x1a
+#define GLOBAL_CONTROL_2       0x1c
+#define GLOBAL_STATS_OP                0x1d
+#define GLOBAL_STATS_OP_BUSY   BIT(15)
+#define GLOBAL_STATS_OP_NOP            (0 << 12)
+#define GLOBAL_STATS_OP_FLUSH_ALL      ((1 << 12) | GLOBAL_STATS_OP_BUSY)
+#define GLOBAL_STATS_OP_FLUSH_PORT     ((2 << 12) | GLOBAL_STATS_OP_BUSY)
+#define GLOBAL_STATS_OP_READ_CAPTURED  ((4 << 12) | GLOBAL_STATS_OP_BUSY)
+#define GLOBAL_STATS_OP_CAPTURE_PORT   ((5 << 12) | GLOBAL_STATS_OP_BUSY)
+#define GLOBAL_STATS_OP_HIST_RX                ((1 << 10) | GLOBAL_STATS_OP_BUSY)
+#define GLOBAL_STATS_OP_HIST_TX                ((2 << 10) | GLOBAL_STATS_OP_BUSY)
+#define GLOBAL_STATS_OP_HIST_RX_TX     ((3 << 10) | GLOBAL_STATS_OP_BUSY)
+#define GLOBAL_STATS_COUNTER_32        0x1e
+#define GLOBAL_STATS_COUNTER_01        0x1f
+
+#define REG_GLOBAL2            0x1c
+#define GLOBAL2_INT_SOURCE     0x00
+#define GLOBAL2_INT_MASK       0x01
+#define GLOBAL2_MGMT_EN_2X     0x02
+#define GLOBAL2_MGMT_EN_0X     0x03
+#define GLOBAL2_FLOW_CONTROL   0x04
+#define GLOBAL2_SWITCH_MGMT    0x05
+#define GLOBAL2_DEVICE_MAPPING 0x06
+#define GLOBAL2_TRUNK_MASK     0x07
+#define GLOBAL2_TRUNK_MAPPING  0x08
+#define GLOBAL2_INGRESS_OP     0x09
+#define GLOBAL2_INGRESS_DATA   0x0a
+#define GLOBAL2_PVT_ADDR       0x0b
+#define GLOBAL2_PVT_DATA       0x0c
+#define GLOBAL2_SWITCH_MAC     0x0d
+#define GLOBAL2_SWITCH_MAC_BUSY BIT(15)
+#define GLOBAL2_ATU_STATS      0x0e
+#define GLOBAL2_PRIO_OVERRIDE  0x0f
+#define GLOBAL2_EEPROM_OP      0x14
+#define GLOBAL2_EEPROM_OP_BUSY BIT(15)
+#define GLOBAL2_EEPROM_OP_LOAD BIT(11)
+#define GLOBAL2_EEPROM_DATA    0x15
+#define GLOBAL2_PTP_AVB_OP     0x16
+#define GLOBAL2_PTP_AVB_DATA   0x17
+#define GLOBAL2_SMI_OP         0x18
+#define GLOBAL2_SMI_OP_BUSY            BIT(15)
+#define GLOBAL2_SMI_OP_CLAUSE_22       BIT(12)
+#define GLOBAL2_SMI_OP_22_WRITE                ((1 << 10) | GLOBAL2_SMI_OP_BUSY | \
+                                        GLOBAL2_SMI_OP_CLAUSE_22)
+#define GLOBAL2_SMI_OP_22_READ         ((2 << 10) | GLOBAL2_SMI_OP_BUSY | \
+                                        GLOBAL2_SMI_OP_CLAUSE_22)
+#define GLOBAL2_SMI_OP_45_WRITE_ADDR   ((0 << 10) | GLOBAL2_SMI_OP_BUSY)
+#define GLOBAL2_SMI_OP_45_WRITE_DATA   ((1 << 10) | GLOBAL2_SMI_OP_BUSY)
+#define GLOBAL2_SMI_OP_45_READ_DATA    ((2 << 10) | GLOBAL2_SMI_OP_BUSY)
+#define GLOBAL2_SMI_DATA       0x19
+#define GLOBAL2_SCRATCH_MISC   0x1a
+#define GLOBAL2_WDOG_CONTROL   0x1b
+#define GLOBAL2_QOS_WEIGHT     0x1c
+#define GLOBAL2_MISC           0x1d
+
+struct mv88e6xxx_priv_state {
+       /* When using multi-chip addressing, this mutex protects
+        * access to the indirect access registers.  (In single-chip
+        * mode, this mutex is effectively useless.)
+        */
+       struct mutex    smi_mutex;
+
+#ifdef CONFIG_NET_DSA_MV88E6XXX_NEED_PPU
+       /* Handles automatic disabling and re-enabling of the PHY
+        * polling unit.
+        */
+       struct mutex            ppu_mutex;
+       int                     ppu_disabled;
+       struct work_struct      ppu_work;
+       struct timer_list       ppu_timer;
+#endif
+
+       /* This mutex serialises access to the statistics unit.
+        * Hold this mutex over snapshot + dump sequences.
+        */
+       struct mutex    stats_mutex;
+
+       /* This mutex serializes phy access for chips with
+        * indirect phy addressing. It is unused for chips
+        * with direct phy access.
+        */
+       struct mutex    phy_mutex;
+
+       /* This mutex serializes eeprom access for chips with
+        * eeprom support.
+        */
+       struct mutex eeprom_mutex;
+
+       int             id; /* switch product id */
+       int             num_ports;      /* number of switch ports */
+
+       /* hw bridging */
+
+       u32 fid_mask;
+       u8 fid[DSA_MAX_PORTS];
+       u16 bridge_mask[DSA_MAX_PORTS];
+
+       unsigned long port_state_update_mask;
+       u8 port_state[DSA_MAX_PORTS];
+
+       struct work_struct bridge_work;
+};
+
+struct mv88e6xxx_hw_stat {
+       char string[ETH_GSTRING_LEN];
+       int sizeof_stat;
+       int reg;
+};
+
+int mv88e6xxx_switch_reset(struct dsa_switch *ds, bool ppu_active);
+int mv88e6xxx_setup_port_common(struct dsa_switch *ds, int port);
+int mv88e6xxx_setup_common(struct dsa_switch *ds);
+int __mv88e6xxx_reg_read(struct mii_bus *bus, int sw_addr, int addr, int reg);
+int mv88e6xxx_reg_read(struct dsa_switch *ds, int addr, int reg);
+int __mv88e6xxx_reg_write(struct mii_bus *bus, int sw_addr, int addr,
+                         int reg, u16 val);
+int mv88e6xxx_reg_write(struct dsa_switch *ds, int addr, int reg, u16 val);
+int mv88e6xxx_config_prio(struct dsa_switch *ds);
+int mv88e6xxx_set_addr_direct(struct dsa_switch *ds, u8 *addr);
+int mv88e6xxx_set_addr_indirect(struct dsa_switch *ds, u8 *addr);
+int mv88e6xxx_phy_read(struct dsa_switch *ds, int port, int regnum);
+int mv88e6xxx_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val);
+int mv88e6xxx_phy_read_indirect(struct dsa_switch *ds, int port, int regnum);
+int mv88e6xxx_phy_write_indirect(struct dsa_switch *ds, int port, int regnum,
+                                u16 val);
+void mv88e6xxx_ppu_state_init(struct dsa_switch *ds);
+int mv88e6xxx_phy_read_ppu(struct dsa_switch *ds, int addr, int regnum);
+int mv88e6xxx_phy_write_ppu(struct dsa_switch *ds, int addr,
+                           int regnum, u16 val);
+void mv88e6xxx_poll_link(struct dsa_switch *ds);
+void mv88e6xxx_get_strings(struct dsa_switch *ds, int port, uint8_t *data);
+void mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds, int port,
+                                uint64_t *data);
+int mv88e6xxx_get_sset_count(struct dsa_switch *ds);
+int mv88e6xxx_get_sset_count_basic(struct dsa_switch *ds);
+int mv88e6xxx_get_regs_len(struct dsa_switch *ds, int port);
+void mv88e6xxx_get_regs(struct dsa_switch *ds, int port,
+                       struct ethtool_regs *regs, void *_p);
+int  mv88e6xxx_get_temp(struct dsa_switch *ds, int *temp);
+int mv88e6xxx_phy_wait(struct dsa_switch *ds);
+int mv88e6xxx_eeprom_load_wait(struct dsa_switch *ds);
+int mv88e6xxx_eeprom_busy_wait(struct dsa_switch *ds);
+int mv88e6xxx_phy_read_indirect(struct dsa_switch *ds, int addr, int regnum);
+int mv88e6xxx_phy_write_indirect(struct dsa_switch *ds, int addr, int regnum,
+                                u16 val);
+int mv88e6xxx_get_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e);
+int mv88e6xxx_set_eee(struct dsa_switch *ds, int port,
+                     struct phy_device *phydev, struct ethtool_eee *e);
+int mv88e6xxx_join_bridge(struct dsa_switch *ds, int port, u32 br_port_mask);
+int mv88e6xxx_leave_bridge(struct dsa_switch *ds, int port, u32 br_port_mask);
+int mv88e6xxx_port_stp_update(struct dsa_switch *ds, int port, u8 state);
+int mv88e6xxx_port_fdb_add(struct dsa_switch *ds, int port,
+                          const unsigned char *addr, u16 vid);
+int mv88e6xxx_port_fdb_del(struct dsa_switch *ds, int port,
+                          const unsigned char *addr, u16 vid);
+int mv88e6xxx_port_fdb_getnext(struct dsa_switch *ds, int port,
+                              unsigned char *addr, bool *is_static);
+int mv88e6xxx_phy_page_read(struct dsa_switch *ds, int port, int page, int reg);
+int mv88e6xxx_phy_page_write(struct dsa_switch *ds, int port, int page,
+                            int reg, int val);
+extern struct dsa_switch_driver mv88e6131_switch_driver;
+extern struct dsa_switch_driver mv88e6123_61_65_switch_driver;
+extern struct dsa_switch_driver mv88e6352_switch_driver;
+extern struct dsa_switch_driver mv88e6171_switch_driver;
+
+#define REG_READ(addr, reg)                                            \
+       ({                                                              \
+               int __ret;                                              \
+                                                                       \
+               __ret = mv88e6xxx_reg_read(ds, addr, reg);              \
+               if (__ret < 0)                                          \
+                       return __ret;                                   \
+               __ret;                                                  \
+       })
+
+#define REG_WRITE(addr, reg, val)                                      \
+       ({                                                              \
+               int __ret;                                              \
+                                                                       \
+               __ret = mv88e6xxx_reg_write(ds, addr, reg, val);        \
+               if (__ret < 0)                                          \
+                       return __ret;                                   \
+       })
+
+
+
+#endif