+ struct adm5120_sw *priv = netdev_priv(dev);
+ int portmask;
+ unsigned long adm5120_cpup_conf_reg;
+
+ portmask = adm5120_eth_vlans[priv->port] & 0x3f;
+
+ adm5120_cpup_conf_reg = adm5120_get_reg(ADM5120_CPUP_CONF);
+
+ if (dev->flags & IFF_PROMISC)
+ adm5120_cpup_conf_reg &= ~((portmask << ADM5120_DISUNSHIFT) & ADM5120_DISUNALL);
+ else
+ adm5120_cpup_conf_reg |= (portmask << ADM5120_DISUNSHIFT);
+
+ if (dev->flags & IFF_PROMISC || dev->flags & IFF_ALLMULTI || dev->mc_count)
+ adm5120_cpup_conf_reg &= ~((portmask << ADM5120_DISMCSHIFT) & ADM5120_DISMCALL);
+ else
+ adm5120_cpup_conf_reg |= (portmask << ADM5120_DISMCSHIFT);
+
+ /* If there is any port configured to be in promiscuous mode, then the */
+ /* Bridge Test Mode has to be activated. This will result in */
+ /* transporting also packets learned in another VLAN to be forwarded */
+ /* to the CPU. */
+ /* The difficult scenario is when we want to build a bridge on the CPU.*/
+ /* Assume we have port0 and the CPU port in VLAN0 and port1 and the */
+ /* CPU port in VLAN1. Now we build a bridge on the CPU between */
+ /* VLAN0 and VLAN1. Both ports of the VLANs are set in promisc mode. */
+ /* Now assume a packet with ethernet source address 99 enters port 0 */
+ /* It will be forwarded to the CPU because it is unknown. Then the */
+ /* bridge in the CPU will send it to VLAN1 and it goes out at port 1. */
+ /* When now a packet with ethernet destination address 99 comes in at */
+ /* port 1 in VLAN1, then the switch has learned that this address is */
+ /* located at port 0 in VLAN0. Therefore the switch will drop */
+ /* this packet. In order to avoid this and to send the packet still */
+ /* to the CPU, the Bridge Test Mode has to be activated. */
+
+ /* Check if there is any vlan in promisc mode. */
+ if (~adm5120_cpup_conf_reg & ADM5120_DISUNALL)
+ adm5120_cpup_conf_reg |= ADM5120_BTM; /* Set the BTM */
+ else
+ adm5120_cpup_conf_reg &= ~ADM5120_BTM; /* Disable the BTM */
+
+ adm5120_set_reg(ADM5120_CPUP_CONF,adm5120_cpup_conf_reg);
+