Commit 1bbe0ecc authored by Antoine Tenart's avatar Antoine Tenart Committed by David S. Miller
Browse files

net: phy: mscc: macsec initialization



This patch adds support for initializing the MACsec engine found within
some Microsemi PHYs. The engine is initialized in a passthrough mode and
does not modify any incoming or outgoing packet. But thanks to this it
now can be configured to perform MACsec transformations on packets,
which will be supported by a future patch.

The MACsec read and write functions are wrapped into two versions: one
called during the init phase, and the other one later on. This is
because the init functions in the Microsemi PHY driver are called while
the MDIO bus lock is taken.

Signed-off-by: default avatarAntoine Tenart <antoine.tenart@bootlin.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent dcb780fb
Loading
Loading
Loading
Loading
+382 −0
Original line number Original line Diff line number Diff line
@@ -18,6 +18,10 @@
#include <linux/netdevice.h>
#include <linux/netdevice.h>
#include <dt-bindings/net/mscc-phy-vsc8531.h>
#include <dt-bindings/net/mscc-phy-vsc8531.h>


#include "mscc_macsec.h"
#include "mscc_mac.h"
#include "mscc_fc_buffer.h"

enum rgmii_rx_clock_delay {
enum rgmii_rx_clock_delay {
	RGMII_RX_CLK_DELAY_0_2_NS = 0,
	RGMII_RX_CLK_DELAY_0_2_NS = 0,
	RGMII_RX_CLK_DELAY_0_8_NS = 1,
	RGMII_RX_CLK_DELAY_0_8_NS = 1,
@@ -121,6 +125,26 @@ enum rgmii_rx_clock_delay {
#define PHY_S6G_PLL_FSM_CTRL_DATA_POS	  8
#define PHY_S6G_PLL_FSM_CTRL_DATA_POS	  8
#define PHY_S6G_PLL_FSM_ENA_POS		  7
#define PHY_S6G_PLL_FSM_ENA_POS		  7


#define MSCC_EXT_PAGE_MACSEC_17		  17
#define MSCC_EXT_PAGE_MACSEC_18		  18

#define MSCC_EXT_PAGE_MACSEC_19		  19
#define MSCC_PHY_MACSEC_19_REG_ADDR(x)	  (x)
#define MSCC_PHY_MACSEC_19_TARGET(x)	  ((x) << 12)
#define MSCC_PHY_MACSEC_19_READ		  BIT(14)
#define MSCC_PHY_MACSEC_19_CMD		  BIT(15)

#define MSCC_EXT_PAGE_MACSEC_20		  20
#define MSCC_PHY_MACSEC_20_TARGET(x)	  (x)
enum macsec_bank {
	FC_BUFFER   = 0x04,
	HOST_MAC    = 0x05,
	LINE_MAC    = 0x06,
	IP_1588     = 0x0e,
	MACSEC_INGR = 0x38,
	MACSEC_EGR  = 0x3c,
};

#define MSCC_EXT_PAGE_ACCESS		  31
#define MSCC_EXT_PAGE_ACCESS		  31
#define MSCC_PHY_PAGE_STANDARD		  0x0000 /* Standard registers */
#define MSCC_PHY_PAGE_STANDARD		  0x0000 /* Standard registers */
#define MSCC_PHY_PAGE_EXTENDED		  0x0001 /* Extended registers */
#define MSCC_PHY_PAGE_EXTENDED		  0x0001 /* Extended registers */
@@ -128,6 +152,7 @@ enum rgmii_rx_clock_delay {
#define MSCC_PHY_PAGE_EXTENDED_3	  0x0003 /* Extended reg - page 3 */
#define MSCC_PHY_PAGE_EXTENDED_3	  0x0003 /* Extended reg - page 3 */
#define MSCC_PHY_PAGE_EXTENDED_4	  0x0004 /* Extended reg - page 4 */
#define MSCC_PHY_PAGE_EXTENDED_4	  0x0004 /* Extended reg - page 4 */
#define MSCC_PHY_PAGE_CSR_CNTL		  MSCC_PHY_PAGE_EXTENDED_4
#define MSCC_PHY_PAGE_CSR_CNTL		  MSCC_PHY_PAGE_EXTENDED_4
#define MSCC_PHY_PAGE_MACSEC		  MSCC_PHY_PAGE_EXTENDED_4
/* Extended reg - GPIO; this is a bank of registers that are shared for all PHYs
/* Extended reg - GPIO; this is a bank of registers that are shared for all PHYs
 * in the same package.
 * in the same package.
 */
 */
@@ -1584,6 +1609,350 @@ out:
	return ret;
	return ret;
}
}


#if IS_ENABLED(CONFIG_MACSEC)
static u32 vsc8584_macsec_phy_read(struct phy_device *phydev,
				   enum macsec_bank bank, u32 reg)
{
	u32 val, val_l = 0, val_h = 0;
	unsigned long deadline;
	int rc;

	rc = phy_select_page(phydev, MSCC_PHY_PAGE_MACSEC);
	if (rc < 0)
		goto failed;

	__phy_write(phydev, MSCC_EXT_PAGE_MACSEC_20,
		    MSCC_PHY_MACSEC_20_TARGET(bank >> 2));

	if (bank >> 2 == 0x1)
		/* non-MACsec access */
		bank &= 0x3;
	else
		bank = 0;

	__phy_write(phydev, MSCC_EXT_PAGE_MACSEC_19,
		    MSCC_PHY_MACSEC_19_CMD | MSCC_PHY_MACSEC_19_READ |
		    MSCC_PHY_MACSEC_19_REG_ADDR(reg) |
		    MSCC_PHY_MACSEC_19_TARGET(bank));

	deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
	do {
		val = __phy_read(phydev, MSCC_EXT_PAGE_MACSEC_19);
	} while (time_before(jiffies, deadline) && !(val & MSCC_PHY_MACSEC_19_CMD));

	val_l = __phy_read(phydev, MSCC_EXT_PAGE_MACSEC_17);
	val_h = __phy_read(phydev, MSCC_EXT_PAGE_MACSEC_18);

failed:
	phy_restore_page(phydev, rc, rc);

	return (val_h << 16) | val_l;
}

static void vsc8584_macsec_phy_write(struct phy_device *phydev,
				     enum macsec_bank bank, u32 reg, u32 val)
{
	unsigned long deadline;
	int rc;

	rc = phy_select_page(phydev, MSCC_PHY_PAGE_MACSEC);
	if (rc < 0)
		goto failed;

	__phy_write(phydev, MSCC_EXT_PAGE_MACSEC_20,
		    MSCC_PHY_MACSEC_20_TARGET(bank >> 2));

	if ((bank >> 2 == 0x1) || (bank >> 2 == 0x3))
		bank &= 0x3;
	else
		/* MACsec access */
		bank = 0;

	__phy_write(phydev, MSCC_EXT_PAGE_MACSEC_17, (u16)val);
	__phy_write(phydev, MSCC_EXT_PAGE_MACSEC_18, (u16)(val >> 16));

	__phy_write(phydev, MSCC_EXT_PAGE_MACSEC_19,
		    MSCC_PHY_MACSEC_19_CMD | MSCC_PHY_MACSEC_19_REG_ADDR(reg) |
		    MSCC_PHY_MACSEC_19_TARGET(bank));

	deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
	do {
		val = __phy_read(phydev, MSCC_EXT_PAGE_MACSEC_19);
	} while (time_before(jiffies, deadline) && !(val & MSCC_PHY_MACSEC_19_CMD));

failed:
	phy_restore_page(phydev, rc, rc);
}

static void vsc8584_macsec_classification(struct phy_device *phydev,
					  enum macsec_bank bank)
{
	/* enable VLAN tag parsing */
	vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_SAM_CP_TAG,
				 MSCC_MS_SAM_CP_TAG_PARSE_STAG |
				 MSCC_MS_SAM_CP_TAG_PARSE_QTAG |
				 MSCC_MS_SAM_CP_TAG_PARSE_QINQ);
}

static void vsc8584_macsec_flow_default_action(struct phy_device *phydev,
					       enum macsec_bank bank,
					       bool block)
{
	u32 port = (bank == MACSEC_INGR) ?
		    MSCC_MS_PORT_UNCONTROLLED : MSCC_MS_PORT_COMMON;
	u32 action = MSCC_MS_FLOW_BYPASS;

	if (block)
		action = MSCC_MS_FLOW_DROP;

	vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_SAM_NM_FLOW_NCP,
				 /* MACsec untagged */
				 MSCC_MS_SAM_NM_FLOW_NCP_UNTAGGED_FLOW_TYPE(action) |
				 MSCC_MS_SAM_NM_FLOW_NCP_UNTAGGED_DROP_ACTION(MSCC_MS_ACTION_DROP) |
				 MSCC_MS_SAM_NM_FLOW_NCP_UNTAGGED_DEST_PORT(port) |
				 /* MACsec tagged */
				 MSCC_MS_SAM_NM_FLOW_NCP_TAGGED_FLOW_TYPE(action) |
				 MSCC_MS_SAM_NM_FLOW_NCP_TAGGED_DROP_ACTION(MSCC_MS_ACTION_DROP) |
				 MSCC_MS_SAM_NM_FLOW_NCP_TAGGED_DEST_PORT(port) |
				 /* Bad tag */
				 MSCC_MS_SAM_NM_FLOW_NCP_BADTAG_FLOW_TYPE(action) |
				 MSCC_MS_SAM_NM_FLOW_NCP_BADTAG_DROP_ACTION(MSCC_MS_ACTION_DROP) |
				 MSCC_MS_SAM_NM_FLOW_NCP_BADTAG_DEST_PORT(port) |
				 /* Kay tag */
				 MSCC_MS_SAM_NM_FLOW_NCP_KAY_FLOW_TYPE(action) |
				 MSCC_MS_SAM_NM_FLOW_NCP_KAY_DROP_ACTION(MSCC_MS_ACTION_DROP) |
				 MSCC_MS_SAM_NM_FLOW_NCP_KAY_DEST_PORT(port));
	vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_SAM_NM_FLOW_CP,
				 /* MACsec untagged */
				 MSCC_MS_SAM_NM_FLOW_NCP_UNTAGGED_FLOW_TYPE(action) |
				 MSCC_MS_SAM_NM_FLOW_CP_UNTAGGED_DROP_ACTION(MSCC_MS_ACTION_DROP) |
				 MSCC_MS_SAM_NM_FLOW_CP_UNTAGGED_DEST_PORT(port) |
				 /* MACsec tagged */
				 MSCC_MS_SAM_NM_FLOW_NCP_TAGGED_FLOW_TYPE(action) |
				 MSCC_MS_SAM_NM_FLOW_CP_TAGGED_DROP_ACTION(MSCC_MS_ACTION_DROP) |
				 MSCC_MS_SAM_NM_FLOW_CP_TAGGED_DEST_PORT(port) |
				 /* Bad tag */
				 MSCC_MS_SAM_NM_FLOW_NCP_BADTAG_FLOW_TYPE(action) |
				 MSCC_MS_SAM_NM_FLOW_CP_BADTAG_DROP_ACTION(MSCC_MS_ACTION_DROP) |
				 MSCC_MS_SAM_NM_FLOW_CP_BADTAG_DEST_PORT(port) |
				 /* Kay tag */
				 MSCC_MS_SAM_NM_FLOW_NCP_KAY_FLOW_TYPE(action) |
				 MSCC_MS_SAM_NM_FLOW_CP_KAY_DROP_ACTION(MSCC_MS_ACTION_DROP) |
				 MSCC_MS_SAM_NM_FLOW_CP_KAY_DEST_PORT(port));
}

