kernel: set and get vlan 4k for rtl8367d family chips
authorMieczyslaw Nalewaj <namiltd@yahoo.com>
Tue, 20 Aug 2024 19:19:41 +0000 (21:19 +0200)
committerHauke Mehrtens <hauke@hauke-m.de>
Thu, 29 Aug 2024 18:50:01 +0000 (20:50 +0200)
Set and get vlan 4k for rtl8367d family chips

Co-authored-by: Serge Vasilugin <vasilugin@yandex.ru>
Signed-off-by: Mieczyslaw Nalewaj <namiltd@yahoo.com>
Link: https://github.com/openwrt/openwrt/pull/14804
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
target/linux/generic/files/drivers/net/phy/rtl8367b.c

index 75912c44547065ae5a9482c6cfe5304a16d2e22c..0f93e95a6ff417402bc5a13954870eba67278b9f 100644 (file)
@@ -280,6 +280,14 @@ struct rtl8367b_initval {
 #define RTL8367D_VLAN_PVID_CTRL_MASK           0xfff
 #define RTL8367D_VLAN_PVID_CTRL_SHIFT(_p)      0
 
+#define RTL8367D_FIDMAX                        3
+#define RTL8367D_FID_MASK              3
+#define RTL8367D_TA_VLAN1_FID_SHIFT    0
+#define RTL8367D_TA_VLAN1_FID_MASK     RTL8367D_FID_MASK
+
+#define RTL8367D_VID_MASK              0xfff
+#define RTL8367D_TA_VLAN_VID_MASK      RTL8367D_VID_MASK
+
 static struct rtl8366_mib_counter
 rtl8367b_mib_counters[RTL8367B_NUM_MIB_COUNTERS] = {
        {0,   0, 4, "ifInOctets"                        },
@@ -941,8 +949,12 @@ static int rtl8367b_get_vlan_4k(struct rtl8366_smi *smi, u32 vid,
                         RTL8367B_TA_VLAN0_MEMBER_MASK;
        vlan4k->untag = (data[0] >> RTL8367B_TA_VLAN0_UNTAG_SHIFT) &
                        RTL8367B_TA_VLAN0_UNTAG_MASK;
-       vlan4k->fid = (data[1] >> RTL8367B_TA_VLAN1_FID_SHIFT) &
-                     RTL8367B_TA_VLAN1_FID_MASK;
+       if (smi->rtl8367b_chip >= RTL8367B_CHIP_RTL8367S_VB) /* Family D */
+               vlan4k->fid = (data[1] >> RTL8367D_TA_VLAN1_FID_SHIFT) &
+                               RTL8367D_TA_VLAN1_FID_MASK;
+       else
+               vlan4k->fid = (data[1] >> RTL8367B_TA_VLAN1_FID_SHIFT) &
+                               RTL8367B_TA_VLAN1_FID_MASK;
 
        return 0;
 }
@@ -957,7 +969,7 @@ static int rtl8367b_set_vlan_4k(struct rtl8366_smi *smi,
        if (vlan4k->vid >= RTL8367B_NUM_VIDS ||
            vlan4k->member > RTL8367B_TA_VLAN0_MEMBER_MASK ||
            vlan4k->untag > RTL8367B_UNTAG_MASK ||
-           vlan4k->fid > RTL8367B_FIDMAX)
+           vlan4k->fid > ((smi->rtl8367b_chip >= RTL8367B_CHIP_RTL8367S_VB) ? RTL8367D_FIDMAX : RTL8367B_FIDMAX))
                return -EINVAL;
 
        memset(data, 0, sizeof(data));
@@ -966,15 +978,24 @@ static int rtl8367b_set_vlan_4k(struct rtl8366_smi *smi,
                  RTL8367B_TA_VLAN0_MEMBER_SHIFT;
        data[0] |= (vlan4k->untag & RTL8367B_TA_VLAN0_UNTAG_MASK) <<
                   RTL8367B_TA_VLAN0_UNTAG_SHIFT;
-       data[1] = (vlan4k->fid & RTL8367B_TA_VLAN1_FID_MASK) <<
-                 RTL8367B_TA_VLAN1_FID_SHIFT;
+
+       if (smi->rtl8367b_chip >= RTL8367B_CHIP_RTL8367S_VB) /* Family D */
+               data[1] = ((vlan4k->fid & RTL8367D_TA_VLAN1_FID_MASK) <<
+                          RTL8367D_TA_VLAN1_FID_SHIFT) | 12; /* ivl_svl - BIT(3), svlan_chek_ivl_svl - BIT(2) */
+       else
+               data[1] = (vlan4k->fid & RTL8367B_TA_VLAN1_FID_MASK) <<
+                          RTL8367B_TA_VLAN1_FID_SHIFT;
 
        for (i = 0; i < ARRAY_SIZE(data); i++)
                REG_WR(smi, RTL8367B_TA_WRDATA_REG(i), data[i]);
 
        /* write VID */
-       REG_WR(smi, RTL8367B_TA_ADDR_REG,
-              vlan4k->vid & RTL8367B_TA_VLAN_VID_MASK);
+       if (smi->rtl8367b_chip >= RTL8367B_CHIP_RTL8367S_VB) /* Family D */
+               REG_WR(smi, RTL8367B_TA_ADDR_REG,
+                      vlan4k->vid & RTL8367D_TA_VLAN_VID_MASK);
+       else
+               REG_WR(smi, RTL8367B_TA_ADDR_REG,
+                      vlan4k->vid & RTL8367B_TA_VLAN_VID_MASK);
 
        /* write table access control word */
        REG_WR(smi, RTL8367B_TA_CTRL_REG, RTL8367B_TA_CTRL_CVLAN_WRITE);