Lines Matching +full:cpsw +full:- +full:switch
1 // SPDX-License-Identifier: GPL-2.0
2 /* Texas Instruments K3 AM65 Ethernet Switch SubSystem Driver ethtool ops
4 * Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com/
13 #include "am65-cpsw-nuss.h"
14 #include "am65-cpsw-qos.h"
16 #include "am65-cpts.h"
34 * struct am65_cpsw_regdump_hdr - regdump record header
36 * @module_id: CPSW module ID
37 * @len: CPSW module registers space length in u32
46 * struct am65_cpsw_regdump_item - regdump module description
48 * @hdr: CPSW module header
49 * @start_ofs: CPSW module registers start addr
50 * @end_ofs: CPSW module registers end addr
65 .hdr.len = (end + 4 - start) * 2 + \
376 "p0-rx-ptype-rrobin",
384 ret = pm_runtime_resume_and_get(common->dev); in am65_cpsw_ethtool_op_begin()
386 dev_err(common->dev, "ethtool begin failed %d\n", ret); in am65_cpsw_ethtool_op_begin()
396 ret = pm_runtime_put(common->dev); in am65_cpsw_ethtool_op_complete()
397 if (ret < 0 && ret != -EBUSY) in am65_cpsw_ethtool_op_complete()
398 dev_err(common->dev, "ethtool complete failed %d\n", ret); in am65_cpsw_ethtool_op_complete()
406 strscpy(info->driver, dev_driver_string(common->dev), in am65_cpsw_get_drvinfo()
407 sizeof(info->driver)); in am65_cpsw_get_drvinfo()
408 strscpy(info->bus_info, dev_name(common->dev), sizeof(info->bus_info)); in am65_cpsw_get_drvinfo()
415 return priv->msg_enable; in am65_cpsw_get_msglevel()
422 priv->msg_enable = value; in am65_cpsw_set_msglevel()
430 ch->max_rx = AM65_CPSW_MAX_QUEUES; in am65_cpsw_get_channels()
431 ch->max_tx = AM65_CPSW_MAX_QUEUES; in am65_cpsw_get_channels()
432 ch->rx_count = common->rx_ch_num_flows; in am65_cpsw_get_channels()
433 ch->tx_count = common->tx_ch_num; in am65_cpsw_get_channels()
441 if (!chs->rx_count || !chs->tx_count) in am65_cpsw_set_channels()
442 return -EINVAL; in am65_cpsw_set_channels()
447 if (common->usage_count) in am65_cpsw_set_channels()
448 return -EBUSY; in am65_cpsw_set_channels()
450 return am65_cpsw_nuss_update_tx_rx_chns(common, chs->tx_count, in am65_cpsw_set_channels()
451 chs->rx_count); in am65_cpsw_set_channels()
463 ering->tx_pending = common->tx_chns[0].descs_num; in am65_cpsw_get_ringparam()
464 ering->rx_pending = common->rx_chns.descs_num; in am65_cpsw_get_ringparam()
472 phylink_ethtool_get_pauseparam(salve->phylink, pause); in am65_cpsw_get_pauseparam()
480 return phylink_ethtool_set_pauseparam(salve->phylink, pause); in am65_cpsw_set_pauseparam()
488 phylink_ethtool_get_wol(salve->phylink, wol); in am65_cpsw_get_wol()
496 return phylink_ethtool_set_wol(salve->phylink, wol); in am65_cpsw_set_wol()
504 return phylink_ethtool_ksettings_get(salve->phylink, ecmd); in am65_cpsw_get_link_ksettings()
513 return phylink_ethtool_ksettings_set(salve->phylink, ecmd); in am65_cpsw_set_link_ksettings()
520 return phylink_ethtool_get_eee(salve->phylink, edata); in am65_cpsw_get_eee()
527 return phylink_ethtool_set_eee(salve->phylink, edata); in am65_cpsw_set_eee()
534 return phylink_ethtool_nway_reset(salve->phylink); in am65_cpsw_nway_reset()
542 ale_entries = cpsw_ale_get_num_entries(common->ale); in am65_cpsw_get_regs_len()
563 /* update CPSW IP version */ in am65_cpsw_get_regs()
564 regs->version = AM65_CPSW_REGDUMP_VER; in am65_cpsw_get_regs()
565 ale_entries = cpsw_ale_get_num_entries(common->ale); in am65_cpsw_get_regs()
577 cpsw_ale_dump(common->ale, ®[pos]); in am65_cpsw_get_regs()
587 reg[pos++] = readl_relaxed(common->ss_base + j); in am65_cpsw_get_regs()
595 switch (sset) { in am65_cpsw_get_sset_count()
602 return -EOPNOTSUPP; in am65_cpsw_get_sset_count()
613 switch (stringset) { in am65_cpsw_get_strings()
655 *data++ = readl_relaxed(host_p->stat_base + in am65_cpsw_get_ethtool_stats()
661 *data++ = readl_relaxed(port->stat_base + in am65_cpsw_get_ethtool_stats()
671 stats = port->stat_base; in am65_cpsw_get_eth_mac_stats()
673 if (s->src != ETHTOOL_MAC_STATS_SRC_AGGREGATE) in am65_cpsw_get_eth_mac_stats()
676 s->FramesTransmittedOK = readl_relaxed(&stats->tx_good_frames); in am65_cpsw_get_eth_mac_stats()
677 s->SingleCollisionFrames = readl_relaxed(&stats->tx_single_coll_frames); in am65_cpsw_get_eth_mac_stats()
678 s->MultipleCollisionFrames = readl_relaxed(&stats->tx_mult_coll_frames); in am65_cpsw_get_eth_mac_stats()
679 s->FramesReceivedOK = readl_relaxed(&stats->rx_good_frames); in am65_cpsw_get_eth_mac_stats()
680 s->FrameCheckSequenceErrors = readl_relaxed(&stats->rx_crc_errors); in am65_cpsw_get_eth_mac_stats()
681 s->AlignmentErrors = readl_relaxed(&stats->rx_align_code_errors); in am65_cpsw_get_eth_mac_stats()
682 s->OctetsTransmittedOK = readl_relaxed(&stats->tx_octets); in am65_cpsw_get_eth_mac_stats()
683 s->FramesWithDeferredXmissions = readl_relaxed(&stats->tx_deferred_frames); in am65_cpsw_get_eth_mac_stats()
684 s->LateCollisions = readl_relaxed(&stats->tx_late_collisions); in am65_cpsw_get_eth_mac_stats()
685 s->CarrierSenseErrors = readl_relaxed(&stats->tx_carrier_sense_errors); in am65_cpsw_get_eth_mac_stats()
686 s->OctetsReceivedOK = readl_relaxed(&stats->rx_octets); in am65_cpsw_get_eth_mac_stats()
687 s->MulticastFramesXmittedOK = readl_relaxed(&stats->tx_multicast_frames); in am65_cpsw_get_eth_mac_stats()
688 s->BroadcastFramesXmittedOK = readl_relaxed(&stats->tx_broadcast_frames); in am65_cpsw_get_eth_mac_stats()
689 s->MulticastFramesReceivedOK = readl_relaxed(&stats->rx_multicast_frames); in am65_cpsw_get_eth_mac_stats()
690 s->BroadcastFramesReceivedOK = readl_relaxed(&stats->rx_broadcast_frames); in am65_cpsw_get_eth_mac_stats()
712 info->so_timestamping = in am65_cpsw_get_ethtool_ts_info()
717 info->phc_index = am65_cpts_phc_index(common->cpts); in am65_cpsw_get_ethtool_ts_info()
718 info->tx_types = BIT(HWTSTAMP_TX_OFF) | BIT(HWTSTAMP_TX_ON); in am65_cpsw_get_ethtool_ts_info()
719 info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) | ptp_v2_filter; in am65_cpsw_get_ethtool_ts_info()
728 if (common->pf_p0_rx_ptype_rrobin) in am65_cpsw_get_ethtool_priv_flags()
741 if (common->usage_count) in am65_cpsw_set_ethtool_priv_flags()
742 return -EBUSY; in am65_cpsw_set_ethtool_priv_flags()
744 if (common->est_enabled && rrobin) { in am65_cpsw_set_ethtool_priv_flags()
746 "p0-rx-ptype-rrobin flag conflicts with QOS\n"); in am65_cpsw_set_ethtool_priv_flags()
747 return -EINVAL; in am65_cpsw_set_ethtool_priv_flags()
750 common->pf_p0_rx_ptype_rrobin = rrobin; in am65_cpsw_set_ethtool_priv_flags()
759 val = readl(port->port_base + AM65_CPSW_PN_REG_CTL); in am65_cpsw_port_iet_rx_enable()
765 writel(val, port->port_base + AM65_CPSW_PN_REG_CTL); in am65_cpsw_port_iet_rx_enable()
766 am65_cpsw_iet_common_enable(port->common); in am65_cpsw_port_iet_rx_enable()
773 val = readl(port->port_base + AM65_CPSW_PN_REG_IET_CTRL); in am65_cpsw_port_iet_tx_enable()
779 writel(val, port->port_base + AM65_CPSW_PN_REG_IET_CTRL); in am65_cpsw_port_iet_tx_enable()
790 return -EOPNOTSUPP; in am65_cpsw_get_mm()
792 mutex_lock(&priv->mm_lock); in am65_cpsw_get_mm()
794 iet_ctrl = readl(port->port_base + AM65_CPSW_PN_REG_IET_CTRL); in am65_cpsw_get_mm()
795 port_ctrl = readl(port->port_base + AM65_CPSW_PN_REG_CTL); in am65_cpsw_get_mm()
797 state->tx_enabled = !!(iet_ctrl & AM65_CPSW_PN_IET_MAC_PENABLE); in am65_cpsw_get_mm()
798 state->pmac_enabled = !!(port_ctrl & AM65_CPSW_PN_CTL_IET_PORT_EN); in am65_cpsw_get_mm()
800 iet_status = readl(port->port_base + AM65_CPSW_PN_REG_IET_STATUS); in am65_cpsw_get_mm()
803 state->verify_status = ETHTOOL_MM_VERIFY_STATUS_DISABLED; in am65_cpsw_get_mm()
805 state->verify_status = ETHTOOL_MM_VERIFY_STATUS_SUCCEEDED; in am65_cpsw_get_mm()
807 state->verify_status = ETHTOOL_MM_VERIFY_STATUS_FAILED; in am65_cpsw_get_mm()
809 state->verify_status = ETHTOOL_MM_VERIFY_STATUS_UNKNOWN; in am65_cpsw_get_mm()
812 state->tx_min_frag_size = ethtool_mm_frag_size_add_to_min(add_frag_size); in am65_cpsw_get_mm()
815 state->rx_min_frag_size = 124; in am65_cpsw_get_mm()
818 state->tx_active = state->tx_enabled && in am65_cpsw_get_mm()
819 (state->verify_status == ETHTOOL_MM_VERIFY_STATUS_SUCCEEDED || in am65_cpsw_get_mm()
820 state->verify_status == ETHTOOL_MM_VERIFY_STATUS_DISABLED); in am65_cpsw_get_mm()
821 state->verify_enabled = !(iet_ctrl & AM65_CPSW_PN_IET_MAC_DISABLEVERIFY); in am65_cpsw_get_mm()
823 state->verify_time = port->qos.iet.verify_time_ms; in am65_cpsw_get_mm()
825 /* 802.3-2018 clause 30.14.1.6, says that the aMACMergeVerifyTime in am65_cpsw_get_mm()
828 state->max_verify_time = 128; in am65_cpsw_get_mm()
830 mutex_unlock(&priv->mm_lock); in am65_cpsw_get_mm()
840 struct am65_cpsw_iet *iet = &port->qos.iet; in am65_cpsw_set_mm()
845 return -EOPNOTSUPP; in am65_cpsw_set_mm()
847 err = ethtool_mm_frag_size_min_to_add(cfg->tx_min_frag_size, &add_frag_size, extack); in am65_cpsw_set_mm()
851 mutex_lock(&priv->mm_lock); in am65_cpsw_set_mm()
853 if (cfg->pmac_enabled) { in am65_cpsw_set_mm()
855 if (!iet->original_max_blks) in am65_cpsw_set_mm()
856 iet->original_max_blks = readl(port->port_base + AM65_CPSW_PN_REG_MAX_BLKS); in am65_cpsw_set_mm()
859 port->port_base + AM65_CPSW_PN_REG_MAX_BLKS); in am65_cpsw_set_mm()
860 } else if (iet->original_max_blks) { in am65_cpsw_set_mm()
862 writel(iet->original_max_blks, in am65_cpsw_set_mm()
863 port->port_base + AM65_CPSW_PN_REG_MAX_BLKS); in am65_cpsw_set_mm()
866 am65_cpsw_port_iet_rx_enable(port, cfg->pmac_enabled); in am65_cpsw_set_mm()
867 am65_cpsw_port_iet_tx_enable(port, cfg->tx_enabled); in am65_cpsw_set_mm()
869 val = readl(port->port_base + AM65_CPSW_PN_REG_IET_CTRL); in am65_cpsw_set_mm()
870 if (cfg->verify_enabled) { in am65_cpsw_set_mm()
873 * Verification will be done once link-up. in am65_cpsw_set_mm()
884 writel(val, port->port_base + AM65_CPSW_PN_REG_IET_CTRL); in am65_cpsw_set_mm()
887 port->qos.iet.verify_time_ms = cfg->verify_time; in am65_cpsw_set_mm()
892 mutex_unlock(&priv->mm_lock); in am65_cpsw_set_mm()
901 void __iomem *base = port->stat_base; in am65_cpsw_get_mm_stats()
903 s->MACMergeFrameAssOkCount = readl(base + AM65_CPSW_STATN_IET_RX_ASSEMBLY_OK); in am65_cpsw_get_mm_stats()
904 s->MACMergeFrameAssErrorCount = readl(base + AM65_CPSW_STATN_IET_RX_ASSEMBLY_ERROR); in am65_cpsw_get_mm_stats()
905 s->MACMergeFrameSmdErrorCount = readl(base + AM65_CPSW_STATN_IET_RX_SMD_ERROR); in am65_cpsw_get_mm_stats()
906 /* CPSW Functional Spec states: in am65_cpsw_get_mm_stats()
910 s->MACMergeFragCountRx = readl(base + AM65_CPSW_STATN_IET_RX_FRAG) + s->MACMergeFrameAssErrorCount; in am65_cpsw_get_mm_stats()
911 s->MACMergeFragCountTx = readl(base + AM65_CPSW_STATN_IET_TX_FRAG); in am65_cpsw_get_mm_stats()
912 s->MACMergeHoldCount = readl(base + AM65_CPSW_STATN_IET_TX_HOLD); in am65_cpsw_get_mm_stats()
923 return -EINVAL; in am65_cpsw_get_per_queue_coalesce()
925 tx_chn = &common->tx_chns[queue]; in am65_cpsw_get_per_queue_coalesce()
926 coal->tx_coalesce_usecs = tx_chn->tx_pace_timeout / 1000; in am65_cpsw_get_per_queue_coalesce()
928 rx_flow = &common->rx_chns.flows[queue]; in am65_cpsw_get_per_queue_coalesce()
929 coal->rx_coalesce_usecs = rx_flow->rx_pace_timeout / 1000; in am65_cpsw_get_per_queue_coalesce()
949 return -EINVAL; in am65_cpsw_set_per_queue_coalesce()
951 tx_chn = &common->tx_chns[queue]; in am65_cpsw_set_per_queue_coalesce()
952 if (coal->tx_coalesce_usecs && coal->tx_coalesce_usecs < 20) in am65_cpsw_set_per_queue_coalesce()
953 return -EINVAL; in am65_cpsw_set_per_queue_coalesce()
955 tx_chn->tx_pace_timeout = coal->tx_coalesce_usecs * 1000; in am65_cpsw_set_per_queue_coalesce()
957 rx_flow = &common->rx_chns.flows[queue]; in am65_cpsw_set_per_queue_coalesce()
958 if (coal->rx_coalesce_usecs && coal->rx_coalesce_usecs < 20) in am65_cpsw_set_per_queue_coalesce()
959 return -EINVAL; in am65_cpsw_set_per_queue_coalesce()
961 rx_flow->rx_pace_timeout = coal->rx_coalesce_usecs * 1000; in am65_cpsw_set_per_queue_coalesce()