static void vsc8584_macsec_integrity_checks(struct phy_device *phydev,
					    enum macsec_bank bank)
{
	u32 val;

	if (bank != MACSEC_INGR)
		return;

	/* Set default rules to pass unmatched frames */
	val = vsc8584_macsec_phy_read(phydev, bank,
				      MSCC_MS_PARAMS2_IG_CC_CONTROL);
	val |= MSCC_MS_PARAMS2_IG_CC_CONTROL_NON_MATCH_CTRL_ACT |
	       MSCC_MS_PARAMS2_IG_CC_CONTROL_NON_MATCH_ACT;
	vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_PARAMS2_IG_CC_CONTROL,
				 val);

	vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_PARAMS2_IG_CP_TAG,
				 MSCC_MS_PARAMS2_IG_CP_TAG_PARSE_STAG |
				 MSCC_MS_PARAMS2_IG_CP_TAG_PARSE_QTAG |
				 MSCC_MS_PARAMS2_IG_CP_TAG_PARSE_QINQ);
}

static void vsc8584_macsec_block_init(struct phy_device *phydev,
				      enum macsec_bank bank)
{
	u32 val;
	int i;

	vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_ENA_CFG,
				 MSCC_MS_ENA_CFG_SW_RST |
				 MSCC_MS_ENA_CFG_MACSEC_BYPASS_ENA);

	/* Set the MACsec block out of s/w reset and enable clocks */
	vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_ENA_CFG,
				 MSCC_MS_ENA_CFG_CLK_ENA);

	vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_STATUS_CONTEXT_CTRL,
				 bank == MACSEC_INGR ? 0xe5880214 : 0xe5880218);
	vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_MISC_CONTROL,
				 MSCC_MS_MISC_CONTROL_MC_LATENCY_FIX(bank == MACSEC_INGR ? 57 : 40) |
				 MSCC_MS_MISC_CONTROL_XFORM_REC_SIZE(bank == MACSEC_INGR ? 1 : 2));

	/* Clear the counters */
	val = vsc8584_macsec_phy_read(phydev, bank, MSCC_MS_COUNT_CONTROL);
	val |= MSCC_MS_COUNT_CONTROL_AUTO_CNTR_RESET;
	vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_COUNT_CONTROL, val);

	/* Enable octet increment mode */
	vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_PP_CTRL,
				 MSCC_MS_PP_CTRL_MACSEC_OCTET_INCR_MODE);

	vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_BLOCK_CTX_UPDATE, 0x3);

	val = vsc8584_macsec_phy_read(phydev, bank, MSCC_MS_COUNT_CONTROL);
	val |= MSCC_MS_COUNT_CONTROL_RESET_ALL;
	vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_COUNT_CONTROL, val);

	/* Set the MTU */
	vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_NON_VLAN_MTU_CHECK,
				 MSCC_MS_NON_VLAN_MTU_CHECK_NV_MTU_COMPARE(32761) |
				 MSCC_MS_NON_VLAN_MTU_CHECK_NV_MTU_COMP_DROP);

	for (i = 0; i < 8; i++)
		vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_VLAN_MTU_CHECK(i),
					 MSCC_MS_VLAN_MTU_CHECK_MTU_COMPARE(32761) |
					 MSCC_MS_VLAN_MTU_CHECK_MTU_COMP_DROP);

	if (bank == MACSEC_EGR) {
		val = vsc8584_macsec_phy_read(phydev, bank, MSCC_MS_INTR_CTRL_STATUS);
		val &= ~MSCC_MS_INTR_CTRL_STATUS_INTR_ENABLE_M;
		vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_INTR_CTRL_STATUS, val);

		vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_FC_CFG,
					 MSCC_MS_FC_CFG_FCBUF_ENA |
					 MSCC_MS_FC_CFG_LOW_THRESH(0x1) |
					 MSCC_MS_FC_CFG_HIGH_THRESH(0x4) |
					 MSCC_MS_FC_CFG_LOW_BYTES_VAL(0x4) |
					 MSCC_MS_FC_CFG_HIGH_BYTES_VAL(0x6));
	}

	vsc8584_macsec_classification(phydev, bank);
	vsc8584_macsec_flow_default_action(phydev, bank, false);
	vsc8584_macsec_integrity_checks(phydev, bank);

	/* Enable the MACsec block */
	vsc8584_macsec_phy_write(phydev, bank, MSCC_MS_ENA_CFG,
				 MSCC_MS_ENA_CFG_CLK_ENA |
				 MSCC_MS_ENA_CFG_MACSEC_ENA |
				 MSCC_MS_ENA_CFG_MACSEC_SPEED_MODE(0x5));
}

static void vsc8584_macsec_mac_init(struct phy_device *phydev,
				    enum macsec_bank bank)
{
	u32 val;
	int i;

	/* Clear host & line stats */
	for (i = 0; i < 36; i++)
		vsc8584_macsec_phy_write(phydev, bank, 0x1c + i, 0);

	val = vsc8584_macsec_phy_read(phydev, bank,
				      MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL);
	val &= ~MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL_PAUSE_MODE_M;
	val |= MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL_PAUSE_MODE(2) |
	       MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL_PAUSE_VALUE(0xffff);
	vsc8584_macsec_phy_write(phydev, bank,
				 MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL, val);

