mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-10-29 17:42:41 +00:00
ipq807x: CIG WF186w: support port and autoNego setting from user space
Fixes: WIFI-12963 Signed-off-by: Ken <xshi@actiontec.com>
This commit is contained in:
@@ -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 <linux/delay.h>
|
||||
+#include <linux/skbuff.h>
|
||||
+#include <linux/rtl8367.h>
|
||||
+#include <linux/of_device.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+
|
||||
+#include <linux/pm.h>
|
||||
+#include <linux/err.h>
|
||||
+#include <linux/clk.h>
|
||||
+
|
||||
+
|
||||
+
|
||||
+#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))
|
||||
+#define RTL8367S_CLEAR_BIT(x,bit) (x &= ~(1<<bit))
|
||||
+#define RTL8367S_DATA_INIT 0x1140
|
||||
+#define RTL8367S_CHECK_BIT(x,bit) ((x>>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 <juhosg@openwrt.org>");
|
||||
+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
|
||||
===================================================================
|
||||
|
||||
Reference in New Issue
Block a user