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 (3042B)


      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_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_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
     73u32 efx_mcdi_phy_get_caps(struct efx_nic *efx)
     74{
     75	struct efx_mcdi_phy_data *phy_data = efx->phy_data;
     76
     77	return phy_data->supported_cap;
     78}
     79
     80bool efx_mcdi_mac_check_fault(struct efx_nic *efx)
     81{
     82	MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_LINK_OUT_LEN);
     83	size_t outlength;
     84	int rc;
     85
     86	BUILD_BUG_ON(MC_CMD_GET_LINK_IN_LEN != 0);
     87
     88	rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0,
     89			  outbuf, sizeof(outbuf), &outlength);
     90	if (rc)
     91		return true;
     92
     93	return MCDI_DWORD(outbuf, GET_LINK_OUT_MAC_FAULT) != 0;
     94}
     95
     96int efx_mcdi_port_probe(struct efx_nic *efx)
     97{
     98	int rc;
     99
    100	/* Set up MDIO structure for PHY */
    101	efx->mdio.mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22;
    102	efx->mdio.mdio_read = efx_mcdi_mdio_read;
    103	efx->mdio.mdio_write = efx_mcdi_mdio_write;
    104
    105	/* Fill out MDIO structure, loopback modes, and initial link state */
    106	rc = efx_mcdi_phy_probe(efx);
    107	if (rc != 0)
    108		return rc;
    109
    110	return efx_mcdi_mac_init_stats(efx);
    111}
    112
    113void efx_mcdi_port_remove(struct efx_nic *efx)
    114{
    115	efx_mcdi_phy_remove(efx);
    116	efx_mcdi_mac_fini_stats(efx);
    117}