	val = vsc8584_macsec_phy_read(phydev, bank,
				      MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL_2);
	val |= 0xffff;
	vsc8584_macsec_phy_write(phydev, bank,
				 MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL_2, val);

	val = vsc8584_macsec_phy_read(phydev, bank,
				      MSCC_MAC_PAUSE_CFG_RX_FRAME_CTRL);
	if (bank == HOST_MAC)
		val |= MSCC_MAC_PAUSE_CFG_RX_FRAME_CTRL_PAUSE_TIMER_ENA |
		       MSCC_MAC_PAUSE_CFG_RX_FRAME_CTRL_PAUSE_FRAME_DROP_ENA;
	else
		val |= MSCC_MAC_PAUSE_CFG_RX_FRAME_CTRL_PAUSE_REACT_ENA |
		       MSCC_MAC_PAUSE_CFG_RX_FRAME_CTRL_PAUSE_FRAME_DROP_ENA |
		       MSCC_MAC_PAUSE_CFG_RX_FRAME_CTRL_PAUSE_MODE |
		       MSCC_MAC_PAUSE_CFG_RX_FRAME_CTRL_EARLY_PAUSE_DETECT_ENA;
	vsc8584_macsec_phy_write(phydev, bank,
				 MSCC_MAC_PAUSE_CFG_RX_FRAME_CTRL, val);

	vsc8584_macsec_phy_write(phydev, bank, MSCC_MAC_CFG_PKTINF_CFG,
				 MSCC_MAC_CFG_PKTINF_CFG_STRIP_FCS_ENA |
				 MSCC_MAC_CFG_PKTINF_CFG_INSERT_FCS_ENA |
				 MSCC_MAC_CFG_PKTINF_CFG_LPI_RELAY_ENA |
				 MSCC_MAC_CFG_PKTINF_CFG_STRIP_PREAMBLE_ENA |
				 MSCC_MAC_CFG_PKTINF_CFG_INSERT_PREAMBLE_ENA |
				 (bank == HOST_MAC ?
				  MSCC_MAC_CFG_PKTINF_CFG_ENABLE_TX_PADDING : 0));

	val = vsc8584_macsec_phy_read(phydev, bank, MSCC_MAC_CFG_MODE_CFG);
	val &= ~MSCC_MAC_CFG_MODE_CFG_DISABLE_DIC;
	vsc8584_macsec_phy_write(phydev, bank, MSCC_MAC_CFG_MODE_CFG, val);

	val = vsc8584_macsec_phy_read(phydev, bank, MSCC_MAC_CFG_MAXLEN_CFG);
	val &= ~MSCC_MAC_CFG_MAXLEN_CFG_MAX_LEN_M;
	val |= MSCC_MAC_CFG_MAXLEN_CFG_MAX_LEN(10240);
	vsc8584_macsec_phy_write(phydev, bank, MSCC_MAC_CFG_MAXLEN_CFG, val);

	vsc8584_macsec_phy_write(phydev, bank, MSCC_MAC_CFG_ADV_CHK_CFG,
				 MSCC_MAC_CFG_ADV_CHK_CFG_SFD_CHK_ENA |
				 MSCC_MAC_CFG_ADV_CHK_CFG_PRM_CHK_ENA |
				 MSCC_MAC_CFG_ADV_CHK_CFG_OOR_ERR_ENA |
				 MSCC_MAC_CFG_ADV_CHK_CFG_INR_ERR_ENA);

	val = vsc8584_macsec_phy_read(phydev, bank, MSCC_MAC_CFG_LFS_CFG);
	val &= ~MSCC_MAC_CFG_LFS_CFG_LFS_MODE_ENA;
	vsc8584_macsec_phy_write(phydev, bank, MSCC_MAC_CFG_LFS_CFG, val);

	vsc8584_macsec_phy_write(phydev, bank, MSCC_MAC_CFG_ENA_CFG,
				 MSCC_MAC_CFG_ENA_CFG_RX_CLK_ENA |
				 MSCC_MAC_CFG_ENA_CFG_TX_CLK_ENA |
				 MSCC_MAC_CFG_ENA_CFG_RX_ENA |
				 MSCC_MAC_CFG_ENA_CFG_TX_ENA);
}

