diff options
Diffstat (limited to 'drivers/net/ethernet/ti')
-rw-r--r-- | drivers/net/ethernet/ti/am65-cpsw-nuss.c | 198 | ||||
-rw-r--r-- | drivers/net/ethernet/ti/am65-cpsw-nuss.h | 9 | ||||
-rw-r--r-- | drivers/net/ethernet/ti/cpsw.c | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/ti/cpsw_ale.c | 66 | ||||
-rw-r--r-- | drivers/net/ethernet/ti/cpsw_new.c | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/ti/davinci_emac.c | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/ti/davinci_mdio.c | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/ti/icssg/icssg_prueth.c | 47 | ||||
-rw-r--r-- | drivers/net/ethernet/ti/icssg/icssg_prueth_sr1.c | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/ti/netcp_core.c | 2 |
10 files changed, 206 insertions, 126 deletions
diff --git a/drivers/net/ethernet/ti/am65-cpsw-nuss.c b/drivers/net/ethernet/ti/am65-cpsw-nuss.c index ba6db61dd227..14e1df721f2e 100644 --- a/drivers/net/ethernet/ti/am65-cpsw-nuss.c +++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.c @@ -71,6 +71,8 @@ #define AM65_CPSW_PORT_REG_RX_PRI_MAP 0x020 #define AM65_CPSW_PORT_REG_RX_MAXLEN 0x024 +#define AM65_CPSW_PORTN_REG_CTL 0x004 +#define AM65_CPSW_PORTN_REG_DSCP_MAP 0x120 #define AM65_CPSW_PORTN_REG_SA_L 0x308 #define AM65_CPSW_PORTN_REG_SA_H 0x30c #define AM65_CPSW_PORTN_REG_TS_CTL 0x310 @@ -94,6 +96,10 @@ /* AM65_CPSW_PORT_REG_PRI_CTL */ #define AM65_CPSW_PORT_REG_PRI_CTL_RX_PTYPE_RROBIN BIT(8) +/* AM65_CPSW_PN_REG_CTL */ +#define AM65_CPSW_PN_REG_CTL_DSCP_IPV4_EN BIT(1) +#define AM65_CPSW_PN_REG_CTL_DSCP_IPV6_EN BIT(2) + /* AM65_CPSW_PN_TS_CTL register fields */ #define AM65_CPSW_PN_TS_CTL_TX_ANX_F_EN BIT(4) #define AM65_CPSW_PN_TS_CTL_TX_VLAN_LT1_EN BIT(5) @@ -176,6 +182,99 @@ static void am65_cpsw_port_set_sl_mac(struct am65_cpsw_port *slave, writel(mac_lo, slave->port_base + AM65_CPSW_PORTN_REG_SA_L); } +#define AM65_CPSW_DSCP_MAX GENMASK(5, 0) +#define AM65_CPSW_PRI_MAX GENMASK(2, 0) +#define AM65_CPSW_DSCP_PRI_PER_REG 8 +#define AM65_CPSW_DSCP_PRI_SIZE 4 /* in bits */ +static int am65_cpsw_port_set_dscp_map(struct am65_cpsw_port *slave, u8 dscp, u8 pri) +{ + int reg_ofs; + int bit_ofs; + u32 val; + + if (dscp > AM65_CPSW_DSCP_MAX) + return -EINVAL; + + if (pri > AM65_CPSW_PRI_MAX) + return -EINVAL; + + /* 32-bit register offset to this dscp */ + reg_ofs = (dscp / AM65_CPSW_DSCP_PRI_PER_REG) * 4; + /* bit field offset to this dscp */ + bit_ofs = AM65_CPSW_DSCP_PRI_SIZE * (dscp % AM65_CPSW_DSCP_PRI_PER_REG); + + val = readl(slave->port_base + AM65_CPSW_PORTN_REG_DSCP_MAP + reg_ofs); + val &= ~(AM65_CPSW_PRI_MAX << bit_ofs); /* clear */ + val |= pri << bit_ofs; /* set */ + writel(val, slave->port_base + AM65_CPSW_PORTN_REG_DSCP_MAP + reg_ofs); + + return 0; +} + +static void am65_cpsw_port_enable_dscp_map(struct am65_cpsw_port *slave) +{ + int dscp, pri; + u32 val; + + /* Default DSCP to User Priority mapping as per: + * https://datatracker.ietf.org/doc/html/rfc8325#section-4.3 + * and + * https://datatracker.ietf.org/doc/html/rfc8622#section-11 + */ + for (dscp = 0; dscp <= AM65_CPSW_DSCP_MAX; dscp++) { + switch (dscp) { + case 56: /* CS7 */ + case 48: /* CS6 */ + pri = 7; + break; + case 46: /* EF */ + case 44: /* VA */ + pri = 6; + break; + case 40: /* CS5 */ + pri = 5; + break; + case 34: /* AF41 */ + case 36: /* AF42 */ + case 38: /* AF43 */ + case 32: /* CS4 */ + case 26: /* AF31 */ + case 28: /* AF32 */ + case 30: /* AF33 */ + case 24: /* CS3 */ + pri = 4; + break; + case 18: /* AF21 */ + case 20: /* AF22 */ + case 22: /* AF23 */ + pri = 3; + break; + case 16: /* CS2 */ + case 10: /* AF11 */ + case 12: /* AF12 */ + case 14: /* AF13 */ + case 0: /* DF */ + pri = 0; + break; + case 8: /* CS1 */ + case 1: /* LE */ + pri = 1; + break; + default: + pri = 0; + break; + } + + am65_cpsw_port_set_dscp_map(slave, dscp, pri); + } + + /* enable port IPV4 and IPV6 DSCP for this port */ + val = readl(slave->port_base + AM65_CPSW_PORTN_REG_CTL); + val |= AM65_CPSW_PN_REG_CTL_DSCP_IPV4_EN | + AM65_CPSW_PN_REG_CTL_DSCP_IPV6_EN; + writel(val, slave->port_base + AM65_CPSW_PORTN_REG_CTL); +} + static void am65_cpsw_sl_ctl_reset(struct am65_cpsw_port *port) { cpsw_sl_reset(port->slave.mac_sl, 100); @@ -916,6 +1015,7 @@ static int am65_cpsw_nuss_ndo_slave_open(struct net_device *ndev) common->usage_count++; am65_cpsw_port_set_sl_mac(port, ndev->dev_addr); + am65_cpsw_port_enable_dscp_map(port); if (common->is_emac_mode) am65_cpsw_init_port_emac_ale(port); @@ -1026,9 +1126,7 @@ static int am65_cpsw_run_xdp(struct am65_cpsw_rx_flow *flow, int cpu, int *len) { struct am65_cpsw_common *common = flow->common; - struct am65_cpsw_ndev_priv *ndev_priv; struct net_device *ndev = port->ndev; - struct am65_cpsw_ndev_stats *stats; int ret = AM65_CPSW_XDP_CONSUMED; struct am65_cpsw_tx_chn *tx_chn; struct netdev_queue *netif_txq; @@ -1046,9 +1144,6 @@ static int am65_cpsw_run_xdp(struct am65_cpsw_rx_flow *flow, /* XDP prog might have changed packet data and boundaries */ *len = xdp->data_end - xdp->data; - ndev_priv = netdev_priv(ndev); - stats = this_cpu_ptr(ndev_priv->stats); - switch (act) { case XDP_PASS: ret = AM65_CPSW_XDP_PASS; @@ -1068,20 +1163,14 @@ static int am65_cpsw_run_xdp(struct am65_cpsw_rx_flow *flow, if (err) goto drop; - u64_stats_update_begin(&stats->syncp); - stats->rx_bytes += *len; - stats->rx_packets++; - u64_stats_update_end(&stats->syncp); + dev_sw_netstats_tx_add(ndev, 1, *len); ret = AM65_CPSW_XDP_CONSUMED; goto out; case XDP_REDIRECT: if (unlikely(xdp_do_redirect(ndev, xdp, prog))) goto drop; - u64_stats_update_begin(&stats->syncp); - stats->rx_bytes += *len; - stats->rx_packets++; - u64_stats_update_end(&stats->syncp); + dev_sw_netstats_rx_add(ndev, *len); ret = AM65_CPSW_XDP_REDIRECT; goto out; default: @@ -1142,7 +1231,6 @@ static int am65_cpsw_nuss_rx_packets(struct am65_cpsw_rx_flow *flow, u32 buf_dma_len, pkt_len, port_id = 0, csum_info; struct am65_cpsw_common *common = flow->common; struct am65_cpsw_ndev_priv *ndev_priv; - struct am65_cpsw_ndev_stats *stats; struct cppi5_host_desc_t *desc_rx; struct device *dev = common->dev; struct am65_cpsw_swdata *swdata; @@ -1225,12 +1313,7 @@ static int am65_cpsw_nuss_rx_packets(struct am65_cpsw_rx_flow *flow, am65_cpsw_nuss_rx_csum(skb, csum_info); napi_gro_receive(&flow->napi_rx, skb); - stats = this_cpu_ptr(ndev_priv->stats); - - u64_stats_update_begin(&stats->syncp); - stats->rx_packets++; - stats->rx_bytes += pkt_len; - u64_stats_update_end(&stats->syncp); + dev_sw_netstats_rx_add(ndev, pkt_len); allocate: new_page = page_pool_dev_alloc_pages(flow->page_pool); @@ -1311,10 +1394,7 @@ static struct sk_buff * am65_cpsw_nuss_tx_compl_packet_skb(struct am65_cpsw_tx_chn *tx_chn, dma_addr_t desc_dma) { - struct am65_cpsw_ndev_priv *ndev_priv; - struct am65_cpsw_ndev_stats *stats; struct cppi5_host_desc_t *desc_tx; - struct net_device *ndev; struct sk_buff *skb; void **swdata; @@ -1324,16 +1404,9 @@ am65_cpsw_nuss_tx_compl_packet_skb(struct am65_cpsw_tx_chn *tx_chn, skb = *(swdata); am65_cpsw_nuss_xmit_free(tx_chn, desc_tx); - ndev = skb->dev; - am65_cpts_tx_timestamp(tx_chn->common->cpts, skb); - ndev_priv = netdev_priv(ndev); - stats = this_cpu_ptr(ndev_priv->stats); - u64_stats_update_begin(&stats->syncp); - stats->tx_packets++; - stats->tx_bytes += skb->len; - u64_stats_update_end(&stats->syncp); + dev_sw_netstats_tx_add(skb->dev, 1, skb->len); return skb; } @@ -1344,8 +1417,6 @@ am65_cpsw_nuss_tx_compl_packet_xdp(struct am65_cpsw_common *common, dma_addr_t desc_dma, struct net_device **ndev) { - struct am65_cpsw_ndev_priv *ndev_priv; - struct am65_cpsw_ndev_stats *stats; struct cppi5_host_desc_t *desc_tx; struct am65_cpsw_port *port; struct xdp_frame *xdpf; @@ -1359,15 +1430,9 @@ am65_cpsw_nuss_tx_compl_packet_xdp(struct am65_cpsw_common *common, am65_cpsw_nuss_xmit_free(tx_chn, desc_tx); port = am65_common_get_port(common, port_id); + dev_sw_netstats_tx_add(port->ndev, 1, xdpf->len); *ndev = port->ndev; - ndev_priv = netdev_priv(*ndev); - stats = this_cpu_ptr(ndev_priv->stats); - u64_stats_update_begin(&stats->syncp); - stats->tx_packets++; - stats->tx_bytes += xdpf->len; - u64_stats_update_end(&stats->syncp); - return xdpf; } @@ -1889,31 +1954,7 @@ static int am65_cpsw_nuss_ndo_slave_ioctl(struct net_device *ndev, static void am65_cpsw_nuss_ndo_get_stats(struct net_device *dev, struct rtnl_link_stats64 *stats) { - struct am65_cpsw_ndev_priv *ndev_priv = netdev_priv(dev); - unsigned int start; - int cpu; - - for_each_possible_cpu(cpu) { - struct am65_cpsw_ndev_stats *cpu_stats; - u64 rx_packets; - u64 rx_bytes; - u64 tx_packets; - u64 tx_bytes; - - cpu_stats = per_cpu_ptr(ndev_priv->stats, cpu); - do { - start = u64_stats_fetch_begin(&cpu_stats->syncp); - rx_packets = cpu_stats->rx_packets; - rx_bytes = cpu_stats->rx_bytes; - tx_packets = cpu_stats->tx_packets; - tx_bytes = cpu_stats->tx_bytes; - } while (u64_stats_fetch_retry(&cpu_stats->syncp, start)); - - stats->rx_packets += rx_packets; - stats->rx_bytes += rx_bytes; - stats->tx_packets += tx_packets; - stats->tx_bytes += tx_bytes; - } + dev_fetch_sw_netstats(stats, dev->tstats); stats->rx_errors = dev->stats.rx_errors; stats->rx_dropped = dev->stats.rx_dropped; @@ -2699,13 +2740,6 @@ of_node_put: return ret; } -static void am65_cpsw_pcpu_stats_free(void *data) -{ - struct am65_cpsw_ndev_stats __percpu *stats = data; - - free_percpu(stats); -} - static void am65_cpsw_nuss_phylink_cleanup(struct am65_cpsw_common *common) { struct am65_cpsw_port *port; @@ -2725,7 +2759,6 @@ am65_cpsw_nuss_init_port_ndev(struct am65_cpsw_common *common, u32 port_idx) struct device *dev = common->dev; struct am65_cpsw_port *port; struct phylink *phylink; - int ret; port = &common->ports[port_idx]; @@ -2818,21 +2851,13 @@ am65_cpsw_nuss_init_port_ndev(struct am65_cpsw_common *common, u32 port_idx) if (common->pdata.quirks & AM65_CPSW_QUIRK_I2027_NO_TX_CSUM) port->ndev->features &= ~NETIF_F_HW_CSUM; - ndev_priv->stats = netdev_alloc_pcpu_stats(struct am65_cpsw_ndev_stats); - if (!ndev_priv->stats) - return -ENOMEM; - - ret = devm_add_action_or_reset(dev, am65_cpsw_pcpu_stats_free, - ndev_priv->stats); - if (ret) - dev_err(dev, "failed to add percpu stat free action %d\n", ret); - + port->ndev->pcpu_stat_type = NETDEV_PCPU_STAT_TSTATS; port->xdp_prog = NULL; if (!common->dma_ndev) common->dma_ndev = port->ndev; - return ret; + return 0; } static int am65_cpsw_nuss_init_ndevs(struct am65_cpsw_common *common) @@ -3437,7 +3462,8 @@ static const struct am65_cpsw_pdata j7200_cpswxg_pdata = { .quirks = 0, .ale_dev_id = "am64-cpswxg", .fdqring_mode = K3_RINGACC_RING_MODE_RING, - .extra_modes = BIT(PHY_INTERFACE_MODE_QSGMII) | BIT(PHY_INTERFACE_MODE_SGMII), + .extra_modes = BIT(PHY_INTERFACE_MODE_QSGMII) | BIT(PHY_INTERFACE_MODE_SGMII) | + BIT(PHY_INTERFACE_MODE_USXGMII), }; static const struct am65_cpsw_pdata j721e_cpswxg_pdata = { @@ -3489,7 +3515,7 @@ static int am65_cpsw_nuss_probe(struct platform_device *pdev) struct resource *res; struct clk *clk; int ale_entries; - u64 id_temp; + __be64 id_temp; int ret, i; common = devm_kzalloc(dev, sizeof(struct am65_cpsw_common), GFP_KERNEL); @@ -3762,7 +3788,7 @@ static struct platform_driver am65_cpsw_nuss_driver = { .pm = &am65_cpsw_nuss_dev_pm_ops, }, .probe = am65_cpsw_nuss_probe, - .remove_new = am65_cpsw_nuss_remove, + .remove = am65_cpsw_nuss_remove, }; module_platform_driver(am65_cpsw_nuss_driver); diff --git a/drivers/net/ethernet/ti/am65-cpsw-nuss.h b/drivers/net/ethernet/ti/am65-cpsw-nuss.h index 92a27ba4c601..e7832a5cf3cc 100644 --- a/drivers/net/ethernet/ti/am65-cpsw-nuss.h +++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.h @@ -184,18 +184,9 @@ struct am65_cpsw_common { u32 *ale_context; }; -struct am65_cpsw_ndev_stats { - u64 tx_packets; - u64 tx_bytes; - u64 rx_packets; - u64 rx_bytes; - struct u64_stats_sync syncp; -}; - struct am65_cpsw_ndev_priv { u32 msg_enable; struct am65_cpsw_port *port; - struct am65_cpsw_ndev_stats __percpu *stats; bool offload_fwd_mark; /* Serialize access to MAC Merge state between ethtool requests * and link state updates diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index c0a5abd8d9a8..4ef8cf6ea135 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c @@ -1802,7 +1802,7 @@ static struct platform_driver cpsw_driver = { .of_match_table = cpsw_of_mtable, }, .probe = cpsw_probe, - .remove_new = cpsw_remove, + .remove = cpsw_remove, }; module_platform_driver(cpsw_driver); diff --git a/drivers/net/ethernet/ti/cpsw_ale.c b/drivers/net/ethernet/ti/cpsw_ale.c index 8d02d2b21429..52e4e350b734 100644 --- a/drivers/net/ethernet/ti/cpsw_ale.c +++ b/drivers/net/ethernet/ti/cpsw_ale.c @@ -162,27 +162,39 @@ static inline void cpsw_ale_set_field(u32 *ale_entry, u32 start, u32 bits, ale_entry[idx] |= (value << start); } -#define DEFINE_ALE_FIELD(name, start, bits) \ +#define DEFINE_ALE_FIELD_GET(name, start, bits) \ static inline int cpsw_ale_get_##name(u32 *ale_entry) \ { \ return cpsw_ale_get_field(ale_entry, start, bits); \ -} \ +} + +#define DEFINE_ALE_FIELD_SET(name, start, bits) \ static inline void cpsw_ale_set_##name(u32 *ale_entry, u32 value) \ { \ cpsw_ale_set_field(ale_entry, start, bits, value); \ } -#define DEFINE_ALE_FIELD1(name, start) \ +#define DEFINE_ALE_FIELD(name, start, bits) \ +DEFINE_ALE_FIELD_GET(name, start, bits) \ +DEFINE_ALE_FIELD_SET(name, start, bits) + +#define DEFINE_ALE_FIELD1_GET(name, start) \ static inline int cpsw_ale_get_##name(u32 *ale_entry, u32 bits) \ { \ return cpsw_ale_get_field(ale_entry, start, bits); \ -} \ +} + +#define DEFINE_ALE_FIELD1_SET(name, start) \ static inline void cpsw_ale_set_##name(u32 *ale_entry, u32 value, \ u32 bits) \ { \ cpsw_ale_set_field(ale_entry, start, bits, value); \ } +#define DEFINE_ALE_FIELD1(name, start) \ +DEFINE_ALE_FIELD1_GET(name, start) \ +DEFINE_ALE_FIELD1_SET(name, start) + enum { ALE_ENT_VID_MEMBER_LIST = 0, ALE_ENT_VID_UNREG_MCAST_MSK, @@ -238,14 +250,14 @@ static const struct ale_entry_fld vlan_entry_k3_cpswxg[] = { DEFINE_ALE_FIELD(entry_type, 60, 2) DEFINE_ALE_FIELD(vlan_id, 48, 12) -DEFINE_ALE_FIELD(mcast_state, 62, 2) +DEFINE_ALE_FIELD_SET(mcast_state, 62, 2) DEFINE_ALE_FIELD1(port_mask, 66) DEFINE_ALE_FIELD(super, 65, 1) DEFINE_ALE_FIELD(ucast_type, 62, 2) -DEFINE_ALE_FIELD1(port_num, 66) -DEFINE_ALE_FIELD(blocked, 65, 1) -DEFINE_ALE_FIELD(secure, 64, 1) -DEFINE_ALE_FIELD(mcast, 40, 1) +DEFINE_ALE_FIELD1_SET(port_num, 66) +DEFINE_ALE_FIELD_SET(blocked, 65, 1) +DEFINE_ALE_FIELD_SET(secure, 64, 1) +DEFINE_ALE_FIELD_GET(mcast, 40, 1) #define NU_VLAN_UNREG_MCAST_IDX 1 @@ -1692,26 +1704,34 @@ static void cpsw_ale_policer_reset(struct cpsw_ale *ale) void cpsw_ale_classifier_setup_default(struct cpsw_ale *ale, int num_rx_ch) { int pri, idx; - /* IEEE802.1D-2004, Standard for Local and metropolitan area networks - * Table G-2 - Traffic type acronyms - * Table G-3 - Defining traffic types - * User priority values 1 and 2 effectively communicate a lower - * priority than 0. In the below table 0 is assigned to higher priority - * thread than 1 and 2 wherever possible. - * The below table maps which thread the user priority needs to be + + /* Reference: + * IEEE802.1Q-2014, Standard for Local and metropolitan area networks + * Table I-2 - Traffic type acronyms + * Table I-3 - Defining traffic types + * Section I.4 Traffic types and priority values, states: + * "0 is thus used both for default priority and for Best Effort, and + * Background is associated with a priority value of 1. This means + * that the value 1 effectively communicates a lower priority than 0." + * + * In the table below, Priority Code Point (PCP) 0 is assigned + * to a higher priority thread than PCP 1 wherever possible. + * The table maps which thread the PCP traffic needs to be * sent to for a given number of threads (RX channels). Upper threads * have higher priority. * e.g. if number of threads is 8 then user priority 0 will map to - * pri_thread_map[8-1][0] i.e. thread 2 + * pri_thread_map[8-1][0] i.e. thread 1 */ - int pri_thread_map[8][8] = { { 0, 0, 0, 0, 0, 0, 0, 0, }, + + int pri_thread_map[8][8] = { /* BK,BE,EE,CA,VI,VO,IC,NC */ + { 0, 0, 0, 0, 0, 0, 0, 0, }, { 0, 0, 0, 0, 1, 1, 1, 1, }, { 0, 0, 0, 0, 1, 1, 2, 2, }, - { 1, 0, 0, 1, 2, 2, 3, 3, }, - { 1, 0, 0, 1, 2, 3, 4, 4, }, - { 1, 0, 0, 2, 3, 4, 5, 5, }, - { 1, 0, 0, 2, 3, 4, 5, 6, }, - { 2, 0, 1, 3, 4, 5, 6, 7, } }; + { 0, 0, 1, 1, 2, 2, 3, 3, }, + { 0, 0, 1, 1, 2, 2, 3, 4, }, + { 1, 0, 2, 2, 3, 3, 4, 5, }, + { 1, 0, 2, 3, 4, 4, 5, 6, }, + { 1, 0, 2, 3, 4, 5, 6, 7 } }; cpsw_ale_policer_reset(ale); diff --git a/drivers/net/ethernet/ti/cpsw_new.c b/drivers/net/ethernet/ti/cpsw_new.c index 557cc71b9dd2..a98bcc5eb566 100644 --- a/drivers/net/ethernet/ti/cpsw_new.c +++ b/drivers/net/ethernet/ti/cpsw_new.c @@ -2127,7 +2127,7 @@ static struct platform_driver cpsw_driver = { .of_match_table = cpsw_of_mtable, }, .probe = cpsw_probe, - .remove_new = cpsw_remove, + .remove = cpsw_remove, }; module_platform_driver(cpsw_driver); diff --git a/drivers/net/ethernet/ti/davinci_emac.c b/drivers/net/ethernet/ti/davinci_emac.c index b0950a318c42..ed8116fb05e9 100644 --- a/drivers/net/ethernet/ti/davinci_emac.c +++ b/drivers/net/ethernet/ti/davinci_emac.c @@ -2070,7 +2070,7 @@ static struct platform_driver davinci_emac_driver = { .of_match_table = davinci_emac_of_match, }, .probe = davinci_emac_probe, - .remove_new = davinci_emac_remove, + .remove = davinci_emac_remove, }; /** diff --git a/drivers/net/ethernet/ti/davinci_mdio.c b/drivers/net/ethernet/ti/davinci_mdio.c index 8e07d4a1b6ba..68507126be8e 100644 --- a/drivers/net/ethernet/ti/davinci_mdio.c +++ b/drivers/net/ethernet/ti/davinci_mdio.c @@ -760,7 +760,7 @@ static struct platform_driver davinci_mdio_driver = { .of_match_table = of_match_ptr(davinci_mdio_of_mtable), }, .probe = davinci_mdio_probe, - .remove_new = davinci_mdio_remove, + .remove = davinci_mdio_remove, }; static int __init davinci_mdio_init(void) diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.c b/drivers/net/ethernet/ti/icssg/icssg_prueth.c index fe2fd1bfc904..c568c84a032b 100644 --- a/drivers/net/ethernet/ti/icssg/icssg_prueth.c +++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.c @@ -817,6 +817,47 @@ static netdev_features_t emac_ndo_fix_features(struct net_device *ndev, return features; } +static int emac_ndo_vlan_rx_add_vid(struct net_device *ndev, + __be16 proto, u16 vid) +{ + struct prueth_emac *emac = netdev_priv(ndev); + struct prueth *prueth = emac->prueth; + int untag_mask = 0; + int port_mask; + + if (prueth->is_hsr_offload_mode) { + port_mask = BIT(PRUETH_PORT_HOST) | BIT(emac->port_id); + untag_mask = 0; + + netdev_dbg(emac->ndev, "VID add vid:%u port_mask:%X untag_mask %X\n", + vid, port_mask, untag_mask); + + icssg_vtbl_modify(emac, vid, port_mask, untag_mask, true); + icssg_set_pvid(emac->prueth, vid, emac->port_id); + } + return 0; +} + +static int emac_ndo_vlan_rx_del_vid(struct net_device *ndev, + __be16 proto, u16 vid) +{ + struct prueth_emac *emac = netdev_priv(ndev); + struct prueth *prueth = emac->prueth; + int untag_mask = 0; + int port_mask; + + if (prueth->is_hsr_offload_mode) { + port_mask = BIT(PRUETH_PORT_HOST); + untag_mask = 0; + + netdev_dbg(emac->ndev, "VID del vid:%u port_mask:%X untag_mask %X\n", + vid, port_mask, untag_mask); + + icssg_vtbl_modify(emac, vid, port_mask, untag_mask, false); + } + return 0; +} + static const struct net_device_ops emac_netdev_ops = { .ndo_open = emac_ndo_open, .ndo_stop = emac_ndo_stop, @@ -829,6 +870,8 @@ static const struct net_device_ops emac_netdev_ops = { .ndo_get_stats64 = icssg_ndo_get_stats64, .ndo_get_phys_port_name = icssg_ndo_get_phys_port_name, .ndo_fix_features = emac_ndo_fix_features, + .ndo_vlan_rx_add_vid = emac_ndo_vlan_rx_add_vid, + .ndo_vlan_rx_kill_vid = emac_ndo_vlan_rx_del_vid, }; static int prueth_netdev_init(struct prueth *prueth, @@ -956,7 +999,7 @@ static int prueth_netdev_init(struct prueth *prueth, ndev->netdev_ops = &emac_netdev_ops; ndev->ethtool_ops = &icssg_ethtool_ops; ndev->hw_features = NETIF_F_SG; - ndev->features = ndev->hw_features; + ndev->features = ndev->hw_features | NETIF_F_HW_VLAN_CTAG_FILTER; ndev->hw_features |= NETIF_PRUETH_HSR_OFFLOAD_FEATURES; netif_napi_add(ndev, &emac->napi_rx, icssg_napi_rx_poll); @@ -1655,7 +1698,7 @@ MODULE_DEVICE_TABLE(of, prueth_dt_match); static struct platform_driver prueth_driver = { .probe = prueth_probe, - .remove_new = prueth_remove, + .remove = prueth_remove, .driver = { .name = "icssg-prueth", .of_match_table = prueth_dt_match, diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth_sr1.c b/drivers/net/ethernet/ti/icssg/icssg_prueth_sr1.c index 292f04d29f4f..5024f0647a0d 100644 --- a/drivers/net/ethernet/ti/icssg/icssg_prueth_sr1.c +++ b/drivers/net/ethernet/ti/icssg/icssg_prueth_sr1.c @@ -1215,7 +1215,7 @@ MODULE_DEVICE_TABLE(of, prueth_dt_match); static struct platform_driver prueth_driver = { .probe = prueth_probe, - .remove_new = prueth_remove, + .remove = prueth_remove, .driver = { .name = "icssg-prueth-sr1", .of_match_table = prueth_dt_match, diff --git a/drivers/net/ethernet/ti/netcp_core.c b/drivers/net/ethernet/ti/netcp_core.c index 11b90e1da0c6..857820657bac 100644 --- a/drivers/net/ethernet/ti/netcp_core.c +++ b/drivers/net/ethernet/ti/netcp_core.c @@ -2270,7 +2270,7 @@ static struct platform_driver netcp_driver = { .of_match_table = of_match, }, .probe = netcp_probe, - .remove_new = netcp_remove, + .remove = netcp_remove, }; module_platform_driver(netcp_driver); |