mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-26 00:41:17 +00:00
5deb3996e2
Copy and refresh patches and config from 5.4 to 5.10. Most patches require no more then automatic refresh. The only exception is the Ethernet driver patch, which requires some more work: * drop eth_change_mtu() usage since it was removed from the kernel, it anyway useless for drivers that utilizes alloc_etherdev(); * add the txqueue number argument to the .ndo_tx_timeout callback function; * replace ioremap_nocache() which was finally removed from the kernel by the ioremap() with the same behaviour. Switch target to the new kernel version. Signed-off-by: Daniel Golle <daniel@makrotopia.org> [use KERNEL_TESTING_PATCHVER for now] Signed-off-by: Sergey Ryazanov <ryazanov.s.a@gmail.com>
112 lines
2.5 KiB
Diff
112 lines
2.5 KiB
Diff
--- a/drivers/net/ethernet/atheros/ar231x/ar231x.c
|
|
+++ b/drivers/net/ethernet/atheros/ar231x/ar231x.c
|
|
@@ -135,6 +135,7 @@ static int ar231x_mdiobus_write(struct m
|
|
static int ar231x_mdiobus_reset(struct mii_bus *bus);
|
|
static int ar231x_mdiobus_probe(struct net_device *dev);
|
|
static void ar231x_adjust_link(struct net_device *dev);
|
|
+static bool no_phy;
|
|
|
|
#ifndef ERR
|
|
#define ERR(fmt, args...) printk("%s: " fmt, __func__, ##args)
|
|
@@ -166,6 +167,32 @@ static const struct net_device_ops ar231
|
|
#endif
|
|
};
|
|
|
|
+static int get_phy_id(struct mii_bus *bus, int addr, u32 *phy_id)
|
|
+{
|
|
+ int phy_reg;
|
|
+
|
|
+ /**
|
|
+ * Grab the bits from PHYIR1, and put them
|
|
+ * in the upper half.
|
|
+ */
|
|
+ phy_reg = mdiobus_read(bus, addr, MII_PHYSID1);
|
|
+
|
|
+ if (phy_reg < 0)
|
|
+ return -EIO;
|
|
+
|
|
+ *phy_id = (phy_reg & 0xffff) << 16;
|
|
+
|
|
+ /* Grab the bits from PHYIR2, and put them in the lower half */
|
|
+ phy_reg = mdiobus_read(bus, addr, MII_PHYSID2);
|
|
+
|
|
+ if (phy_reg < 0)
|
|
+ return -EIO;
|
|
+
|
|
+ *phy_id |= (phy_reg & 0xffff);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
static int ar231x_probe(struct platform_device *pdev)
|
|
{
|
|
struct net_device *dev;
|
|
@@ -273,6 +300,24 @@ static int ar231x_probe(struct platform_
|
|
|
|
mdiobus_register(sp->mii_bus);
|
|
|
|
+ /**
|
|
+ * Workaround for Micrel switch, which is only available on
|
|
+ * one PHY and cannot be configured through MDIO.
|
|
+ */
|
|
+ if (!no_phy) {
|
|
+ u32 phy_id = 0;
|
|
+
|
|
+ get_phy_id(sp->mii_bus, 1, &phy_id);
|
|
+ if (phy_id == 0x00221450)
|
|
+ no_phy = true;
|
|
+ }
|
|
+ if (no_phy) {
|
|
+ sp->link = 1;
|
|
+ netif_carrier_on(dev);
|
|
+ return 0;
|
|
+ }
|
|
+ no_phy = true;
|
|
+
|
|
if (ar231x_mdiobus_probe(dev) != 0) {
|
|
printk(KERN_ERR "%s: mdiobus_probe failed\n", dev->name);
|
|
rx_tasklet_cleanup(dev);
|
|
@@ -326,8 +371,10 @@ static int ar231x_remove(struct platform
|
|
rx_tasklet_cleanup(dev);
|
|
ar231x_init_cleanup(dev);
|
|
unregister_netdev(dev);
|
|
- mdiobus_unregister(sp->mii_bus);
|
|
- mdiobus_free(sp->mii_bus);
|
|
+ if (sp->mii_bus) {
|
|
+ mdiobus_unregister(sp->mii_bus);
|
|
+ mdiobus_free(sp->mii_bus);
|
|
+ }
|
|
kfree(dev);
|
|
return 0;
|
|
}
|
|
@@ -870,7 +917,8 @@ static int ar231x_open(struct net_device
|
|
|
|
sp->eth_regs->mac_control |= MAC_CONTROL_RE;
|
|
|
|
- phy_start(sp->phy_dev);
|
|
+ if (sp->phy_dev)
|
|
+ phy_start(sp->phy_dev);
|
|
|
|
return 0;
|
|
}
|
|
@@ -951,7 +999,8 @@ static int ar231x_close(struct net_devic
|
|
|
|
#endif
|
|
|
|
- phy_stop(sp->phy_dev);
|
|
+ if (sp->phy_dev)
|
|
+ phy_stop(sp->phy_dev);
|
|
|
|
return 0;
|
|
}
|
|
@@ -995,6 +1044,9 @@ static int ar231x_ioctl(struct net_devic
|
|
{
|
|
struct ar231x_private *sp = netdev_priv(dev);
|
|
|
|
+ if (!sp->phy_dev)
|
|
+ return -ENODEV;
|
|
+
|
|
switch (cmd) {
|
|
case SIOCGMIIPHY:
|
|
case SIOCGMIIREG:
|