/* Must be called with mdio_lock taken */
static int vsc8584_macsec_init(struct phy_device *phydev)
{
	u32 val;

	vsc8584_macsec_block_init(phydev, MACSEC_INGR);
	vsc8584_macsec_block_init(phydev, MACSEC_EGR);
	vsc8584_macsec_mac_init(phydev, HOST_MAC);
	vsc8584_macsec_mac_init(phydev, LINE_MAC);

	vsc8584_macsec_phy_write(phydev, FC_BUFFER,
				 MSCC_FCBUF_FC_READ_THRESH_CFG,
				 MSCC_FCBUF_FC_READ_THRESH_CFG_TX_THRESH(4) |
				 MSCC_FCBUF_FC_READ_THRESH_CFG_RX_THRESH(5));

	val = vsc8584_macsec_phy_read(phydev, FC_BUFFER, MSCC_FCBUF_MODE_CFG);
	val |= MSCC_FCBUF_MODE_CFG_PAUSE_GEN_ENA |
	       MSCC_FCBUF_MODE_CFG_RX_PPM_RATE_ADAPT_ENA |
	       MSCC_FCBUF_MODE_CFG_TX_PPM_RATE_ADAPT_ENA;
	vsc8584_macsec_phy_write(phydev, FC_BUFFER, MSCC_FCBUF_MODE_CFG, val);

	vsc8584_macsec_phy_write(phydev, FC_BUFFER, MSCC_FCBUF_PPM_RATE_ADAPT_THRESH_CFG,
				 MSCC_FCBUF_PPM_RATE_ADAPT_THRESH_CFG_TX_THRESH(8) |
				 MSCC_FCBUF_PPM_RATE_ADAPT_THRESH_CFG_TX_OFFSET(9));

	val = vsc8584_macsec_phy_read(phydev, FC_BUFFER,
				      MSCC_FCBUF_TX_DATA_QUEUE_CFG);
	val &= ~(MSCC_FCBUF_TX_DATA_QUEUE_CFG_START_M |
		 MSCC_FCBUF_TX_DATA_QUEUE_CFG_END_M);
	val |= MSCC_FCBUF_TX_DATA_QUEUE_CFG_START(0) |
		MSCC_FCBUF_TX_DATA_QUEUE_CFG_END(5119);
	vsc8584_macsec_phy_write(phydev, FC_BUFFER,
				 MSCC_FCBUF_TX_DATA_QUEUE_CFG, val);

	val = vsc8584_macsec_phy_read(phydev, FC_BUFFER, MSCC_FCBUF_ENA_CFG);
	val |= MSCC_FCBUF_ENA_CFG_TX_ENA | MSCC_FCBUF_ENA_CFG_RX_ENA;
	vsc8584_macsec_phy_write(phydev, FC_BUFFER, MSCC_FCBUF_ENA_CFG, val);

	val = vsc8584_macsec_phy_read(phydev, IP_1588,
				      MSCC_PROC_0_IP_1588_TOP_CFG_STAT_MODE_CTL);
	val &= ~MSCC_PROC_0_IP_1588_TOP_CFG_STAT_MODE_CTL_PROTOCOL_MODE_M;
	val |= MSCC_PROC_0_IP_1588_TOP_CFG_STAT_MODE_CTL_PROTOCOL_MODE(4);
	vsc8584_macsec_phy_write(phydev, IP_1588,
				 MSCC_PROC_0_IP_1588_TOP_CFG_STAT_MODE_CTL, val);

	return 0;
}
#endif /* CONFIG_MACSEC */

/* Check if one PHY has already done the init of the parts common to all PHYs
/* Check if one PHY has already done the init of the parts common to all PHYs
 * in the Quad PHY package.
 * in the Quad PHY package.
 */
 */
@@ -1733,6 +2102,19 @@ static int vsc8584_config_init(struct phy_device *phydev)


	mutex_unlock(&phydev->mdio.bus->mdio_lock);
	mutex_unlock(&phydev->mdio.bus->mdio_lock);


#if IS_ENABLED(CONFIG_MACSEC)
	/* MACsec */
	switch (phydev->phy_id & phydev->drv->phy_id_mask) {
	case PHY_ID_VSC856X:
	case PHY_ID_VSC8575:
	case PHY_ID_VSC8582:
	case PHY_ID_VSC8584:
		ret = vsc8584_macsec_init(phydev);
		if (ret)
			goto err;
	}
#endif

	phy_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
	phy_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);


	val = phy_read(phydev, MSCC_PHY_EXT_PHY_CNTL_1);
	val = phy_read(phydev, MSCC_PHY_EXT_PHY_CNTL_1);
+64 −0
Original line number Original line Diff line number Diff line
/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */
/*
 * Microsemi Ocelot Switch driver
 *
 * Copyright (C) 2019 Microsemi Corporation
 */

#ifndef _MSCC_OCELOT_FC_BUFFER_H_
#define _MSCC_OCELOT_FC_BUFFER_H_

#define MSCC_FCBUF_ENA_CFG					0x00
#define MSCC_FCBUF_MODE_CFG					0x01
#define MSCC_FCBUF_PPM_RATE_ADAPT_THRESH_CFG			0x02
#define MSCC_FCBUF_TX_CTRL_QUEUE_CFG				0x03
#define MSCC_FCBUF_TX_DATA_QUEUE_CFG				0x04
#define MSCC_FCBUF_RX_DATA_QUEUE_CFG				0x05
#define MSCC_FCBUF_TX_BUFF_XON_XOFF_THRESH_CFG			0x06
#define MSCC_FCBUF_FC_READ_THRESH_CFG				0x07
#define MSCC_FCBUF_TX_FRM_GAP_COMP				0x08

#define MSCC_FCBUF_ENA_CFG_TX_ENA				BIT(0)
#define MSCC_FCBUF_ENA_CFG_RX_ENA				BIT(4)

#define MSCC_FCBUF_MODE_CFG_DROP_BEHAVIOUR			BIT(4)
#define MSCC_FCBUF_MODE_CFG_PAUSE_REACT_ENA			BIT(8)
#define MSCC_FCBUF_MODE_CFG_RX_PPM_RATE_ADAPT_ENA		BIT(12)
#define MSCC_FCBUF_MODE_CFG_TX_PPM_RATE_ADAPT_ENA		BIT(16)
#define MSCC_FCBUF_MODE_CFG_TX_CTRL_QUEUE_ENA			BIT(20)
#define MSCC_FCBUF_MODE_CFG_PAUSE_GEN_ENA			BIT(24)
#define MSCC_FCBUF_MODE_CFG_INCLUDE_PAUSE_RCVD_IN_PAUSE_GEN	BIT(28)

#define MSCC_FCBUF_PPM_RATE_ADAPT_THRESH_CFG_TX_THRESH(x)	(x)
#define MSCC_FCBUF_PPM_RATE_ADAPT_THRESH_CFG_TX_THRESH_M	GENMASK(15, 0)
#define MSCC_FCBUF_PPM_RATE_ADAPT_THRESH_CFG_TX_OFFSET(x)	((x) << 16)
#define MSCC_FCBUF_PPM_RATE_ADAPT_THRESH_CFG_TX_OFFSET_M	GENMASK(19, 16)
#define MSCC_FCBUF_PPM_RATE_ADAPT_THRESH_CFG_RX_THRESH(x)	((x) << 20)
#define MSCC_FCBUF_PPM_RATE_ADAPT_THRESH_CFG_RX_THRESH_M	GENMASK(31, 20)

