// SPDX-License-Identifier: GPL-2.0
/* Texas Instruments ICSSG Ethernet Driver
*
* Copyright (C) 2018-2022 Texas Instruments Incorporated - https://www.ti.com/
* Copyright (C) Siemens AG, 2024
*
*/
#include <linux/dma-mapping.h>
#include <linux/dma/ti-cppi5.h>
#include <linux/etherdevice.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/of.h>
#include <linux/of_mdio.h>
#include <linux/phy.h>
#include <linux/remoteproc/pruss.h>
#include <linux/regmap.h>
#include <linux/remoteproc.h>
#include "icssg_prueth.h"
#include "../k3-cppi-desc-pool.h"
/* Netif debug messages possible */
#define PRUETH_EMAC_DEBUG (NETIF_MSG_DRV | \
NETIF_MSG_PROBE | \
NETIF_MSG_LINK | \
NETIF_MSG_TIMER | \
NETIF_MSG_IFDOWN | \
NETIF_MSG_IFUP | \
NETIF_MSG_RX_ERR | \
NETIF_MSG_TX_ERR | \
NETIF_MSG_TX_QUEUED | \
NETIF_MSG_INTR | \
NETIF_MSG_TX_DONE | \
NETIF_MSG_RX_STATUS | \
NETIF_MSG_PKTDATA | \
NETIF_MSG_HW | \
NETIF_MSG_WOL)
#define prueth_napi_to_emac(napi) container_of(napi, struct prueth_emac, napi_rx)
void prueth_cleanup_rx_chns(struct prueth_emac *emac,
struct prueth_rx_chn *rx_chn,
int max_rflows)
{
if (rx_chn->desc_pool)
k3_cppi_desc_pool_destroy(rx_chn->desc_pool);
if (rx_chn->rx_chn)
k3_udma_glue_release_rx_chn(rx_chn->rx_chn);
}
EXPORT_SYMBOL_GPL(prueth_cleanup_rx_chns);
void prueth_cleanup_tx_chns(struct prueth_emac *emac)
{
int i;
for (i = 0; i < emac->tx_ch_num; i++) {
struct prueth_tx_chn *tx_chn = &emac->tx_chns[i];
if (tx_chn->desc_pool)
k3_cppi_desc_pool_destroy(tx_chn->desc_pool);
if (tx_chn->tx_chn)
k3_udma_glue_release_tx_chn(tx_chn->tx_chn);
/* Assume prueth_cleanup_tx_chns() is called at the
* end after all channel resources are freed
*/
memset(tx_chn, 0, sizeof(*tx_chn));
}
}
EXPORT_SYMBOL_GPL(prueth_cleanup_tx_chns);
void prueth_ndev_del_tx_napi(struct prueth_emac *emac, int num)
{
int i;
for (i = 0; i < num; i++) {
struct prueth_tx_chn *tx_chn = &emac->tx_chns[i];
if (tx_chn->irq)
free_irq(tx_chn->irq, tx_chn);
netif_napi_del(&tx_chn->napi_tx);
}
}
EXPORT_SYMBOL_GPL(prueth_ndev_del_tx_napi);
void prueth_xmit_free(struct prueth_tx_chn *tx_chn,
struct cppi5_host_desc_t *desc)
{
struct cppi5_host_desc_t *first_desc, *next_desc;
dma_addr_t buf_dma, next_desc_dma;
u32 buf_dma_len;
first_desc = desc;
next_desc = first_desc;
cppi5_hdesc_get_obuf(first_desc, &buf_dma, &buf_dma_len);
k3_udma_glue_tx_cppi5_to_dma_addr(tx_chn->tx_chn, &buf_dma);
dma_unmap_single(tx_chn->dma_dev, buf_dma, buf_dma_len,
DMA_TO_DEVICE);
next_desc_dma = cppi5_hdesc_get_next_hbdesc(first_desc);
k3_udma_glue_tx_cppi5_to_dma_addr(tx_chn->tx_chn, &next_desc_dma);
while (next_desc_dma) {
next_desc = k3_cppi_desc_pool_dma2virt(tx_chn->desc_pool,
next_desc_dma);
cppi5_hdesc_get_obuf(next_desc, &buf_dma, &buf_dma_len);
k3_udma_glue_tx_cppi5_to_dma_addr(tx_chn<