mediatek: bump Airoha EN8811H driver to 1.2.4
Upstream commit:cf03c993d5Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org> (cherry picked from commit5c2fddf9b3)
This commit is contained in:
@@ -170,7 +170,7 @@
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&en8811_pwr_a>;
|
||||
|
||||
airoha,rx-pol-reverse;
|
||||
airoha,polarity = <3>;
|
||||
|
||||
interrupt-parent = <&pio>;
|
||||
interrupts = <48 IRQ_TYPE_LEVEL_HIGH>;
|
||||
@@ -189,7 +189,7 @@
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&en8811_pwr_b>;
|
||||
|
||||
airoha,rx-pol-reverse;
|
||||
airoha,polarity = <3>;
|
||||
|
||||
interrupt-parent = <&pio>;
|
||||
interrupts = <46 IRQ_TYPE_LEVEL_HIGH>;
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
#define MII_MMD_ADDR_DATA_REG 0x0e
|
||||
#define MMD_OP_MODE_DATA BIT(14)
|
||||
|
||||
#define EN8811H_DRIVER_VERSION "v1.2.2"
|
||||
#define EN8811H_DRIVER_VERSION "v1.2.4"
|
||||
|
||||
#define LED_ON_CTRL(i) (0x024 + ((i)*2))
|
||||
#define LED_ON_EN (1 << 15)
|
||||
@@ -95,6 +95,7 @@ struct en8811h_priv {
|
||||
unsigned int dm_crc32;
|
||||
unsigned int dsp_crc32;
|
||||
char buf[512];
|
||||
int pol;
|
||||
};
|
||||
|
||||
struct air_base_t_led_cfg {
|
||||
|
||||
@@ -87,7 +87,7 @@ int air_mii_cl22_write(struct mii_bus *ebus, int addr,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __air_mii_cl45_read(struct phy_device *phydev, int devad, u16 reg)
|
||||
int __air_mii_cl45_read(struct phy_device *phydev, int devad, u16 reg)
|
||||
{
|
||||
int ret = 0;
|
||||
int data;
|
||||
@@ -107,7 +107,7 @@ static int __air_mii_cl45_read(struct phy_device *phydev, int devad, u16 reg)
|
||||
return data;
|
||||
}
|
||||
|
||||
static int __air_mii_cl45_write(struct phy_device *phydev,
|
||||
int __air_mii_cl45_write(struct phy_device *phydev,
|
||||
int devad, u16 reg, u16 write_data)
|
||||
{
|
||||
int ret = 0;
|
||||
@@ -334,6 +334,40 @@ int air_buckpbus_reg_write(struct phy_device *phydev,
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#if defined(CONFIG_OF)
|
||||
int en8811h_of_init(struct phy_device *phydev)
|
||||
{
|
||||
struct device *dev = phydev_dev(phydev);
|
||||
struct device_node *of_node = dev->of_node;
|
||||
struct en8811h_priv *priv = phydev->priv;
|
||||
u32 val = 0;
|
||||
|
||||
dev_info(dev, "%s: start\n", __func__);
|
||||
if (of_find_property(of_node, "airoha,polarity", NULL)) {
|
||||
if (of_property_read_u32(of_node, "airoha,polarity",
|
||||
&val) != 0) {
|
||||
phydev_err(phydev, "airoha,polarity value is invalid.");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (val < AIR_POL_TX_REV_RX_NOR ||
|
||||
val > AIR_POL_TX_NOR_RX_REV) {
|
||||
phydev_err(phydev,
|
||||
"airoha,polarity value %u out of range.",
|
||||
val);
|
||||
return -EINVAL;
|
||||
}
|
||||
priv->pol = val;
|
||||
} else
|
||||
priv->pol = AIR_POL_TX_NOR_RX_NOR;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
int en8811h_of_init(struct phy_device *phydev)
|
||||
{
|
||||
return -ESRCH;
|
||||
}
|
||||
#endif /* CONFIG_OF */
|
||||
|
||||
static int air_resolve_an_speed(struct phy_device *phydev)
|
||||
{
|
||||
@@ -588,29 +622,19 @@ static int air_set_mode(struct phy_device *phydev, int dbg_mode)
|
||||
if (unlikely(ret < 0))
|
||||
break;
|
||||
break;
|
||||
case AIR_PORT_MODE_FC_DIS:
|
||||
pr_notice("\nFlow Control Disabled\n");
|
||||
pbus_data = air_buckpbus_reg_read(phydev, 0xe0008);
|
||||
pbus_data &= ~(BIT(6) | BIT(7));
|
||||
ret = air_buckpbus_reg_write(phydev, 0xe0008, pbus_data);
|
||||
if (unlikely(ret < 0))
|
||||
break;
|
||||
pbus_data = air_buckpbus_reg_read(phydev, 0xe000c);
|
||||
pbus_data &= ~(BIT(0) | BIT(1));
|
||||
ret = air_buckpbus_reg_write(phydev, 0xe000c, pbus_data);
|
||||
case AIR_PORT_MODE_SSC_DISABLE:
|
||||
pr_notice("\nSSC Disabled\n");
|
||||
pbus_data = air_buckpbus_reg_read(phydev, 0xca000);
|
||||
pbus_data &= ~BIT(21);
|
||||
ret = air_buckpbus_reg_write(phydev, 0xca000, pbus_data);
|
||||
if (unlikely(ret < 0))
|
||||
break;
|
||||
break;
|
||||
case AIR_PORT_MODE_FC_EN:
|
||||
pr_notice("\nFlow Control Enabled\n");
|
||||
pbus_data = air_buckpbus_reg_read(phydev, 0xe0008);
|
||||
pbus_data |= (BIT(6) | BIT(7));
|
||||
ret = air_buckpbus_reg_write(phydev, 0xe0008, pbus_data);
|
||||
if (unlikely(ret < 0))
|
||||
break;
|
||||
pbus_data = air_buckpbus_reg_read(phydev, 0xe000c);
|
||||
pbus_data |= (BIT(0) | BIT(1));
|
||||
ret = air_buckpbus_reg_write(phydev, 0xe000c, pbus_data);
|
||||
case AIR_PORT_MODE_SSC_ENABLE:
|
||||
pr_notice("\nSSC Enabled\n");
|
||||
pbus_data = air_buckpbus_reg_read(phydev, 0xca000);
|
||||
pbus_data |= BIT(21);
|
||||
ret = air_buckpbus_reg_write(phydev, 0xca000, pbus_data);
|
||||
if (unlikely(ret < 0))
|
||||
break;
|
||||
break;
|
||||
@@ -645,7 +669,6 @@ static int airphy_info_show(struct seq_file *seq, void *v)
|
||||
val = (air_buckpbus_reg_read(phydev, 0xca0f8) & 0x3);
|
||||
seq_printf(seq, "| Tx, Rx Polarity : %s(%02d)\n",
|
||||
tx_rx_string[val], val);
|
||||
|
||||
seq_puts(seq, "\n");
|
||||
|
||||
return 0;
|
||||
@@ -714,7 +737,7 @@ static int airphy_ss_counter_show(struct phy_device *phydev,
|
||||
seq_printf(seq, "%010u |\n", pkt_cnt);
|
||||
seq_puts(seq, "| RX Terminal :");
|
||||
pkt_cnt = air_buckpbus_reg_read(phydev, 0xC60C0);
|
||||
seq_printf(seq, "%010u |\n\n", pkt_cnt);
|
||||
seq_printf(seq, "%010u |\n", pkt_cnt);
|
||||
ret = air_buckpbus_reg_write(phydev, 0xC602C, 0x4);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
@@ -732,9 +755,29 @@ static int airphy_counter_show(struct seq_file *seq, void *v)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
seq_puts(seq, "==========AIR PHY COUNTER==========\n");
|
||||
if (phydev->link) {
|
||||
ret = airphy_ss_counter_show(phydev, seq);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
ret = airphy_fcm_counter_show(phydev, seq);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (phydev->link) {
|
||||
seq_puts(seq, "|\t<<MAC Counter>>\n");
|
||||
seq_puts(seq, "| Tx Error from System side:");
|
||||
pkt_cnt = air_buckpbus_reg_read(phydev, 0x131000);
|
||||
seq_printf(seq, "%010u |\n", pkt_cnt);
|
||||
seq_puts(seq, "| Rx Error to System side :");
|
||||
pkt_cnt = air_buckpbus_reg_read(phydev, 0x132000);
|
||||
seq_printf(seq, "%010u |\n", pkt_cnt);
|
||||
seq_puts(seq, "| Tx from System side :");
|
||||
pkt_cnt = air_buckpbus_reg_read(phydev, 0x131004);
|
||||
seq_printf(seq, "%010u |\n", pkt_cnt);
|
||||
seq_puts(seq, "| Rx to System Side :");
|
||||
pkt_cnt = air_buckpbus_reg_read(phydev, 0x132004);
|
||||
seq_printf(seq, "%010u |\n", pkt_cnt);
|
||||
}
|
||||
if (phydev->link && phydev->speed == SPEED_2500) {
|
||||
seq_puts(seq, "|\t<<LS Counter>>\n");
|
||||
ret = air_buckpbus_reg_write(phydev, 0x30718, 0x10);
|
||||
@@ -744,37 +787,37 @@ static int airphy_counter_show(struct seq_file *seq, void *v)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
seq_puts(seq, "|\tBefore EF\n");
|
||||
seq_puts(seq, "| TX to Line side_S :");
|
||||
seq_puts(seq, "| Tx to Line side_S :");
|
||||
pkt_cnt = air_buckpbus_reg_read(phydev, 0x3071c);
|
||||
seq_printf(seq, "%010u |\n", pkt_cnt);
|
||||
seq_puts(seq, "| TX to Line side_T :");
|
||||
seq_puts(seq, "| Tx to Line side_T :");
|
||||
pkt_cnt = air_buckpbus_reg_read(phydev, 0x30720);
|
||||
seq_printf(seq, "%010u |\n", pkt_cnt);
|
||||
seq_puts(seq, "| RX from Line side_S :");
|
||||
pkt_cnt = air_buckpbus_reg_read(phydev, 0x3072c);
|
||||
seq_printf(seq, "%010u |\n", pkt_cnt);
|
||||
seq_puts(seq, "| RX from Line side_T :");
|
||||
pkt_cnt = air_buckpbus_reg_read(phydev, 0x30730);
|
||||
seq_printf(seq, "%010u |\n", pkt_cnt);
|
||||
seq_puts(seq, "| TX_ENC :");
|
||||
seq_puts(seq, "| Tx_ENC :");
|
||||
pkt_cnt = air_buckpbus_reg_read(phydev, 0x30724);
|
||||
seq_printf(seq, "%010u |\n", pkt_cnt);
|
||||
seq_puts(seq, "| RX_DEC :");
|
||||
seq_puts(seq, "| Rx from Line side_S :");
|
||||
pkt_cnt = air_buckpbus_reg_read(phydev, 0x3072c);
|
||||
seq_printf(seq, "%010u |\n", pkt_cnt);
|
||||
seq_puts(seq, "| Rx from Line side_T :");
|
||||
pkt_cnt = air_buckpbus_reg_read(phydev, 0x30730);
|
||||
seq_printf(seq, "%010u |\n", pkt_cnt);
|
||||
seq_puts(seq, "| Rx_DEC :");
|
||||
pkt_cnt = air_buckpbus_reg_read(phydev, 0x30728);
|
||||
seq_printf(seq, "%010u |\n", pkt_cnt);
|
||||
seq_puts(seq, "|\tAfter EF\n");
|
||||
seq_puts(seq, "| TX to Line side_S :");
|
||||
seq_puts(seq, "| Tx to Line side_S :");
|
||||
pkt_cnt = air_buckpbus_reg_read(phydev, 0x30734);
|
||||
seq_printf(seq, "%010u |\n", pkt_cnt);
|
||||
seq_puts(seq, "| TX to Line side_T :");
|
||||
seq_puts(seq, "| Tx to Line side_T :");
|
||||
pkt_cnt = air_buckpbus_reg_read(phydev, 0x30738);
|
||||
seq_printf(seq, "%010u |\n", pkt_cnt);
|
||||
seq_puts(seq, "| RX from Line side_S :");
|
||||
seq_puts(seq, "| Rx from Line side_S :");
|
||||
pkt_cnt = air_buckpbus_reg_read(phydev, 0x30764);
|
||||
seq_printf(seq, "%010u |\n", pkt_cnt);
|
||||
seq_puts(seq, "| RX from Line side_T :");
|
||||
seq_puts(seq, "| Rx from Line side_T :");
|
||||
pkt_cnt = air_buckpbus_reg_read(phydev, 0x30768);
|
||||
seq_printf(seq, "%010u |\n", pkt_cnt);
|
||||
seq_printf(seq, "%010u |\n\n", pkt_cnt);
|
||||
ret = air_buckpbus_reg_write(phydev, 0x30718, 0x13);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
@@ -787,29 +830,16 @@ static int airphy_counter_show(struct seq_file *seq, void *v)
|
||||
ret = air_buckpbus_reg_write(phydev, 0x30718, 0x0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
seq_puts(seq, "|\t<<MAC Counter>>\n");
|
||||
seq_puts(seq, "| TX Error from System side:");
|
||||
pkt_cnt = air_buckpbus_reg_read(phydev, 0x131000);
|
||||
seq_printf(seq, "%010u |\n", pkt_cnt);
|
||||
seq_puts(seq, "| RX Error to System side :");
|
||||
pkt_cnt = air_buckpbus_reg_read(phydev, 0x132000);
|
||||
seq_printf(seq, "%010u |\n", pkt_cnt);
|
||||
seq_puts(seq, "| TX from System side :");
|
||||
pkt_cnt = air_buckpbus_reg_read(phydev, 0x131004);
|
||||
seq_printf(seq, "%010u |\n", pkt_cnt);
|
||||
seq_puts(seq, "| RX to System Side :");
|
||||
pkt_cnt = air_buckpbus_reg_read(phydev, 0x132004);
|
||||
seq_printf(seq, "%010u |\n", pkt_cnt);
|
||||
}
|
||||
if (phydev->link && ((phydev->speed != SPEED_2500))) {
|
||||
seq_puts(seq, "|\t<<LS Counter>>\n");
|
||||
ret = air_mii_cl22_write(mbus, addr, 0x1f, 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
seq_puts(seq, "| RX from Line side :");
|
||||
seq_puts(seq, "| Rx from Line side :");
|
||||
pkt_cnt = air_mii_cl22_read(mbus, addr, 0x12) & 0x7fff;
|
||||
seq_printf(seq, "%010u |\n", pkt_cnt);
|
||||
seq_puts(seq, "| RX Error from Line side :");
|
||||
seq_puts(seq, "| Rx Error from Line side :");
|
||||
pkt_cnt = air_mii_cl22_read(mbus, addr, 0x17) & 0xff;
|
||||
seq_printf(seq, "%010u |\n", pkt_cnt);
|
||||
ret = air_mii_cl22_write(mbus, addr, 0x1f, 0);
|
||||
@@ -821,22 +851,17 @@ static int airphy_counter_show(struct seq_file *seq, void *v)
|
||||
ret = air_mii_cl22_write(mbus, addr, 0x10, 0xBF92);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
seq_puts(seq, "| TX to Line side :");
|
||||
seq_puts(seq, "| Tx to Line side :");
|
||||
pkt_cnt = (air_mii_cl22_read(mbus, addr, 0x11) & 0x7ffe) >> 1;
|
||||
seq_printf(seq, "%010u |\n", pkt_cnt);
|
||||
seq_puts(seq, "| TX Error to Line side :");
|
||||
seq_puts(seq, "| Tx Error to Line side :");
|
||||
pkt_cnt = air_mii_cl22_read(mbus, addr, 0x12);
|
||||
pkt_cnt &= 0x7f;
|
||||
seq_printf(seq, "%010u |\n", pkt_cnt);
|
||||
seq_printf(seq, "%010u |\n\n", pkt_cnt);
|
||||
ret = air_mii_cl22_write(mbus, addr, 0x1f, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
if (phydev->link) {
|
||||
ret = airphy_ss_counter_show(phydev, seq);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -901,6 +926,7 @@ static void airphy_port_mode_help(void)
|
||||
"echo 2500 > /[debugfs]/port_mode\n"
|
||||
"echo 1000 > /[debugfs]/port_mode\n"
|
||||
"echo 100 > /[debugfs]/port_mode\n"
|
||||
"echo ssc ena/dis > /[debugfs]/port_mode\n"
|
||||
"echo power up/down > /[debugfs]/port_mode\n");
|
||||
}
|
||||
|
||||
@@ -941,9 +967,11 @@ static ssize_t airphy_port_mode(struct file *file, const char __user *ptr,
|
||||
ret = air_set_mode(phydev, AIR_PORT_MODE_POWER_DOWN);
|
||||
else if (!strncmp("up", param, strlen("up")))
|
||||
ret = air_set_mode(phydev, AIR_PORT_MODE_POWER_UP);
|
||||
} else if (!strncmp("int_sw_release", cmd, strlen("int_sw_release"))) {
|
||||
ret = air_pbus_reg_write(phydev, 0xcf928, 0x0);
|
||||
pr_notice("\ninternal sw reset released\n");
|
||||
} else if (!strncmp("ssc", cmd, strlen("ssc"))) {
|
||||
if (!strncmp("dis", param, strlen("dis")))
|
||||
ret = air_set_mode(phydev, AIR_PORT_MODE_SSC_DISABLE);
|
||||
else if (!strncmp("ena", param, strlen("ena")))
|
||||
ret = air_set_mode(phydev, AIR_PORT_MODE_SSC_ENABLE);
|
||||
} else if (!strncmp("help", cmd, strlen("help"))) {
|
||||
airphy_port_mode_help();
|
||||
}
|
||||
@@ -1088,10 +1116,24 @@ static int dbg_regs_show(struct seq_file *seq, void *v)
|
||||
int addr = phydev_addr(phydev);
|
||||
|
||||
seq_puts(seq, "\t<<DEBUG REG DUMP>>\n");
|
||||
seq_printf(seq, "| RG_MII_BMCR : 0x%08x |\n",
|
||||
air_mii_cl22_read(mbus, addr, MII_BMCR));
|
||||
seq_printf(seq, "| RG_MII_BMSR : 0x%08x |\n",
|
||||
air_mii_cl22_read(mbus, addr, MII_BMSR));
|
||||
seq_printf(seq, "| RG_MII_ADVERTISE : 0x%08x |\n",
|
||||
air_mii_cl22_read(mbus, addr, MII_ADVERTISE));
|
||||
seq_printf(seq, "| RG_MII_LPA : 0x%08x |\n",
|
||||
air_mii_cl22_read(mbus, addr, MII_LPA));
|
||||
seq_printf(seq, "| RG_MII_CTRL1000 : 0x%08x |\n",
|
||||
air_mii_cl22_read(mbus, addr, MII_CTRL1000));
|
||||
seq_printf(seq, "| RG_MII_STAT1000 : 0x%08x |\n",
|
||||
air_mii_cl22_read(mbus, addr, MII_STAT1000));
|
||||
seq_printf(seq, "| RG_MII_REF_CLK : 0x%08x |\n",
|
||||
air_mii_cl22_read(mbus, addr, 0x1d));
|
||||
seq_printf(seq, "| RG_HW_STRAP1 : 0x%08x |\n",
|
||||
air_buckpbus_reg_read(phydev, 0xcf910));
|
||||
seq_printf(seq, "| RG_HW_STRAP2 : 0x%08x |\n",
|
||||
air_buckpbus_reg_read(phydev, 0xcf914));
|
||||
seq_printf(seq, "| RG_SYS_LINK_MODE : 0x%08x |\n",
|
||||
air_buckpbus_reg_read(phydev, 0xe0004));
|
||||
seq_printf(seq, "| RG_FCM_CTRL : 0x%08x |\n",
|
||||
@@ -1119,11 +1161,144 @@ static int airphy_dbg_regs_show_open(struct inode *inode, struct file *file)
|
||||
return single_open(file, dbg_regs_show, inode->i_private);
|
||||
}
|
||||
|
||||
|
||||
static int airphy_temp_show(struct seq_file *seq, void *v)
|
||||
{
|
||||
struct phy_device *phydev = seq->private;
|
||||
int ret = 0;
|
||||
u32 pbus_value = 0;
|
||||
|
||||
seq_puts(seq, "<<AIR EN8811H Temp>>\n");
|
||||
air_mii_cl45_write(phydev, 0x1e, 0x800e, 0x1100);
|
||||
air_mii_cl45_write(phydev, 0x1e, 0x800f, 0xe5);
|
||||
pbus_value = air_buckpbus_reg_read(phydev, 0x3B38);
|
||||
seq_printf(seq, "| Temperature : %dC |\n",
|
||||
pbus_value);
|
||||
seq_puts(seq, "\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int airphy_temp_show_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, airphy_temp_show, inode->i_private);
|
||||
}
|
||||
|
||||
|
||||
static unsigned int air_read_lp_speed(struct phy_device *phydev)
|
||||
{
|
||||
int val = 0, an = AUTONEG_DISABLE;
|
||||
unsigned int ret = 0;
|
||||
int count = 15, i, lpa, lpagb;
|
||||
struct air_lp_speed *m;
|
||||
struct device *dev = phydev_dev(phydev);
|
||||
struct mii_bus *mbus = phydev_mdio_bus(phydev);
|
||||
int addr = phydev_addr(phydev);
|
||||
|
||||
val = air_mii_cl22_read(mbus, addr, MII_BMCR) | BIT(9);
|
||||
ret = air_mii_cl22_write(mbus, addr, MII_BMCR, val);
|
||||
if (unlikely(ret < 0))
|
||||
return ret;
|
||||
msleep(1500);
|
||||
do {
|
||||
msleep(100);
|
||||
ret = air_mii_cl45_read(phydev, MDIO_MMD_AN, 0x21);
|
||||
ret &= BIT(5);
|
||||
if (ret)
|
||||
break;
|
||||
count--;
|
||||
} while (count);
|
||||
|
||||
count = 10;
|
||||
do {
|
||||
msleep(500);
|
||||
val = air_mii_cl22_read(mbus, addr, MII_BMSR);
|
||||
if (val < 0) {
|
||||
dev_err(dev, "MII_BMSR reg 0x%x!\n", val);
|
||||
return val;
|
||||
}
|
||||
val = air_mii_cl22_read(mbus, addr, MII_BMSR);
|
||||
if (val < 0) {
|
||||
dev_err(dev, "MII_BMSR reg 0x%x!\n", val);
|
||||
return val;
|
||||
}
|
||||
dev_dbg(dev, "val 0x%x\n", val);
|
||||
if (val & BMSR_LSTATUS) {
|
||||
val = air_mii_cl22_read(mbus, addr, MII_LPA);
|
||||
if (val < 0)
|
||||
return val;
|
||||
lpa = (val & (BIT(5) | BIT(6) | BIT(7) | BIT(8))) >> 5;
|
||||
val = air_mii_cl22_read(mbus, addr, MII_STAT1000);
|
||||
if (val < 0)
|
||||
return val;
|
||||
lpagb = GET_BIT(val, 11) << 4;
|
||||
ret |= (lpagb | lpa);
|
||||
return ret;
|
||||
}
|
||||
} while (count--);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int airphy_lp_speed(struct seq_file *seq, void *v)
|
||||
{
|
||||
unsigned int ret = 0, val = 0, did1 = 0, i;
|
||||
struct phy_device *phydev = seq->private;
|
||||
static const struct {
|
||||
unsigned int bit_index;
|
||||
const char *name;
|
||||
} mode_defs[] = {
|
||||
{ AIR_LINK_MODE_10baseT_Half_BIT,
|
||||
"10baseT/Half" },
|
||||
{ AIR_LINK_MODE_10baseT_Full_BIT,
|
||||
"10baseT/Full" },
|
||||
{ AIR_LINK_MODE_100baseT_Half_BIT,
|
||||
"100baseT/Half" },
|
||||
{ AIR_LINK_MODE_100baseT_Full_BIT,
|
||||
"100baseT/Full" },
|
||||
{ AIR_LINK_MODE_1000baseT_Full_BIT,
|
||||
"1000baseT/Full" },
|
||||
{ AIR_LINK_MODE_2500baseT_Full_BIT,
|
||||
"2500baseT/Full" }
|
||||
};
|
||||
|
||||
seq_printf(seq, "%s Link Partner Ability:\n",
|
||||
dev_name(phydev_dev(phydev)));
|
||||
ret = air_read_lp_speed(phydev);
|
||||
if (val < 0)
|
||||
return val;
|
||||
for (i = 0; i < ARRAY_SIZE(mode_defs); i++) {
|
||||
if (ret & BIT(mode_defs[i].bit_index)) {
|
||||
seq_printf(seq, "\t\t\t %s\n",
|
||||
mode_defs[i].name);
|
||||
did1++;
|
||||
}
|
||||
}
|
||||
if (did1 == 0)
|
||||
seq_puts(seq, "\t\t\t Not reported\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int airphy_lp_speed_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, airphy_lp_speed, inode->i_private);
|
||||
}
|
||||
|
||||
static const struct file_operations airphy_lp_speed_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = airphy_lp_speed_open,
|
||||
.read = seq_read,
|
||||
.llseek = noop_llseek,
|
||||
.release = single_release,
|
||||
};
|
||||
|
||||
static const struct file_operations airphy_info_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = airphy_info_open,
|
||||
.read = seq_read,
|
||||
.llseek = noop_llseek,
|
||||
.release = single_release,
|
||||
};
|
||||
|
||||
static const struct file_operations airphy_counter_fops = {
|
||||
@@ -1131,6 +1306,7 @@ static const struct file_operations airphy_counter_fops = {
|
||||
.open = airphy_counter_open,
|
||||
.read = seq_read,
|
||||
.llseek = noop_llseek,
|
||||
.release = single_release,
|
||||
};
|
||||
|
||||
static const struct file_operations airphy_debugfs_buckpbus_fops = {
|
||||
@@ -1166,6 +1342,7 @@ static const struct file_operations airphy_link_status_fops = {
|
||||
.open = airphy_link_status_open,
|
||||
.read = seq_read,
|
||||
.llseek = noop_llseek,
|
||||
.release = single_release,
|
||||
};
|
||||
|
||||
static const struct file_operations airphy_dbg_reg_show_fops = {
|
||||
@@ -1173,6 +1350,15 @@ static const struct file_operations airphy_dbg_reg_show_fops = {
|
||||
.open = airphy_dbg_regs_show_open,
|
||||
.read = seq_read,
|
||||
.llseek = noop_llseek,
|
||||
.release = single_release,
|
||||
};
|
||||
|
||||
static const struct file_operations airphy_temp_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = airphy_temp_show_open,
|
||||
.read = seq_read,
|
||||
.llseek = noop_llseek,
|
||||
.release = single_release,
|
||||
};
|
||||
|
||||
int airphy_debugfs_init(struct phy_device *phydev)
|
||||
@@ -1212,12 +1398,18 @@ int airphy_debugfs_init(struct phy_device *phydev)
|
||||
debugfs_create_file(DEBUGFS_DBG_REG_SHOW, S_IFREG | 0444,
|
||||
dir, phydev,
|
||||
&airphy_dbg_reg_show_fops);
|
||||
debugfs_create_file(DEBUGFS_TEMPERATURE, S_IFREG | 0444,
|
||||
dir, phydev,
|
||||
&airphy_temp_fops);
|
||||
debugfs_create_file(DEBUGFS_LP_SPEED, S_IFREG | 0444,
|
||||
dir, phydev,
|
||||
&airphy_lp_speed_fops);
|
||||
|
||||
priv->debugfs_root = dir;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void air_debugfs_remove(struct phy_device *phydev)
|
||||
void airphy_debugfs_remove(struct phy_device *phydev)
|
||||
{
|
||||
struct en8811h_priv *priv = phydev->priv;
|
||||
|
||||
|
||||
@@ -21,8 +21,6 @@
|
||||
#define phydev_dev(_dev) (&_dev->mdio.dev)
|
||||
#endif
|
||||
|
||||
#define BUFFER_LENGTH 512
|
||||
|
||||
#define DEBUGFS_COUNTER "counter"
|
||||
#define DEBUGFS_DRIVER_INFO "drvinfo"
|
||||
#define DEBUGFS_PORT_MODE "port_mode"
|
||||
@@ -31,6 +29,8 @@
|
||||
#define DEBUGFS_POLARITY "polarity"
|
||||
#define DEBUGFS_LINK_STATUS "link_status"
|
||||
#define DEBUGFS_DBG_REG_SHOW "dbg_regs_show"
|
||||
#define DEBUGFS_TEMPERATURE "temp"
|
||||
#define DEBUGFS_LP_SPEED "lp_speed"
|
||||
|
||||
enum air_port_mode {
|
||||
AIR_PORT_MODE_FORCE_100,
|
||||
@@ -39,10 +39,8 @@ enum air_port_mode {
|
||||
AIR_PORT_MODE_AUTONEGO,
|
||||
AIR_PORT_MODE_POWER_DOWN,
|
||||
AIR_PORT_MODE_POWER_UP,
|
||||
AIR_PORT_MODE_FC_UNSUPPORT,
|
||||
AIR_PORT_MODE_FC_SUPPORT,
|
||||
AIR_PORT_MODE_FC_DIS,
|
||||
AIR_PORT_MODE_FC_EN,
|
||||
AIR_PORT_MODE_SSC_DISABLE,
|
||||
AIR_PORT_MODE_SSC_ENABLE,
|
||||
AIR_PORT_MODE_LAST = 0xFF,
|
||||
};
|
||||
|
||||
@@ -73,6 +71,9 @@ int air_mii_cl22_write(struct mii_bus *ebus, int addr,
|
||||
unsigned int phy_register, unsigned int write_data);
|
||||
int air_mii_cl22_read(struct mii_bus *ebus,
|
||||
int addr, unsigned int phy_register);
|
||||
int __air_mii_cl45_read(struct phy_device *phydev, int devad, u16 reg);
|
||||
int __air_mii_cl45_write(struct phy_device *phydev,
|
||||
int devad, u16 reg, u16 write_data);
|
||||
int air_mii_cl45_read(struct phy_device *phydev, int devad, u16 reg);
|
||||
int air_mii_cl45_write(struct phy_device *phydev,
|
||||
int devad, u16 reg, u16 write_data);
|
||||
@@ -80,8 +81,9 @@ unsigned int air_buckpbus_reg_read(struct phy_device *phydev,
|
||||
unsigned int pbus_address);
|
||||
int air_buckpbus_reg_write(struct phy_device *phydev,
|
||||
unsigned int pbus_address, unsigned int pbus_data);
|
||||
int en8811h_of_init(struct phy_device *phydev);
|
||||
#ifdef CONFIG_AIROHA_EN8811H_PHY_DEBUGFS
|
||||
int airphy_debugfs_init(struct phy_device *phydev);
|
||||
void air_debugfs_remove(struct phy_device *phydev);
|
||||
void airphy_debugfs_remove(struct phy_device *phydev);
|
||||
#endif /*CONFIG_AIROHA_EN8811H_PHY_DEBUGFS*/
|
||||
#endif /* End of __EN8811H_API_H */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -20,7 +20,6 @@
|
||||
#include <linux/ethtool.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/of.h>
|
||||
#include "air_en8811h_api.h"
|
||||
#include "air_en8811h_fw.h"
|
||||
#include "air_en8811h.h"
|
||||
@@ -113,15 +112,16 @@ static int en8811h_load_firmware(struct phy_device *phydev)
|
||||
struct device *dev = phydev_dev(phydev);
|
||||
int ret = 0;
|
||||
u32 pbus_value = 0;
|
||||
#ifdef CONFIG_AIROHA_EN8811H_PHY_DEBUGFS
|
||||
struct en8811h_priv *priv = phydev->priv;
|
||||
#endif
|
||||
ret = air_buckpbus_reg_write(phydev, 0x0f0018, 0x0);
|
||||
|
||||
ret = air_buckpbus_reg_write(phydev,
|
||||
0x0f0018, 0x0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
pbus_value = air_buckpbus_reg_read(phydev, 0x800000);
|
||||
pbus_value |= BIT(11);
|
||||
ret = air_buckpbus_reg_write(phydev, 0x800000, pbus_value);
|
||||
ret = air_buckpbus_reg_write(phydev,
|
||||
0x800000, pbus_value);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
/* Download DM */
|
||||
@@ -131,6 +131,7 @@ static int en8811h_load_firmware(struct phy_device *phydev)
|
||||
"MDIOWriteBuf 0x00000000 fail, ret: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Download PM */
|
||||
ret = MDIOWriteBuf(phydev, 0x00100000, EthMD32_pm_size, EthMD32_pm);
|
||||
if (ret < 0) {
|
||||
@@ -304,26 +305,21 @@ static int en8811h_probe(struct phy_device *phydev)
|
||||
struct mii_bus *mbus = phydev_mdio_bus(phydev);
|
||||
int addr = phydev_addr(phydev);
|
||||
|
||||
#ifdef CONFIG_AIROHA_EN8811H_PHY_DEBUGFS
|
||||
struct en8811h_priv *priv;
|
||||
|
||||
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
phydev->priv = priv;
|
||||
#endif /*CONFIG_AIROHA_EN8811H_PHY_DEBUGFS*/
|
||||
ret = air_pbus_reg_write(phydev, 0xcf928, 0x0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto priv_free;
|
||||
pid1 = air_mii_cl22_read(mbus, addr, MII_PHYSID1);
|
||||
if (pid1 < 0)
|
||||
return pid1;
|
||||
pid2 = air_mii_cl22_read(mbus, addr, MII_PHYSID2);
|
||||
if (pid2 < 0)
|
||||
return pid2;
|
||||
dev_info(dev, "PHY = %x - %x\n", pid1, pid2);
|
||||
if ((pid1 != EN8811H_PHY_ID1) || (pid2 != EN8811H_PHY_ID2)) {
|
||||
dev_err(dev, "EN8811H does not exist !\n");
|
||||
dev_err(dev, "EN8811H dose not exist!!\n");
|
||||
kfree(priv);
|
||||
return -ENODEV;
|
||||
}
|
||||
pbus_value = air_buckpbus_reg_read(phydev, 0xcf914);
|
||||
@@ -333,15 +329,14 @@ static int en8811h_probe(struct phy_device *phydev)
|
||||
ret = en8811h_load_firmware(phydev);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "EN8811H load firmware fail.\n");
|
||||
return ret;
|
||||
goto priv_free;
|
||||
}
|
||||
#ifdef CONFIG_AIROHA_EN8811H_PHY_DEBUGFS
|
||||
ret = airphy_debugfs_init(phydev);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "air_debug_procfs_init fail. (ret=%d)\n", ret);
|
||||
air_debugfs_remove(phydev);
|
||||
kfree(priv);
|
||||
return ret;
|
||||
airphy_debugfs_remove(phydev);
|
||||
goto priv_free;
|
||||
}
|
||||
#endif /* CONFIG_AIROHA_EN8811H_PHY_DEBUGFS */
|
||||
retry = MAX_RETRY;
|
||||
@@ -361,32 +356,36 @@ static int en8811h_probe(struct phy_device *phydev)
|
||||
"Check MD32 FW Version(0x3b3c) : %08x\n", pbus_value);
|
||||
dev_err(dev,
|
||||
"EN8811H initialize fail!\n");
|
||||
return 0;
|
||||
goto priv_free;
|
||||
}
|
||||
/* Mode selection*/
|
||||
dev_info(dev, "EN8811H Mode 1 !\n");
|
||||
ret = air_mii_cl45_write(phydev, 0x1e, 0x800c, 0x0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto priv_free;
|
||||
ret = air_mii_cl45_write(phydev, 0x1e, 0x800d, 0x0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto priv_free;
|
||||
ret = air_mii_cl45_write(phydev, 0x1e, 0x800e, 0x1101);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto priv_free;
|
||||
ret = air_mii_cl45_write(phydev, 0x1e, 0x800f, 0x0002);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto priv_free;
|
||||
/* Serdes polarity */
|
||||
ret = en8811h_of_init(phydev);
|
||||
if (ret < 0)
|
||||
goto priv_free;
|
||||
pbus_value = air_buckpbus_reg_read(phydev, 0xca0f8);
|
||||
pbus_value &= ~0x3;
|
||||
pbus_value |= ((device_property_read_bool(dev, "airoha,rx-pol-reverse") ?
|
||||
EN8811H_RX_POL_REVERSE : EN8811H_RX_POL_NORMAL) |
|
||||
(device_property_read_bool(dev, "airoha,tx-pol-reverse") ?
|
||||
EN8811H_TX_POL_REVERSE : EN8811H_TX_POL_NORMAL));
|
||||
#if defined(CONFIG_OF)
|
||||
pbus_value |= priv->pol;
|
||||
#else
|
||||
pbus_value |= (EN8811H_RX_POL_NORMAL | EN8811H_TX_POL_NORMAL);
|
||||
#endif
|
||||
ret = air_buckpbus_reg_write(phydev, 0xca0f8, pbus_value);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto priv_free;
|
||||
pbus_value = air_buckpbus_reg_read(phydev, 0xca0f8);
|
||||
dev_info(dev, "Tx, Rx Polarity : %08x\n", pbus_value);
|
||||
pbus_value = air_buckpbus_reg_read(phydev, 0x3b3c);
|
||||
@@ -395,25 +394,29 @@ static int en8811h_probe(struct phy_device *phydev)
|
||||
ret = en8811h_led_init(phydev);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "en8811h_led_init fail. (ret=%d)\n", ret);
|
||||
return ret;
|
||||
goto priv_free;
|
||||
}
|
||||
#endif
|
||||
dev_info(dev, "EN8811H initialize OK! (%s)\n", EN8811H_DRIVER_VERSION);
|
||||
return 0;
|
||||
priv_free:
|
||||
kfree(priv);
|
||||
return ret;
|
||||
}
|
||||
void en8811h_remove(struct phy_device *phydev)
|
||||
{
|
||||
#ifdef CONFIG_AIROHA_EN8811H_PHY_DEBUGFS
|
||||
|
||||
struct en8811h_priv *priv = phydev->priv;
|
||||
struct device *dev = phydev_dev(phydev);
|
||||
|
||||
dev_dbg(dev, "%s: start\n", __func__);
|
||||
if (priv) {
|
||||
dev_info(dev, "%s: air_debugfs_remove\n", __func__);
|
||||
air_debugfs_remove(phydev);
|
||||
dev_info(dev, "%s: airphy_debugfs_remove\n", __func__);
|
||||
#ifdef CONFIG_AIROHA_EN8811H_PHY_DEBUGFS
|
||||
airphy_debugfs_remove(phydev);
|
||||
#endif /*CONFIG_AIROHA_EN8811H_PHY_DEBUGFS*/
|
||||
kfree(priv);
|
||||
}
|
||||
#endif /*CONFIG_AIROHA_EN8811H_PHY_DEBUGFS*/
|
||||
}
|
||||
|
||||
static struct phy_driver en8811h_driver[] = {
|
||||
@@ -425,8 +428,8 @@ static struct phy_driver en8811h_driver[] = {
|
||||
.remove = en8811h_remove,
|
||||
#if (KERNEL_VERSION(4, 5, 0) < LINUX_VERSION_CODE)
|
||||
.get_features = en8811h_get_features,
|
||||
.read_mmd = air_mii_cl45_read,
|
||||
.write_mmd = air_mii_cl45_write,
|
||||
.read_mmd = __air_mii_cl45_read,
|
||||
.write_mmd = __air_mii_cl45_write,
|
||||
#endif
|
||||
} };
|
||||
|
||||
|
||||
Reference in New Issue
Block a user