@@ -541,14 +541,93 @@ static inline int cpsw_get_slave_port(struct cpsw_priv *priv, u32 slave_num)
541
541
return slave_num ;
542
542
}
543
543
544
+ static void cpsw_set_promiscious (struct net_device * ndev , bool enable )
545
+ {
546
+ struct cpsw_priv * priv = netdev_priv (ndev );
547
+ struct cpsw_ale * ale = priv -> ale ;
548
+ int i ;
549
+
550
+ if (priv -> data .dual_emac ) {
551
+ bool flag = false;
552
+
553
+ /* Enabling promiscuous mode for one interface will be
554
+ * common for both the interface as the interface shares
555
+ * the same hardware resource.
556
+ */
557
+ for (i = 0 ; i <= priv -> data .slaves ; i ++ )
558
+ if (priv -> slaves [i ].ndev -> flags & IFF_PROMISC )
559
+ flag = true;
560
+
561
+ if (!enable && flag ) {
562
+ enable = true;
563
+ dev_err (& ndev -> dev , "promiscuity not disabled as the other interface is still in promiscuity mode\n" );
564
+ }
565
+
566
+ if (enable ) {
567
+ /* Enable Bypass */
568
+ cpsw_ale_control_set (ale , 0 , ALE_BYPASS , 1 );
569
+
570
+ dev_dbg (& ndev -> dev , "promiscuity enabled\n" );
571
+ } else {
572
+ /* Disable Bypass */
573
+ cpsw_ale_control_set (ale , 0 , ALE_BYPASS , 0 );
574
+ dev_dbg (& ndev -> dev , "promiscuity disabled\n" );
575
+ }
576
+ } else {
577
+ if (enable ) {
578
+ unsigned long timeout = jiffies + HZ ;
579
+
580
+ /* Disable Learn for all ports */
581
+ for (i = 0 ; i <= priv -> data .slaves ; i ++ ) {
582
+ cpsw_ale_control_set (ale , i ,
583
+ ALE_PORT_NOLEARN , 1 );
584
+ cpsw_ale_control_set (ale , i ,
585
+ ALE_PORT_NO_SA_UPDATE , 1 );
586
+ }
587
+
588
+ /* Clear All Untouched entries */
589
+ cpsw_ale_control_set (ale , 0 , ALE_AGEOUT , 1 );
590
+ do {
591
+ cpu_relax ();
592
+ if (cpsw_ale_control_get (ale , 0 , ALE_AGEOUT ))
593
+ break ;
594
+ } while (time_after (timeout , jiffies ));
595
+ cpsw_ale_control_set (ale , 0 , ALE_AGEOUT , 1 );
596
+
597
+ /* Clear all mcast from ALE */
598
+ cpsw_ale_flush_multicast (ale , ALE_ALL_PORTS <<
599
+ priv -> host_port );
600
+
601
+ /* Flood All Unicast Packets to Host port */
602
+ cpsw_ale_control_set (ale , 0 , ALE_P0_UNI_FLOOD , 1 );
603
+ dev_dbg (& ndev -> dev , "promiscuity enabled\n" );
604
+ } else {
605
+ /* Flood All Unicast Packets to Host port */
606
+ cpsw_ale_control_set (ale , 0 , ALE_P0_UNI_FLOOD , 0 );
607
+
608
+ /* Enable Learn for all ports */
609
+ for (i = 0 ; i <= priv -> data .slaves ; i ++ ) {
610
+ cpsw_ale_control_set (ale , i ,
611
+ ALE_PORT_NOLEARN , 0 );
612
+ cpsw_ale_control_set (ale , i ,
613
+ ALE_PORT_NO_SA_UPDATE , 0 );
614
+ }
615
+ dev_dbg (& ndev -> dev , "promiscuity disabled\n" );
616
+ }
617
+ }
618
+ }
619
+
544
620
static void cpsw_ndo_set_rx_mode (struct net_device * ndev )
545
621
{
546
622
struct cpsw_priv * priv = netdev_priv (ndev );
547
623
548
624
if (ndev -> flags & IFF_PROMISC ) {
549
625
/* Enable promiscuous mode */
550
- dev_err ( priv -> dev , "Ignoring Promiscuous mode\n" );
626
+ cpsw_set_promiscious ( ndev , true );
551
627
return ;
628
+ } else {
629
+ /* Disable promiscuous mode */
630
+ cpsw_set_promiscious (ndev , false);
552
631
}
553
632
554
633
/* Clear all mcast from ALE */
@@ -1257,29 +1336,6 @@ static netdev_tx_t cpsw_ndo_start_xmit(struct sk_buff *skb,
1257
1336
return NETDEV_TX_BUSY ;
1258
1337
}
1259
1338
1260
- static void cpsw_ndo_change_rx_flags (struct net_device * ndev , int flags )
1261
- {
1262
- /*
1263
- * The switch cannot operate in promiscuous mode without substantial
1264
- * headache. For promiscuous mode to work, we would need to put the
1265
- * ALE in bypass mode and route all traffic to the host port.
1266
- * Subsequently, the host will need to operate as a "bridge", learn,
1267
- * and flood as needed. For now, we simply complain here and
1268
- * do nothing about it :-)
1269
- */
1270
- if ((flags & IFF_PROMISC ) && (ndev -> flags & IFF_PROMISC ))
1271
- dev_err (& ndev -> dev , "promiscuity ignored!\n" );
1272
-
1273
- /*
1274
- * The switch cannot filter multicast traffic unless it is configured
1275
- * in "VLAN Aware" mode. Unfortunately, VLAN awareness requires a
1276
- * whole bunch of additional logic that this driver does not implement
1277
- * at present.
1278
- */
1279
- if ((flags & IFF_ALLMULTI ) && !(ndev -> flags & IFF_ALLMULTI ))
1280
- dev_err (& ndev -> dev , "multicast traffic cannot be filtered!\n" );
1281
- }
1282
-
1283
1339
#ifdef CONFIG_TI_CPTS
1284
1340
1285
1341
static void cpsw_hwtstamp_v1 (struct cpsw_priv * priv )
@@ -1575,7 +1631,6 @@ static const struct net_device_ops cpsw_netdev_ops = {
1575
1631
.ndo_open = cpsw_ndo_open ,
1576
1632
.ndo_stop = cpsw_ndo_stop ,
1577
1633
.ndo_start_xmit = cpsw_ndo_start_xmit ,
1578
- .ndo_change_rx_flags = cpsw_ndo_change_rx_flags ,
1579
1634
.ndo_set_mac_address = cpsw_ndo_set_mac_address ,
1580
1635
.ndo_do_ioctl = cpsw_ndo_ioctl ,
1581
1636
.ndo_validate_addr = eth_validate_addr ,
0 commit comments