#include "ksz_common.h"
 #include "ksz8795_reg.h"
+#include "ksz8.h"
+
+static const u8 ksz8795_regs[] = {
+       [REG_IND_CTRL_0]                = 0x6E,
+       [REG_IND_DATA_8]                = 0x70,
+       [REG_IND_DATA_CHECK]            = 0x72,
+       [REG_IND_DATA_HI]               = 0x71,
+       [REG_IND_DATA_LO]               = 0x75,
+       [REG_IND_MIB_CHECK]             = 0x74,
+       [P_FORCE_CTRL]                  = 0x0C,
+       [P_LINK_STATUS]                 = 0x0E,
+       [P_LOCAL_CTRL]                  = 0x07,
+       [P_NEG_RESTART_CTRL]            = 0x0D,
+       [P_REMOTE_STATUS]               = 0x08,
+       [P_SPEED_STATUS]                = 0x09,
+       [S_TAIL_TAG_CTRL]               = 0x0C,
+};
+
+static const u32 ksz8795_masks[] = {
+       [PORT_802_1P_REMAPPING]         = BIT(7),
+       [SW_TAIL_TAG_ENABLE]            = BIT(1),
+       [MIB_COUNTER_OVERFLOW]          = BIT(6),
+       [MIB_COUNTER_VALID]             = BIT(5),
+       [VLAN_TABLE_FID]                = GENMASK(6, 0),
+       [VLAN_TABLE_MEMBERSHIP]         = GENMASK(11, 7),
+       [VLAN_TABLE_VALID]              = BIT(12),
+       [STATIC_MAC_TABLE_VALID]        = BIT(21),
+       [STATIC_MAC_TABLE_USE_FID]      = BIT(23),
+       [STATIC_MAC_TABLE_FID]          = GENMASK(30, 24),
+       [STATIC_MAC_TABLE_OVERRIDE]     = BIT(26),
+       [STATIC_MAC_TABLE_FWD_PORTS]    = GENMASK(24, 20),
+       [DYNAMIC_MAC_TABLE_ENTRIES_H]   = GENMASK(6, 0),
+       [DYNAMIC_MAC_TABLE_MAC_EMPTY]   = BIT(8),
+       [DYNAMIC_MAC_TABLE_NOT_READY]   = BIT(7),
+       [DYNAMIC_MAC_TABLE_ENTRIES]     = GENMASK(31, 29),
+       [DYNAMIC_MAC_TABLE_FID]         = GENMASK(26, 20),
+       [DYNAMIC_MAC_TABLE_SRC_PORT]    = GENMASK(26, 24),
+       [DYNAMIC_MAC_TABLE_TIMESTAMP]   = GENMASK(28, 27),
+};
+
+static const u8 ksz8795_shifts[] = {
+       [VLAN_TABLE_MEMBERSHIP_S]       = 7,
+       [VLAN_TABLE]                    = 16,
+       [STATIC_MAC_FWD_PORTS]          = 16,
+       [STATIC_MAC_FID]                = 24,
+       [DYNAMIC_MAC_ENTRIES_H]         = 3,
+       [DYNAMIC_MAC_ENTRIES]           = 29,
+       [DYNAMIC_MAC_FID]               = 16,
+       [DYNAMIC_MAC_TIMESTAMP]         = 27,
+       [DYNAMIC_MAC_SRC_PORT]          = 24,
+};
 
 static const struct {
        char string[ETH_GSTRING_LEN];
 
 static void ksz8_r_mib_cnt(struct ksz_device *dev, int port, u16 addr, u64 *cnt)
 {
+       struct ksz8 *ksz8 = dev->priv;
+       const u32 *masks;
+       const u8 *regs;
        u16 ctrl_addr;
        u32 data;
        u8 check;
        int loop;
 
+       masks = ksz8->masks;
+       regs = ksz8->regs;
+
        ctrl_addr = addr + dev->reg_mib_cnt * port;
        ctrl_addr |= IND_ACC_TABLE(TABLE_MIB | TABLE_READ);
 
        mutex_lock(&dev->alu_mutex);
-       ksz_write16(dev, REG_IND_CTRL_0, ctrl_addr);
+       ksz_write16(dev, regs[REG_IND_CTRL_0], ctrl_addr);
 
        /* It is almost guaranteed to always read the valid bit because of
         * slow SPI speed.
         */
        for (loop = 2; loop > 0; loop--) {
-               ksz_read8(dev, REG_IND_MIB_CHECK, &check);
+               ksz_read8(dev, regs[REG_IND_MIB_CHECK], &check);
 
-               if (check & MIB_COUNTER_VALID) {
-                       ksz_read32(dev, REG_IND_DATA_LO, &data);
-                       if (check & MIB_COUNTER_OVERFLOW)
+               if (check & masks[MIB_COUNTER_VALID]) {
+                       ksz_read32(dev, regs[REG_IND_DATA_LO], &data);
+                       if (check & masks[MIB_COUNTER_OVERFLOW])
                                *cnt += MIB_COUNTER_VALUE + 1;
                        *cnt += data & MIB_COUNTER_VALUE;
                        break;
 static void ksz8_r_mib_pkt(struct ksz_device *dev, int port, u16 addr,
                           u64 *dropped, u64 *cnt)
 {
+       struct ksz8 *ksz8 = dev->priv;
+       const u32 *masks;
+       const u8 *regs;
        u16 ctrl_addr;
        u32 data;
        u8 check;
        int loop;
 
+       masks = ksz8->masks;
+       regs = ksz8->regs;
+
        addr -= dev->reg_mib_cnt;
        ctrl_addr = (KS_MIB_TOTAL_RX_1 - KS_MIB_TOTAL_RX_0) * port;
        ctrl_addr += addr + KS_MIB_TOTAL_RX_0;
        ctrl_addr |= IND_ACC_TABLE(TABLE_MIB | TABLE_READ);
 
        mutex_lock(&dev->alu_mutex);
-       ksz_write16(dev, REG_IND_CTRL_0, ctrl_addr);
+       ksz_write16(dev, regs[REG_IND_CTRL_0], ctrl_addr);
 
        /* It is almost guaranteed to always read the valid bit because of
         * slow SPI speed.
         */
        for (loop = 2; loop > 0; loop--) {
-               ksz_read8(dev, REG_IND_MIB_CHECK, &check);
+               ksz_read8(dev, regs[REG_IND_MIB_CHECK], &check);
 
-               if (check & MIB_COUNTER_VALID) {
-                       ksz_read32(dev, REG_IND_DATA_LO, &data);
+               if (check & masks[MIB_COUNTER_VALID]) {
+                       ksz_read32(dev, regs[REG_IND_DATA_LO], &data);
                        if (addr < 2) {
                                u64 total;
 
                                total <<= 32;
                                *cnt += total;
                                *cnt += data;
-                               if (check & MIB_COUNTER_OVERFLOW) {
+                               if (check & masks[MIB_COUNTER_OVERFLOW]) {
                                        total = MIB_TOTAL_BYTES_H + 1;
                                        total <<= 32;
                                        *cnt += total;
                                }
                        } else {
-                               if (check & MIB_COUNTER_OVERFLOW)
+                               if (check & masks[MIB_COUNTER_OVERFLOW])
                                        *cnt += MIB_PACKET_DROPPED + 1;
                                *cnt += data & MIB_PACKET_DROPPED;
                        }
 
 static void ksz8_r_table(struct ksz_device *dev, int table, u16 addr, u64 *data)
 {
+       struct ksz8 *ksz8 = dev->priv;
+       const u8 *regs = ksz8->regs;
        u16 ctrl_addr;
 
        ctrl_addr = IND_ACC_TABLE(table | TABLE_READ) | addr;
 
        mutex_lock(&dev->alu_mutex);
-       ksz_write16(dev, REG_IND_CTRL_0, ctrl_addr);
-       ksz_read64(dev, REG_IND_DATA_HI, data);
+       ksz_write16(dev, regs[REG_IND_CTRL_0], ctrl_addr);
+       ksz_read64(dev, regs[REG_IND_DATA_HI], data);
        mutex_unlock(&dev->alu_mutex);
 }
 
 static void ksz8_w_table(struct ksz_device *dev, int table, u16 addr, u64 data)
 {
+       struct ksz8 *ksz8 = dev->priv;
+       const u8 *regs = ksz8->regs;
        u16 ctrl_addr;
 
        ctrl_addr = IND_ACC_TABLE(table) | addr;
 
        mutex_lock(&dev->alu_mutex);
-       ksz_write64(dev, REG_IND_DATA_HI, data);
-       ksz_write16(dev, REG_IND_CTRL_0, ctrl_addr);
+       ksz_write64(dev, regs[REG_IND_DATA_HI], data);
+       ksz_write16(dev, regs[REG_IND_CTRL_0], ctrl_addr);
        mutex_unlock(&dev->alu_mutex);
 }
 
 static int ksz8_valid_dyn_entry(struct ksz_device *dev, u8 *data)
 {
+       struct ksz8 *ksz8 = dev->priv;
        int timeout = 100;
+       const u32 *masks;
+       const u8 *regs;
+
+       masks = ksz8->masks;
+       regs = ksz8->regs;
 
        do {
-               ksz_read8(dev, REG_IND_DATA_CHECK, data);
+               ksz_read8(dev, regs[REG_IND_DATA_CHECK], data);
                timeout--;
-       } while ((*data & DYNAMIC_MAC_TABLE_NOT_READY) && timeout);
+       } while ((*data & masks[DYNAMIC_MAC_TABLE_NOT_READY]) && timeout);
 
        /* Entry is not ready for accessing. */
-       if (*data & DYNAMIC_MAC_TABLE_NOT_READY) {
+       if (*data & masks[DYNAMIC_MAC_TABLE_NOT_READY]) {
                return -EAGAIN;
        /* Entry is ready for accessing. */
        } else {
-               ksz_read8(dev, REG_IND_DATA_8, data);
+               ksz_read8(dev, regs[REG_IND_DATA_8], data);
 
                /* There is no valid entry in the table. */
-               if (*data & DYNAMIC_MAC_TABLE_MAC_EMPTY)
+               if (*data & masks[DYNAMIC_MAC_TABLE_MAC_EMPTY])
                        return -ENXIO;
        }
        return 0;
                                u8 *mac_addr, u8 *fid, u8 *src_port,
                                u8 *timestamp, u16 *entries)
 {
+       struct ksz8 *ksz8 = dev->priv;
        u32 data_hi, data_lo;
+       const u8 *shifts;
+       const u32 *masks;
+       const u8 *regs;
        u16 ctrl_addr;
        u8 data;
        int rc;
 
+       shifts = ksz8->shifts;
+       masks = ksz8->masks;
+       regs = ksz8->regs;
+
        ctrl_addr = IND_ACC_TABLE(TABLE_DYNAMIC_MAC | TABLE_READ) | addr;
 
        mutex_lock(&dev->alu_mutex);
-       ksz_write16(dev, REG_IND_CTRL_0, ctrl_addr);
+       ksz_write16(dev, regs[REG_IND_CTRL_0], ctrl_addr);
 
        rc = ksz8_valid_dyn_entry(dev, &data);
        if (rc == -EAGAIN) {
                u64 buf = 0;
                int cnt;
 
-               ksz_read64(dev, REG_IND_DATA_HI, &buf);
+               ksz_read64(dev, regs[REG_IND_DATA_HI], &buf);
                data_hi = (u32)(buf >> 32);
                data_lo = (u32)buf;
 
                /* Check out how many valid entry in the table. */
-               cnt = data & DYNAMIC_MAC_TABLE_ENTRIES_H;
-               cnt <<= DYNAMIC_MAC_ENTRIES_H_S;
-               cnt |= (data_hi & DYNAMIC_MAC_TABLE_ENTRIES) >>
-                       DYNAMIC_MAC_ENTRIES_S;
+               cnt = data & masks[DYNAMIC_MAC_TABLE_ENTRIES_H];
+               cnt <<= shifts[DYNAMIC_MAC_ENTRIES_H];
+               cnt |= (data_hi & masks[DYNAMIC_MAC_TABLE_ENTRIES]) >>
+                       shifts[DYNAMIC_MAC_ENTRIES];
                *entries = cnt + 1;
 
-               *fid = (data_hi & DYNAMIC_MAC_TABLE_FID) >>
-                       DYNAMIC_MAC_FID_S;
-               *src_port = (data_hi & DYNAMIC_MAC_TABLE_SRC_PORT) >>
-                       DYNAMIC_MAC_SRC_PORT_S;
-               *timestamp = (data_hi & DYNAMIC_MAC_TABLE_TIMESTAMP) >>
-                       DYNAMIC_MAC_TIMESTAMP_S;
+               *fid = (data_hi & masks[DYNAMIC_MAC_TABLE_FID]) >>
+                       shifts[DYNAMIC_MAC_FID];
+               *src_port = (data_hi & masks[DYNAMIC_MAC_TABLE_SRC_PORT]) >>
+                       shifts[DYNAMIC_MAC_SRC_PORT];
+               *timestamp = (data_hi & masks[DYNAMIC_MAC_TABLE_TIMESTAMP]) >>
+                       shifts[DYNAMIC_MAC_TIMESTAMP];
 
                mac_addr[5] = (u8)data_lo;
                mac_addr[4] = (u8)(data_lo >> 8);
 static int ksz8_r_sta_mac_table(struct ksz_device *dev, u16 addr,
                                struct alu_struct *alu)
 {
+       struct ksz8 *ksz8 = dev->priv;
        u32 data_hi, data_lo;
+       const u8 *shifts;
+       const u32 *masks;
        u64 data;
 
+       shifts = ksz8->shifts;
+       masks = ksz8->masks;
+
        ksz8_r_table(dev, TABLE_STATIC_MAC, addr, &data);
        data_hi = data >> 32;
        data_lo = (u32)data;
-       if (data_hi & (STATIC_MAC_TABLE_VALID | STATIC_MAC_TABLE_OVERRIDE)) {
+       if (data_hi & (masks[STATIC_MAC_TABLE_VALID] |
+                       masks[STATIC_MAC_TABLE_OVERRIDE])) {
                alu->mac[5] = (u8)data_lo;
                alu->mac[4] = (u8)(data_lo >> 8);
                alu->mac[3] = (u8)(data_lo >> 16);
                alu->mac[2] = (u8)(data_lo >> 24);
                alu->mac[1] = (u8)data_hi;
                alu->mac[0] = (u8)(data_hi >> 8);
-               alu->port_forward = (data_hi & STATIC_MAC_TABLE_FWD_PORTS) >>
-                       STATIC_MAC_FWD_PORTS_S;
+               alu->port_forward =
+                       (data_hi & masks[STATIC_MAC_TABLE_FWD_PORTS]) >>
+                               shifts[STATIC_MAC_FWD_PORTS];
                alu->is_override =
-                       (data_hi & STATIC_MAC_TABLE_OVERRIDE) ? 1 : 0;
+                       (data_hi & masks[STATIC_MAC_TABLE_OVERRIDE]) ? 1 : 0;
                data_hi >>= 1;
-               alu->is_use_fid = (data_hi & STATIC_MAC_TABLE_USE_FID) ? 1 : 0;
-               alu->fid = (data_hi & STATIC_MAC_TABLE_FID) >>
-                       STATIC_MAC_FID_S;
+               alu->is_static = true;
+               alu->is_use_fid =
+                       (data_hi & masks[STATIC_MAC_TABLE_USE_FID]) ? 1 : 0;
+               alu->fid = (data_hi & masks[STATIC_MAC_TABLE_FID]) >>
+                               shifts[STATIC_MAC_FID];
                return 0;
        }
        return -ENXIO;
 static void ksz8_w_sta_mac_table(struct ksz_device *dev, u16 addr,
                                 struct alu_struct *alu)
 {
+       struct ksz8 *ksz8 = dev->priv;
        u32 data_hi, data_lo;
+       const u8 *shifts;
+       const u32 *masks;
        u64 data;
 
+       shifts = ksz8->shifts;
+       masks = ksz8->masks;
+
        data_lo = ((u32)alu->mac[2] << 24) |
                ((u32)alu->mac[3] << 16) |
                ((u32)alu->mac[4] << 8) | alu->mac[5];
        data_hi = ((u32)alu->mac[0] << 8) | alu->mac[1];
-       data_hi |= (u32)alu->port_forward << STATIC_MAC_FWD_PORTS_S;
+       data_hi |= (u32)alu->port_forward << shifts[STATIC_MAC_FWD_PORTS];
 
        if (alu->is_override)
-               data_hi |= STATIC_MAC_TABLE_OVERRIDE;
+               data_hi |= masks[STATIC_MAC_TABLE_OVERRIDE];
        if (alu->is_use_fid) {
-               data_hi |= STATIC_MAC_TABLE_USE_FID;
-               data_hi |= (u32)alu->fid << STATIC_MAC_FID_S;
+               data_hi |= masks[STATIC_MAC_TABLE_USE_FID];
+               data_hi |= (u32)alu->fid << shifts[STATIC_MAC_FID];
        }
        if (alu->is_static)
-               data_hi |= STATIC_MAC_TABLE_VALID;
+               data_hi |= masks[STATIC_MAC_TABLE_VALID];
        else
-               data_hi &= ~STATIC_MAC_TABLE_OVERRIDE;
+               data_hi &= ~masks[STATIC_MAC_TABLE_OVERRIDE];
 
        data = (u64)data_hi << 32 | data_lo;
        ksz8_w_table(dev, TABLE_STATIC_MAC, addr, data);
 }
 
-static void ksz8_from_vlan(u16 vlan, u8 *fid, u8 *member, u8 *valid)
+static void ksz8_from_vlan(struct ksz_device *dev, u32 vlan, u8 *fid,
+                          u8 *member, u8 *valid)
 {
-       *fid = vlan & VLAN_TABLE_FID;
-       *member = (vlan & VLAN_TABLE_MEMBERSHIP) >> VLAN_TABLE_MEMBERSHIP_S;
-       *valid = !!(vlan & VLAN_TABLE_VALID);
+       struct ksz8 *ksz8 = dev->priv;
+       const u8 *shifts;
+       const u32 *masks;
+
+       shifts = ksz8->shifts;
+       masks = ksz8->masks;
+
+       *fid = vlan & masks[VLAN_TABLE_FID];
+       *member = (vlan & masks[VLAN_TABLE_MEMBERSHIP]) >>
+                       shifts[VLAN_TABLE_MEMBERSHIP_S];
+       *valid = !!(vlan & masks[VLAN_TABLE_VALID]);
 }
 
-static void ksz8_to_vlan(u8 fid, u8 member, u8 valid, u16 *vlan)
+static void ksz8_to_vlan(struct ksz_device *dev, u8 fid, u8 member, u8 valid,
+                        u16 *vlan)
 {
+       struct ksz8 *ksz8 = dev->priv;
+       const u8 *shifts;
+       const u32 *masks;
+
+       shifts = ksz8->shifts;
+       masks = ksz8->masks;
+
        *vlan = fid;
-       *vlan |= (u16)member << VLAN_TABLE_MEMBERSHIP_S;
+       *vlan |= (u16)member << shifts[VLAN_TABLE_MEMBERSHIP_S];
        if (valid)
-               *vlan |= VLAN_TABLE_VALID;
+               *vlan |= masks[VLAN_TABLE_VALID];
 }
 
 static void ksz8_r_vlan_entries(struct ksz_device *dev, u16 addr)
 {
+       struct ksz8 *ksz8 = dev->priv;
+       const u8 *shifts;
        u64 data;
        int i;
 
+       shifts = ksz8->shifts;
+
        ksz8_r_table(dev, TABLE_VLAN, addr, &data);
        addr *= dev->phy_port_cnt;
        for (i = 0; i < dev->phy_port_cnt; i++) {
                dev->vlan_cache[addr + i].table[0] = (u16)data;
-               data >>= VLAN_TABLE_S;
+               data >>= shifts[VLAN_TABLE];
        }
 }
 
 
 static void ksz8_r_phy(struct ksz_device *dev, u16 phy, u16 reg, u16 *val)
 {
+       struct ksz8 *ksz8 = dev->priv;
        u8 restart, speed, ctrl, link;
+       const u8 *regs = ksz8->regs;
        int processed = true;
        u16 data = 0;
        u8 p = phy;
 
        switch (reg) {
        case PHY_REG_CTRL:
-               ksz_pread8(dev, p, P_NEG_RESTART_CTRL, &restart);
-               ksz_pread8(dev, p, P_SPEED_STATUS, &speed);
-               ksz_pread8(dev, p, P_FORCE_CTRL, &ctrl);
+               ksz_pread8(dev, p, regs[P_NEG_RESTART_CTRL], &restart);
+               ksz_pread8(dev, p, regs[P_SPEED_STATUS], &speed);
+               ksz_pread8(dev, p, regs[P_FORCE_CTRL], &ctrl);
                if (restart & PORT_PHY_LOOPBACK)
                        data |= PHY_LOOPBACK;
                if (ctrl & PORT_FORCE_100_MBIT)
                        data |= PHY_LED_DISABLE;
                break;
        case PHY_REG_STATUS:
-               ksz_pread8(dev, p, P_LINK_STATUS, &link);
+               ksz_pread8(dev, p, regs[P_LINK_STATUS], &link);
                data = PHY_100BTX_FD_CAPABLE |
                       PHY_100BTX_CAPABLE |
                       PHY_10BT_FD_CAPABLE |
                data = KSZ8795_ID_LO;
                break;
        case PHY_REG_AUTO_NEGOTIATION:
-               ksz_pread8(dev, p, P_LOCAL_CTRL, &ctrl);
+               ksz_pread8(dev, p, regs[P_LOCAL_CTRL], &ctrl);
                data = PHY_AUTO_NEG_802_3;
                if (ctrl & PORT_AUTO_NEG_SYM_PAUSE)
                        data |= PHY_AUTO_NEG_SYM_PAUSE;
                        data |= PHY_AUTO_NEG_10BT;
                break;
        case PHY_REG_REMOTE_CAPABILITY:
-               ksz_pread8(dev, p, P_REMOTE_STATUS, &link);
+               ksz_pread8(dev, p, regs[P_REMOTE_STATUS], &link);
                data = PHY_AUTO_NEG_802_3;
                if (link & PORT_REMOTE_SYM_PAUSE)
                        data |= PHY_AUTO_NEG_SYM_PAUSE;
 
 static void ksz8_w_phy(struct ksz_device *dev, u16 phy, u16 reg, u16 val)
 {
-       u8 p = phy;
+       struct ksz8 *ksz8 = dev->priv;
        u8 restart, speed, ctrl, data;
+       const u8 *regs = ksz8->regs;
+       u8 p = phy;
 
        switch (reg) {
        case PHY_REG_CTRL:
                /* Do not support PHY reset function. */
                if (val & PHY_RESET)
                        break;
-               ksz_pread8(dev, p, P_SPEED_STATUS, &speed);
+               ksz_pread8(dev, p, regs[P_SPEED_STATUS], &speed);
                data = speed;
                if (val & PHY_HP_MDIX)
                        data |= PORT_HP_MDIX;
                else
                        data &= ~PORT_HP_MDIX;
                if (data != speed)
-                       ksz_pwrite8(dev, p, P_SPEED_STATUS, data);
-               ksz_pread8(dev, p, P_FORCE_CTRL, &ctrl);
+                       ksz_pwrite8(dev, p, regs[P_SPEED_STATUS], data);
+               ksz_pread8(dev, p, regs[P_FORCE_CTRL], &ctrl);
                data = ctrl;
                if (!(val & PHY_AUTO_NEG_ENABLE))
                        data |= PORT_AUTO_NEG_DISABLE;
                else
                        data &= ~PORT_FORCE_FULL_DUPLEX;
                if (data != ctrl)
-                       ksz_pwrite8(dev, p, P_FORCE_CTRL, data);
-               ksz_pread8(dev, p, P_NEG_RESTART_CTRL, &restart);
+                       ksz_pwrite8(dev, p, regs[P_FORCE_CTRL], data);
+               ksz_pread8(dev, p, regs[P_NEG_RESTART_CTRL], &restart);
                data = restart;
                if (val & PHY_LED_DISABLE)
                        data |= PORT_LED_OFF;
                else
                        data &= ~PORT_PHY_LOOPBACK;
                if (data != restart)
-                       ksz_pwrite8(dev, p, P_NEG_RESTART_CTRL, data);
+                       ksz_pwrite8(dev, p, regs[P_NEG_RESTART_CTRL], data);
                break;
        case PHY_REG_AUTO_NEGOTIATION:
-               ksz_pread8(dev, p, P_LOCAL_CTRL, &ctrl);
+               ksz_pread8(dev, p, regs[P_LOCAL_CTRL], &ctrl);
                data = ctrl;
                data &= ~(PORT_AUTO_NEG_SYM_PAUSE |
                          PORT_AUTO_NEG_100BTX_FD |
                if (val & PHY_AUTO_NEG_10BT)
                        data |= PORT_AUTO_NEG_10BT;
                if (data != ctrl)
-                       ksz_pwrite8(dev, p, P_LOCAL_CTRL, data);
+                       ksz_pwrite8(dev, p, regs[P_LOCAL_CTRL], data);
                break;
        default:
                break;
        ksz_port_cfg(dev, port, P_TAG_CTRL, PORT_REMOVE_TAG, untagged);
 
        ksz8_r_vlan_table(dev, vlan->vid, &data);
-       ksz8_from_vlan(data, &fid, &member, &valid);
+       ksz8_from_vlan(dev, data, &fid, &member, &valid);
 
        /* First time to setup the VLAN entry. */
        if (!valid) {
        }
        member |= BIT(port);
 
-       ksz8_to_vlan(fid, member, valid, &data);
+       ksz8_to_vlan(dev, fid, member, valid, &data);
        ksz8_w_vlan_table(dev, vlan->vid, data);
 
        /* change PVID */
        ksz_port_cfg(dev, port, P_TAG_CTRL, PORT_REMOVE_TAG, untagged);
 
        ksz8_r_vlan_table(dev, vlan->vid, &data);
-       ksz8_from_vlan(data, &fid, &member, &valid);
+       ksz8_from_vlan(dev, data, &fid, &member, &valid);
 
        member &= ~BIT(port);
 
        if (pvid == vlan->vid)
                new_pvid = 1;
 
-       ksz8_to_vlan(fid, member, valid, &data);
+       ksz8_to_vlan(dev, fid, member, valid, &data);
        ksz8_w_vlan_table(dev, vlan->vid, data);
 
        if (new_pvid != pvid)
 static void ksz8_port_setup(struct ksz_device *dev, int port, bool cpu_port)
 {
        struct ksz_port *p = &dev->ports[port];
+       struct ksz8 *ksz8 = dev->priv;
+       const u32 *masks;
        u8 member;
 
+       masks = ksz8->masks;
+
        /* enable broadcast storm limit */
        ksz_port_cfg(dev, port, P_BCAST_STORM_CTRL, PORT_BROADCAST_STORM, true);
 
        ksz_port_cfg(dev, port, P_PRIO_CTRL, PORT_DIFFSERV_ENABLE, false);
 
        /* replace priority */
-       ksz_port_cfg(dev, port, P_802_1P_CTRL, PORT_802_1P_REMAPPING, false);
+       ksz_port_cfg(dev, port, P_802_1P_CTRL,
+                    masks[PORT_802_1P_REMAPPING], false);
 
        /* enable 802.1p priority */
        ksz_port_cfg(dev, port, P_PRIO_CTRL, PORT_802_1P_ENABLE, true);
 static void ksz8_config_cpu_port(struct dsa_switch *ds)
 {
        struct ksz_device *dev = ds->priv;
+       struct ksz8 *ksz8 = dev->priv;
+       const u8 *regs = ksz8->regs;
        struct ksz_port *p;
+       const u32 *masks;
        u8 remote;
        int i;
 
+       masks = ksz8->masks;
+
        /* Switch marks the maximum frame with extra byte as oversize. */
        ksz_cfg(dev, REG_SW_CTRL_2, SW_LEGAL_PACKET_DISABLE, true);
-       ksz_cfg(dev, S_TAIL_TAG_CTRL, SW_TAIL_TAG_ENABLE, true);
+       ksz_cfg(dev, regs[S_TAIL_TAG_CTRL], masks[SW_TAIL_TAG_ENABLE], true);
 
        p = &dev->ports[dev->cpu_port];
        p->vid_member = dev->port_mask;
                p = &dev->ports[i];
                if (!p->on)
                        continue;
-               ksz_pread8(dev, i, P_REMOTE_STATUS, &remote);
+               ksz_pread8(dev, i, regs[P_REMOTE_STATUS], &remote);
                if (remote & PORT_FIBER_MODE)
                        p->fiber = 1;
                if (p->fiber)
 
 static int ksz8_switch_init(struct ksz_device *dev)
 {
+       struct ksz8 *ksz8 = dev->priv;
        int i;
 
        dev->ds->ops = &ksz8_switch_ops;
        if (!dev->cpu_ports)
                return -ENODEV;
 
+       ksz8->regs = ksz8795_regs;
+       ksz8->masks = ksz8795_masks;
+       ksz8->shifts = ksz8795_shifts;
+
        dev->reg_mib_cnt = KSZ8795_COUNTER_NUM;
        dev->mib_cnt = ARRAY_SIZE(mib_names);
 
 
 
 #define REG_SW_CTRL_10                 0x0C
 
-#define SW_TAIL_TAG_ENABLE             BIT(1)
 #define SW_PASS_PAUSE                  BIT(0)
 
 #define REG_SW_CTRL_11                 0x0D
 #define REG_PORT_4_CTRL_2              0x42
 #define REG_PORT_5_CTRL_2              0x52
 
-#define PORT_802_1P_REMAPPING          BIT(7)
 #define PORT_INGRESS_FILTER            BIT(6)
 #define PORT_DISCARD_NON_VID           BIT(5)
 #define PORT_FORCE_FLOW_CTRL           BIT(4)
 
 #define REG_PORT_CTRL_5                        0x05
 
-#define REG_PORT_CTRL_7                        0x07
 #define REG_PORT_STATUS_0              0x08
 #define REG_PORT_STATUS_1              0x09
 #define REG_PORT_LINK_MD_CTRL          0x0A
 #define REG_PORT_LINK_MD_RESULT                0x0B
 #define REG_PORT_CTRL_9                        0x0C
 #define REG_PORT_CTRL_10               0x0D
-#define REG_PORT_STATUS_2              0x0E
 #define REG_PORT_STATUS_3              0x0F
 
 #define REG_PORT_CTRL_12               0xA0
 #define REG_SW_MAC_ADDR_4              0x6C
 #define REG_SW_MAC_ADDR_5              0x6D
 
-#define REG_IND_CTRL_0                 0x6E
-
 #define TABLE_EXT_SELECT_S             5
 #define TABLE_EEE_V                    1
 #define TABLE_ACL_V                    2
 #define TABLE_ENTRY_MASK               0x03FF
 #define TABLE_EXT_ENTRY_MASK           0x0FFF
 
-#define REG_IND_DATA_8                 0x70
-#define REG_IND_DATA_7                 0x71
-#define REG_IND_DATA_6                 0x72
 #define REG_IND_DATA_5                 0x73
-#define REG_IND_DATA_4                 0x74
-#define REG_IND_DATA_3                 0x75
 #define REG_IND_DATA_2                 0x76
 #define REG_IND_DATA_1                 0x77
 #define REG_IND_DATA_0                 0x78
 
 #define REG_IND_DATA_PME_EEE_ACL       0xA0
 
-#define REG_IND_DATA_CHECK             REG_IND_DATA_6
-#define REG_IND_MIB_CHECK              REG_IND_DATA_4
-#define REG_IND_DATA_HI                        REG_IND_DATA_7
-#define REG_IND_DATA_LO                        REG_IND_DATA_3
-
 #define REG_INT_STATUS                 0x7C
 #define REG_INT_ENABLE                 0x7D
 
 #define P_MIRROR_CTRL                  REG_PORT_CTRL_1
 #define P_802_1P_CTRL                  REG_PORT_CTRL_2
 #define P_STP_CTRL                     REG_PORT_CTRL_2
-#define P_LOCAL_CTRL                   REG_PORT_CTRL_7
-#define P_REMOTE_STATUS                        REG_PORT_STATUS_0
-#define P_FORCE_CTRL                   REG_PORT_CTRL_9
-#define P_NEG_RESTART_CTRL             REG_PORT_CTRL_10
-#define P_SPEED_STATUS                 REG_PORT_STATUS_1
-#define P_LINK_STATUS                  REG_PORT_STATUS_2
 #define P_PASS_ALL_CTRL                        REG_PORT_CTRL_12
 #define P_INS_SRC_PVID_CTRL            REG_PORT_CTRL_12
 #define P_DROP_TAG_CTRL                        REG_PORT_CTRL_13
 #define S_MIRROR_CTRL                  REG_SW_CTRL_3
 #define S_REPLACE_VID_CTRL             REG_SW_CTRL_4
 #define S_PASS_PAUSE_CTRL              REG_SW_CTRL_10
-#define S_TAIL_TAG_CTRL                        REG_SW_CTRL_10
 #define S_802_1P_PRIO_CTRL             REG_SW_CTRL_12
 #define S_TOS_PRIO_CTRL                        REG_TOS_PRIO_CTRL_0
 #define S_IPV6_MLD_CTRL                        REG_SW_CTRL_21
 /* 148,800 frames * 67 ms / 100 */
 #define BROADCAST_STORM_VALUE          9969
 
-/**
- * STATIC_MAC_TABLE_ADDR               00-0000FFFF-FFFFFFFF
- * STATIC_MAC_TABLE_FWD_PORTS          00-001F0000-00000000
- * STATIC_MAC_TABLE_VALID              00-00200000-00000000
- * STATIC_MAC_TABLE_OVERRIDE           00-00400000-00000000
- * STATIC_MAC_TABLE_USE_FID            00-00800000-00000000
- * STATIC_MAC_TABLE_FID                        00-7F000000-00000000
- */
-
-#define STATIC_MAC_TABLE_ADDR          0x0000FFFF
-#define STATIC_MAC_TABLE_FWD_PORTS     0x001F0000
-#define STATIC_MAC_TABLE_VALID         0x00200000
-#define STATIC_MAC_TABLE_OVERRIDE      0x00400000
-#define STATIC_MAC_TABLE_USE_FID       0x00800000
-#define STATIC_MAC_TABLE_FID           0x7F000000
-
-#define STATIC_MAC_FWD_PORTS_S         16
-#define STATIC_MAC_FID_S               24
-
-/**
- * VLAN_TABLE_FID                      00-007F007F-007F007F
- * VLAN_TABLE_MEMBERSHIP               00-0F800F80-0F800F80
- * VLAN_TABLE_VALID                    00-10001000-10001000
- */
-
-#define VLAN_TABLE_FID                 0x007F
-#define VLAN_TABLE_MEMBERSHIP          0x0F80
-#define VLAN_TABLE_VALID               0x1000
-
-#define VLAN_TABLE_MEMBERSHIP_S                7
-#define VLAN_TABLE_S                   16
-
-/**
- * DYNAMIC_MAC_TABLE_ADDR              00-0000FFFF-FFFFFFFF
- * DYNAMIC_MAC_TABLE_FID               00-007F0000-00000000
- * DYNAMIC_MAC_TABLE_NOT_READY         00-00800000-00000000
- * DYNAMIC_MAC_TABLE_SRC_PORT          00-07000000-00000000
- * DYNAMIC_MAC_TABLE_TIMESTAMP         00-18000000-00000000
- * DYNAMIC_MAC_TABLE_ENTRIES           7F-E0000000-00000000
- * DYNAMIC_MAC_TABLE_MAC_EMPTY         80-00000000-00000000
- */
-
-#define DYNAMIC_MAC_TABLE_ADDR         0x0000FFFF
-#define DYNAMIC_MAC_TABLE_FID          0x007F0000
-#define DYNAMIC_MAC_TABLE_SRC_PORT     0x07000000
-#define DYNAMIC_MAC_TABLE_TIMESTAMP    0x18000000
-#define DYNAMIC_MAC_TABLE_ENTRIES      0xE0000000
-
-#define DYNAMIC_MAC_TABLE_NOT_READY    0x80
-
-#define DYNAMIC_MAC_TABLE_ENTRIES_H    0x7F
-#define DYNAMIC_MAC_TABLE_MAC_EMPTY    0x80
-
-#define DYNAMIC_MAC_FID_S              16
-#define DYNAMIC_MAC_SRC_PORT_S         24
-#define DYNAMIC_MAC_TIMESTAMP_S                27
-#define DYNAMIC_MAC_ENTRIES_S          29
-#define DYNAMIC_MAC_ENTRIES_H_S                3
-
 /**
  * MIB_COUNTER_VALUE                   00-00000000-3FFFFFFF
  * MIB_TOTAL_BYTES                     00-0000000F-FFFFFFFF
  * MIB_COUNTER_OVERFLOW                        00-00000040-00000000
  */
 
-#define MIB_COUNTER_OVERFLOW           BIT(6)
-#define MIB_COUNTER_VALID              BIT(5)
-
 #define MIB_COUNTER_VALUE              0x3FFFFFFF
 
 #define KS_MIB_TOTAL_RX_0              0x100