Commit 8585661b authored by WingMan Kwok's avatar WingMan Kwok Committed by David S. Miller

net: netcp: ethss: k2g: add promiscuous mode support

This patch adds support for promiscuous mode in k2g's network
driver. When upper layer instructs to transition from
non-promiscuous mode to promiscuous mode or vice versa
K2G network driver needs to configure ALE accordingly
so that in case of non-promiscuous mode, ALE will not flood
all unicast packets to host port, while in promiscuous
mode, it will pass all received unicast packets to
host port.
Signed-off-by: default avatarWingMan Kwok <w-kwok2@ti.com>
Signed-off-by: default avatarMurali Karicheri <m-karicheri2@ti.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 0542a87c
...@@ -2775,6 +2775,61 @@ static inline int gbe_hwtstamp_set(struct gbe_intf *gbe_intf, struct ifreq *req) ...@@ -2775,6 +2775,61 @@ static inline int gbe_hwtstamp_set(struct gbe_intf *gbe_intf, struct ifreq *req)
} }
#endif /* CONFIG_TI_CPTS */ #endif /* CONFIG_TI_CPTS */
static int gbe_set_rx_mode(void *intf_priv, bool promisc)
{
struct gbe_intf *gbe_intf = intf_priv;
struct gbe_priv *gbe_dev = gbe_intf->gbe_dev;
struct cpsw_ale *ale = gbe_dev->ale;
unsigned long timeout;
int i, ret = -ETIMEDOUT;
/* Disable(1)/Enable(0) Learn for all ports (host is port 0 and
* slaves are port 1 and up
*/
for (i = 0; i <= gbe_dev->num_slaves; i++) {
cpsw_ale_control_set(ale, i,
ALE_PORT_NOLEARN, !!promisc);
cpsw_ale_control_set(ale, i,
ALE_PORT_NO_SA_UPDATE, !!promisc);
}
if (!promisc) {
/* Don't Flood All Unicast Packets to Host port */
cpsw_ale_control_set(ale, 0, ALE_P0_UNI_FLOOD, 0);
dev_vdbg(gbe_dev->dev, "promiscuous mode disabled\n");
return 0;
}
timeout = jiffies + HZ;
/* Clear All Untouched entries */
cpsw_ale_control_set(ale, 0, ALE_AGEOUT, 1);
do {
cpu_relax();
if (cpsw_ale_control_get(ale, 0, ALE_AGEOUT)) {
ret = 0;
break;
}
} while (time_after(timeout, jiffies));
/* Make sure it is not a false timeout */
if (ret && !cpsw_ale_control_get(ale, 0, ALE_AGEOUT))
return ret;
cpsw_ale_control_set(ale, 0, ALE_AGEOUT, 1);
/* Clear all mcast from ALE */
cpsw_ale_flush_multicast(ale,
GBE_PORT_MASK(gbe_dev->ale_ports),
-1);
/* Flood All Unicast Packets to Host port */
cpsw_ale_control_set(ale, 0, ALE_P0_UNI_FLOOD, 1);
dev_vdbg(gbe_dev->dev, "promiscuous mode enabled\n");
return ret;
}
static int gbe_ioctl(void *intf_priv, struct ifreq *req, int cmd) static int gbe_ioctl(void *intf_priv, struct ifreq *req, int cmd)
{ {
struct gbe_intf *gbe_intf = intf_priv; struct gbe_intf *gbe_intf = intf_priv;
...@@ -3529,6 +3584,7 @@ static int gbe_probe(struct netcp_device *netcp_device, struct device *dev, ...@@ -3529,6 +3584,7 @@ static int gbe_probe(struct netcp_device *netcp_device, struct device *dev,
gbe_dev->max_num_slaves = 8; gbe_dev->max_num_slaves = 8;
} else if (of_device_is_compatible(node, "ti,netcp-gbe-2")) { } else if (of_device_is_compatible(node, "ti,netcp-gbe-2")) {
gbe_dev->max_num_slaves = 1; gbe_dev->max_num_slaves = 1;
gbe_module.set_rx_mode = gbe_set_rx_mode;
} else if (of_device_is_compatible(node, "ti,netcp-xgbe")) { } else if (of_device_is_compatible(node, "ti,netcp-xgbe")) {
gbe_dev->max_num_slaves = 2; gbe_dev->max_num_slaves = 2;
} else { } else {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment