Skip to content

Commit 8585661

Browse files
wingmankwokdavem330
authored andcommitted
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: WingMan Kwok <w-kwok2@ti.com> Signed-off-by: Murali Karicheri <m-karicheri2@ti.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 0542a87 commit 8585661

File tree

1 file changed

+56
-0
lines changed

1 file changed

+56
-0
lines changed

drivers/net/ethernet/ti/netcp_ethss.c

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2775,6 +2775,61 @@ static inline int gbe_hwtstamp_set(struct gbe_intf *gbe_intf, struct ifreq *req)
27752775
}
27762776
#endif /* CONFIG_TI_CPTS */
27772777

2778+
static int gbe_set_rx_mode(void *intf_priv, bool promisc)
2779+
{
2780+
struct gbe_intf *gbe_intf = intf_priv;
2781+
struct gbe_priv *gbe_dev = gbe_intf->gbe_dev;
2782+
struct cpsw_ale *ale = gbe_dev->ale;
2783+
unsigned long timeout;
2784+
int i, ret = -ETIMEDOUT;
2785+
2786+
/* Disable(1)/Enable(0) Learn for all ports (host is port 0 and
2787+
* slaves are port 1 and up
2788+
*/
2789+
for (i = 0; i <= gbe_dev->num_slaves; i++) {
2790+
cpsw_ale_control_set(ale, i,
2791+
ALE_PORT_NOLEARN, !!promisc);
2792+
cpsw_ale_control_set(ale, i,
2793+
ALE_PORT_NO_SA_UPDATE, !!promisc);
2794+
}
2795+
2796+
if (!promisc) {
2797+
/* Don't Flood All Unicast Packets to Host port */
2798+
cpsw_ale_control_set(ale, 0, ALE_P0_UNI_FLOOD, 0);
2799+
dev_vdbg(gbe_dev->dev, "promiscuous mode disabled\n");
2800+
return 0;
2801+
}
2802+
2803+
timeout = jiffies + HZ;
2804+
2805+
/* Clear All Untouched entries */
2806+
cpsw_ale_control_set(ale, 0, ALE_AGEOUT, 1);
2807+
do {
2808+
cpu_relax();
2809+
if (cpsw_ale_control_get(ale, 0, ALE_AGEOUT)) {
2810+
ret = 0;
2811+
break;
2812+
}
2813+
2814+
} while (time_after(timeout, jiffies));
2815+
2816+
/* Make sure it is not a false timeout */
2817+
if (ret && !cpsw_ale_control_get(ale, 0, ALE_AGEOUT))
2818+
return ret;
2819+
2820+
cpsw_ale_control_set(ale, 0, ALE_AGEOUT, 1);
2821+
2822+
/* Clear all mcast from ALE */
2823+
cpsw_ale_flush_multicast(ale,
2824+
GBE_PORT_MASK(gbe_dev->ale_ports),
2825+
-1);
2826+
2827+
/* Flood All Unicast Packets to Host port */
2828+
cpsw_ale_control_set(ale, 0, ALE_P0_UNI_FLOOD, 1);
2829+
dev_vdbg(gbe_dev->dev, "promiscuous mode enabled\n");
2830+
return ret;
2831+
}
2832+
27782833
static int gbe_ioctl(void *intf_priv, struct ifreq *req, int cmd)
27792834
{
27802835
struct gbe_intf *gbe_intf = intf_priv;
@@ -3529,6 +3584,7 @@ static int gbe_probe(struct netcp_device *netcp_device, struct device *dev,
35293584
gbe_dev->max_num_slaves = 8;
35303585
} else if (of_device_is_compatible(node, "ti,netcp-gbe-2")) {
35313586
gbe_dev->max_num_slaves = 1;
3587+
gbe_module.set_rx_mode = gbe_set_rx_mode;
35323588
} else if (of_device_is_compatible(node, "ti,netcp-xgbe")) {
35333589
gbe_dev->max_num_slaves = 2;
35343590
} else {

0 commit comments

Comments
 (0)