#define MSCC_FCBUF_TX_CTRL_QUEUE_CFG_START(x)			(x)
#define MSCC_FCBUF_TX_CTRL_QUEUE_CFG_START_M			GENMASK(15, 0)
#define MSCC_FCBUF_TX_CTRL_QUEUE_CFG_END(x)			((x) << 16)
#define MSCC_FCBUF_TX_CTRL_QUEUE_CFG_END_M			GENMASK(31, 16)

#define MSCC_FCBUF_TX_DATA_QUEUE_CFG_START(x)			(x)
#define MSCC_FCBUF_TX_DATA_QUEUE_CFG_START_M			GENMASK(15, 0)
#define MSCC_FCBUF_TX_DATA_QUEUE_CFG_END(x)			((x) << 16)
#define MSCC_FCBUF_TX_DATA_QUEUE_CFG_END_M			GENMASK(31, 16)

#define MSCC_FCBUF_RX_DATA_QUEUE_CFG_START(x)			(x)
#define MSCC_FCBUF_RX_DATA_QUEUE_CFG_START_M			GENMASK(15, 0)
#define MSCC_FCBUF_RX_DATA_QUEUE_CFG_END(x)			((x) << 16)
#define MSCC_FCBUF_RX_DATA_QUEUE_CFG_END_M			GENMASK(31, 16)

#define MSCC_FCBUF_TX_BUFF_XON_XOFF_THRESH_CFG_XOFF_THRESH(x)	(x)
#define MSCC_FCBUF_TX_BUFF_XON_XOFF_THRESH_CFG_XOFF_THRESH_M	GENMASK(15, 0)
#define MSCC_FCBUF_TX_BUFF_XON_XOFF_THRESH_CFG_XON_THRESH(x)	((x) << 16)
#define MSCC_FCBUF_TX_BUFF_XON_XOFF_THRESH_CFG_XON_THRESH_M	GENMASK(31, 16)

#define MSCC_FCBUF_FC_READ_THRESH_CFG_TX_THRESH(x)		(x)
#define MSCC_FCBUF_FC_READ_THRESH_CFG_TX_THRESH_M		GENMASK(15, 0)
#define MSCC_FCBUF_FC_READ_THRESH_CFG_RX_THRESH(x)		((x) << 16)
#define MSCC_FCBUF_FC_READ_THRESH_CFG_RX_THRESH_M		GENMASK(31, 16)

#endif
+159 −0
Original line number Original line Diff line number Diff line
/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */
/*
 * Microsemi Ocelot Switch driver
 *
 * Copyright (c) 2017 Microsemi Corporation
 */

#ifndef _MSCC_OCELOT_LINE_MAC_H_
#define _MSCC_OCELOT_LINE_MAC_H_

