treewide: backport support for nvmem on non platform devices
[openwrt/staging/ldir.git] / target / linux / realtek / files-5.4 / drivers / net / ethernet / rtl838x_eth.c
index 38b2901652b1728a377f0afb3240c881d8d2d54c..f810f7eb581025aad0ae8a7b392b969056b00a32 100644 (file)
@@ -897,28 +897,30 @@ static int rtl838x_eth_open(struct net_device *ndev)
        switch (priv->family_id) {
        case RTL8380_FAMILY_ID:
                rtl838x_hw_en_rxtx(priv);
-               /* Trap IGMP traffic to CPU-Port */
+               /* Trap IGMP/MLD traffic to CPU-Port */
                sw_w32(0x3, RTL838X_SPCL_TRAP_IGMP_CTRL);
                /* Flush learned FDB entries on link down of a port */
                sw_w32_mask(0, BIT(7), RTL838X_L2_CTRL_0);
                break;
+
        case RTL8390_FAMILY_ID:
                rtl839x_hw_en_rxtx(priv);
+               // Trap MLD and IGMP messages to CPU_PORT
                sw_w32(0x3, RTL839X_SPCL_TRAP_IGMP_CTRL);
                /* Flush learned FDB entries on link down of a port */
                sw_w32_mask(0, BIT(7), RTL839X_L2_CTRL_0);
                break;
+
        case RTL9300_FAMILY_ID:
                rtl93xx_hw_en_rxtx(priv);
                /* Flush learned FDB entries on link down of a port */
                sw_w32_mask(0, BIT(7), RTL930X_L2_CTRL);
-               sw_w32_mask(BIT(28), 0, RTL930X_L2_PORT_SABLK_CTRL);
-               sw_w32_mask(BIT(28), 0, RTL930X_L2_PORT_DABLK_CTRL);
+               // Trap MLD and IGMP messages to CPU_PORT
+               sw_w32((0x2 << 3) | 0x2,  RTL930X_VLAN_APP_PKT_CTRL);
                break;
 
        case RTL9310_FAMILY_ID:
                rtl93xx_hw_en_rxtx(priv);
-//             TODO: Add trapping of IGMP frames to CPU-port
                break;
        }
 
@@ -1127,23 +1129,16 @@ static int rtl838x_eth_tx(struct sk_buff *skb, struct net_device *dev)
 
        /* Check for DSA tagging at the end of the buffer */
        if (netdev_uses_dsa(dev) && skb->data[len-4] == 0x80 && skb->data[len-3] > 0
-                       && skb->data[len-3] < 28 &&  skb->data[len-2] == 0x10
+                       && skb->data[len-3] < priv->cpu_port &&  skb->data[len-2] == 0x10
                        &&  skb->data[len-1] == 0x00) {
                /* Reuse tag space for CRC if possible */
                dest_port = skb->data[len-3];
+               skb->data[len-4] = skb->data[len-3] = skb->data[len-2] = skb->data[len-1] = 0x00;
                len -= 4;
        }
 
        len += 4; // Add space for CRC
 
-       // On RTL8380 SoCs, the packet needs extra padding
-       if (priv->family_id == RTL8380_FAMILY_ID) {
-               if (len < ETH_ZLEN)
-                       len = ETH_ZLEN; // SoC not automatically padding to ETH_ZLEN
-               else
-                       len += 4;
-       }
-
        if (skb_padto(skb, len)) {
                ret = NETDEV_TX_OK;
                goto txdone;
@@ -1156,6 +1151,11 @@ static int rtl838x_eth_tx(struct sk_buff *skb, struct net_device *dev)
                h = &ring->tx_header[q][ring->c_tx[q]];
                h->size = len;
                h->len = len;
+               // On RTL8380 SoCs, small packet lengths being sent need adjustments
+               if (priv->family_id == RTL8380_FAMILY_ID) {
+                       if (len < ETH_ZLEN - 4)
+                               h->len -= 4;
+               }
 
                priv->r->create_tx_header(h, dest_port, skb->priority >> 1);
 
@@ -1968,7 +1968,6 @@ static int __init rtl838x_eth_probe(struct platform_device *pdev)
        struct device_node *dn = pdev->dev.of_node;
        struct rtl838x_eth_priv *priv;
        struct resource *res, *mem;
-       const void *mac;
        phy_interface_t phy_mode;
        struct phylink *phylink;
        int err = 0, i, rxrings, rxringlen;
@@ -2089,10 +2088,9 @@ static int __init rtl838x_eth_probe(struct platform_device *pdev)
         * 1) from device tree data
         * 2) from internal registers set by bootloader
         */
-       mac = of_get_mac_address(pdev->dev.of_node);
-       if (!IS_ERR(mac)) {
-               memcpy(dev->dev_addr, mac, ETH_ALEN);
-               rtl838x_set_mac_hw(dev, (u8 *)mac);
+       of_get_mac_address(pdev->dev.of_node, dev->dev_addr);
+       if (is_valid_ether_addr(dev->dev_addr))) {
+               rtl838x_set_mac_hw(dev, (u8 *)dev->dev_addr);
        } else {
                dev->dev_addr[0] = (sw_r32(priv->r->mac) >> 8) & 0xff;
                dev->dev_addr[1] = sw_r32(priv->r->mac) & 0xff;