drivers/net/ethernet/freescale/enetc/enetc_pf.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/freescale/enetc/enetc_pf.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/freescale/enetc/enetc_pf.c
Extension
.c
Size
25365 bytes
Lines
1022
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: operation-table or driver-model contract
Status
pattern implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

static const struct net_device_ops enetc_ndev_ops = {
	.ndo_open		= enetc_open,
	.ndo_stop		= enetc_close,
	.ndo_start_xmit		= enetc_xmit,
	.ndo_get_stats		= enetc_get_stats,
	.ndo_set_mac_address	= enetc_pf_set_mac_addr,
	.ndo_set_rx_mode	= enetc_pf_set_rx_mode,
	.ndo_vlan_rx_add_vid	= enetc_vlan_rx_add_vid,
	.ndo_vlan_rx_kill_vid	= enetc_vlan_rx_del_vid,
	.ndo_set_vf_mac		= enetc_pf_set_vf_mac,
	.ndo_set_vf_vlan	= enetc_pf_set_vf_vlan,
	.ndo_set_vf_spoofchk	= enetc_pf_set_vf_spoofchk,
	.ndo_set_features	= enetc_pf_set_features,
	.ndo_eth_ioctl		= enetc_ioctl,
	.ndo_setup_tc		= enetc_pf_setup_tc,
	.ndo_bpf		= enetc_setup_bpf,
	.ndo_xdp_xmit		= enetc_xdp_xmit,
	.ndo_hwtstamp_get	= enetc_hwtstamp_get,
	.ndo_hwtstamp_set	= enetc_hwtstamp_set,
};

static struct phylink_pcs *
enetc_pl_mac_select_pcs(struct phylink_config *config, phy_interface_t iface)
{
	struct enetc_pf *pf = phylink_to_enetc_pf(config);

	return pf->pcs;
}

static void enetc_pl_mac_config(struct phylink_config *config,
				unsigned int mode,
				const struct phylink_link_state *state)
{
	struct enetc_pf *pf = phylink_to_enetc_pf(config);

	enetc_mac_config(pf->si, state->interface);
}

static void enetc_force_rgmii_mac(struct enetc_si *si, int speed, int duplex)
{
	u32 old_val, val;

	old_val = val = enetc_port_mac_rd(si, ENETC_PM0_IF_MODE);

	if (speed == SPEED_1000) {
		val &= ~ENETC_PM0_IFM_SSP_MASK;
		val |= ENETC_PM0_IFM_SSP_1000;
	} else if (speed == SPEED_100) {
		val &= ~ENETC_PM0_IFM_SSP_MASK;
		val |= ENETC_PM0_IFM_SSP_100;
	} else if (speed == SPEED_10) {
		val &= ~ENETC_PM0_IFM_SSP_MASK;
		val |= ENETC_PM0_IFM_SSP_10;
	}

	if (duplex == DUPLEX_FULL)
		val |= ENETC_PM0_IFM_FULL_DPX;
	else
		val &= ~ENETC_PM0_IFM_FULL_DPX;

	if (val == old_val)
		return;

	enetc_port_mac_wr(si, ENETC_PM0_IF_MODE, val);
}

static void enetc_pl_mac_link_up(struct phylink_config *config,
				 struct phy_device *phy, unsigned int mode,
				 phy_interface_t interface, int speed,
				 int duplex, bool tx_pause, bool rx_pause)
{
	struct enetc_pf *pf = phylink_to_enetc_pf(config);
	u32 pause_off_thresh = 0, pause_on_thresh = 0;
	u32 init_quanta = 0, refresh_quanta = 0;
	struct enetc_hw *hw = &pf->si->hw;
	struct enetc_si *si = pf->si;
	struct enetc_ndev_priv *priv;
	u32 rbmr, cmd_cfg;
	int idx;

	priv = netdev_priv(pf->si->ndev);

	if (pf->si->hw_features & ENETC_SI_F_QBV)
		enetc_sched_speed_set(priv, speed);

	if (!phylink_autoneg_inband(mode) &&
	    phy_interface_mode_is_rgmii(interface))
		enetc_force_rgmii_mac(si, speed, duplex);

	/* Flow control */

Annotation

Implementation Notes