<commit_before>/****************************************************************************
 * Driver for Solarflare Solarstorm network controllers and boards
 * Copyright 2005-2006 Fen Systems Ltd.
 * Copyright 2006-2008 Solarflare Communications Inc.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 as published
 * by the Free Software Foundation, incorporated herein by reference.
 */

#include <linux/delay.h>
#include "net_driver.h"
#include "efx.h"
#include "falcon.h"
#include "falcon_hwdefs.h"
#include "falcon_io.h"
#include "mac.h"
#include "gmii.h"
#include "mdio_10g.h"
#include "phy.h"
#include "boards.h"
#include "workarounds.h"

/**************************************************************************
 *
 * MAC register access
 *
 **************************************************************************/

/* Offset of an XMAC register within Falcon */
#define FALCON_XMAC_REG(mac_reg)					\
	(FALCON_XMAC_REGBANK + ((mac_reg) * FALCON_XMAC_REG_SIZE))

void falcon_xmac_writel(struct efx_nic *efx,
			efx_dword_t *value, unsigned int mac_reg)
{
	efx_oword_t temp;

	EFX_POPULATE_OWORD_1(temp, MAC_DATA, EFX_DWORD_FIELD(*value, MAC_DATA));
	falcon_write(efx, &temp, FALCON_XMAC_REG(mac_reg));
}

void falcon_xmac_readl(struct efx_nic *efx,
		       efx_dword_t *value, unsigned int mac_reg)
{
	efx_oword_t temp;

	falcon_read(efx, &temp, FALCON_XMAC_REG(mac_reg));
	EFX_POPULATE_DWORD_1(*value, MAC_DATA, EFX_OWORD_FIELD(temp, MAC_DATA));
}

/**************************************************************************
 *
 * MAC operations
 *
 *************************************************************************/
static int falcon_reset_xmac(struct efx_nic *efx)
{
	efx_dword_t reg;
	int count;

	EFX_POPULATE_DWORD_1(reg, XM_CORE_RST, 1);
	falcon_xmac_writel(efx, &reg, XM_GLB_CFG_REG_MAC);

	for (count = 0; count < 10000; count++) {	/* wait upto 100ms */
		falcon_xmac_readl(efx, &reg, XM_GLB_CFG_REG_MAC);
		if (EFX_DWORD_FIELD(reg, XM_CORE_RST) == 0)
			return 0;
		udelay(10);
	}

	/* This often fails when DSP is disabled, ignore it */
	if (sfe4001_phy_flash_cfg != 0)
		return 0;

	EFX_ERR(efx, "timed out waiting for XMAC core reset\n");
	return -ETIMEDOUT;
}

/* Configure the XAUI driver that is an output from Falcon */
static void falcon_setup_xaui(struct efx_nic *efx)
{
	efx_dword_t sdctl, txdrv;

	/* Move the XAUI into low power, unless there is no PHY, in
	 * which case the XAUI will have to drive a cable. */
	if (efx->phy_type == PHY_TYPE_NONE)
		return;

	falcon_xmac_readl(efx, &sdctl, XX_SD_CTL_REG_MAC);
	EFX_SET_DWORD_FIELD(sdctl, XX_HIDRVD, XX_SD_CTL_DRV_DEFAULT);
	EFX_SET_DWORD_FIELD(sdctl, XX_LODRVD, XX_SD_CTL_DRV_DEFAULT);
	EFX_SET_DWORD_FIELD(sdctl, XX_HIDRVC, XX_SD_CTL_DRV_DEFAULT);
	EFX_SET_DWORD_FIELD(sdctl, XX_LODRVC, XX_SD_CTL_DRV_DEFAULT);
	EFX_SET_DWORD_FIELD(sdctl, XX_HIDRVB, XX_SD_CTL_DRV_DEFAULT);
	EFX_SET_DWORD_FIELD(sdctl, XX_LODRVB, XX_SD_CTL_DRV_DEFAULT);
	EFX_SET_DWORD_FIELD(sdctl, XX_HIDRVA, XX_SD_CTL_DRV_DEFAULT);
	EFX_SET_DWORD_FIELD(sdctl, XX_LODRVA, XX_SD_CTL_DRV_DEFAULT);
	falcon_xmac_writel(efx, &sdctl, XX_SD_CTL_REG_MAC);

	EFX_POPULATE_DWORD_8(txdrv,
			     XX_DEQD, XX_TXDRV_DEQ_DEFAULT,
			     XX_DEQC, XX_TXDRV_DEQ_DEFAULT,
			     XX_DEQB, XX_TXDRV_DEQ_DEFAULT,
			     XX_DEQA, XX_TXDRV_DEQ_DEFAULT,
			     XX_DTXD, XX_TXDRV_DTX_DEFAULT,
			     XX_DTXC, XX_TXDRV_DTX_DEFAULT,
			     XX_DTXB, XX_TXDRV_DTX_DEFAULT,
			     XX_DTXA, XX_TXDRV_DTX_DEFAULT);
	falcon_xmac_writel(efx, &txdrv, XX_TXDRV_CTL_REG_MAC);
}

