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

mcdi_port.c (2960B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/****************************************************************************
      3 * Driver for Solarflare network controllers and boards
      4 * Copyright 2009-2013 Solarflare Communications Inc.
      5 */
      6
      7/*
      8 * Driver for PHY related operations via MCDI.
      9 */
     10
     11#include <linux/slab.h>
     12#include "efx.h"
     13#include "mcdi_port.h"
     14#include "mcdi.h"
     15#include "mcdi_pcol.h"
     16#include "nic.h"
     17#include "selftest.h"
     18#include "mcdi_port_common.h"
     19
     20static int efx_mcdi_mdio_read(struct net_device *net_dev,
     21			      int prtad, int devad, u16 addr)
     22{
     23	struct efx_nic *efx = netdev_priv(net_dev);
     24	MCDI_DECLARE_BUF(inbuf, MC_CMD_MDIO_READ_IN_LEN);
     25	MCDI_DECLARE_BUF(outbuf, MC_CMD_MDIO_READ_OUT_LEN);
     26	size_t outlen;
     27	int rc;
     28
     29	MCDI_SET_DWORD(inbuf, MDIO_READ_IN_BUS, efx->mdio_bus);
     30	MCDI_SET_DWORD(inbuf, MDIO_READ_IN_PRTAD, prtad);
     31	MCDI_SET_DWORD(inbuf, MDIO_READ_IN_DEVAD, devad);
     32	MCDI_SET_DWORD(inbuf, MDIO_READ_IN_ADDR, addr);
     33
     34	rc = efx_siena_mcdi_rpc(efx, MC_CMD_MDIO_READ, inbuf, sizeof(inbuf),
     35				outbuf, sizeof(outbuf), &outlen);
     36	if (rc)
     37		return rc;
     38
     39	if (MCDI_DWORD(outbuf, MDIO_READ_OUT_STATUS) !=
     40	    MC_CMD_MDIO_STATUS_GOOD)
     41		return -EIO;
     42
     43	return (u16)MCDI_DWORD(outbuf, MDIO_READ_OUT_VALUE);
     44}
     45
     46static int efx_mcdi_mdio_write(struct net_device *net_dev,
     47			       int prtad, int devad, u16 addr, u16 value)
     48{
     49	struct efx_nic *efx = netdev_priv(net_dev);
     50	MCDI_DECLARE_BUF(inbuf, MC_CMD_MDIO_WRITE_IN_LEN);
     51	MCDI_DECLARE_BUF(outbuf, MC_CMD_MDIO_WRITE_OUT_LEN);
     52	size_t outlen;
     53	int rc;
     54
     55	MCDI_SET_DWORD(inbuf, MDIO_WRITE_IN_BUS, efx->mdio_bus);
     56	MCDI_SET_DWORD(inbuf, MDIO_WRITE_IN_PRTAD, prtad);
     57	MCDI_SET_DWORD(inbuf, MDIO_WRITE_IN_DEVAD, devad);
     58	MCDI_SET_DWORD(inbuf, MDIO_WRITE_IN_ADDR, addr);
     59	MCDI_SET_DWORD(inbuf, MDIO_WRITE_IN_VALUE, value);
     60
     61	rc = efx_siena_mcdi_rpc(efx, MC_CMD_MDIO_WRITE, inbuf, sizeof(inbuf),
     62				outbuf, sizeof(outbuf), &outlen);
     63	if (rc)
     64		return rc;
     65
     66	if (MCDI_DWORD(outbuf, MDIO_WRITE_OUT_STATUS) !=
     67	    MC_CMD_MDIO_STATUS_GOOD)
     68		return -EIO;
     69
     70	return 0;
     71}
     72
     73bool efx_siena_mcdi_mac_check_fault(struct efx_nic *efx)
     74{
     75	MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_LINK_OUT_LEN);
     76	size_t outlength;
     77	int rc;
     78
     79	BUILD_BUG_ON(MC_CMD_GET_LINK_IN_LEN != 0);
     80
     81	rc = efx_siena_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0,
     82				outbuf, sizeof(outbuf), &outlength);
     83	if (rc)
     84		return true;
     85
     86	return MCDI_DWORD(outbuf, GET_LINK_OUT_MAC_FAULT) != 0;
     87}
     88
     89int efx_siena_mcdi_port_probe(struct efx_nic *efx)
     90{
     91	int rc;
     92
     93	/* Set up MDIO structure for PHY */
     94	efx->mdio.mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22;
     95	efx->mdio.mdio_read = efx_mcdi_mdio_read;
     96	efx->mdio.mdio_write = efx_mcdi_mdio_write;
     97
     98	/* Fill out MDIO structure, loopback modes, and initial link state */
     99	rc = efx_siena_mcdi_phy_probe(efx);
    100	if (rc != 0)
    101		return rc;
    102
    103	return efx_siena_mcdi_mac_init_stats(efx);
    104}
    105
    106void efx_siena_mcdi_port_remove(struct efx_nic *efx)
    107{
    108	efx_siena_mcdi_phy_remove(efx);
    109	efx_siena_mcdi_mac_fini_stats(efx);
    110}