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

qt202x_phy.c (14262B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/****************************************************************************
      3 * Driver for Solarflare network controllers and boards
      4 * Copyright 2006-2012 Solarflare Communications Inc.
      5 */
      6/*
      7 * Driver for AMCC QT202x SFP+ and XFP adapters; see www.amcc.com for details
      8 */
      9
     10#include <linux/slab.h>
     11#include <linux/timer.h>
     12#include <linux/delay.h>
     13#include "efx.h"
     14#include "mdio_10g.h"
     15#include "phy.h"
     16#include "nic.h"
     17
     18#define QT202X_REQUIRED_DEVS (MDIO_DEVS_PCS |		\
     19			      MDIO_DEVS_PMAPMD |	\
     20			      MDIO_DEVS_PHYXS)
     21
     22#define QT202X_LOOPBACKS ((1 << LOOPBACK_PCS) |		\
     23			  (1 << LOOPBACK_PMAPMD) |	\
     24			  (1 << LOOPBACK_PHYXS_WS))
     25
     26/****************************************************************************/
     27/* Quake-specific MDIO registers */
     28#define MDIO_QUAKE_LED0_REG	(0xD006)
     29
     30/* QT2025C only */
     31#define PCS_FW_HEARTBEAT_REG	0xd7ee
     32#define PCS_FW_HEARTB_LBN	0
     33#define PCS_FW_HEARTB_WIDTH	8
     34#define PCS_FW_PRODUCT_CODE_1	0xd7f0
     35#define PCS_FW_VERSION_1	0xd7f3
     36#define PCS_FW_BUILD_1		0xd7f6
     37#define PCS_UC8051_STATUS_REG	0xd7fd
     38#define PCS_UC_STATUS_LBN	0
     39#define PCS_UC_STATUS_WIDTH	8
     40#define PCS_UC_STATUS_FW_SAVE	0x20
     41#define PMA_PMD_MODE_REG	0xc301
     42#define PMA_PMD_RXIN_SEL_LBN	6
     43#define PMA_PMD_FTX_CTRL2_REG	0xc309
     44#define PMA_PMD_FTX_STATIC_LBN	13
     45#define PMA_PMD_VEND1_REG	0xc001
     46#define PMA_PMD_VEND1_LBTXD_LBN	15
     47#define PCS_VEND1_REG		0xc000
     48#define PCS_VEND1_LBTXD_LBN	5
     49
     50void falcon_qt202x_set_led(struct ef4_nic *p, int led, int mode)
     51{
     52	int addr = MDIO_QUAKE_LED0_REG + led;
     53	ef4_mdio_write(p, MDIO_MMD_PMAPMD, addr, mode);
     54}
     55
     56struct qt202x_phy_data {
     57	enum ef4_phy_mode phy_mode;
     58	bool bug17190_in_bad_state;
     59	unsigned long bug17190_timer;
     60	u32 firmware_ver;
     61};
     62
     63#define QT2022C2_MAX_RESET_TIME 500
     64#define QT2022C2_RESET_WAIT 10
     65
     66#define QT2025C_MAX_HEARTB_TIME (5 * HZ)
     67#define QT2025C_HEARTB_WAIT 100
     68#define QT2025C_MAX_FWSTART_TIME (25 * HZ / 10)
     69#define QT2025C_FWSTART_WAIT 100
     70
     71#define BUG17190_INTERVAL (2 * HZ)
     72
     73static int qt2025c_wait_heartbeat(struct ef4_nic *efx)
     74{
     75	unsigned long timeout = jiffies + QT2025C_MAX_HEARTB_TIME;
     76	int reg, old_counter = 0;
     77
     78	/* Wait for firmware heartbeat to start */
     79	for (;;) {
     80		int counter;
     81		reg = ef4_mdio_read(efx, MDIO_MMD_PCS, PCS_FW_HEARTBEAT_REG);
     82		if (reg < 0)
     83			return reg;
     84		counter = ((reg >> PCS_FW_HEARTB_LBN) &
     85			    ((1 << PCS_FW_HEARTB_WIDTH) - 1));
     86		if (old_counter == 0)
     87			old_counter = counter;
     88		else if (counter != old_counter)
     89			break;
     90		if (time_after(jiffies, timeout)) {
     91			/* Some cables have EEPROMs that conflict with the
     92			 * PHY's on-board EEPROM so it cannot load firmware */
     93			netif_err(efx, hw, efx->net_dev,
     94				  "If an SFP+ direct attach cable is"
     95				  " connected, please check that it complies"
     96				  " with the SFP+ specification\n");
     97			return -ETIMEDOUT;
     98		}
     99		msleep(QT2025C_HEARTB_WAIT);
    100	}
    101
    102	return 0;
    103}
    104
    105static int qt2025c_wait_fw_status_good(struct ef4_nic *efx)
    106{
    107	unsigned long timeout = jiffies + QT2025C_MAX_FWSTART_TIME;
    108	int reg;
    109
    110	/* Wait for firmware status to look good */
    111	for (;;) {
    112		reg = ef4_mdio_read(efx, MDIO_MMD_PCS, PCS_UC8051_STATUS_REG);
    113		if (reg < 0)
    114			return reg;
    115		if ((reg &
    116		     ((1 << PCS_UC_STATUS_WIDTH) - 1) << PCS_UC_STATUS_LBN) >=
    117		    PCS_UC_STATUS_FW_SAVE)
    118			break;
    119		if (time_after(jiffies, timeout))
    120			return -ETIMEDOUT;
    121		msleep(QT2025C_FWSTART_WAIT);
    122	}
    123
    124	return 0;
    125}
    126
    127static void qt2025c_restart_firmware(struct ef4_nic *efx)
    128{
    129	/* Restart microcontroller execution of firmware from RAM */
    130	ef4_mdio_write(efx, 3, 0xe854, 0x00c0);
    131	ef4_mdio_write(efx, 3, 0xe854, 0x0040);
    132	msleep(50);
    133}
    134
    135static int qt2025c_wait_reset(struct ef4_nic *efx)
    136{
    137	int rc;
    138
    139	rc = qt2025c_wait_heartbeat(efx);
    140	if (rc != 0)
    141		return rc;
    142
    143	rc = qt2025c_wait_fw_status_good(efx);
    144	if (rc == -ETIMEDOUT) {
    145		/* Bug 17689: occasionally heartbeat starts but firmware status
    146		 * code never progresses beyond 0x00.  Try again, once, after
    147		 * restarting execution of the firmware image. */
    148		netif_dbg(efx, hw, efx->net_dev,
    149			  "bashing QT2025C microcontroller\n");
    150		qt2025c_restart_firmware(efx);
    151		rc = qt2025c_wait_heartbeat(efx);
    152		if (rc != 0)
    153			return rc;
    154		rc = qt2025c_wait_fw_status_good(efx);
    155	}
    156
    157	return rc;
    158}
    159
    160static void qt2025c_firmware_id(struct ef4_nic *efx)
    161{
    162	struct qt202x_phy_data *phy_data = efx->phy_data;
    163	u8 firmware_id[9];
    164	size_t i;
    165
    166	for (i = 0; i < sizeof(firmware_id); i++)
    167		firmware_id[i] = ef4_mdio_read(efx, MDIO_MMD_PCS,
    168					       PCS_FW_PRODUCT_CODE_1 + i);
    169	netif_info(efx, probe, efx->net_dev,
    170		   "QT2025C firmware %xr%d v%d.%d.%d.%d [20%02d-%02d-%02d]\n",
    171		   (firmware_id[0] << 8) | firmware_id[1], firmware_id[2],
    172		   firmware_id[3] >> 4, firmware_id[3] & 0xf,
    173		   firmware_id[4], firmware_id[5],
    174		   firmware_id[6], firmware_id[7], firmware_id[8]);
    175	phy_data->firmware_ver = ((firmware_id[3] & 0xf0) << 20) |
    176				 ((firmware_id[3] & 0x0f) << 16) |
    177				 (firmware_id[4] << 8) | firmware_id[5];
    178}
    179
    180static void qt2025c_bug17190_workaround(struct ef4_nic *efx)
    181{
    182	struct qt202x_phy_data *phy_data = efx->phy_data;
    183
    184	/* The PHY can get stuck in a state where it reports PHY_XS and PMA/PMD
    185	 * layers up, but PCS down (no block_lock).  If we notice this state
    186	 * persisting for a couple of seconds, we switch PMA/PMD loopback
    187	 * briefly on and then off again, which is normally sufficient to
    188	 * recover it.
    189	 */
    190	if (efx->link_state.up ||
    191	    !ef4_mdio_links_ok(efx, MDIO_DEVS_PMAPMD | MDIO_DEVS_PHYXS)) {
    192		phy_data->bug17190_in_bad_state = false;
    193		return;
    194	}
    195
    196	if (!phy_data->bug17190_in_bad_state) {
    197		phy_data->bug17190_in_bad_state = true;
    198		phy_data->bug17190_timer = jiffies + BUG17190_INTERVAL;
    199		return;
    200	}
    201
    202	if (time_after_eq(jiffies, phy_data->bug17190_timer)) {
    203		netif_dbg(efx, hw, efx->net_dev, "bashing QT2025C PMA/PMD\n");
    204		ef4_mdio_set_flag(efx, MDIO_MMD_PMAPMD, MDIO_CTRL1,
    205				  MDIO_PMA_CTRL1_LOOPBACK, true);
    206		msleep(100);
    207		ef4_mdio_set_flag(efx, MDIO_MMD_PMAPMD, MDIO_CTRL1,
    208				  MDIO_PMA_CTRL1_LOOPBACK, false);
    209		phy_data->bug17190_timer = jiffies + BUG17190_INTERVAL;
    210	}
    211}
    212
    213static int qt2025c_select_phy_mode(struct ef4_nic *efx)
    214{
    215	struct qt202x_phy_data *phy_data = efx->phy_data;
    216	struct falcon_board *board = falcon_board(efx);
    217	int reg, rc, i;
    218	uint16_t phy_op_mode;
    219
    220	/* Only 2.0.1.0+ PHY firmware supports the more optimal SFP+
    221	 * Self-Configure mode.  Don't attempt any switching if we encounter
    222	 * older firmware. */
    223	if (phy_data->firmware_ver < 0x02000100)
    224		return 0;
    225
    226	/* In general we will get optimal behaviour in "SFP+ Self-Configure"
    227	 * mode; however, that powers down most of the PHY when no module is
    228	 * present, so we must use a different mode (any fixed mode will do)
    229	 * to be sure that loopbacks will work. */
    230	phy_op_mode = (efx->loopback_mode == LOOPBACK_NONE) ? 0x0038 : 0x0020;
    231
    232	/* Only change mode if really necessary */
    233	reg = ef4_mdio_read(efx, 1, 0xc319);
    234	if ((reg & 0x0038) == phy_op_mode)
    235		return 0;
    236	netif_dbg(efx, hw, efx->net_dev, "Switching PHY to mode 0x%04x\n",
    237		  phy_op_mode);
    238
    239	/* This sequence replicates the register writes configured in the boot
    240	 * EEPROM (including the differences between board revisions), except
    241	 * that the operating mode is changed, and the PHY is prevented from
    242	 * unnecessarily reloading the main firmware image again. */
    243	ef4_mdio_write(efx, 1, 0xc300, 0x0000);
    244	/* (Note: this portion of the boot EEPROM sequence, which bit-bashes 9
    245	 * STOPs onto the firmware/module I2C bus to reset it, varies across
    246	 * board revisions, as the bus is connected to different GPIO/LED
    247	 * outputs on the PHY.) */
    248	if (board->major == 0 && board->minor < 2) {
    249		ef4_mdio_write(efx, 1, 0xc303, 0x4498);
    250		for (i = 0; i < 9; i++) {
    251			ef4_mdio_write(efx, 1, 0xc303, 0x4488);
    252			ef4_mdio_write(efx, 1, 0xc303, 0x4480);
    253			ef4_mdio_write(efx, 1, 0xc303, 0x4490);
    254			ef4_mdio_write(efx, 1, 0xc303, 0x4498);
    255		}
    256	} else {
    257		ef4_mdio_write(efx, 1, 0xc303, 0x0920);
    258		ef4_mdio_write(efx, 1, 0xd008, 0x0004);
    259		for (i = 0; i < 9; i++) {
    260			ef4_mdio_write(efx, 1, 0xc303, 0x0900);
    261			ef4_mdio_write(efx, 1, 0xd008, 0x0005);
    262			ef4_mdio_write(efx, 1, 0xc303, 0x0920);
    263			ef4_mdio_write(efx, 1, 0xd008, 0x0004);
    264		}
    265		ef4_mdio_write(efx, 1, 0xc303, 0x4900);
    266	}
    267	ef4_mdio_write(efx, 1, 0xc303, 0x4900);
    268	ef4_mdio_write(efx, 1, 0xc302, 0x0004);
    269	ef4_mdio_write(efx, 1, 0xc316, 0x0013);
    270	ef4_mdio_write(efx, 1, 0xc318, 0x0054);
    271	ef4_mdio_write(efx, 1, 0xc319, phy_op_mode);
    272	ef4_mdio_write(efx, 1, 0xc31a, 0x0098);
    273	ef4_mdio_write(efx, 3, 0x0026, 0x0e00);
    274	ef4_mdio_write(efx, 3, 0x0027, 0x0013);
    275	ef4_mdio_write(efx, 3, 0x0028, 0xa528);
    276	ef4_mdio_write(efx, 1, 0xd006, 0x000a);
    277	ef4_mdio_write(efx, 1, 0xd007, 0x0009);
    278	ef4_mdio_write(efx, 1, 0xd008, 0x0004);
    279	/* This additional write is not present in the boot EEPROM.  It
    280	 * prevents the PHY's internal boot ROM doing another pointless (and
    281	 * slow) reload of the firmware image (the microcontroller's code
    282	 * memory is not affected by the microcontroller reset). */
    283	ef4_mdio_write(efx, 1, 0xc317, 0x00ff);
    284	/* PMA/PMD loopback sets RXIN to inverse polarity and the firmware
    285	 * restart doesn't reset it. We need to do that ourselves. */
    286	ef4_mdio_set_flag(efx, 1, PMA_PMD_MODE_REG,
    287			  1 << PMA_PMD_RXIN_SEL_LBN, false);
    288	ef4_mdio_write(efx, 1, 0xc300, 0x0002);
    289	msleep(20);
    290
    291	/* Restart microcontroller execution of firmware from RAM */
    292	qt2025c_restart_firmware(efx);
    293
    294	/* Wait for the microcontroller to be ready again */
    295	rc = qt2025c_wait_reset(efx);
    296	if (rc < 0) {
    297		netif_err(efx, hw, efx->net_dev,
    298			  "PHY microcontroller reset during mode switch "
    299			  "timed out\n");
    300		return rc;
    301	}
    302
    303	return 0;
    304}
    305
    306static int qt202x_reset_phy(struct ef4_nic *efx)
    307{
    308	int rc;
    309
    310	if (efx->phy_type == PHY_TYPE_QT2025C) {
    311		/* Wait for the reset triggered by falcon_reset_hw()
    312		 * to complete */
    313		rc = qt2025c_wait_reset(efx);
    314		if (rc < 0)
    315			goto fail;
    316	} else {
    317		/* Reset the PHYXS MMD. This is documented as doing
    318		 * a complete soft reset. */
    319		rc = ef4_mdio_reset_mmd(efx, MDIO_MMD_PHYXS,
    320					QT2022C2_MAX_RESET_TIME /
    321					QT2022C2_RESET_WAIT,
    322					QT2022C2_RESET_WAIT);
    323		if (rc < 0)
    324			goto fail;
    325	}
    326
    327	/* Wait 250ms for the PHY to complete bootup */
    328	msleep(250);
    329
    330	falcon_board(efx)->type->init_phy(efx);
    331
    332	return 0;
    333
    334 fail:
    335	netif_err(efx, hw, efx->net_dev, "PHY reset timed out\n");
    336	return rc;
    337}
    338
    339static int qt202x_phy_probe(struct ef4_nic *efx)
    340{
    341	struct qt202x_phy_data *phy_data;
    342
    343	phy_data = kzalloc(sizeof(struct qt202x_phy_data), GFP_KERNEL);
    344	if (!phy_data)
    345		return -ENOMEM;
    346	efx->phy_data = phy_data;
    347	phy_data->phy_mode = efx->phy_mode;
    348	phy_data->bug17190_in_bad_state = false;
    349	phy_data->bug17190_timer = 0;
    350
    351	efx->mdio.mmds = QT202X_REQUIRED_DEVS;
    352	efx->mdio.mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22;
    353	efx->loopback_modes = QT202X_LOOPBACKS | FALCON_XMAC_LOOPBACKS;
    354	return 0;
    355}
    356
    357static int qt202x_phy_init(struct ef4_nic *efx)
    358{
    359	u32 devid;
    360	int rc;
    361
    362	rc = qt202x_reset_phy(efx);
    363	if (rc) {
    364		netif_err(efx, probe, efx->net_dev, "PHY init failed\n");
    365		return rc;
    366	}
    367
    368	devid = ef4_mdio_read_id(efx, MDIO_MMD_PHYXS);
    369	netif_info(efx, probe, efx->net_dev,
    370		   "PHY ID reg %x (OUI %06x model %02x revision %x)\n",
    371		   devid, ef4_mdio_id_oui(devid), ef4_mdio_id_model(devid),
    372		   ef4_mdio_id_rev(devid));
    373
    374	if (efx->phy_type == PHY_TYPE_QT2025C)
    375		qt2025c_firmware_id(efx);
    376
    377	return 0;
    378}
    379
    380static int qt202x_link_ok(struct ef4_nic *efx)
    381{
    382	return ef4_mdio_links_ok(efx, QT202X_REQUIRED_DEVS);
    383}
    384
    385static bool qt202x_phy_poll(struct ef4_nic *efx)
    386{
    387	bool was_up = efx->link_state.up;
    388
    389	efx->link_state.up = qt202x_link_ok(efx);
    390	efx->link_state.speed = 10000;
    391	efx->link_state.fd = true;
    392	efx->link_state.fc = efx->wanted_fc;
    393
    394	if (efx->phy_type == PHY_TYPE_QT2025C)
    395		qt2025c_bug17190_workaround(efx);
    396
    397	return efx->link_state.up != was_up;
    398}
    399
    400static int qt202x_phy_reconfigure(struct ef4_nic *efx)
    401{
    402	struct qt202x_phy_data *phy_data = efx->phy_data;
    403
    404	if (efx->phy_type == PHY_TYPE_QT2025C) {
    405		int rc = qt2025c_select_phy_mode(efx);
    406		if (rc)
    407			return rc;
    408
    409		/* There are several different register bits which can
    410		 * disable TX (and save power) on direct-attach cables
    411		 * or optical transceivers, varying somewhat between
    412		 * firmware versions.  Only 'static mode' appears to
    413		 * cover everything. */
    414		mdio_set_flag(
    415			&efx->mdio, efx->mdio.prtad, MDIO_MMD_PMAPMD,
    416			PMA_PMD_FTX_CTRL2_REG, 1 << PMA_PMD_FTX_STATIC_LBN,
    417			efx->phy_mode & PHY_MODE_TX_DISABLED ||
    418			efx->phy_mode & PHY_MODE_LOW_POWER ||
    419			efx->loopback_mode == LOOPBACK_PCS ||
    420			efx->loopback_mode == LOOPBACK_PMAPMD);
    421	} else {
    422		/* Reset the PHY when moving from tx off to tx on */
    423		if (!(efx->phy_mode & PHY_MODE_TX_DISABLED) &&
    424		    (phy_data->phy_mode & PHY_MODE_TX_DISABLED))
    425			qt202x_reset_phy(efx);
    426
    427		ef4_mdio_transmit_disable(efx);
    428	}
    429
    430	ef4_mdio_phy_reconfigure(efx);
    431
    432	phy_data->phy_mode = efx->phy_mode;
    433
    434	return 0;
    435}
    436
    437static void qt202x_phy_get_link_ksettings(struct ef4_nic *efx,
    438					  struct ethtool_link_ksettings *cmd)
    439{
    440	mdio45_ethtool_ksettings_get(&efx->mdio, cmd);
    441}
    442
    443static void qt202x_phy_remove(struct ef4_nic *efx)
    444{
    445	/* Free the context block */
    446	kfree(efx->phy_data);
    447	efx->phy_data = NULL;
    448}
    449
    450static int qt202x_phy_get_module_info(struct ef4_nic *efx,
    451				      struct ethtool_modinfo *modinfo)
    452{
    453	modinfo->type = ETH_MODULE_SFF_8079;
    454	modinfo->eeprom_len = ETH_MODULE_SFF_8079_LEN;
    455	return 0;
    456}
    457
    458static int qt202x_phy_get_module_eeprom(struct ef4_nic *efx,
    459					struct ethtool_eeprom *ee, u8 *data)
    460{
    461	int mmd, reg_base, rc, i;
    462
    463	if (efx->phy_type == PHY_TYPE_QT2025C) {
    464		mmd = MDIO_MMD_PCS;
    465		reg_base = 0xd000;
    466	} else {
    467		mmd = MDIO_MMD_PMAPMD;
    468		reg_base = 0x8007;
    469	}
    470
    471	for (i = 0; i < ee->len; i++) {
    472		rc = ef4_mdio_read(efx, mmd, reg_base + ee->offset + i);
    473		if (rc < 0)
    474			return rc;
    475		data[i] = rc;
    476	}
    477
    478	return 0;
    479}
    480
    481const struct ef4_phy_operations falcon_qt202x_phy_ops = {
    482	.probe		 = qt202x_phy_probe,
    483	.init		 = qt202x_phy_init,
    484	.reconfigure	 = qt202x_phy_reconfigure,
    485	.poll		 = qt202x_phy_poll,
    486	.fini		 = ef4_port_dummy_op_void,
    487	.remove		 = qt202x_phy_remove,
    488	.get_link_ksettings = qt202x_phy_get_link_ksettings,
    489	.set_link_ksettings = ef4_mdio_set_link_ksettings,
    490	.test_alive	 = ef4_mdio_test_alive,
    491	.get_module_eeprom = qt202x_phy_get_module_eeprom,
    492	.get_module_info = qt202x_phy_get_module_info,
    493};