static void falcon_hold_xaui_in_rst(struct efx_nic *efx)
{
	efx_dword_t reg;

	EFX_ZERO_DWORD(reg);
	EFX_SET_DWORD_FIELD(reg, XX_PWRDNA_EN, 1);
	EFX_SET_DWORD_FIELD(reg, XX_PWRDNB_EN, 1);
	EFX_SET_DWORD_FIELD(reg, XX_PWRDNC_EN, 1);
	EFX_SET_DWORD_FIELD(reg, XX_PWRDND_EN, 1);
	EFX_SET_DWORD_FIELD(reg, XX_RSTPLLAB_EN, 1);
	EFX_SET_DWORD_FIELD(reg, XX_RSTPLLCD_EN, 1);
	EFX_SET_DWORD_FIELD(reg, XX_RESETA_EN, 1);
	EFX_SET_DWORD_FIELD(reg, XX_RESETB_EN, 1);
	EFX_SET_DWORD_FIELD(reg, XX_RESETC_EN, 1);
	EFX_SET_DWORD_FIELD(reg, XX_RESETD_EN, 1);
	EFX_SET_DWORD_FIELD(reg, XX_RSTXGXSRX_EN, 1);
	EFX_SET_DWORD_FIELD(reg, XX_RSTXGXSTX_EN, 1);
	falcon_xmac_writel(efx, &reg, XX_PWR_RST_REG_MAC);
	udelay(10);
}

static int _falcon_reset_xaui_a(struct efx_nic *efx)
{
	efx_dword_t reg;

	falcon_hold_xaui_in_rst(efx);
	falcon_xmac_readl(efx, &reg, XX_PWR_RST_REG_MAC);

	/* Follow the RAMBUS XAUI data reset sequencing
	 * Channels A and B first: power down, reset PLL, reset, clear
	 */
	EFX_SET_DWORD_FIELD(reg, XX_PWRDNA_EN, 0);
	EFX_SET_DWORD_FIELD(reg, XX_PWRDNB_EN, 0);
	falcon_xmac_writel(efx, &reg, XX_PWR_RST_REG_MAC);
	udelay(10);

	EFX_SET_DWORD_FIELD(reg, XX_RSTPLLAB_EN, 0);
	falcon_xmac_writel(efx, &reg, XX_PWR_RST_REG_MAC);
	udelay(10);

	EFX_SET_DWORD_FIELD(reg, XX_RESETA_EN, 0);
	EFX_SET_DWORD_FIELD(reg, XX_RESETB_EN, 0);
	falcon_xmac_writel(efx, &reg, XX_PWR_RST_REG_MAC);
	udelay(10);

	/* Channels C and D: power down, reset PLL, reset, clear */
	EFX_SET_DWORD_FIELD(reg, XX_PWRDNC_EN, 0);
	EFX_SET_DWORD_FIELD(reg, XX_PWRDND_EN, 0);
	falcon_xmac_writel(efx, &reg, XX_PWR_RST_REG_MAC);
	udelay(10);

	EFX_SET_DWORD_FIELD(reg, XX_RSTPLLCD_EN, 0);
	falcon_xmac_writel(efx, &reg, XX_PWR_RST_REG_MAC);
	udelay(10);

	EFX_SET_DWORD_FIELD(reg, XX_RESETC_EN, 0);
	EFX_SET_DWORD_FIELD(reg, XX_RESETD_EN, 0);
	falcon_xmac_writel(efx, &reg, XX_PWR_RST_REG_MAC);
	udelay(10);

	/* Setup XAUI */
	falcon_setup_xaui(efx);
	udelay(10);

	/* Take XGXS out of reset */
	EFX_ZERO_DWORD(reg);
	falcon_xmac_writel(efx, &reg, XX_PWR_RST_REG_MAC);
	udelay(10);

	return 0;
}