#define MSCC_MAC_CFG_ENA_CFG					0x00
#define MSCC_MAC_CFG_MODE_CFG					0x01
#define MSCC_MAC_CFG_MAXLEN_CFG					0x02
#define MSCC_MAC_CFG_NUM_TAGS_CFG				0x03
#define MSCC_MAC_CFG_TAGS_CFG					0x04
#define MSCC_MAC_CFG_ADV_CHK_CFG				0x07
#define MSCC_MAC_CFG_LFS_CFG					0x08
#define MSCC_MAC_CFG_LB_CFG					0x09
#define MSCC_MAC_CFG_PKTINF_CFG					0x0a
#define MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL			0x0b
#define MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL_2			0x0c
#define MSCC_MAC_PAUSE_CFG_RX_FRAME_CTRL			0x0d
#define MSCC_MAC_PAUSE_CFG_STATE				0x0e
#define MSCC_MAC_PAUSE_CFG_MAC_ADDRESS_LSB			0x0f
#define MSCC_MAC_PAUSE_CFG_MAC_ADDRESS_MSB			0x10
#define MSCC_MAC_STATUS_RX_LANE_STICKY_0			0x11
#define MSCC_MAC_STATUS_RX_LANE_STICKY_1			0x12
#define MSCC_MAC_STATUS_TX_MONITOR_STICKY			0x13
#define MSCC_MAC_STATUS_TX_MONITOR_STICKY_MASK			0x14
#define MSCC_MAC_STATUS_STICKY					0x15
#define MSCC_MAC_STATUS_STICKY_MASK				0x16
#define MSCC_MAC_STATS_32BIT_RX_HIH_CKSM_ERR_CNT		0x17
#define MSCC_MAC_STATS_32BIT_RX_XGMII_PROT_ERR_CNT		0x18
#define MSCC_MAC_STATS_32BIT_RX_SYMBOL_ERR_CNT			0x19
#define MSCC_MAC_STATS_32BIT_RX_PAUSE_CNT			0x1a
#define MSCC_MAC_STATS_32BIT_RX_UNSUP_OPCODE_CNT		0x1b
#define MSCC_MAC_STATS_32BIT_RX_UC_CNT				0x1c
#define MSCC_MAC_STATS_32BIT_RX_MC_CNT				0x1d
#define MSCC_MAC_STATS_32BIT_RX_BC_CNT				0x1e
#define MSCC_MAC_STATS_32BIT_RX_CRC_ERR_CNT			0x1f
#define MSCC_MAC_STATS_32BIT_RX_UNDERSIZE_CNT			0x20
#define MSCC_MAC_STATS_32BIT_RX_FRAGMENTS_CNT			0x21
#define MSCC_MAC_STATS_32BIT_RX_IN_RANGE_LEN_ERR_CNT		0x22
#define MSCC_MAC_STATS_32BIT_RX_OUT_OF_RANGE_LEN_ERR_CNT	0x23
#define MSCC_MAC_STATS_32BIT_RX_OVERSIZE_CNT			0x24
#define MSCC_MAC_STATS_32BIT_RX_JABBERS_CNT			0x25
#define MSCC_MAC_STATS_32BIT_RX_SIZE64_CNT			0x26
#define MSCC_MAC_STATS_32BIT_RX_SIZE65TO127_CNT			0x27
#define MSCC_MAC_STATS_32BIT_RX_SIZE128TO255_CNT		0x28
#define MSCC_MAC_STATS_32BIT_RX_SIZE256TO511_CNT		0x29
#define MSCC_MAC_STATS_32BIT_RX_SIZE512TO1023_CNT		0x2a
#define MSCC_MAC_STATS_32BIT_RX_SIZE1024TO1518_CNT		0x2b
#define MSCC_MAC_STATS_32BIT_RX_SIZE1519TOMAX_CNT		0x2c
#define MSCC_MAC_STATS_32BIT_RX_IPG_SHRINK_CNT			0x2d
#define MSCC_MAC_STATS_32BIT_TX_PAUSE_CNT			0x2e
#define MSCC_MAC_STATS_32BIT_TX_UC_CNT				0x2f
#define MSCC_MAC_STATS_32BIT_TX_MC_CNT				0x30
#define MSCC_MAC_STATS_32BIT_TX_BC_CNT				0x31
#define MSCC_MAC_STATS_32BIT_TX_SIZE64_CNT			0x32
#define MSCC_MAC_STATS_32BIT_TX_SIZE65TO127_CNT			0x33
#define MSCC_MAC_STATS_32BIT_TX_SIZE128TO255_CNT		0x34
#define MSCC_MAC_STATS_32BIT_TX_SIZE256TO511_CNT		0x35
#define MSCC_MAC_STATS_32BIT_TX_SIZE512TO1023_CNT		0x36
#define MSCC_MAC_STATS_32BIT_TX_SIZE1024TO1518_CNT		0x37
#define MSCC_MAC_STATS_32BIT_TX_SIZE1519TOMAX_CNT		0x38
#define MSCC_MAC_STATS_40BIT_RX_BAD_BYTES_CNT			0x39
#define MSCC_MAC_STATS_40BIT_RX_BAD_BYTES_MSB_CNT		0x3a
#define MSCC_MAC_STATS_40BIT_RX_OK_BYTES_CNT			0x3b
#define MSCC_MAC_STATS_40BIT_RX_OK_BYTES_MSB_CNT		0x3c
#define MSCC_MAC_STATS_40BIT_RX_IN_BYTES_CNT			0x3d
#define MSCC_MAC_STATS_40BIT_RX_IN_BYTES_MSB_CNT		0x3e
#define MSCC_MAC_STATS_40BIT_TX_OK_BYTES_CNT			0x3f
#define MSCC_MAC_STATS_40BIT_TX_OK_BYTES_MSB_CNT		0x40
#define MSCC_MAC_STATS_40BIT_TX_OUT_BYTES_CNT			0x41
#define MSCC_MAC_STATS_40BIT_TX_OUT_BYTES_MSB_CNT		0x42

#define MSCC_MAC_CFG_ENA_CFG_RX_CLK_ENA				BIT(0)
#define MSCC_MAC_CFG_ENA_CFG_TX_CLK_ENA				BIT(4)
#define MSCC_MAC_CFG_ENA_CFG_RX_SW_RST				BIT(8)
#define MSCC_MAC_CFG_ENA_CFG_TX_SW_RST				BIT(12)
#define MSCC_MAC_CFG_ENA_CFG_RX_ENA				BIT(16)
#define MSCC_MAC_CFG_ENA_CFG_TX_ENA				BIT(20)

#define MSCC_MAC_CFG_MODE_CFG_FORCE_CW_UPDATE_INTERVAL(x)	((x) << 20)
#define MSCC_MAC_CFG_MODE_CFG_FORCE_CW_UPDATE_INTERVAL_M	GENMASK(29, 20)
#define MSCC_MAC_CFG_MODE_CFG_FORCE_CW_UPDATE			BIT(16)
#define MSCC_MAC_CFG_MODE_CFG_TUNNEL_PAUSE_FRAMES		BIT(14)
#define MSCC_MAC_CFG_MODE_CFG_MAC_PREAMBLE_CFG(x)		((x) << 10)
#define MSCC_MAC_CFG_MODE_CFG_MAC_PREAMBLE_CFG_M		GENMASK(12, 10)
#define MSCC_MAC_CFG_MODE_CFG_MAC_IPG_CFG			BIT(6)
#define MSCC_MAC_CFG_MODE_CFG_XGMII_GEN_MODE_ENA		BIT(4)
#define MSCC_MAC_CFG_MODE_CFG_HIH_CRC_CHECK			BIT(2)
#define MSCC_MAC_CFG_MODE_CFG_UNDERSIZED_FRAME_DROP_DIS		BIT(1)
#define MSCC_MAC_CFG_MODE_CFG_DISABLE_DIC			BIT(0)

#define MSCC_MAC_CFG_MAXLEN_CFG_MAX_LEN_TAG_CHK			BIT(16)
#define MSCC_MAC_CFG_MAXLEN_CFG_MAX_LEN(x)			(x)
#define MSCC_MAC_CFG_MAXLEN_CFG_MAX_LEN_M			GENMASK(15, 0)

