blob: 80490f66bc066eb7c13b64c69c96f7287f480db2 [file] [log] [blame]
Lennert Buytenhek91da11f2008-10-07 13:44:02 +00001/*
Vivien Didelot4d5f2ba72017-06-02 17:06:15 -04002 * Marvell 88E6xxx Ethernet switch single-chip definition
Vivien Didelot0d3cd4b2016-06-21 12:28:19 -04003 *
Lennert Buytenhek91da11f2008-10-07 13:44:02 +00004 * Copyright (c) 2008 Marvell Semiconductor
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 */
11
Vivien Didelot4d5f2ba72017-06-02 17:06:15 -040012#ifndef _MV88E6XXX_CHIP_H
13#define _MV88E6XXX_CHIP_H
Lennert Buytenhek91da11f2008-10-07 13:44:02 +000014
Vivien Didelot194fea72015-08-10 09:09:47 -040015#include <linux/if_vlan.h>
Andrew Lunndc30c352016-10-16 19:56:49 +020016#include <linux/irq.h>
Andrew Lunn52638f72016-05-10 23:27:22 +020017#include <linux/gpio/consumer.h>
Andrew Lunn294d7112018-02-22 22:58:32 +010018#include <linux/kthread.h>
Russell King4d56a292017-02-07 15:03:05 -080019#include <linux/phy.h>
Brandon Streiff2fa8d3a2018-02-14 01:07:45 +010020#include <linux/ptp_clock_kernel.h>
21#include <linux/timecounter.h>
Andrew Lunnc6e970a2017-03-28 23:45:06 +020022#include <net/dsa.h>
Vivien Didelot194fea72015-08-10 09:09:47 -040023
Andrew Lunn80c46272015-06-20 18:42:30 +020024#ifndef UINT64_MAX
25#define UINT64_MAX (u64)(~((u64)0))
26#endif
27
Andrew Lunncca8b132015-04-02 04:06:39 +020028#define SMI_CMD 0x00
29#define SMI_CMD_BUSY BIT(15)
30#define SMI_CMD_CLAUSE_22 BIT(12)
31#define SMI_CMD_OP_22_WRITE ((1 << 10) | SMI_CMD_BUSY | SMI_CMD_CLAUSE_22)
32#define SMI_CMD_OP_22_READ ((2 << 10) | SMI_CMD_BUSY | SMI_CMD_CLAUSE_22)
33#define SMI_CMD_OP_45_WRITE_ADDR ((0 << 10) | SMI_CMD_BUSY)
34#define SMI_CMD_OP_45_WRITE_DATA ((1 << 10) | SMI_CMD_BUSY)
35#define SMI_CMD_OP_45_READ_DATA ((2 << 10) | SMI_CMD_BUSY)
36#define SMI_CMD_OP_45_READ_DATA_INC ((3 << 10) | SMI_CMD_BUSY)
37#define SMI_DATA 0x01
Guenter Roeckb2eb0662015-04-02 04:06:30 +020038
Vivien Didelot3285f9e2016-02-26 13:16:03 -050039#define MV88E6XXX_N_FID 4096
40
Vivien Didelot17a15942017-03-30 17:37:09 -040041/* PVT limits for 4-bit port and 5-bit switch */
42#define MV88E6XXX_MAX_PVT_SWITCHES 32
43#define MV88E6XXX_MAX_PVT_PORTS 16
44
Brandon Streiffa73ccd62018-02-14 01:07:46 +010045#define MV88E6XXX_MAX_GPIO 16
46
Vivien Didelot31bef4e2017-06-08 18:34:09 -040047enum mv88e6xxx_egress_mode {
48 MV88E6XXX_EGRESS_MODE_UNMODIFIED,
49 MV88E6XXX_EGRESS_MODE_UNTAGGED,
50 MV88E6XXX_EGRESS_MODE_TAGGED,
51 MV88E6XXX_EGRESS_MODE_ETHERTYPE,
52};
53
Andrew Lunn56995cb2016-12-03 04:35:19 +010054enum mv88e6xxx_frame_mode {
55 MV88E6XXX_FRAME_MODE_NORMAL,
56 MV88E6XXX_FRAME_MODE_DSA,
57 MV88E6XXX_FRAME_MODE_PROVIDER,
58 MV88E6XXX_FRAME_MODE_ETHERTYPE,
59};
60
Vivien Didelotf81ec902016-05-09 13:22:58 -040061/* List of supported models */
62enum mv88e6xxx_model {
63 MV88E6085,
64 MV88E6095,
Stefan Eichenberger7d381a02016-11-22 17:47:21 +010065 MV88E6097,
Vivien Didelotf81ec902016-05-09 13:22:58 -040066 MV88E6123,
67 MV88E6131,
Gregory CLEMENT15587272017-01-30 20:29:35 +010068 MV88E6141,
Vivien Didelotf81ec902016-05-09 13:22:58 -040069 MV88E6161,
70 MV88E6165,
71 MV88E6171,
72 MV88E6172,
73 MV88E6175,
74 MV88E6176,
75 MV88E6185,
Andrew Lunn1a3b39e2016-11-21 23:26:57 +010076 MV88E6190,
77 MV88E6190X,
78 MV88E6191,
Vivien Didelotf81ec902016-05-09 13:22:58 -040079 MV88E6240,
Andrew Lunn1a3b39e2016-11-21 23:26:57 +010080 MV88E6290,
Vivien Didelotf81ec902016-05-09 13:22:58 -040081 MV88E6320,
82 MV88E6321,
Gregory CLEMENTa75961d2017-01-30 20:29:34 +010083 MV88E6341,
Vivien Didelotf81ec902016-05-09 13:22:58 -040084 MV88E6350,
85 MV88E6351,
86 MV88E6352,
Andrew Lunn1a3b39e2016-11-21 23:26:57 +010087 MV88E6390,
88 MV88E6390X,
Vivien Didelotf81ec902016-05-09 13:22:58 -040089};
90
Vivien Didelot22356472016-04-17 13:24:00 -040091enum mv88e6xxx_family {
92 MV88E6XXX_FAMILY_NONE,
93 MV88E6XXX_FAMILY_6065, /* 6031 6035 6061 6065 */
94 MV88E6XXX_FAMILY_6095, /* 6092 6095 */
95 MV88E6XXX_FAMILY_6097, /* 6046 6085 6096 6097 */
96 MV88E6XXX_FAMILY_6165, /* 6123 6161 6165 */
97 MV88E6XXX_FAMILY_6185, /* 6108 6121 6122 6131 6152 6155 6182 6185 */
98 MV88E6XXX_FAMILY_6320, /* 6320 6321 */
Gregory CLEMENTa75961d2017-01-30 20:29:34 +010099 MV88E6XXX_FAMILY_6341, /* 6141 6341 */
Vivien Didelot22356472016-04-17 13:24:00 -0400100 MV88E6XXX_FAMILY_6351, /* 6171 6175 6350 6351 */
101 MV88E6XXX_FAMILY_6352, /* 6172 6176 6240 6352 */
Andrew Lunn1a3b39e2016-11-21 23:26:57 +0100102 MV88E6XXX_FAMILY_6390, /* 6190 6190X 6191 6290 6390 6390X */
Vivien Didelot22356472016-04-17 13:24:00 -0400103};
104
Andrew Lunnc0e4dad2017-02-09 00:00:43 +0100105struct mv88e6xxx_ops;
106
Vivien Didelotf6271e62016-04-17 13:23:59 -0400107struct mv88e6xxx_info {
Vivien Didelot22356472016-04-17 13:24:00 -0400108 enum mv88e6xxx_family family;
Vivien Didelotf6271e62016-04-17 13:23:59 -0400109 u16 prod_num;
110 const char *name;
Vivien Didelotcd5a2c82016-04-17 13:24:02 -0400111 unsigned int num_databases;
Vivien Didelot009a2b92016-04-17 13:24:01 -0400112 unsigned int num_ports;
Andrew Lunnbc393152018-03-17 20:32:04 +0100113 unsigned int num_internal_phys;
Brandon Streiffa73ccd62018-02-14 01:07:46 +0100114 unsigned int num_gpio;
Vivien Didelot3cf3c842017-05-01 14:05:10 -0400115 unsigned int max_vid;
Vivien Didelot9dddd472016-06-20 13:14:10 -0400116 unsigned int port_base_addr;
Vivien Didelota935c052016-09-29 12:21:53 -0400117 unsigned int global1_addr;
Vivien Didelot9069c132017-07-17 13:03:44 -0400118 unsigned int global2_addr;
Vivien Didelotacddbd22016-07-18 20:45:39 -0400119 unsigned int age_time_coeff;
Andrew Lunndc30c352016-10-16 19:56:49 +0200120 unsigned int g1_irqs;
Vivien Didelotd6c5e6a2017-07-17 13:03:40 -0400121 unsigned int g2_irqs;
Vivien Didelotf3645652017-03-30 17:37:07 -0400122 bool pvt;
Vivien Didelotb3e05aa2017-07-17 13:03:46 -0400123
124 /* Multi-chip Addressing Mode.
125 * Some chips respond to only 2 registers of its own SMI device address
126 * when it is non-zero, and use indirect access to internal registers.
127 */
128 bool multi_chip;
Andrew Lunn443d5a12016-12-03 04:35:18 +0100129 enum dsa_tag_protocol tag_protocol;
Vivien Didelote606ca32017-03-11 16:12:55 -0500130
131 /* Mask for FromPort and ToPort value of PortVec used in ATU Move
132 * operation. 0 means that the ATU Move operation is not supported.
133 */
134 u8 atu_move_port_mask;
Vivien Didelotb3469dd2016-09-29 12:22:00 -0400135 const struct mv88e6xxx_ops *ops;
Brandon Streiff2fa8d3a2018-02-14 01:07:45 +0100136
137 /* Supports PTP */
138 bool ptp_support;
Vivien Didelotb9b37712015-10-30 19:39:48 -0400139};
140
Vivien Didelotfd231c82015-08-10 09:09:50 -0400141struct mv88e6xxx_atu_entry {
Vivien Didelotfd231c82015-08-10 09:09:50 -0400142 u8 state;
143 bool trunk;
Vivien Didelot01bd96c2017-03-11 16:12:57 -0500144 u16 portvec;
Vivien Didelotfd231c82015-08-10 09:09:50 -0400145 u8 mac[ETH_ALEN];
146};
147
Vivien Didelotb4e47c02016-09-29 12:21:58 -0400148struct mv88e6xxx_vtu_entry {
Vivien Didelotb8fee952015-08-13 12:52:19 -0400149 u16 vid;
150 u16 fid;
Vivien Didelotb8fee952015-08-13 12:52:19 -0400151 u8 sid;
152 bool valid;
Vivien Didelotbd00e052017-05-01 14:05:11 -0400153 u8 member[DSA_MAX_PORTS];
154 u8 state[DSA_MAX_PORTS];
Vivien Didelotb8fee952015-08-13 12:52:19 -0400155};
156
Vivien Didelotc08026a2016-09-29 12:21:59 -0400157struct mv88e6xxx_bus_ops;
Andrew Lunnfcd25162017-02-09 00:03:42 +0100158struct mv88e6xxx_irq_ops;
Brandon Streiffa73ccd62018-02-14 01:07:46 +0100159struct mv88e6xxx_gpio_ops;
Brandon Streiff0d632c32018-02-14 01:07:44 +0100160struct mv88e6xxx_avb_ops;
Vivien Didelot914b32f2016-06-20 13:14:11 -0400161
Andrew Lunndc30c352016-10-16 19:56:49 +0200162struct mv88e6xxx_irq {
163 u16 masked;
164 struct irq_chip chip;
165 struct irq_domain *domain;
166 unsigned int nirqs;
167};
168
Brandon Streiffc6fe0ad2018-02-14 01:07:50 +0100169/* state flags for mv88e6xxx_port_hwtstamp::state */
170enum {
171 MV88E6XXX_HWTSTAMP_ENABLED,
172 MV88E6XXX_HWTSTAMP_TX_IN_PROGRESS,
173};
174
175struct mv88e6xxx_port_hwtstamp {
176 /* Port index */
177 int port_id;
178
179 /* Timestamping state */
180 unsigned long state;
181
182 /* Resources for receive timestamping */
183 struct sk_buff_head rx_queue;
184 struct sk_buff_head rx_queue2;
185
186 /* Resources for transmit timestamping */
187 unsigned long tx_tstamp_start;
188 struct sk_buff *tx_skb;
189 u16 tx_seq_id;
190
191 /* Current timestamp configuration */
192 struct hwtstamp_config tstamp_config;
193};
194
Andrew Lunncda9f4a2018-03-01 02:02:31 +0100195struct mv88e6xxx_port {
196 u64 serdes_stats[2];
Andrew Lunn65f60e42018-03-28 23:50:28 +0200197 u64 atu_member_violation;
198 u64 atu_miss_violation;
199 u64 atu_full_violation;
200 u64 vtu_member_violation;
201 u64 vtu_miss_violation;
Andrew Lunncda9f4a2018-03-01 02:02:31 +0100202};
203
Vivien Didelotfad09c72016-06-21 12:28:20 -0400204struct mv88e6xxx_chip {
Vivien Didelotf6271e62016-04-17 13:23:59 -0400205 const struct mv88e6xxx_info *info;
206
Andrew Lunn7543a6d2016-04-13 02:40:40 +0200207 /* The dsa_switch this private structure is related to */
208 struct dsa_switch *ds;
209
Andrew Lunn158bc062016-04-28 21:24:06 -0400210 /* The device this structure is associated to */
211 struct device *dev;
212
Vivien Didelot9f8b3ee2016-06-20 13:14:05 -0400213 /* This mutex protects the access to the switch registers */
214 struct mutex reg_lock;
Lennert Buytenhek91da11f2008-10-07 13:44:02 +0000215
Andrew Lunna77d43f2016-04-13 02:40:42 +0200216 /* The MII bus and the address on the bus that is used to
217 * communication with the switch
218 */
Vivien Didelotc08026a2016-09-29 12:21:59 -0400219 const struct mv88e6xxx_bus_ops *smi_ops;
Andrew Lunna77d43f2016-04-13 02:40:42 +0200220 struct mii_bus *bus;
221 int sw_addr;
222
Barry Grussling3675c8d2013-01-08 16:05:53 +0000223 /* Handles automatic disabling and re-enabling of the PHY
Lennert Buytenhek2e5f0322008-10-07 13:45:18 +0000224 * polling unit.
225 */
Vivien Didelotc08026a2016-09-29 12:21:59 -0400226 const struct mv88e6xxx_bus_ops *phy_ops;
Lennert Buytenhek2e5f0322008-10-07 13:45:18 +0000227 struct mutex ppu_mutex;
228 int ppu_disabled;
229 struct work_struct ppu_work;
230 struct timer_list ppu_timer;
Lennert Buytenhek2e5f0322008-10-07 13:45:18 +0000231
Barry Grussling3675c8d2013-01-08 16:05:53 +0000232 /* This mutex serialises access to the statistics unit.
Lennert Buytenhek91da11f2008-10-07 13:44:02 +0000233 * Hold this mutex over snapshot + dump sequences.
234 */
235 struct mutex stats_mutex;
Peter Korsgaardec80bfc2011-04-05 03:03:56 +0000236
Andrew Lunn52638f72016-05-10 23:27:22 +0200237 /* A switch may have a GPIO line tied to its reset pin. Parse
238 * this from the device tree, and use it before performing
239 * switch soft reset.
240 */
241 struct gpio_desc *reset;
Andrew Lunnf8cd8752016-05-10 23:27:25 +0200242
243 /* set to size of eeprom if supported by the switch */
244 int eeprom_len;
Andrew Lunnb516d452016-06-04 21:17:06 +0200245
Andrew Lunna3c53be2017-01-24 14:53:50 +0100246 /* List of mdio busses */
247 struct list_head mdios;
Andrew Lunndc30c352016-10-16 19:56:49 +0200248
249 /* There can be two interrupt controllers, which are chained
250 * off a GPIO as interrupt source
251 */
252 struct mv88e6xxx_irq g1_irq;
253 struct mv88e6xxx_irq g2_irq;
254 int irq;
Andrew Lunn8e757eb2016-11-20 20:14:18 +0100255 int device_irq;
Andrew Lunnfcd25162017-02-09 00:03:42 +0100256 int watchdog_irq;
Andrew Lunncda9f4a2018-03-01 02:02:31 +0100257
Andrew Lunn09776442018-01-14 02:32:44 +0100258 int atu_prob_irq;
Andrew Lunn62eb1162018-01-14 02:32:45 +0100259 int vtu_prob_irq;
Andrew Lunn294d7112018-02-22 22:58:32 +0100260 struct kthread_worker *kworker;
261 struct kthread_delayed_work irq_poll_work;
Brandon Streiff2fa8d3a2018-02-14 01:07:45 +0100262
Brandon Streiffa73ccd62018-02-14 01:07:46 +0100263 /* GPIO resources */
264 u8 gpio_data[2];
265
Brandon Streiff2fa8d3a2018-02-14 01:07:45 +0100266 /* This cyclecounter abstracts the switch PTP time.
267 * reg_lock must be held for any operation that read()s.
268 */
269 struct cyclecounter tstamp_cc;
270 struct timecounter tstamp_tc;
271 struct delayed_work overflow_work;
272
273 struct ptp_clock *ptp_clock;
274 struct ptp_clock_info ptp_clock_info;
Brandon Streiff4eb3be22018-02-14 01:07:47 +0100275 struct delayed_work tai_event_work;
276 struct ptp_pin_desc pin_config[MV88E6XXX_MAX_GPIO];
277 u16 trig_config;
278 u16 evcap_config;
Brandon Streiffc6fe0ad2018-02-14 01:07:50 +0100279
280 /* Per-port timestamping resources. */
281 struct mv88e6xxx_port_hwtstamp port_hwtstamp[DSA_MAX_PORTS];
Andrew Lunncda9f4a2018-03-01 02:02:31 +0100282
283 /* Array of port structures. */
284 struct mv88e6xxx_port ports[DSA_MAX_PORTS];
Lennert Buytenhek91da11f2008-10-07 13:44:02 +0000285};
286
Vivien Didelotc08026a2016-09-29 12:21:59 -0400287struct mv88e6xxx_bus_ops {
Vivien Didelotfad09c72016-06-21 12:28:20 -0400288 int (*read)(struct mv88e6xxx_chip *chip, int addr, int reg, u16 *val);
289 int (*write)(struct mv88e6xxx_chip *chip, int addr, int reg, u16 val);
Vivien Didelot914b32f2016-06-20 13:14:11 -0400290};
291
Andrew Lunn0dd12d52017-01-24 14:53:49 +0100292struct mv88e6xxx_mdio_bus {
Andrew Lunna3c53be2017-01-24 14:53:50 +0100293 struct mii_bus *bus;
Andrew Lunn0dd12d52017-01-24 14:53:49 +0100294 struct mv88e6xxx_chip *chip;
Andrew Lunna3c53be2017-01-24 14:53:50 +0100295 struct list_head list;
296 bool external;
Andrew Lunn0dd12d52017-01-24 14:53:49 +0100297};
298
Vivien Didelotb3469dd2016-09-29 12:22:00 -0400299struct mv88e6xxx_ops {
Vivien Didelotcd8da8b2017-06-19 10:55:36 -0400300 /* Ingress Rate Limit unit (IRL) operations */
301 int (*irl_init_all)(struct mv88e6xxx_chip *chip, int port);
302
Vivien Didelotee4dc2e72016-09-29 12:22:02 -0400303 int (*get_eeprom)(struct mv88e6xxx_chip *chip,
304 struct ethtool_eeprom *eeprom, u8 *data);
305 int (*set_eeprom)(struct mv88e6xxx_chip *chip,
306 struct ethtool_eeprom *eeprom, u8 *data);
307
Vivien Didelotb073d4e2016-09-29 12:22:01 -0400308 int (*set_switch_mac)(struct mv88e6xxx_chip *chip, u8 *addr);
309
Andrew Lunnee26a222017-01-24 14:53:48 +0100310 int (*phy_read)(struct mv88e6xxx_chip *chip,
311 struct mii_bus *bus,
312 int addr, int reg, u16 *val);
313 int (*phy_write)(struct mv88e6xxx_chip *chip,
314 struct mii_bus *bus,
315 int addr, int reg, u16 val);
Vivien Didelot08ef7f12016-11-04 03:23:32 +0100316
Vivien Didelot9e907d72017-07-17 13:03:43 -0400317 /* Priority Override Table operations */
318 int (*pot_clear)(struct mv88e6xxx_chip *chip);
319
Vivien Didelota199d8b2016-12-05 17:30:28 -0500320 /* PHY Polling Unit (PPU) operations */
321 int (*ppu_enable)(struct mv88e6xxx_chip *chip);
322 int (*ppu_disable)(struct mv88e6xxx_chip *chip);
323
Vivien Didelot17e708b2016-12-05 17:30:27 -0500324 /* Switch Software Reset */
325 int (*reset)(struct mv88e6xxx_chip *chip);
326
Vivien Didelota0a0f622016-11-04 03:23:34 +0100327 /* RGMII Receive/Transmit Timing Control
328 * Add delay on PHY_INTERFACE_MODE_RGMII_*ID, no delay otherwise.
329 */
330 int (*port_set_rgmii_delay)(struct mv88e6xxx_chip *chip, int port,
331 phy_interface_t mode);
332
Vivien Didelot08ef7f12016-11-04 03:23:32 +0100333#define LINK_FORCED_DOWN 0
334#define LINK_FORCED_UP 1
335#define LINK_UNFORCED -2
336
337 /* Port's MAC link state
338 * Use LINK_FORCED_UP or LINK_FORCED_DOWN to force link up or down,
339 * or LINK_UNFORCED for normal link detection.
340 */
341 int (*port_set_link)(struct mv88e6xxx_chip *chip, int port, int link);
Vivien Didelot7f1ae072016-11-04 03:23:33 +0100342
343#define DUPLEX_UNFORCED -2
344
345 /* Port's MAC duplex mode
346 *
347 * Use DUPLEX_HALF or DUPLEX_FULL to force half or full duplex,
348 * or DUPLEX_UNFORCED for normal duplex detection.
349 */
350 int (*port_set_duplex)(struct mv88e6xxx_chip *chip, int port, int dup);
Vivien Didelot96a2b402016-11-04 03:23:35 +0100351
352#define SPEED_MAX INT_MAX
353#define SPEED_UNFORCED -2
354
355 /* Port's MAC speed (in Mbps)
356 *
357 * Depending on the chip, 10, 100, 200, 1000, 2500, 10000 are valid.
358 * Use SPEED_UNFORCED for normal detection, SPEED_MAX for max value.
359 */
360 int (*port_set_speed)(struct mv88e6xxx_chip *chip, int port, int speed);
Andrew Lunna605a0f2016-11-21 23:26:58 +0100361
Andrew Lunnef0a7312016-12-03 04:35:16 +0100362 int (*port_tag_remap)(struct mv88e6xxx_chip *chip, int port);
363
Andrew Lunn56995cb2016-12-03 04:35:19 +0100364 int (*port_set_frame_mode)(struct mv88e6xxx_chip *chip, int port,
365 enum mv88e6xxx_frame_mode mode);
Vivien Didelot601aeed2017-03-11 16:13:00 -0500366 int (*port_set_egress_floods)(struct mv88e6xxx_chip *chip, int port,
367 bool unicast, bool multicast);
Andrew Lunn56995cb2016-12-03 04:35:19 +0100368 int (*port_set_ether_type)(struct mv88e6xxx_chip *chip, int port,
369 u16 etype);
Vivien Didelotcd782652017-06-08 18:34:13 -0400370 int (*port_set_jumbo_size)(struct mv88e6xxx_chip *chip, int port,
371 size_t size);
Andrew Lunn56995cb2016-12-03 04:35:19 +0100372
Andrew Lunnef70b112016-12-03 04:45:18 +0100373 int (*port_egress_rate_limiting)(struct mv88e6xxx_chip *chip, int port);
Vivien Didelot08984322017-06-08 18:34:12 -0400374 int (*port_pause_limit)(struct mv88e6xxx_chip *chip, int port, u8 in,
375 u8 out);
Vivien Didelotc8c94892017-03-11 16:13:01 -0500376 int (*port_disable_learn_limit)(struct mv88e6xxx_chip *chip, int port);
Vivien Didelot9dbfb4e2017-03-11 16:13:02 -0500377 int (*port_disable_pri_override)(struct mv88e6xxx_chip *chip, int port);
Andrew Lunnef70b112016-12-03 04:45:18 +0100378
Andrew Lunnf39908d2017-02-04 20:02:50 +0100379 /* CMODE control what PHY mode the MAC will use, eg. SGMII, RGMII, etc.
380 * Some chips allow this to be configured on specific ports.
381 */
382 int (*port_set_cmode)(struct mv88e6xxx_chip *chip, int port,
383 phy_interface_t mode);
384
Andrew Lunna23b2962017-02-04 20:15:28 +0100385 /* Some devices have a per port register indicating what is
386 * the upstream port this port should forward to.
387 */
388 int (*port_set_upstream_port)(struct mv88e6xxx_chip *chip, int port,
389 int upstream_port);
390
Andrew Lunna605a0f2016-11-21 23:26:58 +0100391 /* Snapshot the statistics for a port. The statistics can then
392 * be read back a leisure but still with a consistent view.
393 */
394 int (*stats_snapshot)(struct mv88e6xxx_chip *chip, int port);
Andrew Lunnde2273872016-11-21 23:27:01 +0100395
396 /* Set the histogram mode for statistics, when the control registers
397 * are separated out of the STATS_OP register.
398 */
399 int (*stats_set_histogram)(struct mv88e6xxx_chip *chip);
Andrew Lunndfafe442016-11-21 23:27:02 +0100400
401 /* Return the number of strings describing statistics */
402 int (*stats_get_sset_count)(struct mv88e6xxx_chip *chip);
Andrew Lunn436fe172018-03-01 02:02:29 +0100403 int (*stats_get_strings)(struct mv88e6xxx_chip *chip, uint8_t *data);
404 int (*stats_get_stats)(struct mv88e6xxx_chip *chip, int port,
405 uint64_t *data);
Vivien Didelotfa8d1172017-06-08 18:34:11 -0400406 int (*set_cpu_port)(struct mv88e6xxx_chip *chip, int port);
407 int (*set_egress_port)(struct mv88e6xxx_chip *chip, int port);
Andrew Lunnfcd25162017-02-09 00:03:42 +0100408 const struct mv88e6xxx_irq_ops *watchdog_ops;
Andrew Lunn6e55f692016-12-03 04:45:16 +0100409
Andrew Lunn6e55f692016-12-03 04:45:16 +0100410 int (*mgmt_rsvd2cpu)(struct mv88e6xxx_chip *chip);
Vivien Didelotf1394b72017-05-01 14:05:22 -0400411
Andrew Lunn6d917822017-05-26 01:03:21 +0200412 /* Power on/off a SERDES interface */
413 int (*serdes_power)(struct mv88e6xxx_chip *chip, int port, bool on);
414
Andrew Lunn436fe172018-03-01 02:02:29 +0100415 /* Statistics from the SERDES interface */
416 int (*serdes_get_sset_count)(struct mv88e6xxx_chip *chip, int port);
Andrew Lunn65f60e42018-03-28 23:50:28 +0200417 int (*serdes_get_strings)(struct mv88e6xxx_chip *chip, int port,
418 uint8_t *data);
419 int (*serdes_get_stats)(struct mv88e6xxx_chip *chip, int port,
420 uint64_t *data);
Andrew Lunn436fe172018-03-01 02:02:29 +0100421
Vivien Didelotf1394b72017-05-01 14:05:22 -0400422 /* VLAN Translation Unit operations */
423 int (*vtu_getnext)(struct mv88e6xxx_chip *chip,
424 struct mv88e6xxx_vtu_entry *entry);
Vivien Didelot0ad5daf2017-05-01 14:05:23 -0400425 int (*vtu_loadpurge)(struct mv88e6xxx_chip *chip,
426 struct mv88e6xxx_vtu_entry *entry);
Brandon Streiff0d632c32018-02-14 01:07:44 +0100427
Brandon Streiffa73ccd62018-02-14 01:07:46 +0100428 /* GPIO operations */
429 const struct mv88e6xxx_gpio_ops *gpio_ops;
430
Brandon Streiff0d632c32018-02-14 01:07:44 +0100431 /* Interface to the AVB/PTP registers */
432 const struct mv88e6xxx_avb_ops *avb_ops;
Vivien Didelotb3469dd2016-09-29 12:22:00 -0400433};
434
Andrew Lunnfcd25162017-02-09 00:03:42 +0100435struct mv88e6xxx_irq_ops {
436 /* Action to be performed when the interrupt happens */
437 int (*irq_action)(struct mv88e6xxx_chip *chip, int irq);
438 /* Setup the hardware to generate the interrupt */
439 int (*irq_setup)(struct mv88e6xxx_chip *chip);
440 /* Reset the hardware to stop generating the interrupt */
441 void (*irq_free)(struct mv88e6xxx_chip *chip);
442};
443
Brandon Streiffa73ccd62018-02-14 01:07:46 +0100444struct mv88e6xxx_gpio_ops {
445 /* Get/set data on GPIO pin */
446 int (*get_data)(struct mv88e6xxx_chip *chip, unsigned int pin);
447 int (*set_data)(struct mv88e6xxx_chip *chip, unsigned int pin,
448 int value);
449
450 /* get/set GPIO direction */
451 int (*get_dir)(struct mv88e6xxx_chip *chip, unsigned int pin);
452 int (*set_dir)(struct mv88e6xxx_chip *chip, unsigned int pin,
453 bool input);
454
455 /* get/set GPIO pin control */
456 int (*get_pctl)(struct mv88e6xxx_chip *chip, unsigned int pin,
457 int *func);
458 int (*set_pctl)(struct mv88e6xxx_chip *chip, unsigned int pin,
459 int func);
460};
461
Brandon Streiff0d632c32018-02-14 01:07:44 +0100462struct mv88e6xxx_avb_ops {
463 /* Access port-scoped Precision Time Protocol registers */
464 int (*port_ptp_read)(struct mv88e6xxx_chip *chip, int port, int addr,
465 u16 *data, int len);
466 int (*port_ptp_write)(struct mv88e6xxx_chip *chip, int port, int addr,
467 u16 data);
468
469 /* Access global Precision Time Protocol registers */
470 int (*ptp_read)(struct mv88e6xxx_chip *chip, int addr, u16 *data,
471 int len);
472 int (*ptp_write)(struct mv88e6xxx_chip *chip, int addr, u16 data);
473
474 /* Access global Time Application Interface registers */
475 int (*tai_read)(struct mv88e6xxx_chip *chip, int addr, u16 *data,
476 int len);
477 int (*tai_write)(struct mv88e6xxx_chip *chip, int addr, u16 data);
478};
479
Andrew Lunndfafe442016-11-21 23:27:02 +0100480#define STATS_TYPE_PORT BIT(0)
481#define STATS_TYPE_BANK0 BIT(1)
482#define STATS_TYPE_BANK1 BIT(2)
Andrew Lunnf5e2ed02015-12-23 13:23:17 +0100483
Lennert Buytenhek91da11f2008-10-07 13:44:02 +0000484struct mv88e6xxx_hw_stat {
485 char string[ETH_GSTRING_LEN];
Andrew Lunncda9f4a2018-03-01 02:02:31 +0100486 size_t size;
Lennert Buytenhek91da11f2008-10-07 13:44:02 +0000487 int reg;
Andrew Lunndfafe442016-11-21 23:27:02 +0100488 int type;
Lennert Buytenhek91da11f2008-10-07 13:44:02 +0000489};
490
Vivien Didelotf3645652017-03-30 17:37:07 -0400491static inline bool mv88e6xxx_has_pvt(struct mv88e6xxx_chip *chip)
492{
493 return chip->info->pvt;
494}
495
Vivien Didelotde333762016-09-29 12:21:56 -0400496static inline unsigned int mv88e6xxx_num_databases(struct mv88e6xxx_chip *chip)
497{
498 return chip->info->num_databases;
499}
500
Vivien Didelot370b4ff2016-09-29 12:21:57 -0400501static inline unsigned int mv88e6xxx_num_ports(struct mv88e6xxx_chip *chip)
502{
503 return chip->info->num_ports;
504}
505
Vivien Didelot4d294af2017-03-11 16:12:47 -0500506static inline u16 mv88e6xxx_port_mask(struct mv88e6xxx_chip *chip)
507{
508 return GENMASK(mv88e6xxx_num_ports(chip) - 1, 0);
509}
510
Brandon Streiffa73ccd62018-02-14 01:07:46 +0100511static inline unsigned int mv88e6xxx_num_gpio(struct mv88e6xxx_chip *chip)
512{
513 return chip->info->num_gpio;
514}
515
Vivien Didelotec561272016-09-02 14:45:33 -0400516int mv88e6xxx_read(struct mv88e6xxx_chip *chip, int addr, int reg, u16 *val);
517int mv88e6xxx_write(struct mv88e6xxx_chip *chip, int addr, int reg, u16 val);
518int mv88e6xxx_update(struct mv88e6xxx_chip *chip, int addr, int reg,
519 u16 update);
520int mv88e6xxx_wait(struct mv88e6xxx_chip *chip, int addr, int reg, u16 mask);
Andrew Lunn10fa5bf2017-05-26 01:03:20 +0200521struct mii_bus *mv88e6xxx_default_mdio_bus(struct mv88e6xxx_chip *chip);
Vivien Didelot4d5f2ba72017-06-02 17:06:15 -0400522
523#endif /* _MV88E6XXX_CHIP_H */