static int _falcon_reset_xaui_b(struct efx_nic *efx)
{
	efx_dword_t reg;
	int count;

	EFX_POPULATE_DWORD_1(reg, XX_RST_XX_EN, 1);
	falcon_xmac_writel(efx, &reg, XX_PWR_RST_REG_MAC);

	/* Give some time for the link to establish */
	for (count = 0; count < 1000; count++) { /* wait upto 10ms */
		falcon_xmac_readl(efx, &reg, XX_PWR_RST_REG_MAC);
		if (EFX_DWORD_FIELD(reg, XX_RST_XX_EN) == 0) {
			falcon_setup_xaui(efx);
			return 0;
		}
		udelay(10);
	}
	EFX_ERR(efx, "timed out waiting for XAUI/XGXS reset\n");
	return -ETIMEDOUT;
}

int falcon_reset_xaui(struct efx_nic *efx)
{
	int rc;

	if (EFX_WORKAROUND_9388(efx)) {
		falcon_hold_xaui_in_rst(efx);
		efx->phy_op->reset_xaui(efx);
		rc = _falcon_reset_xaui_a(efx);
	} else {
		rc = _falcon_reset_xaui_b(efx);
	}
	return rc;
}

static int falcon_xgmii_status(struct efx_nic *efx)
{
	efx_dword_t reg;

	if (FALCON_REV(efx) < FALCON_REV_B0)
		return 1;

	/* The ISR latches, so clear it and re-read */
	falcon_xmac_readl(efx, &reg, XM_MGT_INT_REG_MAC_B0);
	falcon_xmac_readl(efx, &reg, XM_MGT_INT_REG_MAC_B0);
	
	if (EFX_DWORD_FIELD(reg, XM_LCLFLT) ||
	    EFX_DWORD_FIELD(reg, XM_RMTFLT)) {
		EFX_INFO(efx, "MGT_INT: "EFX_DWORD_FMT"\n", EFX_DWORD_VAL(reg));
		return 0;
	}

	return 1;
}

