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

xgbe-i2c.c (15738B)


      1/*
      2 * AMD 10Gb Ethernet driver
      3 *
      4 * This file is available to you under your choice of the following two
      5 * licenses:
      6 *
      7 * License 1: GPLv2
      8 *
      9 * Copyright (c) 2016 Advanced Micro Devices, Inc.
     10 *
     11 * This file is free software; you may copy, redistribute and/or modify
     12 * it under the terms of the GNU General Public License as published by
     13 * the Free Software Foundation, either version 2 of the License, or (at
     14 * your option) any later version.
     15 *
     16 * This file is distributed in the hope that it will be useful, but
     17 * WITHOUT ANY WARRANTY; without even the implied warranty of
     18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     19 * General Public License for more details.
     20 *
     21 * You should have received a copy of the GNU General Public License
     22 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
     23 *
     24 * This file incorporates work covered by the following copyright and
     25 * permission notice:
     26 *     The Synopsys DWC ETHER XGMAC Software Driver and documentation
     27 *     (hereinafter "Software") is an unsupported proprietary work of Synopsys,
     28 *     Inc. unless otherwise expressly agreed to in writing between Synopsys
     29 *     and you.
     30 *
     31 *     The Software IS NOT an item of Licensed Software or Licensed Product
     32 *     under any End User Software License Agreement or Agreement for Licensed
     33 *     Product with Synopsys or any supplement thereto.  Permission is hereby
     34 *     granted, free of charge, to any person obtaining a copy of this software
     35 *     annotated with this license and the Software, to deal in the Software
     36 *     without restriction, including without limitation the rights to use,
     37 *     copy, modify, merge, publish, distribute, sublicense, and/or sell copies
     38 *     of the Software, and to permit persons to whom the Software is furnished
     39 *     to do so, subject to the following conditions:
     40 *
     41 *     The above copyright notice and this permission notice shall be included
     42 *     in all copies or substantial portions of the Software.
     43 *
     44 *     THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
     45 *     BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     46 *     TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
     47 *     PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
     48 *     BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     49 *     CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     50 *     SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     51 *     INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     52 *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     53 *     ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
     54 *     THE POSSIBILITY OF SUCH DAMAGE.
     55 *
     56 *
     57 * License 2: Modified BSD
     58 *
     59 * Copyright (c) 2016 Advanced Micro Devices, Inc.
     60 * All rights reserved.
     61 *
     62 * Redistribution and use in source and binary forms, with or without
     63 * modification, are permitted provided that the following conditions are met:
     64 *     * Redistributions of source code must retain the above copyright
     65 *       notice, this list of conditions and the following disclaimer.
     66 *     * Redistributions in binary form must reproduce the above copyright
     67 *       notice, this list of conditions and the following disclaimer in the
     68 *       documentation and/or other materials provided with the distribution.
     69 *     * Neither the name of Advanced Micro Devices, Inc. nor the
     70 *       names of its contributors may be used to endorse or promote products
     71 *       derived from this software without specific prior written permission.
     72 *
     73 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     74 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     75 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     76 * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
     77 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     78 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     79 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
     80 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     81 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     82 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     83 *
     84 * This file incorporates work covered by the following copyright and
     85 * permission notice:
     86 *     The Synopsys DWC ETHER XGMAC Software Driver and documentation
     87 *     (hereinafter "Software") is an unsupported proprietary work of Synopsys,
     88 *     Inc. unless otherwise expressly agreed to in writing between Synopsys
     89 *     and you.
     90 *
     91 *     The Software IS NOT an item of Licensed Software or Licensed Product
     92 *     under any End User Software License Agreement or Agreement for Licensed
     93 *     Product with Synopsys or any supplement thereto.  Permission is hereby
     94 *     granted, free of charge, to any person obtaining a copy of this software
     95 *     annotated with this license and the Software, to deal in the Software
     96 *     without restriction, including without limitation the rights to use,
     97 *     copy, modify, merge, publish, distribute, sublicense, and/or sell copies
     98 *     of the Software, and to permit persons to whom the Software is furnished
     99 *     to do so, subject to the following conditions:
    100 *
    101 *     The above copyright notice and this permission notice shall be included
    102 *     in all copies or substantial portions of the Software.
    103 *
    104 *     THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
    105 *     BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
    106 *     TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
    107 *     PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
    108 *     BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    109 *     CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    110 *     SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    111 *     INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    112 *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    113 *     ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
    114 *     THE POSSIBILITY OF SUCH DAMAGE.
    115 */
    116
    117#include <linux/module.h>
    118#include <linux/interrupt.h>
    119#include <linux/kmod.h>
    120#include <linux/delay.h>
    121#include <linux/completion.h>
    122#include <linux/mutex.h>
    123
    124#include "xgbe.h"
    125#include "xgbe-common.h"
    126
    127#define XGBE_ABORT_COUNT	500
    128#define XGBE_DISABLE_COUNT	1000
    129
    130#define XGBE_STD_SPEED		1
    131
    132#define XGBE_INTR_RX_FULL	BIT(IC_RAW_INTR_STAT_RX_FULL_INDEX)
    133#define XGBE_INTR_TX_EMPTY	BIT(IC_RAW_INTR_STAT_TX_EMPTY_INDEX)
    134#define XGBE_INTR_TX_ABRT	BIT(IC_RAW_INTR_STAT_TX_ABRT_INDEX)
    135#define XGBE_INTR_STOP_DET	BIT(IC_RAW_INTR_STAT_STOP_DET_INDEX)
    136#define XGBE_DEFAULT_INT_MASK	(XGBE_INTR_RX_FULL  |	\
    137				 XGBE_INTR_TX_EMPTY |	\
    138				 XGBE_INTR_TX_ABRT  |	\
    139				 XGBE_INTR_STOP_DET)
    140
    141#define XGBE_I2C_READ		BIT(8)
    142#define XGBE_I2C_STOP		BIT(9)
    143
    144static int xgbe_i2c_abort(struct xgbe_prv_data *pdata)
    145{
    146	unsigned int wait = XGBE_ABORT_COUNT;
    147
    148	/* Must be enabled to recognize the abort request */
    149	XI2C_IOWRITE_BITS(pdata, IC_ENABLE, EN, 1);
    150
    151	/* Issue the abort */
    152	XI2C_IOWRITE_BITS(pdata, IC_ENABLE, ABORT, 1);
    153
    154	while (wait--) {
    155		if (!XI2C_IOREAD_BITS(pdata, IC_ENABLE, ABORT))
    156			return 0;
    157
    158		usleep_range(500, 600);
    159	}
    160
    161	return -EBUSY;
    162}
    163
    164static int xgbe_i2c_set_enable(struct xgbe_prv_data *pdata, bool enable)
    165{
    166	unsigned int wait = XGBE_DISABLE_COUNT;
    167	unsigned int mode = enable ? 1 : 0;
    168
    169	while (wait--) {
    170		XI2C_IOWRITE_BITS(pdata, IC_ENABLE, EN, mode);
    171		if (XI2C_IOREAD_BITS(pdata, IC_ENABLE_STATUS, EN) == mode)
    172			return 0;
    173
    174		usleep_range(100, 110);
    175	}
    176
    177	return -EBUSY;
    178}
    179
    180static int xgbe_i2c_disable(struct xgbe_prv_data *pdata)
    181{
    182	unsigned int ret;
    183
    184	ret = xgbe_i2c_set_enable(pdata, false);
    185	if (ret) {
    186		/* Disable failed, try an abort */
    187		ret = xgbe_i2c_abort(pdata);
    188		if (ret)
    189			return ret;
    190
    191		/* Abort succeeded, try to disable again */
    192		ret = xgbe_i2c_set_enable(pdata, false);
    193	}
    194
    195	return ret;
    196}
    197
    198static int xgbe_i2c_enable(struct xgbe_prv_data *pdata)
    199{
    200	return xgbe_i2c_set_enable(pdata, true);
    201}
    202
    203static void xgbe_i2c_clear_all_interrupts(struct xgbe_prv_data *pdata)
    204{
    205	XI2C_IOREAD(pdata, IC_CLR_INTR);
    206}
    207
    208static void xgbe_i2c_disable_interrupts(struct xgbe_prv_data *pdata)
    209{
    210	XI2C_IOWRITE(pdata, IC_INTR_MASK, 0);
    211}
    212
    213static void xgbe_i2c_enable_interrupts(struct xgbe_prv_data *pdata)
    214{
    215	XI2C_IOWRITE(pdata, IC_INTR_MASK, XGBE_DEFAULT_INT_MASK);
    216}
    217
    218static void xgbe_i2c_write(struct xgbe_prv_data *pdata)
    219{
    220	struct xgbe_i2c_op_state *state = &pdata->i2c.op_state;
    221	unsigned int tx_slots;
    222	unsigned int cmd;
    223
    224	/* Configured to never receive Rx overflows, so fill up Tx fifo */
    225	tx_slots = pdata->i2c.tx_fifo_size - XI2C_IOREAD(pdata, IC_TXFLR);
    226	while (tx_slots && state->tx_len) {
    227		if (state->op->cmd == XGBE_I2C_CMD_READ)
    228			cmd = XGBE_I2C_READ;
    229		else
    230			cmd = *state->tx_buf++;
    231
    232		if (state->tx_len == 1)
    233			XI2C_SET_BITS(cmd, IC_DATA_CMD, STOP, 1);
    234
    235		XI2C_IOWRITE(pdata, IC_DATA_CMD, cmd);
    236
    237		tx_slots--;
    238		state->tx_len--;
    239	}
    240
    241	/* No more Tx operations, so ignore TX_EMPTY and return */
    242	if (!state->tx_len)
    243		XI2C_IOWRITE_BITS(pdata, IC_INTR_MASK, TX_EMPTY, 0);
    244}
    245
    246static void xgbe_i2c_read(struct xgbe_prv_data *pdata)
    247{
    248	struct xgbe_i2c_op_state *state = &pdata->i2c.op_state;
    249	unsigned int rx_slots;
    250
    251	/* Anything to be read? */
    252	if (state->op->cmd != XGBE_I2C_CMD_READ)
    253		return;
    254
    255	rx_slots = XI2C_IOREAD(pdata, IC_RXFLR);
    256	while (rx_slots && state->rx_len) {
    257		*state->rx_buf++ = XI2C_IOREAD(pdata, IC_DATA_CMD);
    258		state->rx_len--;
    259		rx_slots--;
    260	}
    261}
    262
    263static void xgbe_i2c_clear_isr_interrupts(struct xgbe_prv_data *pdata,
    264					  unsigned int isr)
    265{
    266	struct xgbe_i2c_op_state *state = &pdata->i2c.op_state;
    267
    268	if (isr & XGBE_INTR_TX_ABRT) {
    269		state->tx_abort_source = XI2C_IOREAD(pdata, IC_TX_ABRT_SOURCE);
    270		XI2C_IOREAD(pdata, IC_CLR_TX_ABRT);
    271	}
    272
    273	if (isr & XGBE_INTR_STOP_DET)
    274		XI2C_IOREAD(pdata, IC_CLR_STOP_DET);
    275}
    276
    277static void xgbe_i2c_isr_task(struct tasklet_struct *t)
    278{
    279	struct xgbe_prv_data *pdata = from_tasklet(pdata, t, tasklet_i2c);
    280	struct xgbe_i2c_op_state *state = &pdata->i2c.op_state;
    281	unsigned int isr;
    282
    283	isr = XI2C_IOREAD(pdata, IC_RAW_INTR_STAT);
    284	if (!isr)
    285		goto reissue_check;
    286
    287	netif_dbg(pdata, intr, pdata->netdev,
    288		  "I2C interrupt received: status=%#010x\n", isr);
    289
    290	xgbe_i2c_clear_isr_interrupts(pdata, isr);
    291
    292	if (isr & XGBE_INTR_TX_ABRT) {
    293		netif_dbg(pdata, link, pdata->netdev,
    294			  "I2C TX_ABRT received (%#010x) for target %#04x\n",
    295			  state->tx_abort_source, state->op->target);
    296
    297		xgbe_i2c_disable_interrupts(pdata);
    298
    299		state->ret = -EIO;
    300		goto out;
    301	}
    302
    303	/* Check for data in the Rx fifo */
    304	xgbe_i2c_read(pdata);
    305
    306	/* Fill up the Tx fifo next */
    307	xgbe_i2c_write(pdata);
    308
    309out:
    310	/* Complete on an error or STOP condition */
    311	if (state->ret || XI2C_GET_BITS(isr, IC_RAW_INTR_STAT, STOP_DET))
    312		complete(&pdata->i2c_complete);
    313
    314reissue_check:
    315	/* Reissue interrupt if status is not clear */
    316	if (pdata->vdata->irq_reissue_support)
    317		XP_IOWRITE(pdata, XP_INT_REISSUE_EN, 1 << 2);
    318}
    319
    320static irqreturn_t xgbe_i2c_isr(int irq, void *data)
    321{
    322	struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)data;
    323
    324	if (pdata->isr_as_tasklet)
    325		tasklet_schedule(&pdata->tasklet_i2c);
    326	else
    327		xgbe_i2c_isr_task(&pdata->tasklet_i2c);
    328
    329	return IRQ_HANDLED;
    330}
    331
    332static void xgbe_i2c_set_mode(struct xgbe_prv_data *pdata)
    333{
    334	unsigned int reg;
    335
    336	reg = XI2C_IOREAD(pdata, IC_CON);
    337	XI2C_SET_BITS(reg, IC_CON, MASTER_MODE, 1);
    338	XI2C_SET_BITS(reg, IC_CON, SLAVE_DISABLE, 1);
    339	XI2C_SET_BITS(reg, IC_CON, RESTART_EN, 1);
    340	XI2C_SET_BITS(reg, IC_CON, SPEED, XGBE_STD_SPEED);
    341	XI2C_SET_BITS(reg, IC_CON, RX_FIFO_FULL_HOLD, 1);
    342	XI2C_IOWRITE(pdata, IC_CON, reg);
    343}
    344
    345static void xgbe_i2c_get_features(struct xgbe_prv_data *pdata)
    346{
    347	struct xgbe_i2c *i2c = &pdata->i2c;
    348	unsigned int reg;
    349
    350	reg = XI2C_IOREAD(pdata, IC_COMP_PARAM_1);
    351	i2c->max_speed_mode = XI2C_GET_BITS(reg, IC_COMP_PARAM_1,
    352					    MAX_SPEED_MODE);
    353	i2c->rx_fifo_size = XI2C_GET_BITS(reg, IC_COMP_PARAM_1,
    354					  RX_BUFFER_DEPTH);
    355	i2c->tx_fifo_size = XI2C_GET_BITS(reg, IC_COMP_PARAM_1,
    356					  TX_BUFFER_DEPTH);
    357
    358	if (netif_msg_probe(pdata))
    359		dev_dbg(pdata->dev, "I2C features: %s=%u, %s=%u, %s=%u\n",
    360			"MAX_SPEED_MODE", i2c->max_speed_mode,
    361			"RX_BUFFER_DEPTH", i2c->rx_fifo_size,
    362			"TX_BUFFER_DEPTH", i2c->tx_fifo_size);
    363}
    364
    365static void xgbe_i2c_set_target(struct xgbe_prv_data *pdata, unsigned int addr)
    366{
    367	XI2C_IOWRITE(pdata, IC_TAR, addr);
    368}
    369
    370static irqreturn_t xgbe_i2c_combined_isr(struct xgbe_prv_data *pdata)
    371{
    372	xgbe_i2c_isr_task(&pdata->tasklet_i2c);
    373
    374	return IRQ_HANDLED;
    375}
    376
    377static int xgbe_i2c_xfer(struct xgbe_prv_data *pdata, struct xgbe_i2c_op *op)
    378{
    379	struct xgbe_i2c_op_state *state = &pdata->i2c.op_state;
    380	int ret;
    381
    382	mutex_lock(&pdata->i2c_mutex);
    383
    384	reinit_completion(&pdata->i2c_complete);
    385
    386	ret = xgbe_i2c_disable(pdata);
    387	if (ret) {
    388		netdev_err(pdata->netdev, "failed to disable i2c master\n");
    389		goto unlock;
    390	}
    391
    392	xgbe_i2c_set_target(pdata, op->target);
    393
    394	memset(state, 0, sizeof(*state));
    395	state->op = op;
    396	state->tx_len = op->len;
    397	state->tx_buf = op->buf;
    398	state->rx_len = op->len;
    399	state->rx_buf = op->buf;
    400
    401	xgbe_i2c_clear_all_interrupts(pdata);
    402	ret = xgbe_i2c_enable(pdata);
    403	if (ret) {
    404		netdev_err(pdata->netdev, "failed to enable i2c master\n");
    405		goto unlock;
    406	}
    407
    408	/* Enabling the interrupts will cause the TX FIFO empty interrupt to
    409	 * fire and begin to process the command via the ISR.
    410	 */
    411	xgbe_i2c_enable_interrupts(pdata);
    412
    413	if (!wait_for_completion_timeout(&pdata->i2c_complete, HZ)) {
    414		netdev_err(pdata->netdev, "i2c operation timed out\n");
    415		ret = -ETIMEDOUT;
    416		goto disable;
    417	}
    418
    419	ret = state->ret;
    420	if (ret) {
    421		if (state->tx_abort_source & IC_TX_ABRT_7B_ADDR_NOACK)
    422			ret = -ENOTCONN;
    423		else if (state->tx_abort_source & IC_TX_ABRT_ARB_LOST)
    424			ret = -EAGAIN;
    425	}
    426
    427disable:
    428	xgbe_i2c_disable_interrupts(pdata);
    429	xgbe_i2c_disable(pdata);
    430
    431unlock:
    432	mutex_unlock(&pdata->i2c_mutex);
    433
    434	return ret;
    435}
    436
    437static void xgbe_i2c_stop(struct xgbe_prv_data *pdata)
    438{
    439	if (!pdata->i2c.started)
    440		return;
    441
    442	netif_dbg(pdata, link, pdata->netdev, "stopping I2C\n");
    443
    444	pdata->i2c.started = 0;
    445
    446	xgbe_i2c_disable_interrupts(pdata);
    447	xgbe_i2c_disable(pdata);
    448	xgbe_i2c_clear_all_interrupts(pdata);
    449
    450	if (pdata->dev_irq != pdata->i2c_irq)
    451		devm_free_irq(pdata->dev, pdata->i2c_irq, pdata);
    452}
    453
    454static int xgbe_i2c_start(struct xgbe_prv_data *pdata)
    455{
    456	int ret;
    457
    458	if (pdata->i2c.started)
    459		return 0;
    460
    461	netif_dbg(pdata, link, pdata->netdev, "starting I2C\n");
    462
    463	/* If we have a separate I2C irq, enable it */
    464	if (pdata->dev_irq != pdata->i2c_irq) {
    465		tasklet_setup(&pdata->tasklet_i2c, xgbe_i2c_isr_task);
    466
    467		ret = devm_request_irq(pdata->dev, pdata->i2c_irq,
    468				       xgbe_i2c_isr, 0, pdata->i2c_name,
    469				       pdata);
    470		if (ret) {
    471			netdev_err(pdata->netdev, "i2c irq request failed\n");
    472			return ret;
    473		}
    474	}
    475
    476	pdata->i2c.started = 1;
    477
    478	return 0;
    479}
    480
    481static int xgbe_i2c_init(struct xgbe_prv_data *pdata)
    482{
    483	int ret;
    484
    485	xgbe_i2c_disable_interrupts(pdata);
    486
    487	ret = xgbe_i2c_disable(pdata);
    488	if (ret) {
    489		dev_err(pdata->dev, "failed to disable i2c master\n");
    490		return ret;
    491	}
    492
    493	xgbe_i2c_get_features(pdata);
    494
    495	xgbe_i2c_set_mode(pdata);
    496
    497	xgbe_i2c_clear_all_interrupts(pdata);
    498
    499	return 0;
    500}
    501
    502void xgbe_init_function_ptrs_i2c(struct xgbe_i2c_if *i2c_if)
    503{
    504	i2c_if->i2c_init		= xgbe_i2c_init;
    505
    506	i2c_if->i2c_start		= xgbe_i2c_start;
    507	i2c_if->i2c_stop		= xgbe_i2c_stop;
    508
    509	i2c_if->i2c_xfer		= xgbe_i2c_xfer;
    510
    511	i2c_if->i2c_isr			= xgbe_i2c_combined_isr;
    512}