#define MSCC_MAC_CFG_TAGS_CFG_RSZ				0x4
#define MSCC_MAC_CFG_TAGS_CFG_TAG_ID(x)				((x) << 16)
#define MSCC_MAC_CFG_TAGS_CFG_TAG_ID_M				GENMASK(31, 16)
#define MSCC_MAC_CFG_TAGS_CFG_TAG_ENA				BIT(4)

#define MSCC_MAC_CFG_ADV_CHK_CFG_EXT_EOP_CHK_ENA		BIT(24)
#define MSCC_MAC_CFG_ADV_CHK_CFG_EXT_SOP_CHK_ENA		BIT(20)
#define MSCC_MAC_CFG_ADV_CHK_CFG_SFD_CHK_ENA			BIT(16)
#define MSCC_MAC_CFG_ADV_CHK_CFG_PRM_SHK_CHK_DIS		BIT(12)
#define MSCC_MAC_CFG_ADV_CHK_CFG_PRM_CHK_ENA			BIT(8)
#define MSCC_MAC_CFG_ADV_CHK_CFG_OOR_ERR_ENA			BIT(4)
#define MSCC_MAC_CFG_ADV_CHK_CFG_INR_ERR_ENA			BIT(0)

#define MSCC_MAC_CFG_LFS_CFG_LFS_INH_TX				BIT(8)
#define MSCC_MAC_CFG_LFS_CFG_LFS_DIS_TX				BIT(4)
#define MSCC_MAC_CFG_LFS_CFG_LFS_UNIDIR_ENA			BIT(3)
#define MSCC_MAC_CFG_LFS_CFG_USE_LEADING_EDGE_DETECT		BIT(2)
#define MSCC_MAC_CFG_LFS_CFG_SPURIOUS_Q_DIS			BIT(1)
#define MSCC_MAC_CFG_LFS_CFG_LFS_MODE_ENA			BIT(0)

#define MSCC_MAC_CFG_LB_CFG_XGMII_HOST_LB_ENA			BIT(4)
#define MSCC_MAC_CFG_LB_CFG_XGMII_PHY_LB_ENA			BIT(0)

#define MSCC_MAC_CFG_PKTINF_CFG_STRIP_FCS_ENA			BIT(0)
#define MSCC_MAC_CFG_PKTINF_CFG_INSERT_FCS_ENA			BIT(4)
#define MSCC_MAC_CFG_PKTINF_CFG_STRIP_PREAMBLE_ENA		BIT(8)
#define MSCC_MAC_CFG_PKTINF_CFG_INSERT_PREAMBLE_ENA		BIT(12)
#define MSCC_MAC_CFG_PKTINF_CFG_LPI_RELAY_ENA			BIT(16)
#define MSCC_MAC_CFG_PKTINF_CFG_LF_RELAY_ENA			BIT(20)
#define MSCC_MAC_CFG_PKTINF_CFG_RF_RELAY_ENA			BIT(24)
#define MSCC_MAC_CFG_PKTINF_CFG_ENABLE_TX_PADDING		BIT(25)
#define MSCC_MAC_CFG_PKTINF_CFG_ENABLE_RX_PADDING		BIT(26)
#define MSCC_MAC_CFG_PKTINF_CFG_ENABLE_4BYTE_PREAMBLE		BIT(27)
#define MSCC_MAC_CFG_PKTINF_CFG_MACSEC_BYPASS_NUM_PTP_STALL_CLKS(x)	((x) << 28)
#define MSCC_MAC_CFG_PKTINF_CFG_MACSEC_BYPASS_NUM_PTP_STALL_CLKS_M	GENMASK(30, 28)

#define MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL_PAUSE_VALUE(x)		((x) << 16)
#define MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL_PAUSE_VALUE_M		GENMASK(31, 16)
#define MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL_WAIT_FOR_LPI_LOW	BIT(12)
#define MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL_USE_PAUSE_STALL_ENA	BIT(8)
#define MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL_PAUSE_REPL_MODE	BIT(4)
#define MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL_PAUSE_FRC_FRAME	BIT(2)
#define MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL_PAUSE_MODE(x)		(x)
#define MSCC_MAC_PAUSE_CFG_TX_FRAME_CTRL_PAUSE_MODE_M		GENMASK(1, 0)

#define MSCC_MAC_PAUSE_CFG_RX_FRAME_CTRL_EARLY_PAUSE_DETECT_ENA	BIT(16)
#define MSCC_MAC_PAUSE_CFG_RX_FRAME_CTRL_PRE_CRC_MODE		BIT(20)
#define MSCC_MAC_PAUSE_CFG_RX_FRAME_CTRL_PAUSE_TIMER_ENA	BIT(12)
#define MSCC_MAC_PAUSE_CFG_RX_FRAME_CTRL_PAUSE_REACT_ENA	BIT(8)
#define MSCC_MAC_PAUSE_CFG_RX_FRAME_CTRL_PAUSE_FRAME_DROP_ENA	BIT(4)
#define MSCC_MAC_PAUSE_CFG_RX_FRAME_CTRL_PAUSE_MODE		BIT(0)

#define MSCC_MAC_PAUSE_CFG_STATE_PAUSE_STATE			BIT(0)
#define MSCC_MAC_PAUSE_CFG_STATE_MAC_TX_PAUSE_GEN		BIT(4)

#define MSCC_PROC_0_IP_1588_TOP_CFG_STAT_MODE_CTL			0x2
#define MSCC_PROC_0_IP_1588_TOP_CFG_STAT_MODE_CTL_PROTOCOL_MODE(x)	(x)
#define MSCC_PROC_0_IP_1588_TOP_CFG_STAT_MODE_CTL_PROTOCOL_MODE_M	GENMASK(2, 0)

#endif /* _MSCC_OCELOT_LINE_MAC_H_ */
+260 −0

File added.

Preview size limit exceeded, changes collapsed.