nvethernet: Add Multiple DMA channels route

- Add a new DT node to enable Multiple DMA routing
for netdev MC MAC ddress. Read the DT value
and store it into OSI core private data.
- Add new driver private IOCTL for MC DMA channels
selection as inputs and call ether_set_rx_mode
to update MAC filters with given DMA channels route.

Bug 200565911

Change-Id: I1e65322489e34c4b6318a769dac963073d4887ad
Signed-off-by: Mohan Thadikamalla <mohant@nvidia.com>
This commit is contained in:
Mohan Thadikamalla
2020-03-27 16:06:57 +05:30
committed by Revanth Kumar Uppala
parent 65801ffa7b
commit 9f70a55384
4 changed files with 83 additions and 3 deletions

View File

@@ -2396,6 +2396,7 @@ static int ether_prepare_mc_list(struct net_device *dev,
filter->dma_chan = 0x0;
filter->addr_mask = OSI_AMASK_DISABLE;
filter->src_dest = OSI_DA_MATCH;
filter->dma_chansel = osi_core->mc_dmasel;
ret = osi_l2_filter(osi_core, filter);
if (ret < 0) {
dev_err(pdata->dev, "issue in creating mc list\n");
@@ -2513,7 +2514,7 @@ static int ether_prepare_uc_list(struct net_device *dev,
*
* @note MAC and PHY need to be initialized.
*/
static void ether_set_rx_mode(struct net_device *dev)
void ether_set_rx_mode(struct net_device *dev)
{
struct ether_priv_data *pdata = netdev_priv(dev);
struct osi_core_priv_data *osi_core = pdata->osi_core;
@@ -2576,6 +2577,7 @@ static void ether_set_rx_mode(struct net_device *dev)
filter.dma_chan = OSI_CHAN_ANY;
filter.addr_mask = OSI_AMASK_DISABLE;
filter.src_dest = OSI_DA_MATCH;
filter.dma_chansel = OSI_DISABLE;
ret = osi_l2_filter(osi_core, &filter);
if (ret < 0) {
dev_err(pdata->dev, "Invalidating expired L2 filter failed\n");
@@ -3898,7 +3900,7 @@ static int ether_parse_dt(struct ether_priv_data *pdata)
unsigned int tmp_value[OSI_MGBE_MAX_NUM_QUEUES];
struct device_node *np = dev->of_node;
int ret = -EINVAL;
unsigned int i, mtlq, chan;
unsigned int i, mtlq, chan, bitmap;
/* read ptp clock */
ret = of_property_read_u32(np, "nvidia,ptp_ref_clock_speed",
@@ -4115,6 +4117,33 @@ static int ether_parse_dt(struct ether_priv_data *pdata)
osi_core->dcs_en = OSI_DISABLE;
}
/* Read XDCS input for DMA channels route */
ret = of_property_read_u32(np, "nvidia,mc-dmasel",
&osi_core->mc_dmasel);
if (ret < 0) {
/* Disable Multiple DMA selection on DT read failure */
osi_core->mc_dmasel = osi_dma->dma_chans[0];
} else {
/* Validate MC DMA channel selection flags */
bitmap = osi_core->mc_dmasel;
while (bitmap != 0U) {
chan = __builtin_ctz(bitmap);
for (i = 0; i < osi_dma->num_dma_chans; i++) {
if (osi_dma->dma_chans[i] == chan) {
/* channel is enabled */
break;
}
}
if (i == osi_dma->num_dma_chans) {
/* Invalid MC DMA selection */
dev_err(dev, "Invalid %d MC DMA selection\n", chan);
osi_core->mc_dmasel = osi_dma->dma_chans[0];
break;
}
bitmap &= ~OSI_BIT(chan);
}
}
/* Read MAX MTU size supported */
ret = of_property_read_u32(np, "nvidia,max-platform-mtu",
&pdata->max_platform_mtu);

View File

@@ -516,7 +516,7 @@ void ether_assign_osd_ops(struct osi_core_priv_data *osi_core,
struct osi_dma_priv_data *osi_dma);
/**
* @brief osd_send_cmd - OSD ivc send cmd
* @brief osd_ivc_send_cmd - OSD ivc send cmd
*
* @param[in] priv: OSD private data
* @param[in] func: data
@@ -528,4 +528,5 @@ void ether_assign_osd_ops(struct osi_core_priv_data *osi_core,
* - De-initialization: Yes
*/
int osd_ivc_send_cmd(void *priv, void *data, unsigned int len);
void ether_set_rx_mode(struct net_device *dev);
#endif /* ETHER_LINUX_H */

View File

@@ -553,6 +553,52 @@ static int ether_config_vlan_filter(struct net_device *dev,
return ret;
}
/**
* @brief This function is invoked by ioctl function when user issues an ioctl
* command to configure multiple DMA routing for MC packets.
*
* @param[in] dev: Pointer to net device structure.
* @param[in] ifdata: Pointer to IOCTL specific structure.
*
* @note MAC and PHY need to be initialized.
*
* @retval 0 on Success
* @retval "negative value" on Failure
*/
static int ether_config_mc_dmasel(struct net_device *dev,
unsigned int flags)
{
struct ether_priv_data *pdata = netdev_priv(dev);
struct osi_core_priv_data *osi_core = pdata->osi_core;
struct osi_dma_priv_data *osi_dma = pdata->osi_dma;
unsigned int bitmap = 0U, i = 0U, chan = 0U;
/* Validate MC DMA channel selection flags */
bitmap = flags;
while (bitmap != 0U) {
chan = __builtin_ctz(bitmap);
for (i = 0; i < osi_dma->num_dma_chans; i++) {
if (osi_dma->dma_chans[i] == chan) {
/* channel is enabled */
break;
}
}
if (i == osi_dma->num_dma_chans) {
/* Invalid MC DMA selection */
dev_err(pdata->dev, "Invalid %d MC DMA selection\n", chan);
return -EINVAL;
}
bitmap &= ~OSI_BIT(chan);
}
/* Store flags into OSI core data */
osi_core->mc_dmasel = flags;
/* Set RX mode with latest flags */
ether_set_rx_mode(dev);
return 0;
}
/**
* @brief This function is invoked by ioctl function when user issues an ioctl
* command to configure L2 destination addressing filtering mode.
@@ -975,6 +1021,9 @@ int ether_handle_priv_ioctl(struct net_device *ndev,
case EQOS_L2_DA_FILTERING_CMD:
ret = ether_config_l2_da_filter(ndev, &ifdata);
break;
case ETHER_MC_DMA_ROUTE:
ret = ether_config_mc_dmasel(ndev, ifdata.if_flags);
break;
case ETHER_CONFIG_LOOPBACK_MODE:
ret = ether_config_loopback_mode(ndev, ifdata.if_flags);
break;

View File

@@ -60,6 +60,7 @@
#define ETHER_CONFIG_FPE 50
/* FRP Command */
#define ETHER_CONFIG_FRP_CMD 51
#define ETHER_MC_DMA_ROUTE 52
/** @} */
/**