Commit 51bf2976 authored by Al Viro's avatar Al Viro Committed by Jeff Garzik

asix fixes

* usb_control_message() to/from stack (breaks on e.g. arm); some
  places did kmalloc() for buffer, some just worked from stack.
  Added kmalloc()/memcpy()/kfree() in asix_read_cmd()/asix_write_cmd(),
  removed that crap from callers.
* Fixed a leak in ax88172_bind() - on success it forgot to kfree() the
  buffer.
* Endianness bug in ax88178_bind() - we read a word from eeprom and work with
  it without converting to host-endian
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
Signed-off-by: default avatarJeff Garzik <jeff@garzik.org>
parent 7fd71e58
...@@ -172,45 +172,76 @@ struct asix_data { ...@@ -172,45 +172,76 @@ struct asix_data {
}; };
struct ax88172_int_data { struct ax88172_int_data {
u16 res1; __le16 res1;
u8 link; u8 link;
u16 res2; __le16 res2;
u8 status; u8 status;
u16 res3; __le16 res3;
} __attribute__ ((packed)); } __attribute__ ((packed));
static int asix_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, static int asix_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index,
u16 size, void *data) u16 size, void *data)
{ {
void *buf;
int err = -ENOMEM;
devdbg(dev,"asix_read_cmd() cmd=0x%02x value=0x%04x index=0x%04x size=%d", devdbg(dev,"asix_read_cmd() cmd=0x%02x value=0x%04x index=0x%04x size=%d",
cmd, value, index, size); cmd, value, index, size);
return usb_control_msg(
buf = kmalloc(size, GFP_KERNEL);
if (!buf)
goto out;
err = usb_control_msg(
dev->udev, dev->udev,
usb_rcvctrlpipe(dev->udev, 0), usb_rcvctrlpipe(dev->udev, 0),
cmd, cmd,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
value, value,
index, index,
data, buf,
size, size,
USB_CTRL_GET_TIMEOUT); USB_CTRL_GET_TIMEOUT);
if (err >= 0 && err < size)
err = -EINVAL;
if (!err)
memcpy(data, buf, size);
kfree(buf);
out:
return err;
} }
static int asix_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, static int asix_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index,
u16 size, void *data) u16 size, void *data)
{ {
void *buf = NULL;
int err = -ENOMEM;
devdbg(dev,"asix_write_cmd() cmd=0x%02x value=0x%04x index=0x%04x size=%d", devdbg(dev,"asix_write_cmd() cmd=0x%02x value=0x%04x index=0x%04x size=%d",
cmd, value, index, size); cmd, value, index, size);
return usb_control_msg(
if (data) {
buf = kmalloc(size, GFP_KERNEL);
if (!buf)
goto out;
memcpy(buf, data, size);
}
err = usb_control_msg(
dev->udev, dev->udev,
usb_sndctrlpipe(dev->udev, 0), usb_sndctrlpipe(dev->udev, 0),
cmd, cmd,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
value, value,
index, index,
data, buf,
size, size,
USB_CTRL_SET_TIMEOUT); USB_CTRL_SET_TIMEOUT);
kfree(buf);
out:
return err;
} }
static void asix_async_cmd_callback(struct urb *urb) static void asix_async_cmd_callback(struct urb *urb)
...@@ -402,25 +433,19 @@ static inline int asix_set_hw_mii(struct usbnet *dev) ...@@ -402,25 +433,19 @@ static inline int asix_set_hw_mii(struct usbnet *dev)
static inline int asix_get_phy_addr(struct usbnet *dev) static inline int asix_get_phy_addr(struct usbnet *dev)
{ {
int ret = 0; u8 buf[2];
void *buf; int ret = asix_read_cmd(dev, AX_CMD_READ_PHY_ID, 0, 0, 2, buf);
devdbg(dev, "asix_get_phy_addr()"); devdbg(dev, "asix_get_phy_addr()");
buf = kmalloc(2, GFP_KERNEL); if (ret < 0) {
if (!buf)
goto out1;
if ((ret = asix_read_cmd(dev, AX_CMD_READ_PHY_ID,
0, 0, 2, buf)) < 2) {
deverr(dev, "Error reading PHYID register: %02x", ret); deverr(dev, "Error reading PHYID register: %02x", ret);
goto out2; goto out;
} }
devdbg(dev, "asix_get_phy_addr() returning 0x%04x", *((u16 *)buf)); devdbg(dev, "asix_get_phy_addr() returning 0x%04x", *((__le16 *)buf));
ret = *((u8 *)buf + 1); ret = buf[1];
out2:
kfree(buf); out:
out1:
return ret; return ret;
} }
...@@ -437,22 +462,15 @@ static int asix_sw_reset(struct usbnet *dev, u8 flags) ...@@ -437,22 +462,15 @@ static int asix_sw_reset(struct usbnet *dev, u8 flags)
static u16 asix_read_rx_ctl(struct usbnet *dev) static u16 asix_read_rx_ctl(struct usbnet *dev)
{ {
u16 ret = 0; __le16 v;
void *buf; int ret = asix_read_cmd(dev, AX_CMD_READ_RX_CTL, 0, 0, 2, &v);
buf = kmalloc(2, GFP_KERNEL);
if (!buf)
goto out1;
if ((ret = asix_read_cmd(dev, AX_CMD_READ_RX_CTL, if (ret < 0) {
0, 0, 2, buf)) < 2) {
deverr(dev, "Error reading RX_CTL register: %02x", ret); deverr(dev, "Error reading RX_CTL register: %02x", ret);
goto out2; goto out;
} }
ret = le16_to_cpu(*((u16 *)buf)); ret = le16_to_cpu(v);
out2: out:
kfree(buf);
out1:
return ret; return ret;
} }
...@@ -471,22 +489,15 @@ static int asix_write_rx_ctl(struct usbnet *dev, u16 mode) ...@@ -471,22 +489,15 @@ static int asix_write_rx_ctl(struct usbnet *dev, u16 mode)
static u16 asix_read_medium_status(struct usbnet *dev) static u16 asix_read_medium_status(struct usbnet *dev)
{ {
u16 ret = 0; __le16 v;
void *buf; int ret = asix_read_cmd(dev, AX_CMD_READ_MEDIUM_STATUS, 0, 0, 2, &v);
buf = kmalloc(2, GFP_KERNEL); if (ret < 0) {
if (!buf)
goto out1;
if ((ret = asix_read_cmd(dev, AX_CMD_READ_MEDIUM_STATUS,
0, 0, 2, buf)) < 2) {
deverr(dev, "Error reading Medium Status register: %02x", ret); deverr(dev, "Error reading Medium Status register: %02x", ret);
goto out2; goto out;
} }
ret = le16_to_cpu(*((u16 *)buf)); ret = le16_to_cpu(v);
out2: out:
kfree(buf);
out1:
return ret; return ret;
} }
...@@ -568,31 +579,30 @@ static void asix_set_multicast(struct net_device *net) ...@@ -568,31 +579,30 @@ static void asix_set_multicast(struct net_device *net)
static int asix_mdio_read(struct net_device *netdev, int phy_id, int loc) static int asix_mdio_read(struct net_device *netdev, int phy_id, int loc)
{ {
struct usbnet *dev = netdev_priv(netdev); struct usbnet *dev = netdev_priv(netdev);
u16 res; __le16 res;
mutex_lock(&dev->phy_mutex); mutex_lock(&dev->phy_mutex);
asix_set_sw_mii(dev); asix_set_sw_mii(dev);
asix_read_cmd(dev, AX_CMD_READ_MII_REG, phy_id, asix_read_cmd(dev, AX_CMD_READ_MII_REG, phy_id,
(__u16)loc, 2, (u16 *)&res); (__u16)loc, 2, &res);
asix_set_hw_mii(dev); asix_set_hw_mii(dev);
mutex_unlock(&dev->phy_mutex); mutex_unlock(&dev->phy_mutex);
devdbg(dev, "asix_mdio_read() phy_id=0x%02x, loc=0x%02x, returns=0x%04x", phy_id, loc, le16_to_cpu(res & 0xffff)); devdbg(dev, "asix_mdio_read() phy_id=0x%02x, loc=0x%02x, returns=0x%04x", phy_id, loc, le16_to_cpu(res));
return le16_to_cpu(res & 0xffff); return le16_to_cpu(res);
} }
static void static void
asix_mdio_write(struct net_device *netdev, int phy_id, int loc, int val) asix_mdio_write(struct net_device *netdev, int phy_id, int loc, int val)
{ {
struct usbnet *dev = netdev_priv(netdev); struct usbnet *dev = netdev_priv(netdev);
u16 res = cpu_to_le16(val); __le16 res = cpu_to_le16(val);
devdbg(dev, "asix_mdio_write() phy_id=0x%02x, loc=0x%02x, val=0x%04x", phy_id, loc, val); devdbg(dev, "asix_mdio_write() phy_id=0x%02x, loc=0x%02x, val=0x%04x", phy_id, loc, val);
mutex_lock(&dev->phy_mutex); mutex_lock(&dev->phy_mutex);
asix_set_sw_mii(dev); asix_set_sw_mii(dev);
asix_write_cmd(dev, AX_CMD_WRITE_MII_REG, phy_id, asix_write_cmd(dev, AX_CMD_WRITE_MII_REG, phy_id, (__u16)loc, 2, &res);
(__u16)loc, 2, (u16 *)&res);
asix_set_hw_mii(dev); asix_set_hw_mii(dev);
mutex_unlock(&dev->phy_mutex); mutex_unlock(&dev->phy_mutex);
} }
...@@ -644,7 +654,6 @@ asix_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo) ...@@ -644,7 +654,6 @@ asix_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo)
{ {
struct usbnet *dev = netdev_priv(net); struct usbnet *dev = netdev_priv(net);
u8 opt = 0; u8 opt = 0;
u8 buf[1];
if (wolinfo->wolopts & WAKE_PHY) if (wolinfo->wolopts & WAKE_PHY)
opt |= AX_MONITOR_LINK; opt |= AX_MONITOR_LINK;
...@@ -654,7 +663,7 @@ asix_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo) ...@@ -654,7 +663,7 @@ asix_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo)
opt |= AX_MONITOR_MODE; opt |= AX_MONITOR_MODE;
if (asix_write_cmd(dev, AX_CMD_WRITE_MONITOR_MODE, if (asix_write_cmd(dev, AX_CMD_WRITE_MONITOR_MODE,
opt, 0, 0, &buf) < 0) opt, 0, 0, NULL) < 0)
return -EINVAL; return -EINVAL;
return 0; return 0;
...@@ -672,7 +681,7 @@ static int asix_get_eeprom(struct net_device *net, ...@@ -672,7 +681,7 @@ static int asix_get_eeprom(struct net_device *net,
struct ethtool_eeprom *eeprom, u8 *data) struct ethtool_eeprom *eeprom, u8 *data)
{ {
struct usbnet *dev = netdev_priv(net); struct usbnet *dev = netdev_priv(net);
u16 *ebuf = (u16 *)data; __le16 *ebuf = (__le16 *)data;
int i; int i;
/* Crude hack to ensure that we don't overwrite memory /* Crude hack to ensure that we don't overwrite memory
...@@ -801,7 +810,7 @@ static int ax88172_link_reset(struct usbnet *dev) ...@@ -801,7 +810,7 @@ static int ax88172_link_reset(struct usbnet *dev)
static int ax88172_bind(struct usbnet *dev, struct usb_interface *intf) static int ax88172_bind(struct usbnet *dev, struct usb_interface *intf)
{ {
int ret = 0; int ret = 0;
void *buf; u8 buf[ETH_ALEN];
int i; int i;
unsigned long gpio_bits = dev->driver_info->data; unsigned long gpio_bits = dev->driver_info->data;
struct asix_data *data = (struct asix_data *)&dev->data; struct asix_data *data = (struct asix_data *)&dev->data;
...@@ -810,30 +819,23 @@ static int ax88172_bind(struct usbnet *dev, struct usb_interface *intf) ...@@ -810,30 +819,23 @@ static int ax88172_bind(struct usbnet *dev, struct usb_interface *intf)
usbnet_get_endpoints(dev,intf); usbnet_get_endpoints(dev,intf);
buf = kmalloc(ETH_ALEN, GFP_KERNEL);
if(!buf) {
ret = -ENOMEM;
goto out1;
}
/* Toggle the GPIOs in a manufacturer/model specific way */ /* Toggle the GPIOs in a manufacturer/model specific way */
for (i = 2; i >= 0; i--) { for (i = 2; i >= 0; i--) {
if ((ret = asix_write_cmd(dev, AX_CMD_WRITE_GPIOS, if ((ret = asix_write_cmd(dev, AX_CMD_WRITE_GPIOS,
(gpio_bits >> (i * 8)) & 0xff, 0, 0, (gpio_bits >> (i * 8)) & 0xff, 0, 0,
buf)) < 0) NULL)) < 0)
goto out2; goto out;
msleep(5); msleep(5);
} }
if ((ret = asix_write_rx_ctl(dev, 0x80)) < 0) if ((ret = asix_write_rx_ctl(dev, 0x80)) < 0)
goto out2; goto out;
/* Get the MAC address */ /* Get the MAC address */
memset(buf, 0, ETH_ALEN);
if ((ret = asix_read_cmd(dev, AX88172_CMD_READ_NODE_ID, if ((ret = asix_read_cmd(dev, AX88172_CMD_READ_NODE_ID,
0, 0, 6, buf)) < 0) { 0, 0, ETH_ALEN, buf)) < 0) {
dbg("read AX_CMD_READ_NODE_ID failed: %d", ret); dbg("read AX_CMD_READ_NODE_ID failed: %d", ret);
goto out2; goto out;
} }
memcpy(dev->net->dev_addr, buf, ETH_ALEN); memcpy(dev->net->dev_addr, buf, ETH_ALEN);
...@@ -855,9 +857,8 @@ static int ax88172_bind(struct usbnet *dev, struct usb_interface *intf) ...@@ -855,9 +857,8 @@ static int ax88172_bind(struct usbnet *dev, struct usb_interface *intf)
mii_nway_restart(&dev->mii); mii_nway_restart(&dev->mii);
return 0; return 0;
out2:
kfree(buf); out:
out1:
return ret; return ret;
} }
...@@ -900,66 +901,58 @@ static int ax88772_link_reset(struct usbnet *dev) ...@@ -900,66 +901,58 @@ static int ax88772_link_reset(struct usbnet *dev)
static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf) static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
{ {
int ret, embd_phy; int ret, embd_phy;
void *buf;
u16 rx_ctl; u16 rx_ctl;
struct asix_data *data = (struct asix_data *)&dev->data; struct asix_data *data = (struct asix_data *)&dev->data;
u8 buf[ETH_ALEN];
u32 phyid; u32 phyid;
data->eeprom_len = AX88772_EEPROM_LEN; data->eeprom_len = AX88772_EEPROM_LEN;
usbnet_get_endpoints(dev,intf); usbnet_get_endpoints(dev,intf);
buf = kmalloc(6, GFP_KERNEL);
if(!buf) {
dbg ("Cannot allocate memory for buffer");
ret = -ENOMEM;
goto out1;
}
if ((ret = asix_write_gpio(dev, if ((ret = asix_write_gpio(dev,
AX_GPIO_RSE | AX_GPIO_GPO_2 | AX_GPIO_GPO2EN, 5)) < 0) AX_GPIO_RSE | AX_GPIO_GPO_2 | AX_GPIO_GPO2EN, 5)) < 0)
goto out2; goto out;
/* 0x10 is the phy id of the embedded 10/100 ethernet phy */ /* 0x10 is the phy id of the embedded 10/100 ethernet phy */
embd_phy = ((asix_get_phy_addr(dev) & 0x1f) == 0x10 ? 1 : 0); embd_phy = ((asix_get_phy_addr(dev) & 0x1f) == 0x10 ? 1 : 0);
if ((ret = asix_write_cmd(dev, AX_CMD_SW_PHY_SELECT, if ((ret = asix_write_cmd(dev, AX_CMD_SW_PHY_SELECT,
embd_phy, 0, 0, buf)) < 0) { embd_phy, 0, 0, NULL)) < 0) {
dbg("Select PHY #1 failed: %d", ret); dbg("Select PHY #1 failed: %d", ret);
goto out2; goto out;
} }
if ((ret = asix_sw_reset(dev, AX_SWRESET_IPPD | AX_SWRESET_PRL)) < 0) if ((ret = asix_sw_reset(dev, AX_SWRESET_IPPD | AX_SWRESET_PRL)) < 0)
goto out2; goto out;
msleep(150); msleep(150);
if ((ret = asix_sw_reset(dev, AX_SWRESET_CLEAR)) < 0) if ((ret = asix_sw_reset(dev, AX_SWRESET_CLEAR)) < 0)
goto out2; goto out;
msleep(150); msleep(150);
if (embd_phy) { if (embd_phy) {
if ((ret = asix_sw_reset(dev, AX_SWRESET_IPRL)) < 0) if ((ret = asix_sw_reset(dev, AX_SWRESET_IPRL)) < 0)
goto out2; goto out;
} }
else { else {
if ((ret = asix_sw_reset(dev, AX_SWRESET_PRTE)) < 0) if ((ret = asix_sw_reset(dev, AX_SWRESET_PRTE)) < 0)
goto out2; goto out;
} }
msleep(150); msleep(150);
rx_ctl = asix_read_rx_ctl(dev); rx_ctl = asix_read_rx_ctl(dev);
dbg("RX_CTL is 0x%04x after software reset", rx_ctl); dbg("RX_CTL is 0x%04x after software reset", rx_ctl);
if ((ret = asix_write_rx_ctl(dev, 0x0000)) < 0) if ((ret = asix_write_rx_ctl(dev, 0x0000)) < 0)
goto out2; goto out;
rx_ctl = asix_read_rx_ctl(dev); rx_ctl = asix_read_rx_ctl(dev);
dbg("RX_CTL is 0x%04x setting to 0x0000", rx_ctl); dbg("RX_CTL is 0x%04x setting to 0x0000", rx_ctl);
/* Get the MAC address */ /* Get the MAC address */
memset(buf, 0, ETH_ALEN);
if ((ret = asix_read_cmd(dev, AX_CMD_READ_NODE_ID, if ((ret = asix_read_cmd(dev, AX_CMD_READ_NODE_ID,
0, 0, ETH_ALEN, buf)) < 0) { 0, 0, ETH_ALEN, buf)) < 0) {
dbg("Failed to read MAC address: %d", ret); dbg("Failed to read MAC address: %d", ret);
goto out2; goto out;
} }
memcpy(dev->net->dev_addr, buf, ETH_ALEN); memcpy(dev->net->dev_addr, buf, ETH_ALEN);
...@@ -976,12 +969,12 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf) ...@@ -976,12 +969,12 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
dbg("PHYID=0x%08x", phyid); dbg("PHYID=0x%08x", phyid);
if ((ret = asix_sw_reset(dev, AX_SWRESET_PRL)) < 0) if ((ret = asix_sw_reset(dev, AX_SWRESET_PRL)) < 0)
goto out2; goto out;
msleep(150); msleep(150);
if ((ret = asix_sw_reset(dev, AX_SWRESET_IPRL | AX_SWRESET_PRL)) < 0) if ((ret = asix_sw_reset(dev, AX_SWRESET_IPRL | AX_SWRESET_PRL)) < 0)
goto out2; goto out;
msleep(150); msleep(150);
...@@ -994,18 +987,18 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf) ...@@ -994,18 +987,18 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
mii_nway_restart(&dev->mii); mii_nway_restart(&dev->mii);
if ((ret = asix_write_medium_mode(dev, AX88772_MEDIUM_DEFAULT)) < 0) if ((ret = asix_write_medium_mode(dev, AX88772_MEDIUM_DEFAULT)) < 0)
goto out2; goto out;
if ((ret = asix_write_cmd(dev, AX_CMD_WRITE_IPG0, if ((ret = asix_write_cmd(dev, AX_CMD_WRITE_IPG0,
AX88772_IPG0_DEFAULT | AX88772_IPG1_DEFAULT, AX88772_IPG0_DEFAULT | AX88772_IPG1_DEFAULT,
AX88772_IPG2_DEFAULT, 0, buf)) < 0) { AX88772_IPG2_DEFAULT, 0, NULL)) < 0) {
dbg("Write IPG,IPG1,IPG2 failed: %d", ret); dbg("Write IPG,IPG1,IPG2 failed: %d", ret);
goto out2; goto out;
} }
/* Set RX_CTL to default values with 2k buffer, and enable cactus */ /* Set RX_CTL to default values with 2k buffer, and enable cactus */
if ((ret = asix_write_rx_ctl(dev, AX_DEFAULT_RX_CTL)) < 0) if ((ret = asix_write_rx_ctl(dev, AX_DEFAULT_RX_CTL)) < 0)
goto out2; goto out;
rx_ctl = asix_read_rx_ctl(dev); rx_ctl = asix_read_rx_ctl(dev);
dbg("RX_CTL is 0x%04x after all initializations", rx_ctl); dbg("RX_CTL is 0x%04x after all initializations", rx_ctl);
...@@ -1013,20 +1006,15 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf) ...@@ -1013,20 +1006,15 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
rx_ctl = asix_read_medium_status(dev); rx_ctl = asix_read_medium_status(dev);
dbg("Medium Status is 0x%04x after all initializations", rx_ctl); dbg("Medium Status is 0x%04x after all initializations", rx_ctl);
kfree(buf);
/* Asix framing packs multiple eth frames into a 2K usb bulk transfer */ /* Asix framing packs multiple eth frames into a 2K usb bulk transfer */
if (dev->driver_info->flags & FLAG_FRAMING_AX) { if (dev->driver_info->flags & FLAG_FRAMING_AX) {
/* hard_mtu is still the default - the device does not support /* hard_mtu is still the default - the device does not support
jumbo eth frames */ jumbo eth frames */
dev->rx_urb_size = 2048; dev->rx_urb_size = 2048;
} }
return 0; return 0;
out2: out:
kfree(buf);
out1:
return ret; return ret;
} }
...@@ -1195,23 +1183,16 @@ static int ax88178_bind(struct usbnet *dev, struct usb_interface *intf) ...@@ -1195,23 +1183,16 @@ static int ax88178_bind(struct usbnet *dev, struct usb_interface *intf)
{ {
struct asix_data *data = (struct asix_data *)&dev->data; struct asix_data *data = (struct asix_data *)&dev->data;
int ret; int ret;
void *buf; u8 buf[ETH_ALEN];
u16 eeprom; __le16 eeprom;
u8 status;
int gpio0 = 0; int gpio0 = 0;
u32 phyid; u32 phyid;
usbnet_get_endpoints(dev,intf); usbnet_get_endpoints(dev,intf);
buf = kmalloc(6, GFP_KERNEL); asix_read_cmd(dev, AX_CMD_READ_GPIOS, 0, 0, 1, &status);
if(!buf) { dbg("GPIO Status: 0x%04x", status);
dbg ("Cannot allocate memory for buffer");
ret = -ENOMEM;
goto out1;
}
eeprom = 0;
asix_read_cmd(dev, AX_CMD_READ_GPIOS, 0, 0, 1, &eeprom);
dbg("GPIO Status: 0x%04x", eeprom);
asix_write_cmd(dev, AX_CMD_WRITE_ENABLE, 0, 0, 0, NULL); asix_write_cmd(dev, AX_CMD_WRITE_ENABLE, 0, 0, 0, NULL);
asix_read_cmd(dev, AX_CMD_READ_EEPROM, 0x0017, 0, 2, &eeprom); asix_read_cmd(dev, AX_CMD_READ_EEPROM, 0x0017, 0, 2, &eeprom);
...@@ -1219,19 +1200,19 @@ static int ax88178_bind(struct usbnet *dev, struct usb_interface *intf) ...@@ -1219,19 +1200,19 @@ static int ax88178_bind(struct usbnet *dev, struct usb_interface *intf)
dbg("EEPROM index 0x17 is 0x%04x", eeprom); dbg("EEPROM index 0x17 is 0x%04x", eeprom);
if (eeprom == 0xffff) { if (eeprom == cpu_to_le16(0xffff)) {
data->phymode = PHY_MODE_MARVELL; data->phymode = PHY_MODE_MARVELL;
data->ledmode = 0; data->ledmode = 0;
gpio0 = 1; gpio0 = 1;
} else { } else {
data->phymode = eeprom & 7; data->phymode = le16_to_cpu(eeprom) & 7;
data->ledmode = eeprom >> 8; data->ledmode = le16_to_cpu(eeprom) >> 8;
gpio0 = (eeprom & 0x80) ? 0 : 1; gpio0 = (le16_to_cpu(eeprom) & 0x80) ? 0 : 1;
} }
dbg("GPIO0: %d, PhyMode: %d", gpio0, data->phymode); dbg("GPIO0: %d, PhyMode: %d", gpio0, data->phymode);
asix_write_gpio(dev, AX_GPIO_RSE | AX_GPIO_GPO_1 | AX_GPIO_GPO1EN, 40); asix_write_gpio(dev, AX_GPIO_RSE | AX_GPIO_GPO_1 | AX_GPIO_GPO1EN, 40);
if ((eeprom >> 8) != 1) { if ((le16_to_cpu(eeprom) >> 8) != 1) {
asix_write_gpio(dev, 0x003c, 30); asix_write_gpio(dev, 0x003c, 30);
asix_write_gpio(dev, 0x001c, 300); asix_write_gpio(dev, 0x001c, 300);
asix_write_gpio(dev, 0x003c, 30); asix_write_gpio(dev, 0x003c, 30);
...@@ -1250,11 +1231,10 @@ static int ax88178_bind(struct usbnet *dev, struct usb_interface *intf) ...@@ -1250,11 +1231,10 @@ static int ax88178_bind(struct usbnet *dev, struct usb_interface *intf)
asix_write_rx_ctl(dev, 0); asix_write_rx_ctl(dev, 0);
/* Get the MAC address */ /* Get the MAC address */
memset(buf, 0, ETH_ALEN);
if ((ret = asix_read_cmd(dev, AX_CMD_READ_NODE_ID, if ((ret = asix_read_cmd(dev, AX_CMD_READ_NODE_ID,
0, 0, ETH_ALEN, buf)) < 0) { 0, 0, ETH_ALEN, buf)) < 0) {
dbg("Failed to read MAC address: %d", ret); dbg("Failed to read MAC address: %d", ret);
goto out2; goto out;
} }
memcpy(dev->net->dev_addr, buf, ETH_ALEN); memcpy(dev->net->dev_addr, buf, ETH_ALEN);
...@@ -1289,12 +1269,10 @@ static int ax88178_bind(struct usbnet *dev, struct usb_interface *intf) ...@@ -1289,12 +1269,10 @@ static int ax88178_bind(struct usbnet *dev, struct usb_interface *intf)
mii_nway_restart(&dev->mii); mii_nway_restart(&dev->mii);
if ((ret = asix_write_medium_mode(dev, AX88178_MEDIUM_DEFAULT)) < 0) if ((ret = asix_write_medium_mode(dev, AX88178_MEDIUM_DEFAULT)) < 0)
goto out2; goto out;
if ((ret = asix_write_rx_ctl(dev, AX_DEFAULT_RX_CTL)) < 0) if ((ret = asix_write_rx_ctl(dev, AX_DEFAULT_RX_CTL)) < 0)
goto out2; goto out;
kfree(buf);
/* Asix framing packs multiple eth frames into a 2K usb bulk transfer */ /* Asix framing packs multiple eth frames into a 2K usb bulk transfer */
if (dev->driver_info->flags & FLAG_FRAMING_AX) { if (dev->driver_info->flags & FLAG_FRAMING_AX) {
...@@ -1302,12 +1280,9 @@ static int ax88178_bind(struct usbnet *dev, struct usb_interface *intf) ...@@ -1302,12 +1280,9 @@ static int ax88178_bind(struct usbnet *dev, struct usb_interface *intf)
jumbo eth frames */ jumbo eth frames */
dev->rx_urb_size = 2048; dev->rx_urb_size = 2048;
} }
return 0; return 0;
out2: out:
kfree(buf);
out1:
return ret; return ret;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment