Skip to content

Commit

Permalink
net: netcp: ethss: k2g: add promiscuous mode support
Browse files Browse the repository at this point in the history
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: WingMan Kwok <w-kwok2@ti.com>
Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
WingMan Kwok authored and David S. Miller committed Apr 19, 2018
1 parent 0542a87 commit 8585661
Showing 1 changed file with 56 additions and 0 deletions.
56 changes: 56 additions & 0 deletions drivers/net/ethernet/ti/netcp_ethss.c
Original file line number Diff line number Diff line change
Expand Up @@ -2775,6 +2775,61 @@ static inline int gbe_hwtstamp_set(struct gbe_intf *gbe_intf, struct ifreq *req)
}
#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)
{
struct gbe_intf *gbe_intf = intf_priv;
Expand Down Expand Up @@ -3529,6 +3584,7 @@ static int gbe_probe(struct netcp_device *netcp_device, struct device *dev,
gbe_dev->max_num_slaves = 8;
} else if (of_device_is_compatible(node, "ti,netcp-gbe-2")) {
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")) {
gbe_dev->max_num_slaves = 2;
} else {
Expand Down

0 comments on commit 8585661

Please sign in to comment.