cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

global2_avb.c (6545B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * Marvell 88E6xxx Switch Global 2 Registers support
      4 *
      5 * Copyright (c) 2008 Marvell Semiconductor
      6 *
      7 * Copyright (c) 2016-2017 Savoir-faire Linux Inc.
      8 *	Vivien Didelot <vivien.didelot@savoirfairelinux.com>
      9 *
     10 * Copyright (c) 2017 National Instruments
     11 *	Brandon Streiff <brandon.streiff@ni.com>
     12 */
     13
     14#include <linux/bitfield.h>
     15
     16#include "global2.h"
     17
     18/* Offset 0x16: AVB Command Register
     19 * Offset 0x17: AVB Data Register
     20 *
     21 * There are two different versions of this register interface:
     22 *    "6352": 3-bit "op" field, 4-bit "port" field.
     23 *    "6390": 2-bit "op" field, 5-bit "port" field.
     24 *
     25 * The "op" codes are different between the two, as well as the special
     26 * port fields for global PTP and TAI configuration.
     27 */
     28
     29/* mv88e6xxx_g2_avb_read -- Read one or multiple 16-bit words.
     30 * The hardware supports snapshotting up to four contiguous registers.
     31 */
     32static int mv88e6xxx_g2_avb_wait(struct mv88e6xxx_chip *chip)
     33{
     34	int bit = __bf_shf(MV88E6352_G2_AVB_CMD_BUSY);
     35
     36	return mv88e6xxx_g2_wait_bit(chip, MV88E6352_G2_AVB_CMD, bit, 0);
     37}
     38
     39static int mv88e6xxx_g2_avb_read(struct mv88e6xxx_chip *chip, u16 readop,
     40				 u16 *data, int len)
     41{
     42	int err;
     43	int i;
     44
     45	err = mv88e6xxx_g2_avb_wait(chip);
     46	if (err)
     47		return err;
     48
     49	/* Hardware can only snapshot four words. */
     50	if (len > 4)
     51		return -E2BIG;
     52
     53	err = mv88e6xxx_g2_write(chip, MV88E6352_G2_AVB_CMD,
     54				 MV88E6352_G2_AVB_CMD_BUSY | readop);
     55	if (err)
     56		return err;
     57
     58	err = mv88e6xxx_g2_avb_wait(chip);
     59	if (err)
     60		return err;
     61
     62	for (i = 0; i < len; ++i) {
     63		err = mv88e6xxx_g2_read(chip, MV88E6352_G2_AVB_DATA,
     64					&data[i]);
     65		if (err)
     66			return err;
     67	}
     68
     69	return 0;
     70}
     71
     72/* mv88e6xxx_g2_avb_write -- Write one 16-bit word. */
     73static int mv88e6xxx_g2_avb_write(struct mv88e6xxx_chip *chip, u16 writeop,
     74				  u16 data)
     75{
     76	int err;
     77
     78	err = mv88e6xxx_g2_avb_wait(chip);
     79	if (err)
     80		return err;
     81
     82	err = mv88e6xxx_g2_write(chip, MV88E6352_G2_AVB_DATA, data);
     83	if (err)
     84		return err;
     85
     86	err = mv88e6xxx_g2_write(chip, MV88E6352_G2_AVB_CMD,
     87				 MV88E6352_G2_AVB_CMD_BUSY | writeop);
     88
     89	return mv88e6xxx_g2_avb_wait(chip);
     90}
     91
     92static int mv88e6352_g2_avb_port_ptp_read(struct mv88e6xxx_chip *chip,
     93					  int port, int addr, u16 *data,
     94					  int len)
     95{
     96	u16 readop = (len == 1 ? MV88E6352_G2_AVB_CMD_OP_READ :
     97				 MV88E6352_G2_AVB_CMD_OP_READ_INCR) |
     98		     (port << 8) | (MV88E6352_G2_AVB_CMD_BLOCK_PTP << 5) |
     99		     addr;
    100
    101	return mv88e6xxx_g2_avb_read(chip, readop, data, len);
    102}
    103
    104static int mv88e6352_g2_avb_port_ptp_write(struct mv88e6xxx_chip *chip,
    105					   int port, int addr, u16 data)
    106{
    107	u16 writeop = MV88E6352_G2_AVB_CMD_OP_WRITE | (port << 8) |
    108		      (MV88E6352_G2_AVB_CMD_BLOCK_PTP << 5) | addr;
    109
    110	return mv88e6xxx_g2_avb_write(chip, writeop, data);
    111}
    112
    113static int mv88e6352_g2_avb_ptp_read(struct mv88e6xxx_chip *chip, int addr,
    114				     u16 *data, int len)
    115{
    116	return mv88e6352_g2_avb_port_ptp_read(chip,
    117					MV88E6352_G2_AVB_CMD_PORT_PTPGLOBAL,
    118					addr, data, len);
    119}
    120
    121static int mv88e6352_g2_avb_ptp_write(struct mv88e6xxx_chip *chip, int addr,
    122				      u16 data)
    123{
    124	return mv88e6352_g2_avb_port_ptp_write(chip,
    125					MV88E6352_G2_AVB_CMD_PORT_PTPGLOBAL,
    126					addr, data);
    127}
    128
    129static int mv88e6352_g2_avb_tai_read(struct mv88e6xxx_chip *chip, int addr,
    130				     u16 *data, int len)
    131{
    132	return mv88e6352_g2_avb_port_ptp_read(chip,
    133					MV88E6352_G2_AVB_CMD_PORT_TAIGLOBAL,
    134					addr, data, len);
    135}
    136
    137static int mv88e6352_g2_avb_tai_write(struct mv88e6xxx_chip *chip, int addr,
    138				      u16 data)
    139{
    140	return mv88e6352_g2_avb_port_ptp_write(chip,
    141					MV88E6352_G2_AVB_CMD_PORT_TAIGLOBAL,
    142					addr, data);
    143}
    144
    145const struct mv88e6xxx_avb_ops mv88e6352_avb_ops = {
    146	.port_ptp_read		= mv88e6352_g2_avb_port_ptp_read,
    147	.port_ptp_write		= mv88e6352_g2_avb_port_ptp_write,
    148	.ptp_read		= mv88e6352_g2_avb_ptp_read,
    149	.ptp_write		= mv88e6352_g2_avb_ptp_write,
    150	.tai_read		= mv88e6352_g2_avb_tai_read,
    151	.tai_write		= mv88e6352_g2_avb_tai_write,
    152};
    153
    154static int mv88e6165_g2_avb_tai_read(struct mv88e6xxx_chip *chip, int addr,
    155				     u16 *data, int len)
    156{
    157	return mv88e6352_g2_avb_port_ptp_read(chip,
    158					MV88E6165_G2_AVB_CMD_PORT_PTPGLOBAL,
    159					addr, data, len);
    160}
    161
    162static int mv88e6165_g2_avb_tai_write(struct mv88e6xxx_chip *chip, int addr,
    163				      u16 data)
    164{
    165	return mv88e6352_g2_avb_port_ptp_write(chip,
    166					MV88E6165_G2_AVB_CMD_PORT_PTPGLOBAL,
    167					addr, data);
    168}
    169
    170const struct mv88e6xxx_avb_ops mv88e6165_avb_ops = {
    171	.port_ptp_read		= mv88e6352_g2_avb_port_ptp_read,
    172	.port_ptp_write		= mv88e6352_g2_avb_port_ptp_write,
    173	.ptp_read		= mv88e6352_g2_avb_ptp_read,
    174	.ptp_write		= mv88e6352_g2_avb_ptp_write,
    175	.tai_read		= mv88e6165_g2_avb_tai_read,
    176	.tai_write		= mv88e6165_g2_avb_tai_write,
    177};
    178
    179static int mv88e6390_g2_avb_port_ptp_read(struct mv88e6xxx_chip *chip,
    180					  int port, int addr, u16 *data,
    181					  int len)
    182{
    183	u16 readop = (len == 1 ? MV88E6390_G2_AVB_CMD_OP_READ :
    184				 MV88E6390_G2_AVB_CMD_OP_READ_INCR) |
    185		     (port << 8) | (MV88E6352_G2_AVB_CMD_BLOCK_PTP << 5) |
    186		     addr;
    187
    188	return mv88e6xxx_g2_avb_read(chip, readop, data, len);
    189}
    190
    191static int mv88e6390_g2_avb_port_ptp_write(struct mv88e6xxx_chip *chip,
    192					   int port, int addr, u16 data)
    193{
    194	u16 writeop = MV88E6390_G2_AVB_CMD_OP_WRITE | (port << 8) |
    195		      (MV88E6352_G2_AVB_CMD_BLOCK_PTP << 5) | addr;
    196
    197	return mv88e6xxx_g2_avb_write(chip, writeop, data);
    198}
    199
    200static int mv88e6390_g2_avb_ptp_read(struct mv88e6xxx_chip *chip, int addr,
    201				     u16 *data, int len)
    202{
    203	return mv88e6390_g2_avb_port_ptp_read(chip,
    204					MV88E6390_G2_AVB_CMD_PORT_PTPGLOBAL,
    205					addr, data, len);
    206}
    207
    208static int mv88e6390_g2_avb_ptp_write(struct mv88e6xxx_chip *chip, int addr,
    209				      u16 data)
    210{
    211	return mv88e6390_g2_avb_port_ptp_write(chip,
    212					MV88E6390_G2_AVB_CMD_PORT_PTPGLOBAL,
    213					addr, data);
    214}
    215
    216static int mv88e6390_g2_avb_tai_read(struct mv88e6xxx_chip *chip, int addr,
    217				     u16 *data, int len)
    218{
    219	return mv88e6390_g2_avb_port_ptp_read(chip,
    220					MV88E6390_G2_AVB_CMD_PORT_TAIGLOBAL,
    221					addr, data, len);
    222}
    223
    224static int mv88e6390_g2_avb_tai_write(struct mv88e6xxx_chip *chip, int addr,
    225				      u16 data)
    226{
    227	return mv88e6390_g2_avb_port_ptp_write(chip,
    228					MV88E6390_G2_AVB_CMD_PORT_TAIGLOBAL,
    229					addr, data);
    230}
    231
    232const struct mv88e6xxx_avb_ops mv88e6390_avb_ops = {
    233	.port_ptp_read		= mv88e6390_g2_avb_port_ptp_read,
    234	.port_ptp_write		= mv88e6390_g2_avb_port_ptp_write,
    235	.ptp_read		= mv88e6390_g2_avb_ptp_read,
    236	.ptp_write		= mv88e6390_g2_avb_ptp_write,
    237	.tai_read		= mv88e6390_g2_avb_tai_read,
    238	.tai_write		= mv88e6390_g2_avb_tai_write,
    239};