Loading drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c +123 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ #include "dwmac-qcom-ethqos.h" #include "stmmac_ptp.h" #include "dwmac-qcom-ipa-offload.h" #include "dwmac-qcom-ipa.h" #define PHY_LOOPBACK_1000 0x4140 #define PHY_LOOPBACK_100 0x6100 Loading Loading @@ -2575,6 +2576,126 @@ static void ethqos_get_cv2x_dt(struct qcom_ethqos *ethqos, } } inline u32 qcom_ethqos_rgmii_io_macro_num_of_regs(u32 emac_hw_version) { switch (emac_hw_version) { case EMAC_HW_v2_0_0: return 27; case EMAC_HW_v2_1_0: return 27; case EMAC_HW_v2_1_1: return 27; case EMAC_HW_v2_1_2: return 27; case EMAC_HW_v2_2_0: return 27; case EMAC_HW_v2_3_0: return 28; case EMAC_HW_v2_3_1: return 27; case EMAC_HW_v2_3_2: return 29; case EMAC_HW_NONE: default: return 0; } } static void ethqos_dma_desc_stats_read(struct qcom_ethqos *ethqos) { int qinx; struct platform_device *pdev = ethqos->pdev; struct net_device *dev = platform_get_drvdata(pdev); struct stmmac_priv *priv = netdev_priv(dev); u32 tx_count = priv->plat->tx_queues_to_use; u32 rx_count = priv->plat->rx_queues_to_use; ETHQOSDBG("Enter"); ethqos->xstats.dma_ch_intr_status = readl_relaxed(DMA_ISR_RGOFFADDR); ethqos->xstats.dma_debug_status0 = readl_relaxed(DMA_DSR0_RGOFFADDR); ethqos->xstats.dma_debug_status1 = readl_relaxed(DMA_DSR1_RGOFFADDR); for (qinx = 0; qinx < tx_count; qinx++) { if (ethqos->ipa_enabled && qinx == IPA_DMA_TX_CH) continue; ethqos->xstats.dma_ch_status[qinx] = readl_relaxed(DMA_SR_RGOFFADDRESS(qinx)); ethqos->xstats.dma_ch_intr_enable[qinx] = readl_relaxed(DMA_IER_RGOFFADDRESS(qinx)); ethqos->xstats.dma_ch_tx_control[qinx] = readl_relaxed(DMA_TCR_RGOFFADDRESS(qinx)); ethqos->xstats.dma_ch_txdesc_list_addr[qinx] = readl_relaxed(DMA_TDLAR_RGOFFADDRESS(qinx)); ethqos->xstats.dma_ch_txdesc_ring_len[qinx] = readl_relaxed(DMA_TDRLR_RGOFFADDRESS(qinx)); ethqos->xstats.dma_ch_curr_app_txdesc[qinx] = readl_relaxed(DMA_CHTDR_RGOFFADDRESS(qinx)); ethqos->xstats.dma_ch_txdesc_tail_ptr[qinx] = readl_relaxed(DMA_TDTP_TPDR_RGOFFADDRESS(qinx)); ethqos->xstats.dma_ch_curr_app_txbuf[qinx] = readl_relaxed(DMA_CHTBAR_RGOFFADDRESS(qinx)); } for (qinx = 0; qinx < rx_count; qinx++) { if (ethqos->ipa_enabled && qinx == IPA_DMA_RX_CH) continue; ethqos->xstats.dma_ch_rx_control[qinx] = readl_relaxed(DMA_RCR_RGOFFADDRESS(qinx)); ethqos->xstats.dma_ch_rxdesc_list_addr[qinx] = readl_relaxed(DMA_RDLAR_RGOFFADDRESS(qinx)); ethqos->xstats.dma_ch_rxdesc_ring_len[qinx] = readl_relaxed(DMA_RDRLR_RGOFFADDRESS(qinx)); ethqos->xstats.dma_ch_curr_app_rxdesc[qinx] = readl_relaxed(DMA_CHRDR_RGOFFADDRESS(qinx)); ethqos->xstats.dma_ch_rxdesc_tail_ptr[qinx] = readl_relaxed(DMA_RDTP_RPDR_RGOFFADDRESS(qinx)); ethqos->xstats.dma_ch_curr_app_rxbuf[qinx] = readl_relaxed(DMA_CHRBAR_RGOFFADDRESS(qinx)); ethqos->xstats.dma_ch_miss_frame_count[qinx] = readl_relaxed(DMA_CH_MISS_FRAME_CNT_RGOFFADDRESS(qinx)); } ETHQOSDBG("Exit"); } static int qcom_ethos_panic_notifier(struct notifier_block *this, unsigned long event, void *ptr) { u32 size_iomacro_regs; if (pethqos) { size_iomacro_regs = qcom_ethqos_rgmii_io_macro_num_of_regs(pethqos->emac_ver) * 4; ETHQOSINFO("pethqos 0x%p", pethqos); ethqos_dma_desc_stats_read(pethqos); pethqos->iommu_domain = stmmac_emb_smmu_ctx.iommu_domain; ETHQOSINFO("emac iommu domain 0x%p", pethqos->iommu_domain); pethqos->emac_reg_base_address = kzalloc(pethqos->emac_mem_size, GFP_KERNEL); ETHQOSINFO("emac register mem 0x%p", pethqos->emac_mem_base); if (pethqos->emac_mem_base) memcpy_fromio(pethqos->emac_reg_base_address, pethqos->ioaddr, pethqos->emac_mem_size); pethqos->rgmii_reg_base_address = kzalloc(size_iomacro_regs, GFP_KERNEL); ETHQOSINFO ("rgmii register mem 0x%p", pethqos->rgmii_reg_base_address); if (pethqos->rgmii_reg_base_address) memcpy_fromio(pethqos->rgmii_reg_base_address, pethqos->rgmii_base, size_iomacro_regs); } return NOTIFY_DONE; } static struct notifier_block qcom_ethqos_panic_blk = { .notifier_call = qcom_ethos_panic_notifier, }; static int qcom_ethqos_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; Loading Loading @@ -2769,6 +2890,8 @@ static int qcom_ethqos_probe(struct platform_device *pdev) if (ret) goto err_clk; atomic_notifier_chain_register(&panic_notifier_list, &qcom_ethqos_panic_blk); rgmii_dump(ethqos); if (ethqos->emac_ver == EMAC_HW_v2_3_2) { Loading drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.h +33 −0 Original line number Diff line number Diff line Loading @@ -426,6 +426,32 @@ struct ethqos_io_macro { bool rx_dll_bypass; }; struct ethqos_extra_dma_stats { /* DMA status registers for all channels [0-4] */ unsigned long dma_ch_status[MTL_MAX_TX_QUEUES]; unsigned long dma_ch_intr_enable[MTL_MAX_TX_QUEUES]; unsigned long dma_ch_intr_status; unsigned long dma_debug_status0; unsigned long dma_debug_status1; /* RX DMA descriptor status registers for all channels [0-4] */ unsigned long dma_ch_rx_control[MTL_MAX_RX_QUEUES]; unsigned long dma_ch_rxdesc_list_addr[MTL_MAX_RX_QUEUES]; unsigned long dma_ch_rxdesc_ring_len[MTL_MAX_RX_QUEUES]; unsigned long dma_ch_curr_app_rxdesc[MTL_MAX_RX_QUEUES]; unsigned long dma_ch_rxdesc_tail_ptr[MTL_MAX_RX_QUEUES]; unsigned long dma_ch_curr_app_rxbuf[MTL_MAX_RX_QUEUES]; unsigned long dma_ch_miss_frame_count[MTL_MAX_RX_QUEUES]; /* TX DMA descriptors status for all channels [0-5] */ unsigned long dma_ch_tx_control[MTL_MAX_TX_QUEUES]; unsigned long dma_ch_txdesc_list_addr[MTL_MAX_TX_QUEUES]; unsigned long dma_ch_txdesc_ring_len[MTL_MAX_TX_QUEUES]; unsigned long dma_ch_curr_app_txdesc[MTL_MAX_TX_QUEUES]; unsigned long dma_ch_txdesc_tail_ptr[MTL_MAX_TX_QUEUES]; unsigned long dma_ch_curr_app_txbuf[MTL_MAX_TX_QUEUES]; }; struct qcom_ethqos { struct platform_device *pdev; void __iomem *rgmii_base; Loading @@ -438,6 +464,10 @@ struct qcom_ethqos { unsigned int speed; unsigned int vote_idx; struct iommu_domain *iommu_domain; unsigned int *emac_reg_base_address; unsigned int *rgmii_reg_base_address; int gpio_phy_intr_redirect; u32 phy_intr; /* Work struct for handling phy interrupt */ Loading Loading @@ -504,6 +534,7 @@ struct qcom_ethqos { bool ipa_enabled; /* Key Performance Indicators */ bool print_kpi; unsigned int emac_phy_off_suspend; int loopback_speed; enum loopback_mode current_loopback; Loading @@ -527,6 +558,8 @@ struct qcom_ethqos { u32 cv2x_mode; struct ethqos_vlan_info cv2x_vlan; unsigned char cv2x_dev_addr[ETH_ALEN]; struct ethqos_extra_dma_stats xstats; }; struct pps_cfg { Loading drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ipa.h +19 −0 Original line number Diff line number Diff line Loading @@ -460,6 +460,8 @@ static char * const IPA_OFFLOAD_EVENT_string[] = { #define DMA_DSR0_RGRD(data) \ ((data) = readl_relaxed(DMA_DSR0_RGOFFADDR)) #define DMA_DSR1_RGOFFADDR ((BASE_ADDRESS + 0x1010)) #define DMA_CHRDR_RGOFFADDR (BASE_ADDRESS + 0x114c) #define DMA_CHRDR_RGOFFADDRESS(i)\ Loading Loading @@ -503,6 +505,21 @@ static char * const IPA_OFFLOAD_EVENT_string[] = { #define DMA_CHTDR_RGRD(i, data) \ ((data) = readl_relaxed(DMA_CHTDR_RGOFFADDRESS(i))) #define DMA_CHTBAR_RGOFFADDR (BASE_ADDRESS + 0x1154) #define DMA_CHTBAR_RGOFFADDRESS(i)\ ((DMA_CHTBAR_RGOFFADDR + ((i - 0) * 128))) #define DMA_CHRBAR_RGOFFADDR (BASE_ADDRESS + 0x115c) #define DMA_CHRBAR_RGOFFADDRESS(i)\ ((DMA_CHRBAR_RGOFFADDR + ((i - 0) * 128))) #define DMA_CH_MISS_FRAME_CNT_RGOFFADDR (BASE_ADDRESS + 0x1164) #define DMA_CH_MISS_FRAME_CNT_RGOFFADDRESS(i)\ ((DMA_CH_MISS_FRAME_CNT_RGOFFADDR + ((i - 0) * 128))) #define DMA_TDTP_TPDR_RGOFFADDR (BASE_ADDRESS + 0x1120) #define DMA_TDTP_TPDR_RGOFFADDRESS(i)\ Loading Loading @@ -554,6 +571,8 @@ static char * const IPA_OFFLOAD_EVENT_string[] = { data = ((data1 >> 13) & DMA_IER_CDEE_MASK);\ } while (0) #define DMA_ISR_RGOFFADDR ((BASE_ADDRESS + 0x1008)) struct ethqos_tx_queue { struct stmmac_tx_queue *tx_q; unsigned int desc_cnt; Loading Loading
drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c +123 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ #include "dwmac-qcom-ethqos.h" #include "stmmac_ptp.h" #include "dwmac-qcom-ipa-offload.h" #include "dwmac-qcom-ipa.h" #define PHY_LOOPBACK_1000 0x4140 #define PHY_LOOPBACK_100 0x6100 Loading Loading @@ -2575,6 +2576,126 @@ static void ethqos_get_cv2x_dt(struct qcom_ethqos *ethqos, } } inline u32 qcom_ethqos_rgmii_io_macro_num_of_regs(u32 emac_hw_version) { switch (emac_hw_version) { case EMAC_HW_v2_0_0: return 27; case EMAC_HW_v2_1_0: return 27; case EMAC_HW_v2_1_1: return 27; case EMAC_HW_v2_1_2: return 27; case EMAC_HW_v2_2_0: return 27; case EMAC_HW_v2_3_0: return 28; case EMAC_HW_v2_3_1: return 27; case EMAC_HW_v2_3_2: return 29; case EMAC_HW_NONE: default: return 0; } } static void ethqos_dma_desc_stats_read(struct qcom_ethqos *ethqos) { int qinx; struct platform_device *pdev = ethqos->pdev; struct net_device *dev = platform_get_drvdata(pdev); struct stmmac_priv *priv = netdev_priv(dev); u32 tx_count = priv->plat->tx_queues_to_use; u32 rx_count = priv->plat->rx_queues_to_use; ETHQOSDBG("Enter"); ethqos->xstats.dma_ch_intr_status = readl_relaxed(DMA_ISR_RGOFFADDR); ethqos->xstats.dma_debug_status0 = readl_relaxed(DMA_DSR0_RGOFFADDR); ethqos->xstats.dma_debug_status1 = readl_relaxed(DMA_DSR1_RGOFFADDR); for (qinx = 0; qinx < tx_count; qinx++) { if (ethqos->ipa_enabled && qinx == IPA_DMA_TX_CH) continue; ethqos->xstats.dma_ch_status[qinx] = readl_relaxed(DMA_SR_RGOFFADDRESS(qinx)); ethqos->xstats.dma_ch_intr_enable[qinx] = readl_relaxed(DMA_IER_RGOFFADDRESS(qinx)); ethqos->xstats.dma_ch_tx_control[qinx] = readl_relaxed(DMA_TCR_RGOFFADDRESS(qinx)); ethqos->xstats.dma_ch_txdesc_list_addr[qinx] = readl_relaxed(DMA_TDLAR_RGOFFADDRESS(qinx)); ethqos->xstats.dma_ch_txdesc_ring_len[qinx] = readl_relaxed(DMA_TDRLR_RGOFFADDRESS(qinx)); ethqos->xstats.dma_ch_curr_app_txdesc[qinx] = readl_relaxed(DMA_CHTDR_RGOFFADDRESS(qinx)); ethqos->xstats.dma_ch_txdesc_tail_ptr[qinx] = readl_relaxed(DMA_TDTP_TPDR_RGOFFADDRESS(qinx)); ethqos->xstats.dma_ch_curr_app_txbuf[qinx] = readl_relaxed(DMA_CHTBAR_RGOFFADDRESS(qinx)); } for (qinx = 0; qinx < rx_count; qinx++) { if (ethqos->ipa_enabled && qinx == IPA_DMA_RX_CH) continue; ethqos->xstats.dma_ch_rx_control[qinx] = readl_relaxed(DMA_RCR_RGOFFADDRESS(qinx)); ethqos->xstats.dma_ch_rxdesc_list_addr[qinx] = readl_relaxed(DMA_RDLAR_RGOFFADDRESS(qinx)); ethqos->xstats.dma_ch_rxdesc_ring_len[qinx] = readl_relaxed(DMA_RDRLR_RGOFFADDRESS(qinx)); ethqos->xstats.dma_ch_curr_app_rxdesc[qinx] = readl_relaxed(DMA_CHRDR_RGOFFADDRESS(qinx)); ethqos->xstats.dma_ch_rxdesc_tail_ptr[qinx] = readl_relaxed(DMA_RDTP_RPDR_RGOFFADDRESS(qinx)); ethqos->xstats.dma_ch_curr_app_rxbuf[qinx] = readl_relaxed(DMA_CHRBAR_RGOFFADDRESS(qinx)); ethqos->xstats.dma_ch_miss_frame_count[qinx] = readl_relaxed(DMA_CH_MISS_FRAME_CNT_RGOFFADDRESS(qinx)); } ETHQOSDBG("Exit"); } static int qcom_ethos_panic_notifier(struct notifier_block *this, unsigned long event, void *ptr) { u32 size_iomacro_regs; if (pethqos) { size_iomacro_regs = qcom_ethqos_rgmii_io_macro_num_of_regs(pethqos->emac_ver) * 4; ETHQOSINFO("pethqos 0x%p", pethqos); ethqos_dma_desc_stats_read(pethqos); pethqos->iommu_domain = stmmac_emb_smmu_ctx.iommu_domain; ETHQOSINFO("emac iommu domain 0x%p", pethqos->iommu_domain); pethqos->emac_reg_base_address = kzalloc(pethqos->emac_mem_size, GFP_KERNEL); ETHQOSINFO("emac register mem 0x%p", pethqos->emac_mem_base); if (pethqos->emac_mem_base) memcpy_fromio(pethqos->emac_reg_base_address, pethqos->ioaddr, pethqos->emac_mem_size); pethqos->rgmii_reg_base_address = kzalloc(size_iomacro_regs, GFP_KERNEL); ETHQOSINFO ("rgmii register mem 0x%p", pethqos->rgmii_reg_base_address); if (pethqos->rgmii_reg_base_address) memcpy_fromio(pethqos->rgmii_reg_base_address, pethqos->rgmii_base, size_iomacro_regs); } return NOTIFY_DONE; } static struct notifier_block qcom_ethqos_panic_blk = { .notifier_call = qcom_ethos_panic_notifier, }; static int qcom_ethqos_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; Loading Loading @@ -2769,6 +2890,8 @@ static int qcom_ethqos_probe(struct platform_device *pdev) if (ret) goto err_clk; atomic_notifier_chain_register(&panic_notifier_list, &qcom_ethqos_panic_blk); rgmii_dump(ethqos); if (ethqos->emac_ver == EMAC_HW_v2_3_2) { Loading
drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.h +33 −0 Original line number Diff line number Diff line Loading @@ -426,6 +426,32 @@ struct ethqos_io_macro { bool rx_dll_bypass; }; struct ethqos_extra_dma_stats { /* DMA status registers for all channels [0-4] */ unsigned long dma_ch_status[MTL_MAX_TX_QUEUES]; unsigned long dma_ch_intr_enable[MTL_MAX_TX_QUEUES]; unsigned long dma_ch_intr_status; unsigned long dma_debug_status0; unsigned long dma_debug_status1; /* RX DMA descriptor status registers for all channels [0-4] */ unsigned long dma_ch_rx_control[MTL_MAX_RX_QUEUES]; unsigned long dma_ch_rxdesc_list_addr[MTL_MAX_RX_QUEUES]; unsigned long dma_ch_rxdesc_ring_len[MTL_MAX_RX_QUEUES]; unsigned long dma_ch_curr_app_rxdesc[MTL_MAX_RX_QUEUES]; unsigned long dma_ch_rxdesc_tail_ptr[MTL_MAX_RX_QUEUES]; unsigned long dma_ch_curr_app_rxbuf[MTL_MAX_RX_QUEUES]; unsigned long dma_ch_miss_frame_count[MTL_MAX_RX_QUEUES]; /* TX DMA descriptors status for all channels [0-5] */ unsigned long dma_ch_tx_control[MTL_MAX_TX_QUEUES]; unsigned long dma_ch_txdesc_list_addr[MTL_MAX_TX_QUEUES]; unsigned long dma_ch_txdesc_ring_len[MTL_MAX_TX_QUEUES]; unsigned long dma_ch_curr_app_txdesc[MTL_MAX_TX_QUEUES]; unsigned long dma_ch_txdesc_tail_ptr[MTL_MAX_TX_QUEUES]; unsigned long dma_ch_curr_app_txbuf[MTL_MAX_TX_QUEUES]; }; struct qcom_ethqos { struct platform_device *pdev; void __iomem *rgmii_base; Loading @@ -438,6 +464,10 @@ struct qcom_ethqos { unsigned int speed; unsigned int vote_idx; struct iommu_domain *iommu_domain; unsigned int *emac_reg_base_address; unsigned int *rgmii_reg_base_address; int gpio_phy_intr_redirect; u32 phy_intr; /* Work struct for handling phy interrupt */ Loading Loading @@ -504,6 +534,7 @@ struct qcom_ethqos { bool ipa_enabled; /* Key Performance Indicators */ bool print_kpi; unsigned int emac_phy_off_suspend; int loopback_speed; enum loopback_mode current_loopback; Loading @@ -527,6 +558,8 @@ struct qcom_ethqos { u32 cv2x_mode; struct ethqos_vlan_info cv2x_vlan; unsigned char cv2x_dev_addr[ETH_ALEN]; struct ethqos_extra_dma_stats xstats; }; struct pps_cfg { Loading
drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ipa.h +19 −0 Original line number Diff line number Diff line Loading @@ -460,6 +460,8 @@ static char * const IPA_OFFLOAD_EVENT_string[] = { #define DMA_DSR0_RGRD(data) \ ((data) = readl_relaxed(DMA_DSR0_RGOFFADDR)) #define DMA_DSR1_RGOFFADDR ((BASE_ADDRESS + 0x1010)) #define DMA_CHRDR_RGOFFADDR (BASE_ADDRESS + 0x114c) #define DMA_CHRDR_RGOFFADDRESS(i)\ Loading Loading @@ -503,6 +505,21 @@ static char * const IPA_OFFLOAD_EVENT_string[] = { #define DMA_CHTDR_RGRD(i, data) \ ((data) = readl_relaxed(DMA_CHTDR_RGOFFADDRESS(i))) #define DMA_CHTBAR_RGOFFADDR (BASE_ADDRESS + 0x1154) #define DMA_CHTBAR_RGOFFADDRESS(i)\ ((DMA_CHTBAR_RGOFFADDR + ((i - 0) * 128))) #define DMA_CHRBAR_RGOFFADDR (BASE_ADDRESS + 0x115c) #define DMA_CHRBAR_RGOFFADDRESS(i)\ ((DMA_CHRBAR_RGOFFADDR + ((i - 0) * 128))) #define DMA_CH_MISS_FRAME_CNT_RGOFFADDR (BASE_ADDRESS + 0x1164) #define DMA_CH_MISS_FRAME_CNT_RGOFFADDRESS(i)\ ((DMA_CH_MISS_FRAME_CNT_RGOFFADDR + ((i - 0) * 128))) #define DMA_TDTP_TPDR_RGOFFADDR (BASE_ADDRESS + 0x1120) #define DMA_TDTP_TPDR_RGOFFADDRESS(i)\ Loading Loading @@ -554,6 +571,8 @@ static char * const IPA_OFFLOAD_EVENT_string[] = { data = ((data1 >> 13) & DMA_IER_CDEE_MASK);\ } while (0) #define DMA_ISR_RGOFFADDR ((BASE_ADDRESS + 0x1008)) struct ethqos_tx_queue { struct stmmac_tx_queue *tx_q; unsigned int desc_cnt; Loading