static void falcon_mask_status_intr(struct efx_nic *efx, int enable)
{
	efx_dword_t reg;
<commit_msg>[netdrvr] sfc: Fix code formatting<commit_after>/****************************************************************************
 * Driver for Solarflare Solarstorm network controllers and boards
 * Copyright 2005-2006 Fen Systems Ltd.
 * Copyright 2006-2008 Solarflare Communications Inc.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 as published
 * by the Free Software Foundation, incorporated herein by reference.
 */

#include <linux/delay.h>
#include "net_driver.h"
#include "efx.h"
#include "falcon.h"
#include "falcon_hwdefs.h"
#include "falcon_io.h"
#include "mac.h"
#include "gmii.h"
#include "mdio_10g.h"
#include "phy.h"
#include "boards.h"
#include "workarounds.h"

/**************************************************************************
 *
 * MAC register access
 *
 **************************************************************************/

/* Offset of an XMAC register within Falcon */
#define FALCON_XMAC_REG(mac_reg)					\
	(FALCON_XMAC_REGBANK + ((mac_reg) * FALCON_XMAC_REG_SIZE))

void falcon_xmac_writel(struct efx_nic *efx,
			 efx_dword_t *value, unsigned int mac_reg)
{
	efx_oword_t temp;

	EFX_POPULATE_OWORD_1(temp, MAC_DATA, EFX_DWORD_FIELD(*value, MAC_DATA));
	falcon_write(efx, &temp, FALCON_XMAC_REG(mac_reg));
}

void falcon_xmac_readl(struct efx_nic *efx,
		       efx_dword_t *value, unsigned int mac_reg)
{
	efx_oword_t temp;

	falcon_read(efx, &temp, FALCON_XMAC_REG(mac_reg));
	EFX_POPULATE_DWORD_1(*value, MAC_DATA, EFX_OWORD_FIELD(temp, MAC_DATA));
}

/**************************************************************************
 *
 * MAC operations
 *
 *************************************************************************/
static int falcon_reset_xmac(struct efx_nic *efx)
{
	efx_dword_t reg;
	int count;

	EFX_POPULATE_DWORD_1(reg, XM_CORE_RST, 1);
	falcon_xmac_writel(efx, &reg, XM_GLB_CFG_REG_MAC);

	for (count = 0; count < 10000; count++) {	/* wait upto 100ms */
		falcon_xmac_readl(efx, &reg, XM_GLB_CFG_REG_MAC);
		if (EFX_DWORD_FIELD(reg, XM_CORE_RST) == 0)
			return 0;
		udelay(10);
	}

	/* This often fails when DSP is disabled, ignore it */
	if (sfe4001_phy_flash_cfg != 0)
		return 0;

	EFX_ERR(efx, "timed out waiting for XMAC core reset\n");
	return -ETIMEDOUT;
}

/* Configure the XAUI driver that is an output from Falcon */
static void falcon_setup_xaui(struct efx_nic *efx)
{
	efx_dword_t sdctl, txdrv;

	/* Move the XAUI into low power, unless there is no PHY, in
	 * which case the XAUI will have to drive a cable. */
	if (efx->phy_type == PHY_TYPE_NONE)
		return;

	falcon_xmac_readl(efx, &sdctl, XX_SD_CTL_REG_MAC);
	EFX_SET_DWORD_FIELD(sdctl, XX_HIDRVD, XX_SD_CTL_DRV_DEFAULT);
	EFX_SET_DWORD_FIELD(sdctl, XX_LODRVD, XX_SD_CTL_DRV_DEFAULT);
	EFX_SET_DWORD_FIELD(sdctl, XX_HIDRVC, XX_SD_CTL_DRV_DEFAULT);
	EFX_SET_DWORD_FIELD(sdctl, XX_LODRVC, XX_SD_CTL_DRV_DEFAULT);
	EFX_SET_DWORD_FIELD(sdctl, XX_HIDRVB, XX_SD_CTL_DRV_DEFAULT);
	EFX_SET_DWORD_FIELD(sdctl, XX_LODRVB, XX_SD_CTL_DRV_DEFAULT);
	EFX_SET_DWORD_FIELD(sdctl, XX_HIDRVA, XX_SD_CTL_DRV_DEFAULT);
	EFX_SET_DWORD_FIELD(sdctl, XX_LODRVA, XX_SD_CTL_DRV_DEFAULT);
	falcon_xmac_writel(efx, &sdctl, XX_SD_CTL_REG_MAC);

	EFX_POPULATE_DWORD_8(txdrv,
			     XX_DEQD, XX_TXDRV_DEQ_DEFAULT,
			     XX_DEQC, XX_TXDRV_DEQ_DEFAULT,
			     XX_DEQB, XX_TXDRV_DEQ_DEFAULT,
			     XX_DEQA, XX_TXDRV_DEQ_DEFAULT,
			     XX_DTXD, XX_TXDRV_DTX_DEFAULT,
			     XX_DTXC, XX_TXDRV_DTX_DEFAULT,
			     XX_DTXB, XX_TXDRV_DTX_DEFAULT,
			     XX_DTXA, XX_TXDRV_DTX_DEFAULT);
	falcon_xmac_writel(efx, &txdrv, XX_TXDRV_CTL_REG_MAC);
}

static void falcon_hold_xaui_in_rst(struct efx_nic *efx)
{
	efx_dword_t reg;

	EFX_ZERO_DWORD(reg);
	EFX_SET_DWORD_FIELD(reg, XX_PWRDNA_EN, 1);
	EFX_SET_DWORD_FIELD(reg, XX_PWRDNB_EN, 1);
	EFX_SET_DWORD_FIELD(reg, XX_PWRDNC_EN, 1);
	EFX_SET_DWORD_FIELD(reg, XX_PWRDND_EN, 1);
	EFX_SET_DWORD_FIELD(reg, XX_RSTPLLAB_EN, 1);
	EFX_SET_DWORD_FIELD(reg, XX_RSTPLLCD_EN, 1);
	EFX_SET_DWORD_FIELD(reg, XX_RESETA_EN, 1);
	EFX_SET_DWORD_FIELD(reg, XX_RESETB_EN, 1);
	EFX_SET_DWORD_FIELD(reg, XX_RESETC_EN, 1);
	EFX_SET_DWORD_FIELD(reg, XX_RESETD_EN, 1);
	EFX_SET_DWORD_FIELD(reg, XX_RSTXGXSRX_EN, 1);
	EFX_SET_DWORD_FIELD(reg, XX_RSTXGXSTX_EN, 1);
	falcon_xmac_writel(efx, &reg, XX_PWR_RST_REG_MAC);
	udelay(10);
}

static int _falcon_reset_xaui_a(struct efx_nic *efx)
{
	efx_dword_t reg;

	falcon_hold_xaui_in_rst(efx);
	falcon_xmac_readl(efx, &reg, XX_PWR_RST_REG_MAC);

	/* Follow the RAMBUS XAUI data reset sequencing
	 * Channels A and B first: power down, reset PLL, reset, clear
	 */
	EFX_SET_DWORD_FIELD(reg, XX_PWRDNA_EN, 0);
	EFX_SET_DWORD_FIELD(reg, XX_PWRDNB_EN, 0);
	falcon_xmac_writel(efx, &reg, XX_PWR_RST_REG_MAC);
	udelay(10);

	EFX_SET_DWORD_FIELD(reg, XX_RSTPLLAB_EN, 0);
	falcon_xmac_writel(efx, &reg, XX_PWR_RST_REG_MAC);
	udelay(10);

	EFX_SET_DWORD_FIELD(reg, XX_RESETA_EN, 0);
	EFX_SET_DWORD_FIELD(reg, XX_RESETB_EN, 0);
	falcon_xmac_writel(efx, &reg, XX_PWR_RST_REG_MAC);
	udelay(10);

	/* Channels C and D: power down, reset PLL, reset, clear */
	EFX_SET_DWORD_FIELD(reg, XX_PWRDNC_EN, 0);
	EFX_SET_DWORD_FIELD(reg, XX_PWRDND_EN, 0);
	falcon_xmac_writel(efx, &reg, XX_PWR_RST_REG_MAC);
	udelay(10);

	EFX_SET_DWORD_FIELD(reg, XX_RSTPLLCD_EN, 0);
	falcon_xmac_writel(efx, &reg, XX_PWR_RST_REG_MAC);
	udelay(10);

	EFX_SET_DWORD_FIELD(reg, XX_RESETC_EN, 0);
	EFX_SET_DWORD_FIELD(reg, XX_RESETD_EN, 0);
	falcon_xmac_writel(efx, &reg, XX_PWR_RST_REG_MAC);
	udelay(10);

	/* Setup XAUI */
	falcon_setup_xaui(efx);
	udelay(10);

	/* Take XGXS out of reset */
	EFX_ZERO_DWORD(reg);
	falcon_xmac_writel(efx, &reg, XX_PWR_RST_REG_MAC);
	udelay(10);

	return 0;
}

static int _falcon_reset_xaui_b(struct efx_nic *efx)
{
	efx_dword_t reg;
	int count;

	EFX_POPULATE_DWORD_1(reg, XX_RST_XX_EN, 1);
	falcon_xmac_writel(efx, &reg, XX_PWR_RST_REG_MAC);

	/* Give some time for the link to establish */
	for (count = 0; count < 1000; count++) { /* wait upto 10ms */
		falcon_xmac_readl(efx, &reg, XX_PWR_RST_REG_MAC);
		if (EFX_DWORD_FIELD(reg, XX_RST_XX_EN) == 0) {
			falcon_setup_xaui(efx);
			return 0;
		}
		udelay(10);
	}
	EFX_ERR(efx, "timed out waiting for XAUI/XGXS reset\n");
	return -ETIMEDOUT;
}

int falcon_reset_xaui(struct efx_nic *efx)
{
	int rc;

	if (EFX_WORKAROUND_9388(efx)) {
		falcon_hold_xaui_in_rst(efx);
		efx->phy_op->reset_xaui(efx);
		rc = _falcon_reset_xaui_a(efx);
	} else {
		rc = _falcon_reset_xaui_b(efx);
	}
	return rc;
}

static int falcon_xgmii_status(struct efx_nic *efx)
{
	efx_dword_t reg;

	if (FALCON_REV(efx) < FALCON_REV_B0)
		return 1;

	/* The ISR latches, so clear it and re-read */
	falcon_xmac_readl(efx, &reg, XM_MGT_INT_REG_MAC_B0);
	falcon_xmac_readl(efx, &reg, XM_MGT_INT_REG_MAC_B0);

	if (EFX_DWORD_FIELD(reg, XM_LCLFLT) ||
	    EFX_DWORD_FIELD(reg, XM_RMTFLT)) {
		EFX_INFO(efx, "MGT_INT: "EFX_DWORD_FMT"\n", EFX_DWORD_VAL(reg));
		return 0;
	}

	return 1;
}

static void falcon_mask_status_intr(struct efx_nic *efx, int enable)
{
	efx_dword_t reg;

{'fraction_non_alphanumeric': 0.15585246251154858, 'fraction_numerical': 0.015208585033046692, 'mean_word_length': 6.004479840716774, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6117551', 'n_tokens_mistral': 6785, 'n_tokens_neox': 6358, 'n_words': 1116}