mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-22 17:25:35 +03:00
coe: Add Camera Over Ethernet cababilities
The following change is a squash change that aims to reintroduce Camera Over Ethernet (CoE) functionality to kernel. Bug 5401884 Bug 5419655 Change-Id: Id2fc0263c43ed8566241dbf712aa603a3b3a76f4 Signed-off-by: Rakibul Hassan <rakibulh@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3419627 Reviewed-by: Anubhav Rai <arai@nvidia.com> Reviewed-by: Narendra Kondapalli <nkondapalli@nvidia.com> GVS: buildbot_gerritrpt <buildbot_gerritrpt@nvidia.com> Reviewed-by: Igor Mitsyanko <imitsyanko@nvidia.com> Reviewed-by: Jon Hunter <jonathanh@nvidia.com>
This commit is contained in:
committed by
mobile promotions
parent
a7fae6153a
commit
f374450381
@@ -51,5 +51,8 @@ obj-m += tests/
|
||||
tegra-capture-isp-objs += fusa-capture/capture-isp-channel.o
|
||||
tegra-capture-isp-objs += fusa-capture/capture-isp.o
|
||||
obj-m += tegra-capture-isp.o
|
||||
|
||||
tegra-capture-coe-objs += coe/rtcpu-coe.o
|
||||
obj-m += tegra-capture-coe.o
|
||||
endif
|
||||
endif
|
||||
|
||||
1936
drivers/media/platform/tegra/camera/coe/rtcpu-coe.c
Normal file
1936
drivers/media/platform/tegra/camera/coe/rtcpu-coe.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -19,11 +19,7 @@ endif
|
||||
ccflags-y += -DLINUX_OS -DNET30 -DNVPKCS_MACSEC -DLINUX_IVC -mno-outline-atomics -Werror \
|
||||
-I$(srctree.nvidia-oot)/drivers/net/ethernet/nvidia/nvethernet/nvethernetrm/include
|
||||
|
||||
ifdef CONFIG_KASAN
|
||||
ccflags-y += -Wframe-larger-than=4096
|
||||
else
|
||||
ccflags-y += -Wframe-larger-than=2048
|
||||
endif
|
||||
|
||||
#ccflags-y += -DOSI_DEBUG -DMACSEC_SUPPORT -DDEBUG_MACSEC -DMACSEC_KEY_PROGRAM
|
||||
ccflags-y += -DMACSEC_SUPPORT
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <soc/tegra/fuse.h>
|
||||
#include <soc/tegra/fuse-helper.h>
|
||||
#include <soc/tegra/virt/hv-ivc.h>
|
||||
#include <soc/tegra/nvethernet-public.h>
|
||||
#include <linux/time.h>
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
@@ -2053,6 +2054,11 @@ static int ether_request_irqs(struct ether_priv_data *pdata)
|
||||
"unexpected irq name index received (%d)\n", j);
|
||||
goto err_chan_irq;
|
||||
}
|
||||
|
||||
if (osi_core->irq_data[i].is_coe == 1U) {
|
||||
continue;
|
||||
}
|
||||
|
||||
snprintf(pdata->irq_names[j], ETHER_IRQ_NAME_SZ, "%s.vm%d",
|
||||
netdev_name(pdata->ndev), i);
|
||||
ret = devm_request_irq(pdata->dev, pdata->vm_irqs[i],
|
||||
@@ -2169,6 +2175,41 @@ static void ether_napi_enable(struct ether_priv_data *pdata)
|
||||
}
|
||||
}
|
||||
|
||||
static void ether_free_coe_resource(struct ether_priv_data *pdata)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < OSI_MGBE_COE_NUM_RX_FRAMES; i++) {
|
||||
dma_unmap_single(pdata->dev, pdata->mgbe_coe.rx_fb_addr_phys[i], PAGE_SIZE, DMA_FROM_DEVICE);
|
||||
free_page(pdata->mgbe_coe.rx_fb_addr[i]);
|
||||
}
|
||||
dma_free_coherent(pdata->dev, sizeof(struct osi_mgbe_coe_pib) * pdata->mgbe_coe.rx_pib_sz,
|
||||
(void *)pdata->mgbe_coe.rx_pib_addr, pdata->mgbe_coe.rx_pib_addr_phys);
|
||||
}
|
||||
|
||||
|
||||
static int ether_allocate_coe_resource(struct ether_priv_data *pdata)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < OSI_MGBE_COE_NUM_RX_FRAMES; i++) {
|
||||
pdata->mgbe_coe.rx_fb_addr[i] = __get_free_page(GFP_DMA);
|
||||
pdata->mgbe_coe.rx_fb_addr_phys[i] = dma_map_single(pdata->dev,
|
||||
(void *)pdata->mgbe_coe.rx_fb_addr[i],
|
||||
PAGE_SIZE, DMA_FROM_DEVICE);
|
||||
pr_err("%s: rx_fb_addr[%d]: virt: %#llx phys: %#llx\n", __func__, i,
|
||||
pdata->mgbe_coe.rx_fb_addr[i],
|
||||
pdata->mgbe_coe.rx_fb_addr_phys[i]);
|
||||
}
|
||||
pdata->mgbe_coe.rx_pib_addr = (u64) dma_alloc_coherent(pdata->dev,
|
||||
sizeof(struct osi_mgbe_coe_pib) * pdata->mgbe_coe.rx_pib_sz,
|
||||
(dma_addr_t *) &pdata->mgbe_coe.rx_pib_addr_phys,
|
||||
GFP_KERNEL | __GFP_ZERO);
|
||||
pr_err("%s: rx_pib_addr: virt: %#llx phys: %#llx\n", __func__, pdata->mgbe_coe.rx_pib_addr, pdata->mgbe_coe.rx_pib_addr_phys);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Free receive skbs
|
||||
*
|
||||
@@ -2257,6 +2298,10 @@ static void free_rx_dma_resources(struct osi_dma_priv_data *osi_dma,
|
||||
pdata->page_pool[chan] = NULL;
|
||||
}
|
||||
#endif
|
||||
if (i == pdata->mgbe_coe.vdma && pdata->coe_enable) {
|
||||
pr_err("%s: Freeing COE DMA resources for vdma %d\n", __func__, i);
|
||||
ether_free_coe_resource(pdata);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2428,6 +2473,7 @@ static int ether_page_pool_create_per_chan(struct ether_priv_data *pdata,
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* @brief Allocate Receive DMA channel ring resources.
|
||||
*
|
||||
@@ -2448,6 +2494,7 @@ static int ether_allocate_rx_dma_resources(struct osi_dma_priv_data *osi_dma,
|
||||
unsigned int chan;
|
||||
unsigned int i;
|
||||
int ret = 0;
|
||||
struct osi_ioctl ioctl_data = {};
|
||||
const nveu32_t max_dma_chan[OSI_MAX_MAC_IP_TYPES] = {
|
||||
OSI_EQOS_MAX_NUM_CHANS,
|
||||
OSI_MGBE_T23X_MAX_NUM_CHANS,
|
||||
@@ -2478,6 +2525,22 @@ static int ether_allocate_rx_dma_resources(struct osi_dma_priv_data *osi_dma,
|
||||
if (ret < 0) {
|
||||
goto exit;
|
||||
}
|
||||
if (pdata->coe_enable && chan == pdata->mgbe_coe.vdma) {
|
||||
pr_err("%s: Allocating COE DMA resources for vdma %d\n", __func__, chan);
|
||||
ret = ether_allocate_coe_resource(pdata);
|
||||
if (ret < 0) {
|
||||
goto exit;
|
||||
}
|
||||
/* Program the buffers in HW */
|
||||
memcpy(&ioctl_data.data.mgbe_coe, &pdata->mgbe_coe, sizeof(struct osi_mgbe_coe));
|
||||
ioctl_data.cmd = OSI_CMD_GMSL_COE_CONFIG;
|
||||
ret = osi_handle_ioctl(pdata->osi_core, &ioctl_data);
|
||||
if (ret < 0) {
|
||||
dev_err(pdata->dev, "Enabling MAC COE in HW failed\n");
|
||||
} else {
|
||||
dev_info(pdata->dev, "MAC COE enabled in HW\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2666,6 +2729,10 @@ static void ether_init_invalid_chan_ring(struct osi_dma_priv_data *osi_dma)
|
||||
for (i = osi_dma->num_dma_chans; i < max_dma_chan[osi_dma->mac]; i++) {
|
||||
osi_dma->dma_chans[i] = ETHER_INVALID_CHAN_NUM;
|
||||
}
|
||||
|
||||
for (i = osi_dma->num_dma_chans_coe; i < max_dma_chan[osi_dma->mac]; i++) {
|
||||
osi_dma->dma_chans_coe[i] = ETHER_INVALID_CHAN_NUM;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3126,6 +3193,14 @@ int ether_open(struct net_device *dev)
|
||||
}
|
||||
|
||||
/* initialize MAC/MTL/DMA Common registers */
|
||||
/** If COE is enabled, disable RIWT so that IOC is set for all desc. */
|
||||
if (pdata->coe_enable) {
|
||||
pdata->osi_dma->use_riwt = OSI_DISABLE;
|
||||
pdata->osi_dma->coe_enable = pdata->coe_enable;
|
||||
pdata->osi_dma->mgbe_coe = pdata->mgbe_coe;
|
||||
pdata->osi_core->coe_enable = pdata->coe_enable;
|
||||
pdata->osi_core->mgbe_coe = pdata->mgbe_coe;
|
||||
}
|
||||
ret = osi_hw_core_init(pdata->osi_core);
|
||||
if (ret < 0) {
|
||||
dev_err(pdata->dev,
|
||||
@@ -3901,8 +3976,8 @@ unsigned short ether_select_queue(struct net_device *dev,
|
||||
if ((osi_core->pre_sil == OSI_ENABLE) && (pdata->tx_queue_select != 0U)) {
|
||||
txqueue_select = pdata->tx_queue_select;
|
||||
} else {
|
||||
for (i = 0; i < osi_core->num_mtl_queues; i++) {
|
||||
mtlq = osi_core->mtl_queues[i];
|
||||
for (i = 0; i < osi_core->num_dma_chans; i++) {
|
||||
mtlq = osi_core->dma_chans[i];
|
||||
if (pdata->txq_prio[mtlq] == priority) {
|
||||
txqueue_select = (unsigned short)i;
|
||||
break;
|
||||
@@ -4981,6 +5056,26 @@ static void ether_set_vm_irq_chan_mask(struct ether_vm_irq_data *vm_irq_data,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ether_set_coe_chan_mask - Set CoE channels bitmap
|
||||
*
|
||||
* @param[in] osi_dma: DMA data
|
||||
* @param[in] num_vm_chan: Number of VM DMA channels
|
||||
* @param[in] vm_chans: Pointer to list of VM DMA channels
|
||||
*
|
||||
* @retval None.
|
||||
*/
|
||||
static void ether_set_coe_chan_mask(struct osi_dma_priv_data *osi_dma,
|
||||
unsigned int num_vm_chan,
|
||||
unsigned int *vm_chans)
|
||||
{
|
||||
osi_dma->num_dma_chans_coe = num_vm_chan;
|
||||
|
||||
for (u32 i = 0; i < num_vm_chan; i++) {
|
||||
osi_dma->dma_chans_coe[i] = vm_chans[i];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ether_get_rx_riit - Get the rx_riit value for speed.
|
||||
*
|
||||
@@ -5205,6 +5300,8 @@ static int ether_get_vm_irq_data(struct platform_device *pdev,
|
||||
|
||||
child_id = 0;
|
||||
for_each_child_of_node(vm_node, temp) {
|
||||
bool is_coe;
|
||||
|
||||
ret = of_property_read_u32(temp, "nvidia,vm-irq-id", &vm_irq_id);
|
||||
if (ret != 0) {
|
||||
vm_irq_id = child_id;
|
||||
@@ -5246,15 +5343,35 @@ static int ether_get_vm_irq_data(struct platform_device *pdev,
|
||||
}
|
||||
}
|
||||
|
||||
is_coe = of_property_read_bool(temp, "nvidia,camera-over-eth");
|
||||
if (is_coe) {
|
||||
osi_core->irq_data[node].is_coe = 1U;
|
||||
dev_info(&pdev->dev, "VM IRQ is handled by Camera CPU: %u\n",
|
||||
node);
|
||||
} else {
|
||||
osi_core->irq_data[node].is_coe = 0U;
|
||||
}
|
||||
|
||||
/* Assuming there would not be more than 0xFFFF nodes */
|
||||
child_id &= MAX_CHILD_NODES;
|
||||
child_id++;
|
||||
}
|
||||
|
||||
for (node = 0; node < osi_core->num_vm_irqs; node++) {
|
||||
if (osi_core->irq_data[node].is_coe) {
|
||||
if (pdata->osi_dma->num_dma_chans_coe != 0) {
|
||||
dev_err(&pdev->dev, "Only one CoE IRQ allowed\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
/* CoE channels IRQ will be handled by camera CPU */
|
||||
ether_set_coe_chan_mask(pdata->osi_dma,
|
||||
osi_core->irq_data[node].num_vm_chans,
|
||||
osi_core->irq_data[node].vm_chans);
|
||||
} else {
|
||||
ether_set_vm_irq_chan_mask(&pdata->vm_irq_data[node],
|
||||
osi_core->irq_data[node].num_vm_chans,
|
||||
osi_core->irq_data[node].vm_chans);
|
||||
}
|
||||
|
||||
pdata->vm_irq_data[node].pdata = pdata;
|
||||
}
|
||||
@@ -7690,6 +7807,103 @@ void ether_shutdown(struct platform_device *pdev)
|
||||
dev_err(pdata->dev, "Failure in ether_close");
|
||||
}
|
||||
|
||||
int nvether_coe_config(struct net_device *ndev,
|
||||
struct nvether_coe_cfg *ether_coe_cfg)
|
||||
{
|
||||
struct ether_priv_data *pdata = netdev_priv(ndev);
|
||||
struct osi_core_priv_data *osi_core = pdata->osi_core;
|
||||
struct macsec_priv_data *macsec_pdata = pdata->macsec_pdata;
|
||||
struct osi_macsec_lut_config lut_config;
|
||||
int ret = -ENOENT;
|
||||
|
||||
/* If macsec not enabled, enable it.
|
||||
* FIXME: Need a lock to protect any concurrent macsec configuration outside this API from supplicant for ex. */
|
||||
if (macsec_pdata == NULL) {
|
||||
dev_err(pdata->dev, "macsec is not supported in platform, COE config failed\n");
|
||||
return ret;
|
||||
}
|
||||
if (macsec_pdata->enabled != OSI_ENABLE) {
|
||||
ret = macsec_open(macsec_pdata, NULL);
|
||||
if (ret < 0) {
|
||||
dev_err(pdata->dev, "macsec_open failure, COE config failed\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
if (macsec_pdata->coe.enable == OSI_ENABLE) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Program the COE LUT classifier for AVTP COE packets */
|
||||
memset(&lut_config, 0, sizeof(lut_config));
|
||||
lut_config.table_config.ctlr_sel = OSI_CTLR_SEL_RX;
|
||||
lut_config.table_config.index = 0U;
|
||||
if (ether_coe_cfg->vlan_enable == COE_VLAN_ENABLE) {
|
||||
// 16B offset for AV ethtype with VLAN,
|
||||
// divided by 2 as HW expects offset in multiple of 2.
|
||||
lut_config.coe_lut_inout.offset = 8U;
|
||||
}
|
||||
else if (ether_coe_cfg->vlan_enable == COE_VLAN_DISABLE) {
|
||||
// 12B offset for AV ethtype without VLAN,
|
||||
// divided by 2 as HW expects offset in multiple of 2.
|
||||
lut_config.coe_lut_inout.offset = 6U;
|
||||
}
|
||||
else {
|
||||
dev_err(pdata->dev, "Invalid VLAN enable value\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
lut_config.coe_lut_inout.byte_pattern_mask = 0xF;
|
||||
lut_config.coe_lut_inout.byte_pattern[1] = (unsigned char) 0x22;
|
||||
lut_config.coe_lut_inout.byte_pattern[0] = (unsigned char) 0xF0;
|
||||
lut_config.lut_sel = OSI_LUT_SEL_COE;
|
||||
lut_config.table_config.rw = OSI_LUT_WRITE;
|
||||
ret = osi_macsec_config_lut(osi_core, &lut_config);
|
||||
if (ret < 0) {
|
||||
dev_err(pdata->dev, "%s: Failed to config COE LUT\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Program the COE header offset and enable COE engine */
|
||||
ret = macsec_coe_config(macsec_pdata, ether_coe_cfg->coe_enable,
|
||||
ether_coe_cfg->coe_hdr_offset);
|
||||
if (ret < 0) {
|
||||
dev_err(pdata->dev, "COE config in macsec controller failed\n");
|
||||
return ret;
|
||||
} else {
|
||||
macsec_pdata->coe.enable = ether_coe_cfg->coe_enable;
|
||||
macsec_pdata->coe.hdr_offset = ether_coe_cfg->coe_hdr_offset;
|
||||
dev_info(pdata->dev, "COE config success\n");
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nvether_coe_config);
|
||||
|
||||
int nvether_coe_chan_config(struct net_device *ndev,
|
||||
u32 dmachan,
|
||||
struct nvether_per_coe_cfg *p_coe_cfg)
|
||||
{
|
||||
struct ether_priv_data *pdata = netdev_priv(ndev);
|
||||
struct macsec_priv_data *macsec_pdata = pdata->macsec_pdata;
|
||||
int ret;
|
||||
|
||||
if (macsec_pdata == NULL) {
|
||||
dev_err(pdata->dev, "macsec is not supported in platform, COE config failed\n");
|
||||
return -ENONET;
|
||||
}
|
||||
|
||||
if (macsec_pdata->coe.enable != OSI_ENABLE) {
|
||||
dev_err(pdata->dev, "COE not enabled\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
ret = macsec_coe_lc(macsec_pdata, dmachan,
|
||||
p_coe_cfg->lc1,
|
||||
p_coe_cfg->lc2);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nvether_coe_chan_config);
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static s32 ether_handle_rx_buffers(struct ether_priv_data *pdata,
|
||||
uint32_t suspend)
|
||||
@@ -7893,6 +8107,16 @@ int ether_suspend_noirq(struct device *dev)
|
||||
OSI_DMA_INTR_DISABLE);
|
||||
}
|
||||
|
||||
for (i = 0; i < osi_dma->num_dma_chans_coe; i++) {
|
||||
chan = osi_dma->dma_chans_coe[i];
|
||||
osi_handle_dma_intr(osi_dma, chan,
|
||||
OSI_DMA_CH_TX_INTR,
|
||||
OSI_DMA_INTR_DISABLE);
|
||||
osi_handle_dma_intr(osi_dma, chan,
|
||||
OSI_DMA_CH_RX_INTR,
|
||||
OSI_DMA_INTR_DISABLE);
|
||||
}
|
||||
|
||||
if (ether_handle_rx_buffers(pdata, OSI_ENABLE) != 0)
|
||||
dev_err(dev, "Failed to free the Rx buffers\n");
|
||||
|
||||
|
||||
@@ -755,6 +755,10 @@ struct ether_priv_data {
|
||||
/** tx bandwidth pkt work queue */
|
||||
struct workqueue_struct *tx_bw_wq;
|
||||
#endif
|
||||
/** COE mode enabled */
|
||||
u32 coe_enable;
|
||||
/** OSI instance of COE */
|
||||
struct osi_mgbe_coe mgbe_coe;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -211,6 +211,38 @@ int macsec_close(struct macsec_priv_data *macsec_pdata)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int macsec_coe_config(struct macsec_priv_data *macsec_pdata,
|
||||
uint32_t coe_enable, uint32_t coe_hdr_offset)
|
||||
{
|
||||
int ret = 0;
|
||||
struct ether_priv_data *pdata = macsec_pdata->ether_pdata;
|
||||
struct device *dev = pdata->dev;
|
||||
|
||||
/* Input is already validated */
|
||||
ret = osi_macsec_coe_config(pdata->osi_core, coe_enable,
|
||||
coe_hdr_offset);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "osi_macsec_coe_config failed, %d\n", ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int macsec_coe_lc(struct macsec_priv_data *macsec_pdata,
|
||||
uint32_t ch, uint32_t lc1, uint32_t lc2)
|
||||
{
|
||||
int ret = 0;
|
||||
struct ether_priv_data *pdata = macsec_pdata->ether_pdata;
|
||||
struct device *dev = pdata->dev;
|
||||
|
||||
/* Input is already validated */
|
||||
ret = osi_macsec_coe_lc(pdata->osi_core, ch, lc1, lc2);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "osi_macsec_coe_lc failed, %d\n", ret);
|
||||
}
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
int macsec_open(struct macsec_priv_data *macsec_pdata,
|
||||
void *const genl_info)
|
||||
{
|
||||
|
||||
@@ -205,6 +205,20 @@ struct nvpkcs_data {
|
||||
u64 nv_kek;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief MACsec COE private data structure
|
||||
*/
|
||||
struct macsec_coe {
|
||||
/** Macsec COE state */
|
||||
unsigned int enable;
|
||||
/** Macsec COE hdr offset */
|
||||
unsigned int hdr_offset;
|
||||
/** Macsec COE line counter threshold 1 */
|
||||
unsigned int lc1_threshold[OSI_MGBE_MAX_NUM_CHANS];
|
||||
/** Macsec COE line counter threshold 2 */
|
||||
unsigned int lc2_threshold[OSI_MGBE_MAX_NUM_CHANS];
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief MACsec private data structure
|
||||
*/
|
||||
@@ -259,9 +273,15 @@ struct macsec_priv_data {
|
||||
unsigned int macsec_tx_an_map;
|
||||
/** Macsec RX currently enabled AN */
|
||||
unsigned int macsec_rx_an_map;
|
||||
/** Macsec COE instance */
|
||||
struct macsec_coe coe;
|
||||
};
|
||||
|
||||
int macsec_probe(struct ether_priv_data *pdata);
|
||||
int macsec_coe_config(struct macsec_priv_data *macsec_pdata,
|
||||
uint32_t coe_enable, uint32_t coe_hdr_offset);
|
||||
int macsec_coe_lc(struct macsec_priv_data *macsec_pdata,
|
||||
uint32_t ch, uint32_t lc1, uint32_t lc2);
|
||||
void macsec_remove(struct ether_priv_data *pdata);
|
||||
int macsec_open(struct macsec_priv_data *macsec_pdata,
|
||||
void *const genl_info);
|
||||
|
||||
@@ -533,6 +533,336 @@ static DEVICE_ATTR(macsec_enable, (S_IRUGO | S_IWUSR),
|
||||
macsec_enable_show,
|
||||
macsec_enable_store);
|
||||
|
||||
#define MACSEC_COE_LC_INPUT_LEN 3
|
||||
extern int macsec_coe_config(struct macsec_priv_data *macsec_pdata,
|
||||
uint32_t coe_enable, uint32_t coe_hdr_offset);
|
||||
/**
|
||||
* @brief Shows the current COE setting of MACsec controllers enabled
|
||||
*
|
||||
* Algorithm: Display the current COE settings for MACsec controllers.
|
||||
*
|
||||
* @param[in] dev: Device data.
|
||||
* @param[in] attr: Device attribute
|
||||
* @param[in] buf: Buffer to store the current COE setting
|
||||
*/
|
||||
static ssize_t macsec_coe_enable_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct net_device *ndev = (struct net_device *)dev_get_drvdata(dev);
|
||||
struct ether_priv_data *pdata = netdev_priv(ndev);
|
||||
struct macsec_priv_data *macsec_pdata = pdata->macsec_pdata;
|
||||
unsigned int coe_enable;
|
||||
unsigned int coe_hdr_offset;
|
||||
|
||||
if (!netif_running(ndev)) {
|
||||
dev_err(pdata->dev, "Not Allowed. Ether interface is not up\n");
|
||||
return 0;
|
||||
}
|
||||
if ((macsec_pdata == NULL)) {
|
||||
dev_err(pdata->dev, "Not Allowed. MACSec is not supported on this platform\n");
|
||||
return 0;
|
||||
}
|
||||
if (macsec_pdata->enabled != OSI_ENABLE) {
|
||||
dev_err(pdata->dev, "Not Allowed. MACSec is not enabled on the controller\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
coe_enable = macsec_pdata->coe.enable;
|
||||
coe_hdr_offset = macsec_pdata->coe.hdr_offset;
|
||||
|
||||
if (OSI_ENABLE == coe_enable) {
|
||||
return scnprintf(buf, PAGE_SIZE, "COE enabled, COE hdr offset: %u\n",
|
||||
coe_hdr_offset);
|
||||
} else {
|
||||
return scnprintf(buf, PAGE_SIZE, "COE disabled\n");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the MACsec controller COE logic enabled (Rx only)
|
||||
*
|
||||
* Algorithm: This is used to set the Rx MACsec controller COE logic enabled.
|
||||
*
|
||||
* @param[in] dev: Device data.
|
||||
* @param[in] attr: Device attribute
|
||||
* @param[in] buf: Buffer which contains the user settings of MACsec COE enable
|
||||
* @param[in] size: size of buffer
|
||||
*
|
||||
* @return size of buffer.
|
||||
*/
|
||||
static ssize_t macsec_coe_enable_store(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
struct net_device *ndev = (struct net_device *)dev_get_drvdata(dev);
|
||||
struct ether_priv_data *pdata = netdev_priv(ndev);
|
||||
struct macsec_priv_data *macsec_pdata = pdata->macsec_pdata;
|
||||
uint32_t coe_enable, coe_hdr_offset;
|
||||
int ret = 0, i;
|
||||
|
||||
if (!netif_running(ndev)) {
|
||||
dev_err(pdata->dev, "Not Allowed. Ether interface is not up\n");
|
||||
return size;
|
||||
}
|
||||
if ((macsec_pdata == NULL)) {
|
||||
dev_err(pdata->dev, "Not Allowed. MACSec is not supported on this platform\n");
|
||||
return size;
|
||||
}
|
||||
if (macsec_pdata->enabled != OSI_ENABLE) {
|
||||
dev_err(pdata->dev, "Not Allowed. MACSec is not enabled on the controller\n");
|
||||
return size;
|
||||
}
|
||||
|
||||
/* Read user inputs and validate it */
|
||||
i = sscanf(buf, "%u %u", &coe_enable, &coe_hdr_offset);
|
||||
if ((coe_enable != OSI_ENABLE) && (coe_enable != OSI_DISABLE)) {
|
||||
dev_err(pdata->dev, "Invalid value %u for coe_enable\n", coe_enable);
|
||||
return size;
|
||||
}
|
||||
if ((coe_hdr_offset < 16) || (coe_hdr_offset > 56)) {
|
||||
dev_err(pdata->dev, "Invalid value %u for coe_hdr_offset\n", coe_hdr_offset);
|
||||
return size;
|
||||
}
|
||||
|
||||
/* Configure COE */
|
||||
if (coe_enable == OSI_ENABLE) {
|
||||
if (macsec_pdata->coe.enable == OSI_ENABLE) {
|
||||
dev_err(pdata->dev, "COE already enabled\n");
|
||||
return size;
|
||||
}
|
||||
} else {
|
||||
if (macsec_pdata->coe.enable == OSI_DISABLE) {
|
||||
dev_err(pdata->dev, "COE already disabled\n");
|
||||
return size;
|
||||
}
|
||||
}
|
||||
ret = macsec_coe_config(macsec_pdata, coe_enable, coe_hdr_offset);
|
||||
if (0 == ret) {
|
||||
macsec_pdata->coe.enable = coe_enable;
|
||||
macsec_pdata->coe.hdr_offset = coe_hdr_offset;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sysfs attribute for MACsec COE enable
|
||||
*
|
||||
*/
|
||||
static DEVICE_ATTR(macsec_coe_enable, (S_IRUGO | S_IWUSR),
|
||||
macsec_coe_enable_show,
|
||||
macsec_coe_enable_store);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Shows the current COE setting of MAC controllers enabled
|
||||
*
|
||||
* Algorithm: Display the current COE settings for MAC controllers.
|
||||
*
|
||||
* @param[in] dev: Device data.
|
||||
* @param[in] attr: Device attribute
|
||||
* @param[in] buf: Buffer to store the current COE setting for the MAC
|
||||
*/
|
||||
static ssize_t mac_coe_enable_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct net_device *ndev = (struct net_device *)dev_get_drvdata(dev);
|
||||
struct ether_priv_data *pdata = netdev_priv(ndev);
|
||||
char *p = buf;
|
||||
int i, j;
|
||||
|
||||
if (!netif_running(ndev)) {
|
||||
dev_err(pdata->dev, "Not Allowed. Ether interface is not up\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (OSI_ENABLE == pdata->coe_enable) {
|
||||
p += scnprintf(p, PAGE_SIZE, "MGBE COE mode enabled\n");
|
||||
p += scnprintf(p, PAGE_SIZE, "\t vdma: %d\n", pdata->mgbe_coe.vdma);
|
||||
p += scnprintf(p, PAGE_SIZE, "\t pdma: %d\n", pdata->mgbe_coe.pdma);
|
||||
p += scnprintf(p, PAGE_SIZE, "\t PIB size: %d\n", pdata->mgbe_coe.rx_pib_sz);
|
||||
for (j = 0; j < OSI_MGBE_COE_NUM_RX_FRAMES; j++) {
|
||||
p += scnprintf(p, PAGE_SIZE, "\t FB[%d]:\n", j);
|
||||
for (i = 0; i < 200; i++) {
|
||||
p += scnprintf(p, PAGE_SIZE - i, "%02x", *(((unsigned char *)(pdata->mgbe_coe.rx_fb_addr[j])) + i));
|
||||
}
|
||||
p += scnprintf(p, PAGE_SIZE - i, "\n");
|
||||
}
|
||||
p += scnprintf(p, PAGE_SIZE, "\t PIB:\n");
|
||||
for (i = 0; i < 200; i++) {
|
||||
p += scnprintf(p, PAGE_SIZE - i, "%02x", *(((unsigned char *)pdata->mgbe_coe.rx_pib_addr) + i));
|
||||
}
|
||||
return p - buf;
|
||||
} else {
|
||||
return scnprintf(buf, PAGE_SIZE, "MGBE COE mode disabled\n");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the MAC controller COE logic enabled (Rx only)
|
||||
*
|
||||
* Algorithm: This is used to set the Rx MAC controller COE logic enabled.
|
||||
*
|
||||
* @param[in] dev: Device data.
|
||||
* @param[in] attr: Device attribute
|
||||
* @param[in] buf: Buffer which contains the user settings of MAC COE enable
|
||||
* @param[in] size: size of buffer
|
||||
*
|
||||
* @return size of buffer.
|
||||
*/
|
||||
static ssize_t mac_coe_enable_store(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
struct net_device *ndev = (struct net_device *)dev_get_drvdata(dev);
|
||||
struct ether_priv_data *pdata = netdev_priv(ndev);
|
||||
int32_t coe_enable, vdma, pdma, rx_pib_sz;
|
||||
|
||||
if (netif_running(ndev)) {
|
||||
dev_err(pdata->dev, "Not Allowed. Ether interface is not down\n");
|
||||
return size;
|
||||
}
|
||||
|
||||
/* Read user inputs and validate it */
|
||||
sscanf(buf, "%d %d %d %d", &coe_enable, &vdma, &pdma, &rx_pib_sz);
|
||||
if ((coe_enable != OSI_ENABLE) && (coe_enable != OSI_DISABLE)) {
|
||||
dev_err(pdata->dev, "Invalid value %u for coe_enable\n", coe_enable);
|
||||
return size;
|
||||
}
|
||||
if ((rx_pib_sz != 256) &&
|
||||
(rx_pib_sz != 512) &&
|
||||
(rx_pib_sz != 2048) &&
|
||||
(rx_pib_sz != 4096)) {
|
||||
dev_err(pdata->dev, "Invalid value %d for rx_pib_sz\n", rx_pib_sz);
|
||||
return size;
|
||||
}
|
||||
|
||||
/* Configure COE */
|
||||
pdata->coe_enable = coe_enable;
|
||||
pdata->mgbe_coe.vdma = vdma;
|
||||
pdata->mgbe_coe.pdma = pdma;
|
||||
pdata->mgbe_coe.rx_pib_sz = rx_pib_sz;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sysfs attribute for MAC COE enable
|
||||
*
|
||||
*/
|
||||
static DEVICE_ATTR(mac_coe_enable, (S_IRUGO | S_IWUSR),
|
||||
mac_coe_enable_show,
|
||||
mac_coe_enable_store);
|
||||
|
||||
extern int macsec_coe_lc(struct macsec_priv_data *macsec_pdata,
|
||||
uint32_t ch, uint32_t lc1, uint32_t lc2);
|
||||
/**
|
||||
* @brief Shows the current COE Line counter thresholds.
|
||||
*
|
||||
* Algorithm: Loop through the current COE Line counter thresholds per VDMA
|
||||
*
|
||||
* @param[in] dev: Device data.
|
||||
* @param[in] attr: Device attribute
|
||||
* @param[in] buf: Buffer to store the current LC thresholds
|
||||
*/
|
||||
static ssize_t macsec_coe_lc_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct net_device *ndev = (struct net_device *)dev_get_drvdata(dev);
|
||||
struct ether_priv_data *pdata = netdev_priv(ndev);
|
||||
struct macsec_priv_data *macsec_pdata = pdata->macsec_pdata;
|
||||
unsigned int i;
|
||||
char *start = buf;
|
||||
|
||||
if (!netif_running(ndev)) {
|
||||
dev_err(pdata->dev, "Not Allowed. Ether interface is not up\n");
|
||||
return 0;
|
||||
}
|
||||
if ((macsec_pdata == NULL)) {
|
||||
dev_err(pdata->dev, "Not Allowed. MACSec is not supported on this platform\n");
|
||||
return 0;
|
||||
}
|
||||
if (macsec_pdata->enabled != OSI_ENABLE) {
|
||||
dev_err(pdata->dev, "Not Allowed. MACSec is not enabled on the controller\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0U; i < OSI_MGBE_MAX_NUM_CHANS; i++) {
|
||||
buf += scnprintf(buf, PAGE_SIZE, "ch: %u lc1: %u lc2: %u\n", i,
|
||||
macsec_pdata->coe.lc1_threshold[i],
|
||||
macsec_pdata->coe.lc2_threshold[i]);
|
||||
}
|
||||
return (buf - start);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the MACsec controller COE line counter thresholds
|
||||
*
|
||||
* Algorithm: This is used to set threshold per VDMA Rx MACsec COE line counter
|
||||
*
|
||||
* @param[in] dev: Device data.
|
||||
* @param[in] attr: Device attribute
|
||||
* @param[in] buf: Buffer which contains the user settings of MACsec COE LC
|
||||
* @param[in] size: size of buffer
|
||||
*
|
||||
* @return size of buffer.
|
||||
*/
|
||||
static ssize_t macsec_coe_lc_store(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
struct net_device *ndev = (struct net_device *)dev_get_drvdata(dev);
|
||||
struct ether_priv_data *pdata = netdev_priv(ndev);
|
||||
struct macsec_priv_data *macsec_pdata = pdata->macsec_pdata;
|
||||
uint32_t ch, lc1, lc2;
|
||||
int ret = 0, i;
|
||||
|
||||
if (!netif_running(ndev)) {
|
||||
dev_err(pdata->dev, "Not Allowed. Ether interface is not up\n");
|
||||
return size;
|
||||
}
|
||||
if ((macsec_pdata == NULL)) {
|
||||
dev_err(pdata->dev, "Not Allowed. MACSec is not supported on this platform\n");
|
||||
return size;
|
||||
}
|
||||
if (macsec_pdata->enabled != OSI_ENABLE) {
|
||||
dev_err(pdata->dev, "Not Allowed. MACSec is not enabled on the controller\n");
|
||||
return size;
|
||||
}
|
||||
|
||||
/* Read user inputs and validate it */
|
||||
i = sscanf(buf, "%u %u %u", &ch, &lc1, &lc2);
|
||||
if (i != MACSEC_COE_LC_INPUT_LEN) {
|
||||
pr_err("%s: Invalid COE LC inputs(read %d)", __func__, i);
|
||||
return size;
|
||||
}
|
||||
if (ch >= OSI_MGBE_MAX_NUM_CHANS) {
|
||||
dev_err(pdata->dev, "Invalid value %u for channel\n", ch);
|
||||
return size;
|
||||
}
|
||||
if ((lc1 > OSI_MACSEC_COE_MAX_LC) || (lc2 > OSI_MACSEC_COE_MAX_LC)) {
|
||||
dev_err(pdata->dev, "Line counter threshold has to be < %x\n", OSI_MACSEC_COE_MAX_LC);
|
||||
return size;
|
||||
}
|
||||
|
||||
/* Configure COE LC threshold */
|
||||
ret = macsec_coe_lc(macsec_pdata, ch, lc1, lc2);
|
||||
if (ret != 0) {
|
||||
dev_err(pdata->dev, "Line counter threshold config failed\n");
|
||||
} else {
|
||||
macsec_pdata->coe.lc1_threshold[ch] = lc1;
|
||||
macsec_pdata->coe.lc2_threshold[ch] = lc2;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sysfs attribute for MACsec COE LC threshold
|
||||
*
|
||||
*/
|
||||
static DEVICE_ATTR(macsec_coe_lc, (S_IRUGO | S_IWUSR),
|
||||
macsec_coe_lc_show,
|
||||
macsec_coe_lc_store);
|
||||
|
||||
/**
|
||||
* @brief Shows the current setting of MACsec cipther set
|
||||
*
|
||||
@@ -1726,6 +2056,162 @@ static DEVICE_ATTR(macsec_sci_lut, (S_IRUGO | S_IWUSR),
|
||||
NULL,
|
||||
macsec_sci_lut_store);
|
||||
|
||||
/**
|
||||
* @brief Shows the current COE LUT configuration
|
||||
*
|
||||
* @param[in] dev: Device data.
|
||||
* @param[in] attr: Device attribute
|
||||
* @param[in] buf: Buffer to print the current COE LUT configuration
|
||||
*/
|
||||
static ssize_t macsec_coe_lut_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct net_device *ndev = (struct net_device *)dev_get_drvdata(dev);
|
||||
struct ether_priv_data *pdata = netdev_priv(ndev);
|
||||
struct macsec_priv_data *macsec_pdata = pdata->macsec_pdata;
|
||||
struct osi_core_priv_data *osi_core = pdata->osi_core;
|
||||
struct osi_macsec_lut_config lut_config = {0};
|
||||
struct osi_coe_lut_inout coe_lut_inout = {0};
|
||||
int i;
|
||||
char *start = buf;
|
||||
|
||||
if (!netif_running(ndev)) {
|
||||
dev_err(pdata->dev, "Not Allowed. Ether interface is not up\n");
|
||||
return 0;
|
||||
}
|
||||
if (!macsec_pdata) {
|
||||
dev_err(pdata->dev, "Not Allowed. MACsec is not supported in platform\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < OSI_COE_LUT_MAX_INDEX; i++) {
|
||||
memset(&lut_config, OSI_NONE, sizeof(lut_config));
|
||||
lut_config.table_config.ctlr_sel = OSI_CTLR_SEL_RX;
|
||||
lut_config.lut_sel = OSI_LUT_SEL_COE;
|
||||
lut_config.table_config.rw = OSI_LUT_READ;
|
||||
lut_config.table_config.index = i;
|
||||
if (osi_macsec_config_lut(osi_core, &lut_config) < 0) {
|
||||
dev_err(dev, "%s: Failed to read COE LUT\n", __func__);
|
||||
goto exit;
|
||||
} else {
|
||||
buf += scnprintf(buf, PAGE_SIZE, "%d.\t", i);
|
||||
if (lut_config.coe_lut_inout.valid != OSI_COE_LUT_ENTRY_VALID) {
|
||||
buf += scnprintf(buf, PAGE_SIZE, "Invalid\n");
|
||||
continue;
|
||||
}
|
||||
coe_lut_inout = lut_config.coe_lut_inout;
|
||||
/* HW design expects offset to be divided by 2.
|
||||
* So multiply for actual byte offset.
|
||||
*/
|
||||
buf += scnprintf(buf, PAGE_SIZE, "Offset: %u ",
|
||||
coe_lut_inout.offset * 2);
|
||||
buf += scnprintf(buf, PAGE_SIZE, "Mask: %#x ",
|
||||
coe_lut_inout.byte_pattern_mask);
|
||||
buf += scnprintf(buf, PAGE_SIZE, "Pattern: 0x%x%x\n",
|
||||
coe_lut_inout.byte_pattern[1],
|
||||
coe_lut_inout.byte_pattern[0]);
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
return (buf - start);
|
||||
}
|
||||
|
||||
#define COE_LUT_INPUTS 5
|
||||
|
||||
/**
|
||||
* @brief Set the COE LUT configuration
|
||||
*
|
||||
* @param[in] dev: Device data.
|
||||
* @param[in] attr: Device attribute
|
||||
* @param[in] buf: Buffer which contains the desired LUT configuration
|
||||
* @param[in] size: size of buffer
|
||||
*
|
||||
* @return size of buffer.
|
||||
*/
|
||||
static ssize_t macsec_coe_lut_store(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
struct net_device *ndev = (struct net_device *)dev_get_drvdata(dev);
|
||||
struct ether_priv_data *pdata = netdev_priv(ndev);
|
||||
struct macsec_priv_data *macsec_pdata = pdata->macsec_pdata;
|
||||
struct osi_core_priv_data *osi_core = pdata->osi_core;
|
||||
struct osi_macsec_lut_config lut_config;
|
||||
int ret, temp[OSI_COE_LUT_BYTE_PATTERN_MAX];
|
||||
int i;
|
||||
|
||||
if (!netif_running(ndev)) {
|
||||
dev_err(pdata->dev, "Not Allowed. Ether interface is not up\n");
|
||||
return size;
|
||||
}
|
||||
if (!macsec_pdata) {
|
||||
dev_err(pdata->dev, "Not Allowed. MACsec is not supported on platform\n");
|
||||
return size;
|
||||
}
|
||||
|
||||
memset(&lut_config, 0, sizeof(lut_config));
|
||||
lut_config.table_config.ctlr_sel = OSI_CTLR_SEL_RX;
|
||||
|
||||
ret = sscanf(buf, "%hu %u %x %x%x",
|
||||
&lut_config.table_config.index,
|
||||
&lut_config.coe_lut_inout.offset,
|
||||
&lut_config.coe_lut_inout.byte_pattern_mask,
|
||||
&temp[1],
|
||||
&temp[0]);
|
||||
if (ret != COE_LUT_INPUTS) {
|
||||
dev_err(pdata->dev, "Failed to parse COE LUT arguments");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (lut_config.coe_lut_inout.offset % 2 != 0) {
|
||||
dev_err(pdata->dev, "Offset field is not multiple of 2");
|
||||
goto exit;
|
||||
} else {
|
||||
/* HW is expecting offset to be divided by 2 */
|
||||
lut_config.coe_lut_inout.offset /= 2;
|
||||
}
|
||||
|
||||
for (i = OSI_COE_LUT_BYTE_PATTERN_MAX - 1; i >= 0; i--) {
|
||||
if (temp[i] > 0xFF) {
|
||||
dev_err(pdata->dev, "Invalid byte pattern %d\n", temp[i]);
|
||||
}
|
||||
lut_config.coe_lut_inout.byte_pattern[i] = (unsigned char)temp[i];
|
||||
}
|
||||
lut_config.lut_sel = OSI_LUT_SEL_COE;
|
||||
lut_config.table_config.rw = OSI_LUT_WRITE;
|
||||
/* Rest of LUT attributes are filled by parse_inputs() */
|
||||
if (lut_config.table_config.index >= OSI_COE_LUT_MAX_INDEX) {
|
||||
dev_err(dev, "%s: Index can't be >= %d\n", __func__,
|
||||
OSI_COE_LUT_MAX_INDEX);
|
||||
goto exit;
|
||||
}
|
||||
if (lut_config.coe_lut_inout.offset > OSI_COE_LUT_OFFSET_MAX) {
|
||||
dev_err(dev, "%s: COE offset can't be > %d\n", __func__,
|
||||
OSI_COE_LUT_MAX_INDEX);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (osi_macsec_config_lut(osi_core, &lut_config) < 0) {
|
||||
dev_err(dev, "%s: Failed to config COE LUT\n", __func__);
|
||||
goto exit;
|
||||
} else {
|
||||
dev_err(dev, "%s: Added COE LUT idx: %d", __func__,
|
||||
lut_config.table_config.index);
|
||||
}
|
||||
|
||||
exit:
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sysfs attribute for MACsec COE LUT config
|
||||
*
|
||||
*/
|
||||
static DEVICE_ATTR(macsec_coe_lut, (S_IRUGO | S_IWUSR),
|
||||
macsec_coe_lut_show,
|
||||
macsec_coe_lut_store);
|
||||
|
||||
#ifdef MACSEC_KEY_PROGRAM
|
||||
static void dump_kt(char **buf_p, unsigned short ctlr_sel,
|
||||
struct osi_core_priv_data *osi_core,
|
||||
@@ -3487,6 +3973,7 @@ static DEVICE_ATTR(hsi_enable, 0644,
|
||||
#endif
|
||||
#endif /* OSI_STRIPPED_LIB */
|
||||
|
||||
|
||||
/**
|
||||
* @brief Attributes for nvethernet sysfs
|
||||
*/
|
||||
@@ -3529,6 +4016,10 @@ static struct attribute *ether_sysfs_attrs[] = {
|
||||
&dev_attr_macsec_sc_param_rx_lut.attr,
|
||||
&dev_attr_macsec_cipher.attr,
|
||||
&dev_attr_macsec_enable.attr,
|
||||
&dev_attr_macsec_coe_enable.attr,
|
||||
&dev_attr_macsec_coe_lc.attr,
|
||||
&dev_attr_macsec_coe_lut.attr,
|
||||
&dev_attr_mac_coe_enable.attr,
|
||||
&dev_attr_macsec_an_status.attr,
|
||||
&dev_attr_macsec_mmc_counters_tx.attr,
|
||||
&dev_attr_macsec_mmc_counters_rx.attr,
|
||||
|
||||
101
include/media/fusa-capture/capture-coe.h
Normal file
101
include/media/fusa-capture/capture-coe.h
Normal file
@@ -0,0 +1,101 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/* SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES.
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*/
|
||||
|
||||
#ifndef __FUSA_CAPTURE_COE_H__
|
||||
#define __FUSA_CAPTURE_COE_H__
|
||||
|
||||
#if defined(__KERNEL__)
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/types.h>
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
#include <linux/ioctl.h>
|
||||
#include <linux/if_ether.h>
|
||||
#include <linux/if.h>
|
||||
|
||||
#define __COE_CAPTURE_ALIGN __aligned(8)
|
||||
|
||||
/**
|
||||
* @brief CoE channel setup config (COE_IOCTL_CAPTURE_SETUP payload).
|
||||
*
|
||||
*/
|
||||
struct coe_ioctl_data_capture_setup {
|
||||
char if_name[IFNAMSIZ]; /**< Net interface through which the camera is accessible */
|
||||
int32_t scratchBufMem; /**< Memory handle of a scratch buffer allocated by a user */
|
||||
uint8_t sensor_mac_addr[ETH_ALEN]; /**< Ethernet MAC address of a camera */
|
||||
uint8_t vlan_enable; /**< VLAN enable value. 1 - VLAN enabled, 0 - VLAN disabled */
|
||||
uint8_t reserved[1U];
|
||||
} __COE_CAPTURE_ALIGN;
|
||||
|
||||
/**
|
||||
* @brief CoE channel buffer operation (COE_IOCTL_BUFFER_OP payload).
|
||||
*/
|
||||
struct coe_ioctl_data_buffer_op {
|
||||
uint32_t mem; /**< handle to a buffer. */
|
||||
uint32_t flag; /**< Buffer @ref CAPTURE_BUFFER_OPS bitmask. */
|
||||
} __COE_CAPTURE_ALIGN;
|
||||
|
||||
/**
|
||||
* @brief Enqueue CoE capture request (COE_IOCTL_CAPTURE_REQ payload).
|
||||
*
|
||||
* Issue a capture request using a specified buffer mem_fd.
|
||||
* A buffer must previously have been registered with COE_IOCTL_BUFFER_OP.
|
||||
* mem_fd_offset specifies the offset from the beginning of the buffer memory from which
|
||||
* data should be received into. It can be used if an application makes a single large
|
||||
* allocation for all image memory, and then specifies separate offset within it for each
|
||||
* capture.
|
||||
* capture_number is used to track the capture number in userspace. The same capture_number
|
||||
* is returned by the driver in coe_ioctl_data_capture_status when capture is completed.
|
||||
*/
|
||||
struct coe_ioctl_data_capture_req {
|
||||
uint32_t mem_fd; /**< handle to a buffer. */
|
||||
uint32_t buf_size; /**< capture image size in bytes */
|
||||
uint32_t mem_fd_offset; /**< offset from the beginning of a mem_fd */
|
||||
uint32_t capture_number; /**< capture number for a tracking by userspace */
|
||||
} __COE_CAPTURE_ALIGN;
|
||||
|
||||
/**
|
||||
* @brief Wait on the next completion of an enqueued frame (COE_IOCTL_CAPTURE_STATUS payload).
|
||||
*
|
||||
* Wait for the next capture completion with the specified timeout.
|
||||
* The status of the capture will be returned via capture_status.
|
||||
*
|
||||
* @param[in] timeout_ms uint32_t timeout in [ms], 0 for indefinite wait.
|
||||
* @param[out] capture_number uint32_t capture number for which the status is returned.
|
||||
* @param[out] capture_status uint32_t capture status, Valid range: [ @ref CAPTURE_STATUS_UNKNOWN,
|
||||
* @ref CAPTURE_STATUS_INVALID_CAP_SETTINGS]
|
||||
* @param[out] errData uint32_t extended error data.
|
||||
* @param[out] sofTimestamp uint64_t start-of-frame time stamp in nanoseconds.
|
||||
* @param[out] eofTimestamp uint64_t end-of-frame time stamp in nanoseconds.
|
||||
*/
|
||||
struct coe_ioctl_data_capture_status {
|
||||
uint32_t timeout_ms; /**< Capture timeout in milliseconds. */
|
||||
uint32_t capture_number; /**< capture number passed with coe_ioctl_data_capture_req */
|
||||
uint32_t capture_status; /**< Capture status returned by the driver. */
|
||||
uint32_t errData; /**< Extended error data. */
|
||||
uint64_t sofTimestamp; /**< Start-of-frame time stamp in nanoseconds. */
|
||||
uint64_t eofTimestamp; /**< End-of-frame time stamp in nanoseconds. */
|
||||
} __COE_CAPTURE_ALIGN;
|
||||
|
||||
/**
|
||||
* @brief Get info on CoE channel (COE_IOCTL_GET_INFO payload).
|
||||
*/
|
||||
struct coe_ioctl_data_get_info {
|
||||
uint8_t channel_number; /**< channel number value assigned by a driver */
|
||||
uint8_t reserved[7U];
|
||||
} __COE_CAPTURE_ALIGN;
|
||||
|
||||
#endif /* __FUSA_CAPTURE_COE_H__ */
|
||||
@@ -1,6 +1,16 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2016-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/* SPDX-FileCopyrightText: Copyright (c) 2016-2025 NVIDIA CORPORATION & AFFILIATES.
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -121,12 +131,14 @@ struct CAPTURE_MSG_HEADER {
|
||||
#define CAPTURE_CHANNEL_SETUP_REQ MK_U32(0x1E)
|
||||
|
||||
/**
|
||||
* @brief VI capture channel setup response.
|
||||
* @brief VI or CoE capture channel setup response.
|
||||
*
|
||||
* This is a @ref CapCtrlMsgType "capture control message" received in
|
||||
* response to a @ref CAPTURE_CHANNEL_SETUP_REQ message.
|
||||
* response to a @ref CAPTURE_CHANNEL_SETUP_REQ or @ref CAPTURE_COE_CHANNEL_SETUP_REQ
|
||||
* message.
|
||||
*
|
||||
* @pre A @ref CAPTURE_CHANNEL_SETUP_REQ message has been sent.
|
||||
* @pre A @ref CAPTURE_CHANNEL_SETUP_REQ or @ref CAPTURE_COE_CHANNEL_SETUP_REQ message
|
||||
* has been sent.
|
||||
*
|
||||
* @par Header
|
||||
* - @ref CAPTURE_CONTROL_MSG@b::@ref CAPTURE_MSG_HEADER "header"
|
||||
@@ -252,6 +264,130 @@ struct CAPTURE_MSG_HEADER {
|
||||
#define CAPTURE_SYNCGEN_DISABLE_RESP MK_U32(0x1D)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @defgroup CoeCapCtrlMsgType Message types for CoE capture channel control messages
|
||||
*
|
||||
* Capture channel control messages are used to set up, reset, and release
|
||||
* channels for capturing images from an Ethernet imaging stream source, as well as
|
||||
* execute other control operations on the CoE capture channel.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief CoE capture channel setup request.
|
||||
*
|
||||
* This is a "capture control message" to allocate a CoE capture channel and
|
||||
* associated resources.
|
||||
*
|
||||
* @pre The capture-control IVC channel has been set up during
|
||||
* boot using the @ref CAMRTC_HSP_CH_SETUP command.
|
||||
*
|
||||
* @par Header
|
||||
* - @ref CAPTURE_CONTROL_MSG@b::@ref CAPTURE_MSG_HEADER "header"
|
||||
* - @ref CAPTURE_MSG_HEADER::msg_id "msg_id" = @ref CAPTURE_COE_CHANNEL_SETUP_REQ
|
||||
* - @ref CAPTURE_MSG_HEADER::transaction "transaction" = <em>unique ID</em>
|
||||
*
|
||||
* @par Payload
|
||||
* - @ref CAPTURE_COE_CHANNEL_SETUP_REQ_MSG
|
||||
*
|
||||
* @par Response
|
||||
* - @ref CAPTURE_CHANNEL_SETUP_RESP
|
||||
*/
|
||||
#define CAPTURE_COE_CHANNEL_SETUP_REQ MK_U32(0x1F)
|
||||
|
||||
/**
|
||||
* @brief CoE capture channel reset request.
|
||||
*
|
||||
* This is a @ref CapCtrlMsgType "capture control message" to
|
||||
* reset a CoE capture channel.
|
||||
*
|
||||
* When RCE FW receives the @ref CAPTURE_COE_CHANNEL_RESET_REQ message, it
|
||||
* will cancel all capture requests in the channel queue. The response is sent
|
||||
* after the RCE side channel cleanup is complete.
|
||||
*
|
||||
* @pre A CoE capture channel has been set up with
|
||||
* @ref CAPTURE_COE_CHANNEL_SETUP_REQ.
|
||||
*
|
||||
* @par Header
|
||||
* - @ref CAPTURE_CONTROL_MSG@b::@ref CAPTURE_MSG_HEADER "header"
|
||||
* - @ref CAPTURE_MSG_HEADER::msg_id "msg_id" = @ref CAPTURE_COE_CHANNEL_RESET_REQ
|
||||
* - @ref CAPTURE_MSG_HEADER::channel_id "channel_id" =
|
||||
* @ref CAPTURE_COE_CHANNEL_SETUP_RESP_MSG@b::@ref CAPTURE_MSG_HEADER "header"@b::@ref CAPTURE_MSG_HEADER::channel_id "channel_id"
|
||||
*
|
||||
* @par Payload
|
||||
* - @ref CAPTURE_COE_CHANNEL_RESET_REQ_MSG
|
||||
*
|
||||
* @par Response
|
||||
* - @ref CAPTURE_COE_CHANNEL_RESET_RESP
|
||||
*/
|
||||
#define CAPTURE_COE_CHANNEL_RESET_REQ MK_U32(0x26)
|
||||
|
||||
/**
|
||||
* @brief CoE capture channel reset response.
|
||||
*
|
||||
* This is a @ref CapCtrlMsgType "capture control message" received in
|
||||
* response to a @ref CAPTURE_COE_CHANNEL_RESET_REQ message.
|
||||
*
|
||||
* @pre A @ref CAPTURE_COE_CHANNEL_RESET_REQ message has been sent to the
|
||||
* logical channel.
|
||||
*
|
||||
* @par Header
|
||||
* - @ref CAPTURE_CONTROL_MSG@b::@ref CAPTURE_MSG_HEADER "header"
|
||||
* - @ref CAPTURE_MSG_HEADER::msg_id "msg_id" = @ref CAPTURE_COE_CHANNEL_RESET_RESP
|
||||
* - @ref CAPTURE_MSG_HEADER::channel_id "channel_id" =
|
||||
* @ref CAPTURE_COE_CHANNEL_RESET_REQ_MSG@b::@ref CAPTURE_MSG_HEADER "header"@b::@ref CAPTURE_MSG_HEADER::channel_id "channel_id"
|
||||
*
|
||||
* @par Payload
|
||||
* - @ref CAPTURE_COE_CHANNEL_RESET_RESP_MSG
|
||||
*/
|
||||
#define CAPTURE_COE_CHANNEL_RESET_RESP MK_U32(0x27)
|
||||
|
||||
/**
|
||||
* @brief CoE capture channel release request.
|
||||
*
|
||||
* This is a @ref CapCtrlMsgType "capture control message" to
|
||||
* release a CoE capture channel. Cancels all pending capture
|
||||
* requests.
|
||||
*
|
||||
* @pre A CoE capture channel has been set up with
|
||||
* @ref CAPTURE_COE_CHANNEL_SETUP_REQ.
|
||||
*
|
||||
* @par Header
|
||||
* - @ref CAPTURE_CONTROL_MSG@b::@ref CAPTURE_MSG_HEADER "header"
|
||||
* - @ref CAPTURE_MSG_HEADER::msg_id "msg_id" = @ref CAPTURE_COE_CHANNEL_RELEASE_REQ
|
||||
* - @ref CAPTURE_MSG_HEADER::channel_id "channel_id" =
|
||||
* @ref CAPTURE_COE_CHANNEL_SETUP_RESP_MSG@b::@ref CAPTURE_MSG_HEADER "header"@b::@ref CAPTURE_MSG_HEADER::channel_id "channel_id"
|
||||
*
|
||||
* @par Payload
|
||||
* - @ref CAPTURE_COE_CHANNEL_RELEASE_REQ_MSG
|
||||
*
|
||||
* @par Response
|
||||
* - @ref CAPTURE_COE_CHANNEL_RELEASE_RESP
|
||||
*/
|
||||
#define CAPTURE_COE_CHANNEL_RELEASE_REQ MK_U32(0x28)
|
||||
|
||||
/**
|
||||
* @brief CoE capture channel release response.
|
||||
*
|
||||
* This is a @ref CapCtrlMsgType "capture control message" received in
|
||||
* response to a @ref CAPTURE_COE_CHANNEL_RELEASE_REQ message.
|
||||
*
|
||||
* @pre A @ref CAPTURE_COE_CHANNEL_RELEASE_REQ message has been sent to the
|
||||
* logical channel.
|
||||
*
|
||||
* @par Header
|
||||
* - @ref CAPTURE_CONTROL_MSG@b::@ref CAPTURE_MSG_HEADER "header"
|
||||
* - @ref CAPTURE_MSG_HEADER::msg_id "msg_id" = @ref CAPTURE_COE_CHANNEL_RELEASE_RESP
|
||||
* - @ref CAPTURE_MSG_HEADER::channel_id "channel_id" =
|
||||
* @ref CAPTURE_COE_CHANNEL_RELEASE_REQ_MSG@b::@ref CAPTURE_MSG_HEADER "header"@b::@ref CAPTURE_MSG_HEADER::channel_id "channel_id"
|
||||
*
|
||||
* @par Payload
|
||||
* - @ref CAPTURE_COE_CHANNEL_RELEASE_RESP_MSG
|
||||
*/
|
||||
#define CAPTURE_COE_CHANNEL_RELEASE_RESP MK_U32(0x29)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @defgroup IspCapCtrlMsgType Message types for ISP capture-control IVC channel messages.
|
||||
* @{
|
||||
@@ -760,6 +896,66 @@ struct CAPTURE_MSG_HEADER {
|
||||
/** @} */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @defgroup CoeCapMsgType Message types for CoE capture request messages and indications.
|
||||
*
|
||||
* Capture channel messages are used to submit capture requests and to
|
||||
* receive status indications pertaining to submitted requests.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Submit a new capture request on a CoE capture channel.
|
||||
*
|
||||
* This is a @ref CapMsgType "capture channel message" to
|
||||
* submit a CoE capture request. The capture request provides all the information
|
||||
* needed to submit a capture request to the Ethernet engine, like DMA address of the buffer,
|
||||
* buffer size, etc.
|
||||
*
|
||||
* The capture request is sent asynchronously and is queued by RCE for execution.
|
||||
* Status of the request is indicated with @ref CAPTURE_COE_STATUS_IND message.
|
||||
*
|
||||
* @pre A CoE capture channel has been set up with
|
||||
* @ref CAPTURE_COE_CHANNEL_SETUP_REQ.
|
||||
*
|
||||
* @par Header
|
||||
* - @ref CAPTURE_MSG@b::@ref CAPTURE_MSG_HEADER "header"
|
||||
* - @ref CAPTURE_MSG_HEADER::msg_id "msg_id" = @ref CAPTURE_COE_REQUEST
|
||||
* - @ref CAPTURE_MSG_HEADER::channel_id "channel_id" =
|
||||
* @ref CAPTURE_CHANNEL_SETUP_RESP_MSG@b::@ref CAPTURE_MSG_HEADER
|
||||
* "header"@b::@ref CAPTURE_MSG_HEADER::channel_id "channel_id"
|
||||
*
|
||||
* @par Payload
|
||||
* - @ref CAPTURE_COE_REQUEST_MSG
|
||||
*
|
||||
* @par Response
|
||||
* - @ref CAPTURE_COE_STATUS_IND (asynchronous)
|
||||
*/
|
||||
#define CAPTURE_COE_REQUEST MK_U32(0x0A)
|
||||
|
||||
/**
|
||||
* @brief Capture status indication for CoE capture channel.
|
||||
*
|
||||
* This is a @ref CapMsgType "capture channel message"
|
||||
* received in response to a @ref CAPTURE_COE_REQUEST message
|
||||
* when the capture request has been completed.
|
||||
* It is sent asynchronously whenever capture request completion is signalled by a HW.
|
||||
*
|
||||
* @pre A @ref CAPTURE_COE_REQUEST has been sent.
|
||||
*
|
||||
* @par Header
|
||||
* - @ref CAPTURE_MSG@b::@ref CAPTURE_MSG_HEADER "header"
|
||||
* - @ref CAPTURE_MSG_HEADER::msg_id "msg_id" = @ref CAPTURE_COE_STATUS_IND
|
||||
* - @ref CAPTURE_MSG_HEADER::channel_id "channel_id" =
|
||||
* @ref CAPTURE_COE_REQUEST_MSG@b::@ref CAPTURE_MSG_HEADER "header"@b::@ref CAPTURE_MSG_HEADER::channel_id "channel_id"
|
||||
*
|
||||
* @par Payload
|
||||
* - @ref CAPTURE_COE_STATUS_IND_MSG
|
||||
*/
|
||||
#define CAPTURE_COE_STATUS_IND MK_U32(0x0B)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Invalid message type. This can be used to respond to an invalid request.
|
||||
*/
|
||||
@@ -818,6 +1014,22 @@ struct CAPTURE_CHANNEL_SETUP_RESP_MSG {
|
||||
uint64_t vi_channel_mask;
|
||||
} CAPTURE_IVC_ALIGN;
|
||||
|
||||
/** @brief Message data for @ref CAPTURE_COE_CHANNEL_SETUP_REQ message */
|
||||
struct CAPTURE_COE_CHANNEL_SETUP_REQ_MSG {
|
||||
/** Capture channel configuration. */
|
||||
struct capture_coe_channel_config channel_config;
|
||||
} CAPTURE_IVC_ALIGN;
|
||||
|
||||
/** @brief Message data for @ref CAPTURE_COE_REQUEST message. */
|
||||
struct CAPTURE_COE_REQUEST_MSG {
|
||||
/** Index of the buffer to be captured, for tacking by KMD. */
|
||||
uint32_t buffer_index;
|
||||
/** Length of the buffer to be captured. */
|
||||
uint32_t buf_len;
|
||||
/** DMA address of the buffer to be captured. */
|
||||
iova_t buf_mgbe_iova;
|
||||
} CAPTURE_IVC_ALIGN;
|
||||
|
||||
/**
|
||||
* @defgroup CapResetFlags VI Capture channel reset flags
|
||||
* @{
|
||||
@@ -844,6 +1056,42 @@ struct CAPTURE_CHANNEL_RESET_RESP_MSG {
|
||||
uint32_t pad__;
|
||||
} CAPTURE_IVC_ALIGN;
|
||||
|
||||
/** @brief Message data for @ref CAPTURE_CHANNEL_RESET_REQ message */
|
||||
struct CAPTURE_COE_CHANNEL_RESET_REQ_MSG {
|
||||
/** Placeholder. Unused */
|
||||
uint32_t reset_flags;
|
||||
|
||||
/** Reserved */
|
||||
uint32_t pad__;
|
||||
} CAPTURE_IVC_ALIGN;
|
||||
|
||||
/** @brief Message data for @ref CAPTURE_CHANNEL_RESET_RESP message */
|
||||
struct CAPTURE_COE_CHANNEL_RESET_RESP_MSG {
|
||||
/** Request result code. See @ref CapErrorCodes "result codes". */
|
||||
capture_result result;
|
||||
|
||||
/** Reserved */
|
||||
uint32_t pad__;
|
||||
} CAPTURE_IVC_ALIGN;
|
||||
|
||||
/** @brief Message data for @ref CAPTURE_CHANNEL_RELEASE_REQ message */
|
||||
struct CAPTURE_COE_CHANNEL_RELEASE_REQ_MSG {
|
||||
/** Placeholder. Unused */
|
||||
uint32_t reset_flags;
|
||||
|
||||
/** Reserved */
|
||||
uint32_t pad__;
|
||||
} CAPTURE_IVC_ALIGN;
|
||||
|
||||
/** @brief Message data for @ref CAPTURE_CHANNEL_RELEASE_RESP message */
|
||||
struct CAPTURE_COE_CHANNEL_RELEASE_RESP_MSG {
|
||||
/** Request result code. See @ref CapErrorCodes "result codes". */
|
||||
capture_result result;
|
||||
|
||||
/** Reserved */
|
||||
uint32_t pad__;
|
||||
} CAPTURE_IVC_ALIGN;
|
||||
|
||||
/** @brief Message data for @ref CAPTURE_CHANNEL_RELEASE_REQ message */
|
||||
struct CAPTURE_CHANNEL_RELEASE_REQ_MSG {
|
||||
/** Unused */
|
||||
@@ -1740,12 +1988,27 @@ struct CAPTURE_CONTROL_MSG {
|
||||
/** Message data for @ref CAPTURE_CHANNEL_SETUP_RESP message */
|
||||
struct CAPTURE_CHANNEL_SETUP_RESP_MSG channel_setup_resp;
|
||||
/** @anon_union_member */
|
||||
/** Message data for @ref CAPTURE_COE_CHANNEL_SETUP_RESP message */
|
||||
struct CAPTURE_COE_CHANNEL_SETUP_REQ_MSG channel_coe_setup_req;
|
||||
/** @anon_union_member */
|
||||
/** Message data for @ref CAPTURE_CHANNEL_RESET_REQ message */
|
||||
struct CAPTURE_CHANNEL_RESET_REQ_MSG channel_reset_req;
|
||||
/** @anon_union_member */
|
||||
/** Message data for @ref CAPTURE_CHANNEL_RESET_RESP message */
|
||||
struct CAPTURE_CHANNEL_RESET_RESP_MSG channel_reset_resp;
|
||||
/** @anon_union_member */
|
||||
/** Message data for @ref CAPTURE_COE_CHANNEL_RESET_REQ message */
|
||||
struct CAPTURE_COE_CHANNEL_RESET_REQ_MSG channel_coe_reset_req;
|
||||
/** @anon_union_member */
|
||||
/** Message data for @ref CAPTURE_COE_CHANNEL_RESET_RESP message */
|
||||
struct CAPTURE_COE_CHANNEL_RESET_RESP_MSG channel_coe_reset_resp;
|
||||
/** @anon_union_member */
|
||||
/** Message data for @ref CAPTURE_COE_CHANNEL_RELEASE_REQ message */
|
||||
struct CAPTURE_COE_CHANNEL_RELEASE_REQ_MSG channel_coe_release_req;
|
||||
/** @anon_union_member */
|
||||
/** Message data for @ref CAPTURE_COE_CHANNEL_RELEASE_RESP message */
|
||||
struct CAPTURE_COE_CHANNEL_RELEASE_RESP_MSG channel_coe_release_resp;
|
||||
/** @anon_union_member */
|
||||
/** Message data for @ref CAPTURE_CHANNEL_RELEASE_REQ message */
|
||||
struct CAPTURE_CHANNEL_RELEASE_REQ_MSG channel_release_req;
|
||||
/** @anon_union_member */
|
||||
@@ -1923,6 +2186,54 @@ struct CAPTURE_STATUS_IND_MSG {
|
||||
uint32_t pad__;
|
||||
} CAPTURE_IVC_ALIGN;
|
||||
|
||||
/** @brief Message data for @ref CAPTURE_COE_STATUS_IND message. */
|
||||
struct CAPTURE_COE_STATUS_IND_MSG {
|
||||
/**
|
||||
* Buffer index to match against capture request to which
|
||||
* this completion corresponds to.
|
||||
*/
|
||||
uint32_t buffer_index;
|
||||
/**
|
||||
* CoE capture error indicating some Ethernet packets carrying image data were lost.
|
||||
*/
|
||||
#define CAPTURE_STATUS_COE_PACKET_LOSS MK_U32(2)
|
||||
|
||||
/**
|
||||
* CoE capture error indicating Start Of Frame packet was never received.
|
||||
*/
|
||||
#define CAPTURE_STATUS_COE_SOF_MISSED MK_U32(3)
|
||||
|
||||
/**
|
||||
* CoE capture error indicating a frame with an unexpected sequence number was received.
|
||||
* Could be caused by losing EOF packet as an example.
|
||||
*/
|
||||
#define CAPTURE_STATUS_COE_DISCONTINUITY MK_U32(4)
|
||||
|
||||
/**
|
||||
* CoE capture error indicating SW has aborted the capture (did not wait for all
|
||||
* network packets carrying the frame data to be received).
|
||||
*/
|
||||
#define CAPTURE_STATUS_COE_ABORTED MK_U32(5)
|
||||
|
||||
/** Capture status to indicate to the host
|
||||
* Valid range: [ @ref CAPTURE_STATUS_UNKNOWN,
|
||||
* @ref CAPTURE_STATUS_SUCCESS,
|
||||
* @ref CAPTURE_STATUS_COE_*]
|
||||
*/
|
||||
uint32_t capture_status;
|
||||
|
||||
/**
|
||||
* Timestamp of the SOF event in nanoseconds.
|
||||
* Valid range: [0, UINT64_MAX].
|
||||
*/
|
||||
uint64_t timestamp_sof_ns;
|
||||
|
||||
/**
|
||||
* Timestamp of the EOF event in nanoseconds.
|
||||
* Valid range: [0, UINT64_MAX].
|
||||
*/
|
||||
uint64_t timestamp_eof_ns;
|
||||
} CAPTURE_IVC_ALIGN;
|
||||
|
||||
/** @brief Message data for @ref CAPTURE_ISP_REQUEST_REQ message. */
|
||||
struct CAPTURE_ISP_REQUEST_REQ_MSG {
|
||||
@@ -2020,7 +2331,11 @@ struct CAPTURE_MSG {
|
||||
/** @anon_union_member */
|
||||
struct CAPTURE_REQUEST_REQ_MSG capture_request_req;
|
||||
/** @anon_union_member */
|
||||
struct CAPTURE_COE_REQUEST_MSG capture_coe_req;
|
||||
/** @anon_union_member */
|
||||
struct CAPTURE_STATUS_IND_MSG capture_status_ind;
|
||||
/** @anon_union_member */
|
||||
struct CAPTURE_COE_STATUS_IND_MSG capture_coe_status_ind;
|
||||
|
||||
/** @anon_union_member */
|
||||
CAPTURE_ISP_REQUEST_REQ_MSG capture_isp_request_req;
|
||||
|
||||
@@ -1,6 +1,16 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2016-2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/* SPDX-FileCopyrightText: Copyright (c) 2016-2025 NVIDIA CORPORATION & AFFILIATES.
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -852,6 +862,95 @@ struct capture_channel_config {
|
||||
|
||||
} CAPTURE_IVC_ALIGN;
|
||||
|
||||
/** Length of Ethernet MAC address */
|
||||
#define COE_ETH_ALEN 6U
|
||||
|
||||
/**
|
||||
* @brief Describes RTCPU CoE resources for a capture pipe-line.
|
||||
*/
|
||||
struct capture_coe_channel_config {
|
||||
/**
|
||||
* Numerical instance ID of an ethernet controller for the channel
|
||||
*/
|
||||
uint32_t mgbe_instance_id;
|
||||
/**
|
||||
* Virtual DMA channel number for this capture channel
|
||||
*/
|
||||
uint16_t dma_chan;
|
||||
/**
|
||||
* Physical DMA which services the CoE channel
|
||||
*/
|
||||
uint16_t pdma_chan_id;
|
||||
/**
|
||||
* Hardware IRQ ID which will be asserted for events on that DMA channel
|
||||
*/
|
||||
uint16_t mgbe_irq_num;
|
||||
/**
|
||||
* Ethernet address of a camera module which will us the channel
|
||||
*/
|
||||
uint8_t mac_addr[COE_ETH_ALEN];
|
||||
/**
|
||||
* IOVA for RX descriptors for MGBE access
|
||||
*/
|
||||
iova_t rx_desc_ring_iova_mgbe;
|
||||
/**
|
||||
* IOVA for RX descriptors for RCE access
|
||||
*/
|
||||
iova_t rx_desc_ring_iova_rce;
|
||||
/**
|
||||
* IOVA for RX descriptors shadown ring for RCE access
|
||||
*/
|
||||
iova_t rx_desc_shdw_iova_rce;
|
||||
/**
|
||||
* Size of Rx descr ring buffer memory area
|
||||
*/
|
||||
uint64_t rx_desc_ring_mem_size;
|
||||
/**
|
||||
* IOVA for RX packet headers memory area for MGBE access
|
||||
*/
|
||||
iova_t rx_pkthdr_iova_mgbe;
|
||||
/**
|
||||
* Size of Rx packet headers memory area
|
||||
*/
|
||||
uint64_t rx_pkthdr_mem_size;
|
||||
/**
|
||||
* IOVA for RX Packet Info descriptors memory area for MGBE access
|
||||
*/
|
||||
iova_t rx_pktinfo_iova_mgbe;
|
||||
/**
|
||||
* IOVA for RX Packet Info descriptors memory area for RCE access
|
||||
*/
|
||||
iova_t rx_pktinfo_iova_rce;
|
||||
/**
|
||||
* Size of RX Packet Info descriptors memory area
|
||||
*/
|
||||
uint64_t rx_pktinfo_mem_size;
|
||||
/**
|
||||
* IOVA for RX scratch buffer memory area for MGBE access
|
||||
*/
|
||||
iova_t dummy_buf_dma;
|
||||
/**
|
||||
* Size of RX scratch buffer memory area
|
||||
*/
|
||||
uint64_t dummy_buf_dma_size;
|
||||
/**
|
||||
* IOVA for Rx descriptors memory area base address
|
||||
*/
|
||||
iova_t rxmem_base;
|
||||
/**
|
||||
* Size of RX descriptors memory area. Must be power of two.
|
||||
*/
|
||||
uint64_t rxmem_size;
|
||||
/**
|
||||
* VLAN enable value. 1 - VLAN enabled, 0 - VLAN disabled
|
||||
*/
|
||||
uint8_t vlan_enable;
|
||||
/**
|
||||
* Padding to make the structure size a multiple of 8 bytes
|
||||
*/
|
||||
uint8_t _padding[7];
|
||||
} CAPTURE_IVC_ALIGN;
|
||||
|
||||
/**
|
||||
* @defgroup ViDpcmModes VI DPCM Modes (non-safety)
|
||||
*/
|
||||
|
||||
74
include/soc/tegra/nvethernet-public.h
Normal file
74
include/soc/tegra/nvethernet-public.h
Normal file
@@ -0,0 +1,74 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/* SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES.
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*/
|
||||
#ifndef INCLUDE_NVETHERNET_PUBLIC_H
|
||||
#define INCLUDE_NVETHERNET_PUBLIC_H
|
||||
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#define COE_ENABLE 1U
|
||||
#define COE_MACSEC_HDR_OFFSET 42U
|
||||
#define COE_VLAN_ENABLE 1U
|
||||
#define COE_MACSEC_HDR_VLAN_DISABLE_OFFSET 38U
|
||||
#define COE_VLAN_DISABLE 0U
|
||||
#define COE_MACSEC_SFT_LC1 1024U
|
||||
#define COE_MACSEC_SFT_LC2 1024U
|
||||
|
||||
/* These need to be configured only once during the COE plat driver init */
|
||||
struct nvether_coe_cfg {
|
||||
/* Flag to track if COE is already configured */
|
||||
u32 coe_enable;
|
||||
/* System wide COE header offset to be used */
|
||||
u32 coe_hdr_offset;
|
||||
/* System wide config whether COE packets are VLAN tagged */
|
||||
u32 vlan_enable;
|
||||
};
|
||||
|
||||
/* These have to be provided for every COE stream added */
|
||||
struct nvether_per_coe_cfg {
|
||||
/* No. of lines in first subframes */
|
||||
u32 lc1;
|
||||
/* No. of lines in subsequent subframes */
|
||||
u32 lc2;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Configure COE in the macsec controller
|
||||
*
|
||||
* Configure the COE engine in the macsec controller for the
|
||||
* to a DMA channel specified by dma_chan.
|
||||
*
|
||||
* @param[in] ndev: Network device instance to be used for COE
|
||||
* @param[in] ether_coe_config: Struct that defines the system wide COE config.
|
||||
*
|
||||
* @retval value >=0 on success.
|
||||
* @retval "negative value" on failure.
|
||||
*/
|
||||
int nvether_coe_config(struct net_device *ndev,
|
||||
struct nvether_coe_cfg *ether_coe_cfg);
|
||||
|
||||
/**
|
||||
* @brief Configure CoE on a channel
|
||||
*
|
||||
* @param[in] ndev: Network device to operate on.
|
||||
* @param[in] dmachan: Tte dma channel to take ownership of.
|
||||
*
|
||||
* @retval value >=0 on success.
|
||||
* @retval "negative value" on failure.
|
||||
*/
|
||||
int nvether_coe_chan_config(struct net_device *ndev, u32 dmachan,
|
||||
struct nvether_per_coe_cfg *p_coe_cfg);
|
||||
|
||||
#endif /* INCLUDE_NVETHERNET_PUBLIC_H */
|
||||
Reference in New Issue
Block a user