mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-24 10:11:26 +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
@@ -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++) {
|
||||
ether_set_vm_irq_chan_mask(&pdata->vm_irq_data[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,
|
||||
|
||||
Reference in New Issue
Block a user