diff --git a/feeds/ipq807x/ipq807x/patches/700-RTL8367C_S.patch b/feeds/ipq807x/ipq807x/patches/700-RTL8367C_S.patch index 2515c6593..1e3f06333 100644 --- a/feeds/ipq807x/ipq807x/patches/700-RTL8367C_S.patch +++ b/feeds/ipq807x/ipq807x/patches/700-RTL8367C_S.patch @@ -548,7 +548,7 @@ Index: linux-4.4.60-qsdk-11f09717303ecd83c3a64e9efe23f25921dc1016/drivers/net/ph =================================================================== --- /dev/null +++ linux-4.4.60-qsdk-11f09717303ecd83c3a64e9efe23f25921dc1016/drivers/net/phy/rtl8367c.c -@@ -0,0 +1,2462 @@ +@@ -0,0 +1,2976 @@ +/* + * Platform driver for the Realtek RTL8367R-VB/S/C ethernet switches + * @@ -568,6 +568,14 @@ Index: linux-4.4.60-qsdk-11f09717303ecd83c3a64e9efe23f25921dc1016/drivers/net/ph +#include +#include +#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++ + +#include "rtl8366_smi.h" + @@ -845,6 +853,84 @@ Index: linux-4.4.60-qsdk-11f09717303ecd83c3a64e9efe23f25921dc1016/drivers/net/ph + +#define RTL8367S_DW8051_EN_OFFSET 5 +#define SGMII_INIT_SIZE 1223 ++ ++/*****/ ++#define RTL8367S_REG_SPEED_SELECTION_LOW_OFFSET 13 ++#define RTL8367S_REG_AUTO_NEGO_EN_OFFSET 12 ++#define RTL8367S_REG_POWER_DOWN_OFFSET 11 ++#define RTL8367S_REG_RESTART_AUTO_NEGO_OFFSET 9 ++#define RTL8367S_REG_DUPLEX_MODE_OFFSET 8 ++#define RTL8367S_REG_SPEED_SELECTION_HIGH_OFFSET 6 ++#define RTL8367S_SET_BIT(x,bit) (x |= (1<>bit)&0x1) ++ ++#define PHY_CONTROL_REG 0 ++#define PHY_STATUS_REG 1 ++#define RTL8367C_REGBITLENGTH 16 ++#define RTL8367C_REG_PHY_AD 0x130f ++#define RTL8367C_PDNPHY_OFFSET 5 ++#define MDC_MDIO_PHY_ID 0x1d /* PHY ID 0 or 29 */ ++#define MDC_MDIO_CTRL0_REG 0x1f ++#define MDC_MDIO_ADDR_OP 0x000E ++#define MDC_MDIO_ADDRESS_REG 0x17 ++#define MDC_MDIO_DATA_WRITE_REG 0x18 ++#define MDC_MDIO_CTRL1_REG 0x15 ++#define MDC_MDIO_WRITE_OP 0x0003 ++#define MDC_MDIO_READ_OP 0x0001 ++#define MDC_MDIO_DATA_READ_REG 0x19 ++#ifdef MDIO_12_5_MHZ ++#define CTRL_0_REG_C45_DEFAULT_VALUE 0x15107 ++#else ++#define CTRL_0_REG_C45_DEFAULT_VALUE 0x151FF ++#endif ++#define IPQ_MDIO_BASE 0x90000 ++#define MDIO_CTRL_0_REG 0x40 ++#define MDIO_CTRL_1_REG 0x44 ++#define MDIO_CTRL_2_REG 0x48 ++#define MDIO_CTRL_3_REG 0x4c ++#define MDIO_CTRL_4_REG 0x50 ++#define MDIO_CTRL_4_ACCESS_BUSY (1 << 16) ++#define MDIO_CTRL_4_ACCESS_START (1 << 8) ++#define MDIO_CTRL_4_ACCESS_CODE_READ 0 ++#define MDIO_CTRL_4_ACCESS_CODE_WRITE 1 ++#define MDIO_CTRL_4_ACCESS_CODE_C45_ADDR 0 ++#define MDIO_CTRL_4_ACCESS_CODE_C45_WRITE 1 ++#define MDIO_CTRL_4_ACCESS_CODE_C45_READ 2 ++#define CTRL_0_REG_DEFAULT_VALUE 0x150FF ++#define MDIO_CTRL_4_ACCESS_BUSY (1 << 16) ++#define IPQ_MDIO_RETRY 1000 ++#define IPQ_MDIO_DELAY 5 ++#define RTL8367C_REG_GPHY_OCP_MSB_0 0x1d15 ++#define RTL8367C_CFG_CPU_OCPADR_MSB_MASK 0xFC0 ++#define RTL8367C_PHY_BASE 0x2000 ++#define RTL8367C_PHY_EXT_BASE 0xA000 ++#define RTL8367C_REGDATAMAX 0xFFFF ++#define RTL8367C_PHY_OFFSET 5 ++#define RTL8367C_PHY_REGNOMAX 0x1F ++ ++typedef enum rt_error_code_e ++{ ++ RT_ERR_FAILED = -1, /* General Error */ ++ /* 0x0000xxxx for common error code */ ++ RT_ERR_OK = 0, /* 0x00000000, OK */ ++ RT_ERR_INPUT, /* 0x00000001, invalid input parameter */ ++ RT_ERR_UNIT_ID, /* 0x00000002, invalid unit id */ ++ RT_ERR_PORT_ID, /* 0x00000003, invalid port id */ ++ RT_ERR_PORT_MASK, /* 0x00000004, invalid port mask */ ++ RT_ERR_PORT_LINKDOWN, /* 0x00000005, link down port status */ ++ RT_ERR_ENTRY_INDEX, /* 0x00000006, invalid entry index */ ++ RT_ERR_NULL_POINTER, /* 0x00000007, input parameter is null pointer */ ++ RT_ERR_QUEUE_ID, /* 0x00000008, invalid queue id */ ++ RT_ERR_QUEUE_NUM, /* 0x00000009, invalid queue number */ ++ RT_ERR_BUSYWAIT_TIMEOUT, /* 0x0000000a, busy watting time out */ ++ RT_ERR_MAC, /* 0x0000000b, invalid mac address */ ++ RT_ERR_OUT_OF_RANGE, /* 0x0000000c, input parameter out of range */ ++ RT_ERR_PHY_REG_ID, /* 0x000e0001, invalid PHY reg id*/ ++ RT_ERR_SMI, /* 0x0000000e, SMI error */ ++}; ++ +u8 Sgmii_Init[SGMII_INIT_SIZE] = { +0x02,0x03,0xA9,0xE4,0xF5,0xA8, +0xD2,0xAF,0x22,0x00,0x00,0x02,0x04,0x35, @@ -1235,6 +1321,7 @@ Index: linux-4.4.60-qsdk-11f09717303ecd83c3a64e9efe23f25921dc1016/drivers/net/ph +0x00,0x00,0x42,0x06,0x31,0x00,0x00,0x00, +0xE4,0xF5,0x8E,0x22}; + ++static int rtl8367c_setAsicReg(struct rtl8366_smi *smi,u32 reg, u32 value); + +struct rtl8367b_initval { + u16 reg; @@ -2159,7 +2246,423 @@ Index: linux-4.4.60-qsdk-11f09717303ecd83c3a64e9efe23f25921dc1016/drivers/net/ph + return 0; +} + ++static int rtl8367c_setAsicReg(struct rtl8366_smi *smi, u32 reg, u32 value) ++{ + ++ int err; ++ ++ REG_WR(smi, reg, value); ++ if(err != RT_ERR_OK) ++ return RT_ERR_SMI; ++ ++ return RT_ERR_OK; ++} ++ ++static int rtl8367c_getAsicReg(struct rtl8366_smi *smi, u32 reg, u32 *pValue) ++{ ++ u32 regData; ++ int err; ++ ++ REG_RD(smi, reg, ®Data); ++ if(err != RT_ERR_OK) ++ return RT_ERR_SMI; ++ ++ *pValue = regData; ++ ++ return RT_ERR_OK; ++} ++ ++static int rtl8367c_setAsicRegBits(struct rtl8366_smi *smi, u32 reg, u32 bits, u32 value) ++{ ++ u32 regData; ++ int err; ++ u32 bitsShift; ++ u32 valueShifted; ++ ++ if(bits >= (1 << RTL8367C_REGBITLENGTH) ) ++ return RT_ERR_INPUT; ++ ++ bitsShift = 0; ++ while(!(bits & (1 << bitsShift))) ++ { ++ bitsShift++; ++ if(bitsShift >= RTL8367C_REGBITLENGTH) ++ return RT_ERR_INPUT; ++ } ++ valueShifted = value << bitsShift; ++ ++ if(valueShifted > RTL8367C_REGDATAMAX) ++ return RT_ERR_INPUT; ++ REG_RD(smi, reg, ®Data); ++ if(err != RT_ERR_OK) ++ return RT_ERR_SMI; ++ regData = regData & (~bits); ++ regData = regData | (valueShifted & bits); ++ REG_WR(smi, reg, regData); ++ if(err != RT_ERR_OK) ++ return RT_ERR_SMI; ++ ++ return RT_ERR_OK; ++} ++ ++static int rtl8367c_getAsicPHYOCPReg(struct rtl8366_smi *smi, int phyNo, u32 ocpAddr, u32 *pRegData) ++{ ++ int retVal; ++ u32 regAddr; ++ u32 ocpAddrPrefix, ocpAddr9_6, ocpAddr5_1; ++ ++ /* OCP prefix */ ++ ocpAddrPrefix = ((ocpAddr & 0xFC00) >> 10); ++ retVal = rtl8367c_setAsicRegBits(smi, RTL8367C_REG_GPHY_OCP_MSB_0, RTL8367C_CFG_CPU_OCPADR_MSB_MASK, ocpAddrPrefix); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ /*prepare access address*/ ++ ocpAddr9_6 = ((ocpAddr >> 6) & 0x000F); ++ ocpAddr5_1 = ((ocpAddr >> 1) & 0x001F); ++ regAddr = RTL8367C_PHY_BASE | (ocpAddr9_6 << 8) | (phyNo << RTL8367C_PHY_OFFSET) | ocpAddr5_1; ++ retVal = rtl8367c_getAsicReg(smi, regAddr, pRegData); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++ ++ ++} ++ ++static int rtl8367c_setAsicPHYOCPReg(struct rtl8366_smi *smi, int phyNo, u32 ocpAddr, u32 ocpData ) ++{ ++ int retVal; ++ u32 regAddr; ++ u32 ocpAddrPrefix, ocpAddr9_6, ocpAddr5_1; ++ ++ /* OCP prefix */ ++ ocpAddrPrefix = ((ocpAddr & 0xFC00) >> 10); ++ if((retVal = rtl8367c_setAsicRegBits(smi, RTL8367C_REG_GPHY_OCP_MSB_0, RTL8367C_CFG_CPU_OCPADR_MSB_MASK, ocpAddrPrefix)) != RT_ERR_OK) ++ return retVal; ++ ++ /*prepare access address*/ ++ ocpAddr9_6 = ((ocpAddr >> 6) & 0x000F); ++ ocpAddr5_1 = ((ocpAddr >> 1) & 0x001F); ++ regAddr = RTL8367C_PHY_BASE | (ocpAddr9_6 << 8) | (phyNo << RTL8367C_PHY_OFFSET) | ocpAddr5_1; ++ if((retVal = rtl8367c_setAsicReg(smi, regAddr, ocpData)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++static u16 rtl8367c_getAsicPHYReg(struct rtl8366_smi *smi, int phyNo, u32 phyAddr, u32 *pRegData ) ++{ ++ u32 ocp_addr; ++ ++ ocp_addr = 0xa400 + phyAddr*2; ++ ++ return rtl8367c_getAsicPHYOCPReg(smi, phyNo, ocp_addr, pRegData); ++} ++ ++static u32 rtl8367c_setAsicPHYReg(struct rtl8366_smi *smi, int phyNo, u32 phyAddr, u32 phyData ) ++{ ++ u32 ocp_addr; ++ ++ if(phyAddr > RTL8367C_PHY_REGNOMAX) ++ return RT_ERR_PHY_REG_ID; ++ ++ ocp_addr = 0xa400 + phyAddr*2; ++ ++ return rtl8367c_setAsicPHYOCPReg(smi, phyNo, ocp_addr, phyData); ++} ++ ++static int dal_rtl8367c_port_phyReg_set(struct rtl8366_smi *smi, int port, u32 reg, u32 regData) ++{ ++ int retVal; ++ ++ ++ if ((retVal = rtl8367c_setAsicPHYReg(smi, port, reg, regData)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++static int dal_rtl8367c_port_phyReg_get(struct rtl8366_smi *smi, int port, u32 reg, u32 *pData) ++{ ++ int retVal; ++ ++ ++ if ((retVal = rtl8367c_getAsicPHYReg(smi, port, reg, pData)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++static int ipq_mdio_wait_busy(void) ++{ ++ int i; ++ u32 busy; ++ for (i = 0; i < IPQ_MDIO_RETRY; i++) { ++ busy = readl(IPQ_MDIO_BASE + ++ MDIO_CTRL_4_REG) & ++ MDIO_CTRL_4_ACCESS_BUSY; ++ if (!busy) ++ return 0; ++ } ++ printk("%s: MDIO operation timed out\n",__func__); ++ return -ETIMEDOUT; ++} ++ ++ ++static int rtk_mdio_write(struct rtl8366_smi *smi, int mii_id, int regnum, u32 value) ++{ ++ u32 cmd; ++ ++ if (regnum & MII_ADDR_C45) { ++ unsigned int mmd = (regnum >> 16) & 0x1F; ++ unsigned int reg = regnum & 0xFFFF; ++ ++ writel(CTRL_0_REG_C45_DEFAULT_VALUE, ++ IPQ_MDIO_BASE + MDIO_CTRL_0_REG); ++ ++ /* Issue the phy address and reg */ ++ writel((mii_id << 8) | mmd, ++ IPQ_MDIO_BASE + MDIO_CTRL_1_REG); ++ ++ writel(reg, IPQ_MDIO_BASE + MDIO_CTRL_2_REG); ++ ++ /* issue read command */ ++ cmd = MDIO_CTRL_4_ACCESS_START | MDIO_CTRL_4_ACCESS_CODE_C45_ADDR; ++ ++ writel(cmd, IPQ_MDIO_BASE + MDIO_CTRL_4_REG); ++ ++ if (ipq_mdio_wait_busy()) ++ return -ETIMEDOUT; ++ } else { ++ writel(CTRL_0_REG_DEFAULT_VALUE, ++ IPQ_MDIO_BASE + MDIO_CTRL_0_REG); ++ ++ /* Issue the phy addreass and reg */ ++ writel((mii_id << 8 | regnum), ++ IPQ_MDIO_BASE + MDIO_CTRL_1_REG); ++ } ++ ++ /* Issue a write data */ ++ writel(value, IPQ_MDIO_BASE + MDIO_CTRL_2_REG); ++ ++ if (regnum & MII_ADDR_C45) { ++ cmd = MDIO_CTRL_4_ACCESS_START | MDIO_CTRL_4_ACCESS_CODE_C45_WRITE ; ++ } else { ++ cmd = MDIO_CTRL_4_ACCESS_START | MDIO_CTRL_4_ACCESS_CODE_WRITE ; ++ } ++ ++ writel(cmd, IPQ_MDIO_BASE + MDIO_CTRL_4_REG); ++ /* Wait for write complete */ ++ ++ if (ipq_mdio_wait_busy()) ++ return -ETIMEDOUT; ++ ++ return 0; ++} ++ ++static int rtk_mdio_read(struct rtl8366_smi *smi, int mii_id, int regnum, u32 *data) ++{ ++ u32 val,cmd; ++ ++ if (regnum & MII_ADDR_C45) { ++ ++ unsigned int mmd = (regnum >> 16) & 0x1F; ++ unsigned int reg = regnum & 0xFFFF; ++ ++ writel(CTRL_0_REG_C45_DEFAULT_VALUE, ++ IPQ_MDIO_BASE + MDIO_CTRL_0_REG); ++ ++ /* Issue the phy address and reg */ ++ writel((mii_id << 8) | mmd, ++ IPQ_MDIO_BASE + MDIO_CTRL_1_REG); ++ ++ ++ writel(reg, IPQ_MDIO_BASE + MDIO_CTRL_2_REG); ++ ++ /* issue read command */ ++ cmd = MDIO_CTRL_4_ACCESS_START | MDIO_CTRL_4_ACCESS_CODE_C45_ADDR; ++ } else { ++ ++ writel(CTRL_0_REG_DEFAULT_VALUE, ++ IPQ_MDIO_BASE + MDIO_CTRL_0_REG); ++ ++ /* Issue the phy address and reg */ ++ writel((mii_id << 8 | regnum ) , ++ IPQ_MDIO_BASE + MDIO_CTRL_1_REG); ++ ++ /* issue read command */ ++ cmd = MDIO_CTRL_4_ACCESS_START | MDIO_CTRL_4_ACCESS_CODE_READ ; ++ } ++ ++ /* issue read command */ ++ writel(cmd, IPQ_MDIO_BASE + MDIO_CTRL_4_REG); ++ ++ if (ipq_mdio_wait_busy()) ++ return -ETIMEDOUT; ++ ++ if (regnum & MII_ADDR_C45) { ++ cmd = MDIO_CTRL_4_ACCESS_START | MDIO_CTRL_4_ACCESS_CODE_C45_READ; ++ writel(cmd, IPQ_MDIO_BASE + MDIO_CTRL_4_REG); ++ ++ if (ipq_mdio_wait_busy()) ++ return -ETIMEDOUT; ++ } ++ ++ /* Read data */ ++ val = readl(IPQ_MDIO_BASE + MDIO_CTRL_3_REG); ++ ++ if (data != NULL) ++ *data = val; ++ ++ return val; ++} ++ ++static int rtl8367c_setAsicRegBit(struct rtl8366_smi *smi, u32 reg, u32 bit, u32 value) ++{ ++ u32 regData; ++ int err; ++ ++ if(bit >= RTL8367C_REGBITLENGTH) ++ return RT_ERR_INPUT; ++ ++ REG_RD(smi, reg, ®Data); ++ if(err != RT_ERR_OK) ++ return RT_ERR_SMI; ++ ++ if(value) ++ regData = regData | (1 << bit); ++ else ++ regData = regData & (~(1 << bit)); ++ ++ REG_WR(smi, reg, regData); ++ if(err != RT_ERR_OK) ++ return RT_ERR_SMI; ++ ++ return RT_ERR_OK; ++} ++ ++static int rtl8367c_setAsicPortEnableAll(struct rtl8366_smi *smi, u32 enable) ++{ ++ if(enable >= 2) ++ return RT_ERR_INPUT; ++ return rtl8367c_setAsicRegBit(smi, RTL8367C_REG_PHY_AD, RTL8367C_PDNPHY_OFFSET, enable); ++} ++ ++static int dal_rtl8367c_port_phyEnableAll_set(struct switch_dev *dev,const struct switch_attr *attr,struct switch_val *val) ++{ ++ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); ++ int retVal; ++ u32 data; ++ int port = val->port_vlan; ++ int enable; ++ enable = val->value.i; ++ if(enable >= 2) ++ return -EINVAL; ++ ++ if ((retVal = rtl8367c_setAsicPortEnableAll(smi, enable)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = dal_rtl8367c_port_phyReg_get(smi, port, PHY_CONTROL_REG, &data)) != RT_ERR_OK) ++ return retVal; ++ ++ if (1 == enable) ++ { ++ RTL8367S_CLEAR_BIT(data,RTL8367S_REG_POWER_DOWN_OFFSET); ++ RTL8367S_SET_BIT(data,RTL8367S_REG_RESTART_AUTO_NEGO_OFFSET); ++ } ++ else ++ { ++ RTL8367S_SET_BIT(data,RTL8367S_REG_POWER_DOWN_OFFSET); ++ } ++ ++ if ((retVal = dal_rtl8367c_port_phyReg_set(smi, port, PHY_CONTROL_REG, data)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++int get_port_state(struct switch_dev *dev,const struct switch_attr *attr,struct switch_val *val) ++{ ++ ++ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); ++ u32 data; ++ int port; ++ port = val->port_vlan; ++ ++ dal_rtl8367c_port_phyReg_get(smi, port, PHY_CONTROL_REG, &data); ++ ++ if(RTL8367S_CHECK_BIT(data,RTL8367S_REG_POWER_DOWN_OFFSET)) //check whether bit11 is true ++ { ++ printk("disabled\n"); ++ } ++ else ++ { ++ printk("enabled\n"); ++ } ++ ++ return 0; ++} ++ ++static int dal_rtl8367c_port_crtl_status(struct switch_dev *dev,const struct switch_attr *attr,struct switch_val *val) ++{ ++ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); ++ int retVal; ++ u32 data; ++ int port = val->port_vlan; ++ int enable; ++ enable = val->value.i; ++ if(enable >= 5) ++ return -EINVAL; ++ if ((retVal = dal_rtl8367c_port_phyReg_get(smi, port, PHY_CONTROL_REG, &data)) != RT_ERR_OK) ++ return retVal; ++ RTL8367S_CLEAR_BIT(data,RTL8367S_REG_AUTO_NEGO_EN_OFFSET); //diasble auto ++ switch(enable) ++ { ++ case 0: //10M-half ++ { ++ RTL8367S_CLEAR_BIT(data,RTL8367S_REG_DUPLEX_MODE_OFFSET); ++ RTL8367S_CLEAR_BIT(data,RTL8367S_REG_SPEED_SELECTION_LOW_OFFSET); ++ RTL8367S_CLEAR_BIT(data,RTL8367S_REG_SPEED_SELECTION_HIGH_OFFSET); ++ } ++ break; ++ case 1: //10M-full ++ { ++ RTL8367S_SET_BIT(data,RTL8367S_REG_DUPLEX_MODE_OFFSET); ++ RTL8367S_CLEAR_BIT(data,RTL8367S_REG_SPEED_SELECTION_LOW_OFFSET); ++ RTL8367S_CLEAR_BIT(data,RTL8367S_REG_SPEED_SELECTION_HIGH_OFFSET); ++ } ++ break; ++ case 2: //100M-half ++ { ++ RTL8367S_CLEAR_BIT(data,RTL8367S_REG_DUPLEX_MODE_OFFSET); ++ RTL8367S_SET_BIT(data,RTL8367S_REG_SPEED_SELECTION_LOW_OFFSET); ++ RTL8367S_CLEAR_BIT(data,RTL8367S_REG_SPEED_SELECTION_HIGH_OFFSET); ++ } ++ break; ++ case 3: //100M-full ++ { ++ RTL8367S_SET_BIT(data,RTL8367S_REG_DUPLEX_MODE_OFFSET); ++ RTL8367S_SET_BIT(data,RTL8367S_REG_SPEED_SELECTION_LOW_OFFSET); ++ RTL8367S_CLEAR_BIT(data,RTL8367S_REG_SPEED_SELECTION_HIGH_OFFSET); ++ } ++ break; ++ case 4: //1000M-full == auto ++ { ++ RTL8367S_SET_BIT(data,RTL8367S_REG_AUTO_NEGO_EN_OFFSET); ++ RTL8367S_SET_BIT(data,RTL8367S_REG_DUPLEX_MODE_OFFSET); ++ RTL8367S_CLEAR_BIT(data,RTL8367S_REG_SPEED_SELECTION_LOW_OFFSET); ++ RTL8367S_SET_BIT(data,RTL8367S_REG_SPEED_SELECTION_HIGH_OFFSET); ++ } ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ if ((retVal = dal_rtl8367c_port_phyReg_set(smi, port, PHY_CONTROL_REG, data)) != RT_ERR_OK) ++ return retVal; ++ return RT_ERR_OK; ++} + +static int rtl8367s_extif_set_force(struct rtl8366_smi *smi, int id, int mode, + struct rtl8367_port_ability *pa) @@ -2610,7 +3113,6 @@ Index: linux-4.4.60-qsdk-11f09717303ecd83c3a64e9efe23f25921dc1016/drivers/net/ph + rtl8366_smi_read_reg(smi, RTL8367S_SDS_MISC, &sds_misc); + + rtl8366_smi_read_reg(smi, RTL8367B_PORT_STATUS_REG(port), &data); -+ + link->link = !!(data & RTL8367B_PORT_STATUS_LINK); + if (!link->link) + return 0; @@ -2684,14 +3186,13 @@ Index: linux-4.4.60-qsdk-11f09717303ecd83c3a64e9efe23f25921dc1016/drivers/net/ph + RTL8367B_SWC0_MAX_LENGTH_MASK, max_len); +} + -+ +static int rtl8367b_sw_reset_port_mibs(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val) +{ + struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); + int port; -+ ++ + port = val->port_vlan; + if (port >= RTL8367B_NUM_PORTS) + return -EINVAL; @@ -2747,6 +3248,20 @@ Index: linux-4.4.60-qsdk-11f09717303ecd83c3a64e9efe23f25921dc1016/drivers/net/ph + .max = 33, + .set = NULL, + .get = rtl8366_sw_get_port_mib, ++ }, { ++ .type = SWITCH_TYPE_INT, ++ .name = "enable_port", ++ .description = "Enable or disable the port", ++ .set = dal_rtl8367c_port_phyEnableAll_set, ++ .get = get_port_state, ++ .max = 1, ++ }, { ++ .type = SWITCH_TYPE_INT, ++ .name = "set_autoNego", ++ .description = "Set auto nego of the port---" ++ "0:10M-half 1:10M-full 2:100M-half 3:100M-full 4:1000M-full(auto)", ++ .set = dal_rtl8367c_port_crtl_status, ++ .max = 4, + }, +}; + @@ -3006,10 +3521,9 @@ Index: linux-4.4.60-qsdk-11f09717303ecd83c3a64e9efe23f25921dc1016/drivers/net/ph + +module_platform_driver(rtl8367b_driver); + -+MODULE_DESCRIPTION(RTL8367B_DRIVER_DESC); -+MODULE_AUTHOR("Gabor Juhos "); ++MODULE_DESCRIPTION(RTL8367S_DRIVER_DESC); +MODULE_LICENSE("GPL v2"); -+MODULE_ALIAS("platform:" RTL8367B_DRIVER_NAME); ++MODULE_ALIAS("platform:" RTL8367S_DRIVER_NAME); + Index: linux-4.4.60-qsdk-11f09717303ecd83c3a64e9efe23f25921dc1016/include/linux/rtl8367.h ===================================================================