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

ax88796c_spi.c (2926B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Copyright (c) 2010 ASIX Electronics Corporation
      4 * Copyright (c) 2020 Samsung Electronics Co., Ltd.
      5 *
      6 * ASIX AX88796C SPI Fast Ethernet Linux driver
      7 */
      8
      9#define pr_fmt(fmt)	"ax88796c: " fmt
     10
     11#include <linux/string.h>
     12#include <linux/spi/spi.h>
     13
     14#include "ax88796c_spi.h"
     15
     16const u8 ax88796c_rx_cmd_buf[5] = {AX_SPICMD_READ_RXQ, 0xFF, 0xFF, 0xFF, 0xFF};
     17const u8 ax88796c_tx_cmd_buf[4] = {AX_SPICMD_WRITE_TXQ, 0xFF, 0xFF, 0xFF};
     18
     19/* driver bus management functions */
     20int axspi_wakeup(struct axspi_data *ax_spi)
     21{
     22	int ret;
     23
     24	ax_spi->cmd_buf[0] = AX_SPICMD_EXIT_PWD;	/* OP */
     25	ret = spi_write(ax_spi->spi, ax_spi->cmd_buf, 1);
     26	if (ret)
     27		dev_err(&ax_spi->spi->dev, "%s() failed: ret = %d\n", __func__, ret);
     28	return ret;
     29}
     30
     31int axspi_read_status(struct axspi_data *ax_spi, struct spi_status *status)
     32{
     33	int ret;
     34
     35	/* OP */
     36	ax_spi->cmd_buf[0] = AX_SPICMD_READ_STATUS;
     37	ret = spi_write_then_read(ax_spi->spi, ax_spi->cmd_buf, 1, (u8 *)status, 3);
     38	if (ret)
     39		dev_err(&ax_spi->spi->dev, "%s() failed: ret = %d\n", __func__, ret);
     40	else
     41		le16_to_cpus(&status->isr);
     42
     43	return ret;
     44}
     45
     46int axspi_read_rxq(struct axspi_data *ax_spi, void *data, int len)
     47{
     48	struct spi_transfer *xfer = ax_spi->spi_rx_xfer;
     49	int ret;
     50
     51	memcpy(ax_spi->cmd_buf, ax88796c_rx_cmd_buf, 5);
     52
     53	xfer->tx_buf = ax_spi->cmd_buf;
     54	xfer->rx_buf = NULL;
     55	xfer->len = ax_spi->comp ? 2 : 5;
     56	xfer->bits_per_word = 8;
     57	spi_message_add_tail(xfer, &ax_spi->rx_msg);
     58
     59	xfer++;
     60	xfer->rx_buf = data;
     61	xfer->tx_buf = NULL;
     62	xfer->len = len;
     63	xfer->bits_per_word = 8;
     64	spi_message_add_tail(xfer, &ax_spi->rx_msg);
     65	ret = spi_sync(ax_spi->spi, &ax_spi->rx_msg);
     66	if (ret)
     67		dev_err(&ax_spi->spi->dev, "%s() failed: ret = %d\n", __func__, ret);
     68
     69	return ret;
     70}
     71
     72int axspi_write_txq(const struct axspi_data *ax_spi, void *data, int len)
     73{
     74	return spi_write(ax_spi->spi, data, len);
     75}
     76
     77u16 axspi_read_reg(struct axspi_data *ax_spi, u8 reg)
     78{
     79	int ret;
     80	int len = ax_spi->comp ? 3 : 4;
     81
     82	ax_spi->cmd_buf[0] = 0x03;	/* OP code read register */
     83	ax_spi->cmd_buf[1] = reg;	/* register address */
     84	ax_spi->cmd_buf[2] = 0xFF;	/* dumy cycle */
     85	ax_spi->cmd_buf[3] = 0xFF;	/* dumy cycle */
     86	ret = spi_write_then_read(ax_spi->spi,
     87				  ax_spi->cmd_buf, len,
     88				  ax_spi->rx_buf, 2);
     89	if (ret) {
     90		dev_err(&ax_spi->spi->dev,
     91			"%s() failed: ret = %d\n", __func__, ret);
     92		return 0xFFFF;
     93	}
     94
     95	le16_to_cpus((u16 *)ax_spi->rx_buf);
     96
     97	return *(u16 *)ax_spi->rx_buf;
     98}
     99
    100int axspi_write_reg(struct axspi_data *ax_spi, u8 reg, u16 value)
    101{
    102	int ret;
    103
    104	memset(ax_spi->cmd_buf, 0, sizeof(ax_spi->cmd_buf));
    105	ax_spi->cmd_buf[0] = AX_SPICMD_WRITE_REG;	/* OP code read register */
    106	ax_spi->cmd_buf[1] = reg;			/* register address */
    107	ax_spi->cmd_buf[2] = value;
    108	ax_spi->cmd_buf[3] = value >> 8;
    109
    110	ret = spi_write(ax_spi->spi, ax_spi->cmd_buf, 4);
    111	if (ret)
    112		dev_err(&ax_spi->spi->dev, "%s() failed: ret = %d\n", __func__, ret);
    113	return ret;
    114}
    115