Skip to content

Commit

Permalink
net: usb: asix: ax88772: move embedded PHY detection as early as poss…
Browse files Browse the repository at this point in the history
…ible

Some HW revisions need additional MAC configuration before the embedded PHY
can be enabled. If this is not done, we won't be able to get response
from the internal PHY.

This issue was detected on chipcode == AX_AX88772_CHIPCODE variant,
where ax88772_hw_reset() was executed with missing embd_phy flag.

Fixes: e532a09 ("net: usb: asix: ax88772: add phylib support")
Reported-by: Jarkko Nikula <[email protected]>
Tested-by: Jarkko Nikula <[email protected]>
Signed-off-by: Oleksij Rempel <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
olerem authored and davem330 committed Aug 23, 2021
1 parent 359f4cd commit 7a141e6
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 21 deletions.
1 change: 1 addition & 0 deletions drivers/net/usb/asix.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ struct asix_common_private {
struct phy_device *phydev;
u16 phy_addr;
char phy_name[20];
bool embd_phy;
};

extern const struct driver_info ax88172a_info;
Expand Down
41 changes: 20 additions & 21 deletions drivers/net/usb/asix_devices.c
Original file line number Diff line number Diff line change
Expand Up @@ -354,24 +354,23 @@ static int ax88772_reset(struct usbnet *dev)
static int ax88772_hw_reset(struct usbnet *dev, int in_pm)
{
struct asix_data *data = (struct asix_data *)&dev->data;
int ret, embd_phy;
struct asix_common_private *priv = dev->driver_priv;
u16 rx_ctl;
int ret;

ret = asix_write_gpio(dev, AX_GPIO_RSE | AX_GPIO_GPO_2 |
AX_GPIO_GPO2EN, 5, in_pm);
if (ret < 0)
goto out;

embd_phy = ((dev->mii.phy_id & 0x1f) == 0x10 ? 1 : 0);

ret = asix_write_cmd(dev, AX_CMD_SW_PHY_SELECT, embd_phy,
ret = asix_write_cmd(dev, AX_CMD_SW_PHY_SELECT, priv->embd_phy,
0, 0, NULL, in_pm);
if (ret < 0) {
netdev_dbg(dev->net, "Select PHY #1 failed: %d\n", ret);
goto out;
}

if (embd_phy) {
if (priv->embd_phy) {
ret = asix_sw_reset(dev, AX_SWRESET_IPPD, in_pm);
if (ret < 0)
goto out;
Expand Down Expand Up @@ -449,17 +448,16 @@ static int ax88772_hw_reset(struct usbnet *dev, int in_pm)
static int ax88772a_hw_reset(struct usbnet *dev, int in_pm)
{
struct asix_data *data = (struct asix_data *)&dev->data;
int ret, embd_phy;
struct asix_common_private *priv = dev->driver_priv;
u16 rx_ctl, phy14h, phy15h, phy16h;
u8 chipcode = 0;
int ret;

ret = asix_write_gpio(dev, AX_GPIO_RSE, 5, in_pm);
if (ret < 0)
goto out;

embd_phy = ((dev->mii.phy_id & 0x1f) == 0x10 ? 1 : 0);

ret = asix_write_cmd(dev, AX_CMD_SW_PHY_SELECT, embd_phy |
ret = asix_write_cmd(dev, AX_CMD_SW_PHY_SELECT, priv->embd_phy |
AX_PHYSEL_SSEN, 0, 0, NULL, in_pm);
if (ret < 0) {
netdev_dbg(dev->net, "Select PHY #1 failed: %d\n", ret);
Expand Down Expand Up @@ -683,12 +681,6 @@ static int ax88772_init_phy(struct usbnet *dev)
struct asix_common_private *priv = dev->driver_priv;
int ret;

ret = asix_read_phy_addr(dev, true);
if (ret < 0)
return ret;

priv->phy_addr = ret;

snprintf(priv->phy_name, sizeof(priv->phy_name), PHY_ID_FMT,
priv->mdio->id, priv->phy_addr);

Expand Down Expand Up @@ -716,6 +708,12 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
int ret, i;
u32 phyid;

priv = devm_kzalloc(&dev->udev->dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;

dev->driver_priv = priv;

usbnet_get_endpoints(dev, intf);

/* Maybe the boot loader passed the MAC address via device tree */
Expand Down Expand Up @@ -751,6 +749,13 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
dev->net->needed_headroom = 4; /* cf asix_tx_fixup() */
dev->net->needed_tailroom = 4; /* cf asix_tx_fixup() */

ret = asix_read_phy_addr(dev, true);
if (ret < 0)
return ret;

priv->phy_addr = ret;
priv->embd_phy = ((priv->phy_addr & 0x1f) == 0x10 ? true : false);

asix_read_cmd(dev, AX_CMD_STATMNGSTS_REG, 0, 0, 1, &chipcode, 0);
chipcode &= AX_CHIPCODE_MASK;

Expand All @@ -773,12 +778,6 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
dev->rx_urb_size = 2048;
}

priv = devm_kzalloc(&dev->udev->dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;

dev->driver_priv = priv;

priv->presvd_phy_bmcr = 0;
priv->presvd_phy_advertise = 0;
if (chipcode == AX_AX88772_CHIPCODE) {
Expand Down

0 comments on commit 7a141e6

Please sign in to comment.